1package util
  2
  3import (
  4	"strings"
  5	"testing"
  6)
  7
  8func TestTextWrap(t *testing.T) {
  9	cases := []struct {
 10		Input, Output string
 11		Lim           int
 12	}{
 13		// A simple word passes through.
 14		{
 15			"foo",
 16			"foo",
 17			4,
 18		},
 19		// Word breaking
 20		{
 21			"foobarbaz",
 22			"foob\narba\nz",
 23			4,
 24		},
 25		// Lines are broken at whitespace.
 26		{
 27			"foo bar baz",
 28			"foo\nbar\nbaz",
 29			4,
 30		},
 31		// Word breaking
 32		{
 33			"foo bars bazzes",
 34			"foo\nbars\nbazz\nes",
 35			4,
 36		},
 37		// A word that would run beyond the width is wrapped.
 38		{
 39			"fo sop",
 40			"fo\nsop",
 41			4,
 42		},
 43		// A tab counts as 4 characters.
 44		{
 45			"foo\nb\t r\n baz",
 46			"foo\nb\n  r\n baz",
 47			4,
 48		},
 49		// Trailing whitespace is removed after used for wrapping.
 50		// Runs of whitespace on which a line is broken are removed.
 51		{
 52			"foo    \nb   ar   ",
 53			"foo\n\nb\nar\n",
 54			4,
 55		},
 56		// An explicit line break at the end of the input is preserved.
 57		{
 58			"foo bar baz\n",
 59			"foo\nbar\nbaz\n",
 60			4,
 61		},
 62		// Explicit break are always preserved.
 63		{
 64			"\nfoo bar\n\n\nbaz\n",
 65			"\nfoo\nbar\n\n\nbaz\n",
 66			4,
 67		},
 68		// Ignore complete words with terminal color sequence
 69		{
 70			"foo \x1b[31mbar\x1b[0m baz",
 71			"foo\n\x1b[31mbar\x1b[0m\nbaz",
 72			4,
 73		},
 74		// Handle words with colors sequence inside the word
 75		{
 76			"foo b\x1b[31mbar\x1b[0mr baz",
 77			"foo\nb\x1b[31mbar\n\x1b[0mr\nbaz",
 78			4,
 79		},
 80		// Break words with colors sequence inside the word
 81		{
 82			"foo bb\x1b[31mbar\x1b[0mr baz",
 83			"foo\nbb\x1b[31mba\nr\x1b[0mr\nbaz",
 84			4,
 85		},
 86		// Complete example:
 87		{
 88			" This is a list: \n\n\t* foo\n\t* bar\n\n\n\t* baz  \nBAM    ",
 89			" This\nis a\nlist:\n\n\n    *\nfoo\n    *\nbar\n\n\n    *\nbaz\nBAM\n",
 90			6,
 91		},
 92	}
 93
 94	for i, tc := range cases {
 95		actual, lines := TextWrap(tc.Input, tc.Lim)
 96		if actual != tc.Output {
 97			t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%s`\n\nActual Output:\n\n`%s`",
 98				i, tc.Input, tc.Output, actual)
 99		}
100
101		expected := len(strings.Split(tc.Output, "\n"))
102		if expected != lines {
103			t.Fatalf("Case %d Nb lines mismatch\nExpected:%d\nActual:%d",
104				i, expected, lines)
105		}
106	}
107}
108
109func TestWordLen(t *testing.T) {
110	cases := []struct {
111		Input  string
112		Length int
113	}{
114		// A simple word
115		{
116			"foo",
117			3,
118		},
119		// A simple word with colors
120		{
121			"\x1b[31mbar\x1b[0m",
122			3,
123		},
124		// Handle prefix and suffix properly
125		{
126			"foo\x1b[31mfoobarHoy\x1b[0mbaaar",
127			17,
128		},
129	}
130
131	for i, tc := range cases {
132		l := wordLen(tc.Input)
133		if l != tc.Length {
134			t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%d`\n\nActual Output:\n\n`%d`",
135				i, tc.Input, tc.Length, l)
136		}
137	}
138}
139
140func TestSplitWord(t *testing.T) {
141	cases := []struct {
142		Input            string
143		Length           int
144		Result, Leftover string
145	}{
146		// A simple word passes through.
147		{
148			"foo",
149			4,
150			"foo", "",
151		},
152		// Cut at the right place
153		{
154			"foobarHoy",
155			4,
156			"foob", "arHoy",
157		},
158		// A simple word passes through with colors
159		{
160			"\x1b[31mbar\x1b[0m",
161			4,
162			"\x1b[31mbar\x1b[0m", "",
163		},
164		// Cut at the right place with colors
165		{
166			"\x1b[31mfoobarHoy\x1b[0m",
167			4,
168			"\x1b[31mfoob", "arHoy\x1b[0m",
169		},
170		// Handle prefix and suffix properly
171		{
172			"foo\x1b[31mfoobarHoy\x1b[0mbaaar",
173			4,
174			"foo\x1b[31mf", "oobarHoy\x1b[0mbaaar",
175		},
176		// Cut properly with length = 0
177		{
178			"foo",
179			0,
180			"", "foo",
181		},
182	}
183
184	for i, tc := range cases {
185		result, leftover := splitWord(tc.Input, tc.Length)
186		if result != tc.Result || leftover != tc.Leftover {
187			t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%s` - `%s`\n\nActual Output:\n\n`%s` - `%s`",
188				i, tc.Input, tc.Result, tc.Leftover, result, leftover)
189		}
190	}
191}