text_test.go

  1package text
  2
  3import (
  4	"strings"
  5	"testing"
  6)
  7
  8func TestWrap(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		// Handle chinese
 93		{
 94			"婞一枳郲逴靲屮蜧曀殳,掫乇峔掮傎溒兀緉冘仜。",
 95			"婞一枳郲逴靲屮蜧曀殳,掫\n乇峔掮傎溒兀緉冘仜。",
 96			12,
 97		},
 98		// Handle chinese with colors
 99		{
100			"婞一枳郲逴\x1b[31m靲屮蜧曀殳,掫乇峔掮傎溒\x1b[0m兀緉冘仜。",
101			"婞一枳郲逴\x1b[31m靲屮蜧曀殳,掫\n乇峔掮傎溒\x1b[0m兀緉冘仜。",
102			12,
103		},
104	}
105
106	for i, tc := range cases {
107		actual, lines := Wrap(tc.Input, tc.Lim)
108		if actual != tc.Output {
109			t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%s`\n\nActual Output:\n\n`%s`",
110				i, tc.Input, tc.Output, actual)
111		}
112
113		expected := len(strings.Split(tc.Output, "\n"))
114		if expected != lines {
115			t.Fatalf("Case %d Nb lines mismatch\nExpected:%d\nActual:%d",
116				i, expected, lines)
117		}
118	}
119}
120
121func TestWordLen(t *testing.T) {
122	cases := []struct {
123		Input  string
124		Length int
125	}{
126		// A simple word
127		{
128			"foo",
129			3,
130		},
131		// A simple word with colors
132		{
133			"\x1b[31mbar\x1b[0m",
134			3,
135		},
136		// Handle prefix and suffix properly
137		{
138			"foo\x1b[31mfoobarHoy\x1b[0mbaaar",
139			17,
140		},
141		// Handle chinese
142		{
143			"快檢什麼望對",
144			6,
145		},
146		// Handle chinese with colors
147		{
148			"快\x1b[31m檢什麼\x1b[0m望對",
149			6,
150		},
151	}
152
153	for i, tc := range cases {
154		l := wordLen(tc.Input)
155		if l != tc.Length {
156			t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%d`\n\nActual Output:\n\n`%d`",
157				i, tc.Input, tc.Length, l)
158		}
159	}
160}
161
162func TestSplitWord(t *testing.T) {
163	cases := []struct {
164		Input            string
165		Length           int
166		Result, Leftover string
167	}{
168		// A simple word passes through.
169		{
170			"foo",
171			4,
172			"foo", "",
173		},
174		// Cut at the right place
175		{
176			"foobarHoy",
177			4,
178			"foob", "arHoy",
179		},
180		// A simple word passes through with colors
181		{
182			"\x1b[31mbar\x1b[0m",
183			4,
184			"\x1b[31mbar\x1b[0m", "",
185		},
186		// Cut at the right place with colors
187		{
188			"\x1b[31mfoobarHoy\x1b[0m",
189			4,
190			"\x1b[31mfoob", "arHoy\x1b[0m",
191		},
192		// Handle prefix and suffix properly
193		{
194			"foo\x1b[31mfoobarHoy\x1b[0mbaaar",
195			4,
196			"foo\x1b[31mf", "oobarHoy\x1b[0mbaaar",
197		},
198		// Cut properly with length = 0
199		{
200			"foo",
201			0,
202			"", "foo",
203		},
204		// Handle chinese
205		{
206			"快檢什麼望對",
207			2,
208			"快檢", "什麼望對",
209		},
210		// Handle chinese with colors
211		{
212			"快\x1b[31m檢什麼\x1b[0m望對",
213			2,
214			"快\x1b[31m檢", "什麼\x1b[0m望對",
215		},
216	}
217
218	for i, tc := range cases {
219		result, leftover := splitWord(tc.Input, tc.Length)
220		if result != tc.Result || leftover != tc.Leftover {
221			t.Fatalf("Case %d Input:\n\n`%s`\n\nExpected Output:\n\n`%s` - `%s`\n\nActual Output:\n\n`%s` - `%s`",
222				i, tc.Input, tc.Result, tc.Leftover, result, leftover)
223		}
224	}
225}