Коммит 88f1026c создал по автору keewek's avatar keewek
Просмотр файлов

release: v1.0.0

владелец a706ce8c
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package printer
import (
"fmt"
"strings"
"testing"
"github.com/keewek/ansible-pretty-print/src/cmn"
"github.com/keewek/ansible-pretty-print/src/cmn/tst"
"github.com/keewek/ansible-pretty-print/src/processor"
)
func TestNewTablePrinter(t *testing.T) {
wtp := &TablePrinter{
fnChopMarkLine: cmn.ChopMarkLine,
widther: cmn.RunesWidther{},
indentPlay: defaultIndentPlay,
indentTask: defaultIndentTask,
padPlay: strings.Repeat(" ", defaultIndentPlay),
padTask: strings.Repeat(" ", defaultIndentTask),
box: cmn.BoxCharsAscii(),
}
gtp := NewTablePrinter()
want := fmt.Sprintf("%#v", wtp)
got := fmt.Sprintf("%#v", gtp)
tst.DiffError(t, want, got)
}
func Test_TablePrinterSetWidther(t *testing.T) {
w := cmn.MonospaceWidther{}
tp := NewTablePrinter()
tp.SetWidther(w)
want := fmt.Sprintf("%#v", w)
got := fmt.Sprintf("%#v", tp.widther)
tst.DiffError(t, want, got)
}
func Test_TablePrinterSetMaxLineWidth(t *testing.T) {
w := 42
tp := NewTablePrinter()
tp.SetMaxLineWidth(w)
want := w
got := tp.maxLineWidth
tst.DiffError(t, want, got)
}
func Test_TablePrinterSetBoxChars(t *testing.T) {
w := cmn.BoxCharsDos()
tp := NewTablePrinter()
tp.SetBoxChars(w)
want := w
got := tp.box
tst.DiffError(t, want, got)
}
func Test_TablePrinter_makeBorders(t *testing.T) {
t.Run("BoxCharsAscii", func(t *testing.T) {
tests := []struct {
// want []string
top string
middle string
bottom string
width tableWidth
}{
{
top: " +--+--+--+",
middle: " +--+--+--+",
bottom: " +--+--+--+",
width: tableWidth{0, 0, 0}},
{
top: " +---+----+-----+",
middle: " +---+----+-----+",
bottom: " +---+----+-----+",
width: tableWidth{1, 2, 3}},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
tp := NewTablePrinter()
top, middle, bottom := tp.makeBorders(&tt.width)
tst.DiffError(t, tt.top, top)
tst.DiffError(t, tt.middle, middle)
tst.DiffError(t, tt.bottom, bottom)
})
}
})
t.Run("BoxCharsDos", func(t *testing.T) {
tests := []struct {
// want []string
top string
middle string
bottom string
width tableWidth
}{
{
top: " ┌──┬──┬──┐",
middle: " ├──┼──┼──┤",
bottom: " └──┴──┴──┘",
width: tableWidth{0, 0, 0}},
{
top: " ┌───┬────┬─────┐",
middle: " ├───┼────┼─────┤",
bottom: " └───┴────┴─────┘",
width: tableWidth{1, 2, 3}},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
tp := NewTablePrinter()
tp.SetBoxChars(cmn.BoxCharsDos())
top, middle, bottom := tp.makeBorders(&tt.width)
tst.DiffError(t, tt.top, top)
tst.DiffError(t, tt.middle, middle)
tst.DiffError(t, tt.bottom, bottom)
})
}
})
}
func Test_TablePrinter_fitTable(t *testing.T) {
tests := []struct {
stats *processor.Stats
maxLineWidth int
want *tableWidth
}{
{
stats: &processor.Stats{},
maxLineWidth: 80,
want: &tableWidth{block: 5, name: 4, tags: 4},
},
{
stats: &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 20,
LongestTaskTagsLength: 30,
},
maxLineWidth: 60,
want: &tableWidth{block: 10, name: 20, tags: 14},
},
{
stats: &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 20,
LongestTaskTagsLength: 30,
},
maxLineWidth: 30,
want: &tableWidth{block: 6, name: 4, tags: 4},
},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
tp := NewTablePrinter()
tp.SetMaxLineWidth(tt.maxLineWidth)
tw := tp.fitTable(tt.stats)
want := tst.ReprValue(tt.want) // fmt.Sprintf("%#v", tt.want)
got := tst.ReprValue(tw) // fmt.Sprintf("%#v", tw)
tst.DiffError(t, want, got)
})
}
}
func Test_TablePrinter_printLine(t *testing.T) {
tests := []struct {
maxLineWidth int
value string
want string
}{
{0, "12345", "\n"},
{80, "12345", "12345\n"},
{4, "12345", "123▒\n"},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
var lb cmn.LineBuilder
tp := NewTablePrinter()
tp.SetMaxLineWidth(tt.maxLineWidth)
tp.printLine(&lb, tt.value)
got := lb.String()
tst.DiffError(t, tt.want, got)
})
}
}
func Test_TablePrinter_printTable(t *testing.T) {
t.Run("BoxCharsAscii", func(t *testing.T) {
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{},
}
stats := &processor.Stats{}
maxLineWidth := 80
want.WriteLine(" +-------+------+------+")
want.WriteLine(" | Block | Name | Tags |")
want.WriteLine(" +-------+------+------+")
want.WriteLine(" +-------+------+------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{{}},
}
stats := &processor.Stats{}
maxLineWidth := 80
want.WriteLine(" +-------+------+------+")
want.WriteLine(" | Block | Name | Tags |")
want.WriteLine(" +-------+------+------+")
want.WriteLine(" | | | |")
want.WriteLine(" +-------+------+------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{
Block: "0123456789",
Name: "0123456789",
Tags: "0123456789",
},
{
Block: "ABCDEFGHIJ",
Name: "ABCDEFGHIJ",
Tags: "ABCDEFGHIJ",
},
},
}
stats := &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
}
maxLineWidth := 80
want.WriteLine(" +------------+------------+------------+")
want.WriteLine(" | Block | Name | Tags |")
want.WriteLine(" +------------+------------+------------+")
want.WriteLine(" | 0123456789 | 0123456789 | 0123456789 |")
want.WriteLine(" | ABCDEFGHIJ | ABCDEFGHIJ | ABCDEFGHIJ |")
want.WriteLine(" +------------+------------+------------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{
Block: "0123456789",
Name: "0123456789",
Tags: "0123456789",
},
{
Block: "ABCDEFGHIJ",
Name: "ABCDEFGHIJ",
Tags: "ABCDEFGHIJ",
},
},
}
stats := &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
}
maxLineWidth := 40
want.WriteLine(" +------------+------------+------+")
want.WriteLine(" | Block | Name | Tags |")
want.WriteLine(" +------------+------------+------+")
want.WriteLine(" | 0123456789 | 0123456789 | 012▒ |")
want.WriteLine(" | ABCDEFGHIJ | ABCDEFGHIJ | ABC▒ |")
want.WriteLine(" +------------+------------+------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{
Block: "0123456789",
Name: "0123456789",
Tags: "0123456789",
},
{
Block: "ABCDEFGHIJ",
Name: "ABCDEFGHIJ",
Tags: "ABCDEFGHIJ",
},
},
}
stats := &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
}
maxLineWidth := 30
want.WriteLine(" +--------+------+------+")
want.WriteLine(" | Block | Name | Tags |")
want.WriteLine(" +--------+------+------+")
want.WriteLine(" | 01234▒ | 012▒ | 012▒ |")
want.WriteLine(" | ABCDE▒ | ABC▒ | ABC▒ |")
want.WriteLine(" +--------+------+------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
})
t.Run("BoxCharsDos", func(t *testing.T) {
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{},
}
stats := &processor.Stats{}
maxLineWidth := 80
want.WriteLine(" ┌───────┬──────┬──────┐")
want.WriteLine(" │ Block │ Name │ Tags │")
want.WriteLine(" ├───────┼──────┼──────┤")
want.WriteLine(" └───────┴──────┴──────┘")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.SetBoxChars(cmn.BoxCharsDos())
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{{}},
}
stats := &processor.Stats{}
maxLineWidth := 80
want.WriteLine(" ┌───────┬──────┬──────┐")
want.WriteLine(" │ Block │ Name │ Tags │")
want.WriteLine(" ├───────┼──────┼──────┤")
want.WriteLine(" │ │ │ │")
want.WriteLine(" └───────┴──────┴──────┘")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.SetBoxChars(cmn.BoxCharsDos())
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{
Block: "0123456789",
Name: "0123456789",
Tags: "0123456789",
},
{
Block: "ABCDEFGHIJ",
Name: "ABCDEFGHIJ",
Tags: "ABCDEFGHIJ",
},
},
}
stats := &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
}
maxLineWidth := 80
want.WriteLine(" ┌────────────┬────────────┬────────────┐")
want.WriteLine(" │ Block │ Name │ Tags │")
want.WriteLine(" ├────────────┼────────────┼────────────┤")
want.WriteLine(" │ 0123456789 │ 0123456789 │ 0123456789 │")
want.WriteLine(" │ ABCDEFGHIJ │ ABCDEFGHIJ │ ABCDEFGHIJ │")
want.WriteLine(" └────────────┴────────────┴────────────┘")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.SetBoxChars(cmn.BoxCharsDos())
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{
Block: "0123456789",
Name: "0123456789",
Tags: "0123456789",
},
{
Block: "ABCDEFGHIJ",
Name: "ABCDEFGHIJ",
Tags: "ABCDEFGHIJ",
},
},
}
stats := &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
}
maxLineWidth := 40
want.WriteLine(" ┌────────────┬────────────┬──────┐")
want.WriteLine(" │ Block │ Name │ Tags │")
want.WriteLine(" ├────────────┼────────────┼──────┤")
want.WriteLine(" │ 0123456789 │ 0123456789 │ 012▒ │")
want.WriteLine(" │ ABCDEFGHIJ │ ABCDEFGHIJ │ ABC▒ │")
want.WriteLine(" └────────────┴────────────┴──────┘")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.SetBoxChars(cmn.BoxCharsDos())
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
t.Run("", func(t *testing.T) {
var out, want cmn.LineBuilder
tasks := &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{
Block: "0123456789",
Name: "0123456789",
Tags: "0123456789",
},
{
Block: "ABCDEFGHIJ",
Name: "ABCDEFGHIJ",
Tags: "ABCDEFGHIJ",
},
},
}
stats := &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
}
maxLineWidth := 30
want.WriteLine(" ┌────────┬──────┬──────┐")
want.WriteLine(" │ Block │ Name │ Tags │")
want.WriteLine(" ├────────┼──────┼──────┤")
want.WriteLine(" │ 01234▒ │ 012▒ │ 012▒ │")
want.WriteLine(" │ ABCDE▒ │ ABC▒ │ ABC▒ │")
want.WriteLine(" └────────┴──────┴──────┘")
tp := NewTablePrinter()
tp.SetMaxLineWidth(maxLineWidth)
tp.SetBoxChars(cmn.BoxCharsDos())
tp.printTable(&out, tasks, stats)
tst.DiffError(t, want.String(), out.String())
})
})
}
func Test_TablePrinterPrintTo(t *testing.T) {
t.Run("row is fmt.Stringer", func(t *testing.T) {
t.Run("maxLineWidth is 0", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: blockquote("Indent 0")},
{Indent: 2, Data: blockquote("Indent 2")},
},
Stats: &processor.Stats{},
}
var lb, out cmn.LineBuilder
lb.WriteLine("")
lb.WriteLine("")
tp := NewTablePrinter()
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
})
t.Run("maxLineWidth is 5", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: blockquote("Indent 0")},
{Indent: 2, Data: blockquote("Indent 2")},
},
Stats: &processor.Stats{},
}
var lb, out cmn.LineBuilder
lb.WriteLine("| In▒")
lb.WriteLine("| In▒")
tp := NewTablePrinter()
tp.SetMaxLineWidth(5)
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
})
})
t.Run("row is processor.Play", func(t *testing.T) {
t.Run("maxLineWidth is 0", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: &processor.Play{Name: "play #1 (demo): Demo play", Tags: "[p1, demo]"}},
{Indent: 0, Data: &processor.Play{Name: "play #2 (demo): Demo play", Tags: "[p2, demo]"}},
},
Stats: &processor.Stats{},
}
var lb, out cmn.LineBuilder
lb.WriteLine("")
lb.WriteLine("")
tp := NewTablePrinter()
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
})
t.Run("maxLineWidth is 30", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: &processor.Play{Name: "play #1 (demo): Demo play", Tags: "[p1, demo]"}},
{Indent: 0, Data: &processor.Play{Name: "play #2 (demo): Demo play", Tags: "[p2, demo]"}},
},
Stats: &processor.Stats{},
}
var lb, out cmn.LineBuilder
lb.WriteLine(" play #1 (demo): Demo play ▒")
lb.WriteLine(" play #2 (demo): Demo play ▒")
tp := NewTablePrinter()
tp.maxLineWidth = 30
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
})
})
t.Run("row is processor.Tasks", func(t *testing.T) {
t.Run("maxLineWidth is 0", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{Block: "0123456789", Name: "0123456789", Tags: "0123456789"},
{Block: "ABCDEFGHIJ", Name: "ABCDEFGHIJ", Tags: "ABCDEFGHIJ"},
},
}},
},
Stats: &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
},
}
var lb, out cmn.LineBuilder
lb.WriteLine("")
lb.WriteLine("")
lb.WriteLine("")
lb.WriteLine("")
lb.WriteLine("")
lb.WriteLine("")
tp := NewTablePrinter()
tp.SetMaxLineWidth(0)
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
})
t.Run("maxLineWidth is 30", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{Block: "0123456789", Name: "0123456789", Tags: "0123456789"},
{Block: "ABCDEFGHIJ", Name: "ABCDEFGHIJ", Tags: "ABCDEFGHIJ"},
},
}},
},
Stats: &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
},
}
var lb, out cmn.LineBuilder
lb.WriteLine(" +--------+------+------+")
lb.WriteLine(" | Block | Name | Tags |")
lb.WriteLine(" +--------+------+------+")
lb.WriteLine(" | 01234▒ | 012▒ | 012▒ |")
lb.WriteLine(" | ABCDE▒ | ABC▒ | ABC▒ |")
lb.WriteLine(" +--------+------+------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(30)
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
})
})
t.Run("mixed rows", func(t *testing.T) {
// t.Run("maxLineWidth is 30", func(t *testing.T) {
r := processor.Result{
Rows: []*processor.Row{
{Indent: 0, Data: processor.Passthru("Passthru")},
{Indent: 0, Data: &processor.Play{Name: "play #1 (demo): Demo play", Tags: "[p1, demo]"}},
{Indent: 0, Data: blockquote(" blockquote")},
{Indent: 0, Data: &processor.Tasks{
PlayNumber: 1,
Tasks: []*processor.Task{
{Block: "0123456789", Name: "0123456789", Tags: "0123456789"},
{Block: "ABCDEFGHIJ", Name: "ABCDEFGHIJ", Tags: "ABCDEFGHIJ"},
},
}},
},
Stats: &processor.Stats{
LongestTaskBlockLength: 10,
LongestTaskNameLength: 10,
LongestTaskTagsLength: 10,
},
}
var lb, out cmn.LineBuilder
lb.WriteLine("Passthru")
lb.WriteLine(" play #1 (demo): Demo play ▒")
lb.WriteLine("| blockquote")
lb.WriteLine(" +--------+------+------+")
lb.WriteLine(" | Block | Name | Tags |")
lb.WriteLine(" +--------+------+------+")
lb.WriteLine(" | 01234▒ | 012▒ | 012▒ |")
lb.WriteLine(" | ABCDE▒ | ABC▒ | ABC▒ |")
lb.WriteLine(" +--------+------+------+")
tp := NewTablePrinter()
tp.SetMaxLineWidth(30)
tp.PrintTo(&out, &r)
want := lb.String()
got := out.String()
tst.DiffError(t, want, got)
// })
})
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
type Passthru string
func (p Passthru) String() string {
return string(p)
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func Test_Passthru(t *testing.T) {
p := Passthru(" \t123 \n")
t.Run("Implements Stringer interface", func(t *testing.T) {
got := p.String()
want := " \t123 \n"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import "fmt"
type Play struct {
Name string
Tags string
}
func (pl *Play) Description() string {
return pl.Name
}
func (pl *Play) String() string {
return fmt.Sprintf("%s TAGS: %s", pl.Name, pl.Tags)
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func Test_Play(t *testing.T) {
p := &Play{Name: "Name", Tags: "Tags"}
t.Run("Implements 'Stringer' interface", func(t *testing.T) {
got := p.String()
want := "Name TAGS: Tags"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("Description(): returns 'Name' field", func(t *testing.T) {
got := p.Description()
want := "Name"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"bufio"
"errors"
"fmt"
"strings"
"github.com/keewek/ansible-pretty-print/src/cmn"
)
type Row struct {
Indent int // TODO: ATM `Indent` is a deadweight.
Data fmt.Stringer // Drop it or implement indent detection
}
type Result struct {
Rows []*Row
Stats *Stats
}
func processPlay(line string) (*Play, error) {
pair := strings.Split(strings.TrimSpace(line), "TAGS:")
if len(pair) == 2 {
name := strings.TrimSpace(pair[0])
tags := strings.TrimSpace(pair[1])
return &Play{
Name: name,
Tags: tags,
}, nil
}
return nil, errors.New("processor.processPlay: unexpected play format")
}
func processTask(line string) (*Task, error) {
pair := strings.Split(strings.TrimSpace(line), "TAGS:")
if len(pair) == 2 {
block := ""
name := strings.TrimSpace(pair[0])
tags := strings.TrimSpace(pair[1])
pair = strings.SplitN(strings.TrimSpace(name), ":", 2)
if len(pair) == 2 {
block = strings.TrimSpace(pair[0])
name = strings.TrimSpace(pair[1])
}
return &Task{
Block: block,
Name: name,
Tags: tags,
}, nil
}
return nil, errors.New("processor.processTask: unexpected task format")
}
// func calcIndent(line string) int {
// size := len(line)
// indent := 0
// for i := 0; i < size; i++ {
// if line[i] != ' ' {
// break
// }
// indent++
// }
// return indent
// }
func ProcessLines(scanner *bufio.Scanner, widther cmn.Widther) (*Result, error) {
var tasks *Tasks
rows := make([]*Row, 0, 2)
stats := &Stats{Widther: widther}
playsCount := 0
isProcessTasks := false
for scanner.Scan() {
line := scanner.Text()
// indent := calcIndent(line)
if strings.HasPrefix(line, " play") {
playsCount++
play, err := processPlay(line)
if err != nil {
return nil, err
}
rows = append(rows, &Row{Indent: 2, Data: play})
stats.updateWithPlay(play)
continue
} else if strings.HasPrefix(line, " tasks") {
isProcessTasks = true
tasks = &Tasks{PlayNumber: playsCount}
rows = append(rows, &Row{Data: Passthru(line)})
rows = append(rows, &Row{6, tasks})
continue
} else if isProcessTasks {
if strings.HasPrefix(line, " ") {
task, err := processTask(line)
if err != nil {
return nil, err
}
tasks.Add(task)
stats.updateWithTask(task)
continue
} else {
isProcessTasks = false
}
}
rows = append(rows, &Row{Data: Passthru(line)})
}
result := &Result{rows, stats}
return result, scanner.Err()
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"bufio"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/keewek/ansible-pretty-print/src/cmn"
)
func Test_processPlay(t *testing.T) {
t.Run("Returns 'Play' struct", func(t *testing.T) {
tests := []struct {
input string
want *Play
}{{
input: "play #1 (vps1): Test TAGS: []",
want: &Play{"play #1 (vps1): Test", "[]"},
}, {
input: "play #1 (vps1): Test TAGS:",
want: &Play{"play #1 (vps1): Test", ""},
}, {
input: " play #1 (vps1): TestTAGS: [tag1, tag2] ",
want: &Play{"play #1 (vps1): Test", "[tag1, tag2]"},
}, {
input: "TAGS:",
want: &Play{},
}}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
got, err := processPlay(tt.input)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
}
})
t.Run("Returns error upon unexpected format", func(t *testing.T) {
tests := []struct {
input string
want *Play
}{{
input: " play #1 (vps1): Test TAG: [tag1, tag2] ",
want: nil,
}}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
got, err := processPlay(tt.input)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
if err == nil {
t.Errorf("expected an error")
}
})
}
})
}
func Test_processTask(t *testing.T) {
t.Run("Returns 'Task' struct", func(t *testing.T) {
tests := []struct {
input string
want *Task
}{{
input: "Block: Name TAGS: [♪, ♪♪, ♪♪♪]",
want: &Task{"Block", "Name", "[♪, ♪♪, ♪♪♪]"},
}, {
input: "Block NameTAGS: [♪,♪♪,♪♪♪]",
want: &Task{"", "Block Name", "[♪,♪♪,♪♪♪]"},
}, {
input: "Block NameTAGS:",
want: &Task{"", "Block Name", ""},
}, {
input: "TAGS:",
want: &Task{},
}}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
got, err := processTask(tt.input)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
}
})
t.Run("Returns error upon unexpected format", func(t *testing.T) {
tests := []struct {
input string
want *Task
}{{
input: " play #1 (vps1): Test TAG: [tag1, tag2] ",
want: nil,
}}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
got, err := processTask(tt.input)
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
if err == nil {
t.Errorf("expected an error")
}
})
}
})
}
func TestProcessLines(t *testing.T) {
t.Run("Returns 'Result' struct", func(t *testing.T) {
var ll cmn.LineBuilder
ll.WriteLine("playbook: playbooks/vsp/playbook_vps.yml")
ll.WriteLine("")
ll.WriteLine(" play #1 (vps): Test TAGS: []")
ll.WriteLine(" tasks:")
ll.WriteLine(" Block: Name TAGS: [Tag1, Tag2]")
ll.WriteLine(" Gather the package facts TAGS: [apt, facts, vars]")
ll.WriteLine("")
ll.WriteLine(" play #2 (vps): Demo 2 TAGS: []")
ll.WriteLine(" tasks:")
ll.WriteLine(" Task 2.1 TAGS: []")
ll.WriteLine(" Task 2.2 TAGS: []")
want := &Result{
[]*Row{
{0, Passthru("playbook: playbooks/vsp/playbook_vps.yml")},
{0, Passthru("")},
{2, &Play{"play #1 (vps): Test", "[]"}},
{0, Passthru(" tasks:")},
{6, &Tasks{1, []*Task{
{"Block", "Name", "[Tag1, Tag2]"},
{"", "Gather the package facts", "[apt, facts, vars]"},
}}},
{0, Passthru("")},
{2, &Play{"play #2 (vps): Demo 2", "[]"}},
{0, Passthru(" tasks:")},
{6, &Tasks{2, []*Task{
{"", "Task 2.1", "[]"},
{"", "Task 2.2", "[]"},
}}},
},
&Stats{
Widther: cmn.RunesWidther{},
LongestPlayDescription: "play #2 (vps): Demo 2",
LongestPlayDescriptionLength: 21,
LongestPlayTags: "[]",
LongestPlayTagsLength: 2,
LongestTaskBlock: "Block",
LongestTaskBlockLength: 5,
LongestTaskName: "Gather the package facts",
LongestTaskNameLength: 24,
LongestTaskDescription: "Gather the package facts",
LongestTaskDescriptionLength: 24,
LongestTaskTags: "[apt, facts, vars]",
LongestTaskTagsLength: 18,
},
}
scanner := bufio.NewScanner(strings.NewReader(ll.String()))
got, err := ProcessLines(scanner, cmn.RunesWidther{})
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("Returns error upon unexpected play format", func(t *testing.T) {
var ll cmn.LineBuilder
var want *Result
ll.WriteLine("playbook: playbooks/vsp/playbook_vps.yml")
ll.WriteLine("")
ll.WriteLine(" play #1 (vps): Test TAG: []")
ll.WriteLine(" tasks:")
ll.WriteLine(" Block: Name TAGS: [Tag1, Tag2]")
ll.WriteLine(" Gather the package facts TAGS: [apt, facts, vars]")
scanner := bufio.NewScanner(strings.NewReader(ll.String()))
got, err := ProcessLines(scanner, cmn.RunesWidther{})
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
if err == nil {
t.Errorf("expected an error")
}
})
t.Run("Returns error upon unexpected task format", func(t *testing.T) {
var ll cmn.LineBuilder
var want *Result
ll.WriteLine("playbook: playbooks/vsp/playbook_vps.yml")
ll.WriteLine("")
ll.WriteLine(" play #1 (vps): Test TAGS: []")
ll.WriteLine(" tasks:")
ll.WriteLine(" Block: Name TAG: [Tag1, Tag2]")
ll.WriteLine(" Gather the package facts TAGS: [apt, facts, vars]")
scanner := bufio.NewScanner(strings.NewReader(ll.String()))
got, err := ProcessLines(scanner, cmn.RunesWidther{})
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
if err == nil {
t.Errorf("expected an error")
}
})
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"fmt"
"io"
"os"
"reflect"
"unicode/utf8"
"github.com/keewek/ansible-pretty-print/src/cmn"
)
type Stats struct {
Widther cmn.Widther
LongestPlayDescription string
LongestPlayDescriptionLength int
LongestPlayTags string
LongestPlayTagsLength int
LongestTaskBlock string
LongestTaskBlockLength int
LongestTaskName string
LongestTaskNameLength int
LongestTaskDescription string
LongestTaskDescriptionLength int
LongestTaskTags string
LongestTaskTagsLength int
}
func (st *Stats) updatePlayDescription(value string) {
descriptionLength := st.Widther.Width(value)
if st.LongestPlayDescriptionLength < descriptionLength {
st.LongestPlayDescriptionLength = descriptionLength
st.LongestPlayDescription = value
}
}
func (st *Stats) updatePlayTags(value string) {
tagsLength := st.Widther.Width(value)
if st.LongestPlayTagsLength < tagsLength {
st.LongestPlayTagsLength = tagsLength
st.LongestPlayTags = value
}
}
func (st *Stats) updateTaskBlock(value string) {
blockLength := st.Widther.Width(value)
if st.LongestTaskBlockLength < blockLength {
st.LongestTaskBlockLength = blockLength
st.LongestTaskBlock = value
}
}
func (st *Stats) updateTaskName(value string) {
nameLength := st.Widther.Width(value)
if st.LongestTaskNameLength < nameLength {
st.LongestTaskNameLength = nameLength
st.LongestTaskName = value
}
}
func (st *Stats) updateTaskDescription(value string) {
descriptionLength := st.Widther.Width(value)
if st.LongestTaskDescriptionLength < descriptionLength {
st.LongestTaskDescriptionLength = descriptionLength
st.LongestTaskDescription = value
}
}
func (st *Stats) updateTaskTags(value string) {
tagsLength := st.Widther.Width(value)
if st.LongestTaskTagsLength < tagsLength {
st.LongestTaskTagsLength = tagsLength
st.LongestTaskTags = value
}
}
func (st *Stats) updateWithPlay(pl *Play) {
st.updatePlayDescription(pl.Description())
st.updatePlayTags(pl.Tags)
}
func (st *Stats) updateWithTask(t *Task) {
st.updateTaskBlock(t.Block)
st.updateTaskName(t.Name)
st.updateTaskDescription(t.Description())
st.updateTaskTags(t.Tags)
}
func (st *Stats) Lines() []string {
type field struct {
Index int
Name string
}
ft := reflect.TypeOf(*st)
numField := ft.NumField()
sv := reflect.ValueOf(*st)
fields := make([]field, 0, numField)
lines := make([]string, 0, numField)
maxLen := 0
for i := 0; i < numField; i++ {
curField := ft.Field(i)
if curField.Name == "Widther" {
continue
}
fields = append(fields, field{i, curField.Name})
if fl := utf8.RuneCountInString(curField.Name); fl > maxLen {
maxLen = fl
}
}
for _, field := range fields {
lines = append(lines, fmt.Sprintf("%*s: %v", maxLen, field.Name, sv.Field(field.Index)))
}
return lines
}
func (st *Stats) PrintTo(w io.Writer) {
// var fnPrint func(string)
// if lw, ok := w.(cmn.LineWriter); ok {
// fnPrint = func(s string) {
// lw.WriteLine(s)
// }
// } else {
// fnPrint = func(s string) {
// fmt.Fprintln(w, s)
// }
// }
for _, line := range st.Lines() {
// fnPrint(line)
fmt.Fprintln(w, line)
}
}
func (st *Stats) Print() {
st.PrintTo(os.Stdout)
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/keewek/ansible-pretty-print/src/cmn"
)
func Test_Stats(t *testing.T) {
// s := &Stats{}
t.Run("updatePlayDescription():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestPlayDescription: "♪♪♪",
LongestPlayDescriptionLength: 3,
}
got.updatePlayDescription("♪♪♪")
got.updatePlayDescription("♪♪")
got.updatePlayDescription("♪")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updatePlayTags():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestPlayTags: "♪♪♪",
LongestPlayTagsLength: 3,
}
got.updatePlayTags("♪♪♪")
got.updatePlayTags("♪♪")
got.updatePlayTags("♪")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updateBlock():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestTaskBlock: "♪♪♪",
LongestTaskBlockLength: 3,
}
got.updateTaskBlock("♪♪♪")
got.updateTaskBlock("♪♪")
got.updateTaskBlock("♪")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updateName():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestTaskName: "♪♪♪",
LongestTaskNameLength: 3,
}
got.updateTaskName("♪♪♪")
got.updateTaskName("♪♪")
got.updateTaskName("♪")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updateTaskDescription():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestTaskDescription: "♪♪♪",
LongestTaskDescriptionLength: 3,
}
got.updateTaskDescription("♪♪♪")
got.updateTaskDescription("♪♪")
got.updateTaskDescription("♪")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updateTaskTags():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestTaskTags: "♪♪♪",
LongestTaskTagsLength: 3,
}
got.updateTaskTags("♪♪♪")
got.updateTaskTags("♪♪")
got.updateTaskTags("♪")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updateWithPlay():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestPlayDescription: "♪♪♪ Name ♪♪♪",
LongestPlayDescriptionLength: 12,
LongestPlayTags: "♪♪♪ Tags ♪♪♪",
LongestPlayTagsLength: 12,
}
got.updateWithPlay(&Play{"♪♪♪ Name ♪♪♪", "♪♪♪ Tags ♪♪♪"})
got.updateWithPlay(&Play{"♪♪ Name ♪♪", "♪♪ Tags ♪♪"})
got.updateWithPlay(&Play{"♪ Name ♪", "♪ Tags ♪"})
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("updateWithTask():", func(t *testing.T) {
got := Stats{Widther: cmn.RunesWidther{}}
want := Stats{
Widther: cmn.RunesWidther{},
LongestTaskBlock: "♪♪♪ Block ♪♪♪",
LongestTaskBlockLength: 13,
LongestTaskName: "♪♪♪ Name ♪♪♪",
LongestTaskNameLength: 12,
LongestTaskDescription: "♪♪♪ Block ♪♪♪: ♪♪♪ Name ♪♪♪",
LongestTaskDescriptionLength: 27,
LongestTaskTags: "♪♪♪ Tags ♪♪♪",
LongestTaskTagsLength: 12,
}
got.updateWithTask(&Task{"♪♪♪ Block ♪♪♪", "♪♪♪ Name ♪♪♪", "♪♪♪ Tags ♪♪♪"})
got.updateWithTask(&Task{"♪♪ Block ♪♪", "♪♪ Name ♪♪", "♪♪ Tags ♪♪"})
got.updateWithTask(&Task{"♪ Block ♪", "♪ Name ♪", "♪ Tags ♪"})
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import "fmt"
type Task struct {
Block string
Name string
Tags string
}
func (t *Task) Description() string {
var description string
if t.Block == "" {
description = t.Name
} else {
description = t.Block + ": " + t.Name
}
return description
}
func (t *Task) String() string {
return fmt.Sprintf("%s TAGS: %s", t.Description(), t.Tags)
}
// ---
type Tasks struct {
PlayNumber int
Tasks []*Task
}
func (ts *Tasks) String() string {
return fmt.Sprintf("[Play #%d - Tasks]", ts.PlayNumber)
}
func (ts *Tasks) Add(t *Task) {
ts.Tasks = append(ts.Tasks, t)
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package processor
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func Test_Task(t *testing.T) {
task := &Task{Block: "Block", Name: "Name", Tags: "Tags"}
t.Run("Implements 'Stringer' interface", func(t *testing.T) {
got := task.String()
want := "Block: Name TAGS: Tags"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("Description(): returns 'Name' field when 'Block' field is empty", func(t *testing.T) {
task := &Task{Block: "", Name: "Name", Tags: "Tags"}
got := task.Description()
want := "Name"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
t.Run("Description(): returns a join of 'Block' and 'Name' fields when 'Block' field is not empty", func(t *testing.T) {
task := &Task{Block: "Block", Name: "Name", Tags: "Tags"}
got := task.Description()
want := "Block: Name"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got): \n%s", diff)
}
})
}
func Test_Tasks(t *testing.T) {
items := []*Task{
{Block: "Block_1", Name: "Name_1", Tags: "Tags_1"},
{Block: "Block_2", Name: "Name_2", Tags: "Tags_2"},
{Block: "Block_3", Name: "Name_3", Tags: "Tags_3"},
}
task04 := &Task{Block: "Block_4", Name: "Name_4", Tags: "Tags_4"}
tasks := &Tasks{PlayNumber: 42, Tasks: items}
t.Run("Implements 'Stringer' interface", func(t *testing.T) {
got := tasks.String()
want := "[Play #42 - Tasks]"
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Play.String() mismatch (-want +got): \n%s", diff)
}
})
t.Run("Add(): adds task", func(t *testing.T) {
want := make([]*Task, len(items))
copy(want, items)
want = append(want, task04)
tasks.Add(task04)
got := tasks.Tasks
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("Play.String() mismatch (-want +got): \n%s", diff)
}
})
}
+-----------------------+
| 1 |
| 12 |
| Hello world |
| Всем привет |
| 你好世界 |
+-----------------------+
+-------------+
| 1 |
| 12 |
| Hello world |
| Всем привет |
| 你好世界 |
+-------------+
+-------------+
| 1 |
| 12 |
| Hello world |
| Всем привет |
| 你好世界 |
+-------------+
┌───────────────────────┐
│ 1 │
│ 12 │
│ Hello world │
│ Всем привет │
│ 你好世界 │
└───────────────────────┘
┌─────────────┐
│ 1 │
│ 12 │
│ Hello world │
│ Всем привет │
│ 你好世界 │
└─────────────┘
┌─────────────┐
│ 1 │
│ 12 │
│ Hello world │
│ Всем привет │
│ 你好世界 │
└─────────────┘
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package ui
import (
"fmt"
"io"
"os"
"strings"
"github.com/keewek/ansible-pretty-print/src/cmn"
)
var (
Box cmn.BoxChars = cmn.BoxCharsAscii()
FnWidth cmn.WidthFunc = cmn.WidthRunes
)
func MsgBoxFunc(w io.Writer, input []string, box *cmn.BoxChars, fnWidth cmn.WidthFunc) {
padding := 1
maxLen := 0
borderLen := 0
for _, item := range input {
itemLen := fnWidth(item)
if itemLen > maxLen {
maxLen = itemLen
}
}
borderLen = maxLen + padding*2
border := strings.Repeat(box.Hor, borderLen)
pad := strings.Repeat(" ", padding)
fmt.Fprint(w, box.CornerTL, border, box.CornerTR, "\n")
for _, item := range input {
val := cmn.PadRightFunc(item, ' ', maxLen, fnWidth)
fmt.Fprint(w, box.Ver, pad, val, pad, box.Ver, "\n")
}
fmt.Fprint(w, box.CornerBL, border, box.CornerBR, "\n")
}
func MsgBoxTo(output io.Writer, input []string) {
MsgBoxFunc(output, input, &Box, FnWidth)
}
func MsgBox(input []string) {
MsgBoxFunc(os.Stdout, input, &Box, FnWidth)
}
// SPDX-FileCopyrightText: 2023 Alexander Bugrov <abugrov+dev@gmail.com>
//
// SPDX-License-Identifier: MIT
package ui
import (
"os"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/keewek/ansible-pretty-print/src/cmn"
)
func TestMsgBoxFunc(t *testing.T) {
data := []string{
"1",
"12",
"Hello world",
"Всем привет",
"你好世界",
}
t.Run("BoxCharsAscii", func(t *testing.T) {
asciiBytes, err := os.ReadFile("testdata/ascii_bytes.txt")
if err != nil {
t.Fatal(err)
}
asciiRunes, err := os.ReadFile("testdata/ascii_runes.txt")
if err != nil {
t.Fatal(err)
}
asciiMonospace, err := os.ReadFile("testdata/ascii_monospace.txt")
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
want string
fnWidth cmn.WidthFunc
}{
{"WidthBytes", string(asciiBytes), cmn.WidthBytes},
{"WidthRunes", string(asciiRunes), cmn.WidthRunes},
{"WidthMonospace", string(asciiMonospace), cmn.WidthMonospace},
}
var b cmn.LineBuilder
box := cmn.BoxCharsAscii()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b.Reset()
MsgBoxFunc(&b, data, &box, tt.fnWidth)
got := b.String()
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Logf("-want: \n%v\n", tt.want)
t.Logf("-got: \n%v\n", got)
t.Errorf("(-want +got): \n%s", diff)
}
})
}
})
t.Run("BoxCharsDos", func(t *testing.T) {
dosBytes, err := os.ReadFile("testdata/dos_bytes.txt")
if err != nil {
t.Fatal(err)
}
dosRunes, err := os.ReadFile("testdata/dos_runes.txt")
if err != nil {
t.Fatal(err)
}
dosMonospace, err := os.ReadFile("testdata/dos_monospace.txt")
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
want string
fnWidth cmn.WidthFunc
}{
{"WidthBytes", string(dosBytes), cmn.WidthBytes},
{"WidthRunes", string(dosRunes), cmn.WidthRunes},
{"WidthMonospace", string(dosMonospace), cmn.WidthMonospace},
}
var b cmn.LineBuilder
box := cmn.BoxCharsDos()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b.Reset()
MsgBoxFunc(&b, data, &box, tt.fnWidth)
got := b.String()
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Logf("-want: \n%v\n", tt.want)
t.Logf("-got: \n%v\n", got)
t.Errorf("(-want +got): \n%s", diff)
}
})
}
})
}
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать