github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/write_test.go (about) 1 package readline 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/lmorg/murex/test/count" 8 "github.com/lmorg/murex/utils/json" 9 "github.com/mattn/go-runewidth" 10 ) 11 12 func TestLineWrap(t *testing.T) { 13 type TestLineWrapT struct { 14 Prompt string 15 Line string 16 TermWidth int 17 Expected []string 18 } 19 20 tests := []TestLineWrapT{ 21 { 22 Prompt: "foobar", 23 Line: "1234567890", 24 TermWidth: 80, 25 Expected: []string{"1234567890"}, 26 }, 27 { 28 Prompt: "foobar", 29 Line: "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 30 TermWidth: 86, 31 Expected: []string{"12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, 32 }, 33 { 34 Prompt: "foobar", 35 Line: "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 36 TermWidth: 87, 37 Expected: []string{"12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, 38 }, 39 { 40 Prompt: "foobar", 41 Line: "123456789012345678901234567890", 42 TermWidth: 20, 43 Expected: []string{"12345678901234", " 56789012345678", " 90"}, 44 }, 45 { 46 Prompt: "foobar", 47 Line: "1234567890", 48 TermWidth: 4, 49 Expected: []string{"1234", "5678", "90"}, 50 }, 51 { 52 Prompt: "foobar", 53 Line: "1234567890", 54 TermWidth: 5, 55 Expected: []string{"12345", "67890"}, 56 }, 57 { 58 Prompt: "foobar", 59 Line: "1234567890", 60 TermWidth: 6, 61 Expected: []string{"123456", "7890"}, 62 }, 63 { 64 Prompt: "foobar", 65 Line: "1234567890", 66 TermWidth: 7, 67 Expected: []string{"1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", " 0"}, 68 }, 69 { 70 Prompt: "foobar", 71 Line: "1234567890", 72 TermWidth: 8, 73 Expected: []string{"12", " 34", " 56", " 78", " 90"}, 74 }, 75 { 76 Prompt: "foobar", 77 Line: "使用再生纸", 78 TermWidth: 8, 79 Expected: []string{"使", " 用", " 再", " 生", " 纸"}, 80 }, 81 { 82 Prompt: "foobar", 83 Line: "使用再生纸", 84 TermWidth: 9, 85 Expected: []string{"使", " 用", " 再", " 生", " 纸"}, 86 }, 87 } 88 89 count.Tests(t, len(tests)) 90 for i, test := range tests { 91 rl := NewInstance() 92 rl.SetPrompt(test.Prompt) 93 rl.line.Set(rl,[]rune(test.Line)) 94 95 wrap := lineWrap(rl, test.TermWidth) 96 if len(wrap) != len(test.Expected) { 97 t.Error("Slice lens do not match:") 98 t.Logf(" Test: %d (%s)", i, t.Name()) 99 t.Logf(" Prompt: '%s'", test.Prompt) 100 t.Logf(" Line: '%s'", test.Line) 101 t.Logf(" Width: %d", test.TermWidth) 102 t.Logf(" len(exp): %d", len(test.Expected)) 103 t.Logf(" len(act): %d", len(wrap)) 104 t.Logf(" Slice exp: '%s'", fmt.Sprint(test.Expected)) 105 t.Logf(" Slice act: '%s'", fmt.Sprint(wrap)) 106 t.Logf(" Slice json e: %s", json.LazyLogging(test.Expected)) 107 t.Logf(" Slice json a: %s", json.LazyLogging(wrap)) 108 t.Logf(" rl.promptLen: %d'", rl.promptLen) 109 t.Logf(" rl.line: '%s'", rl.line.String()) 110 continue 111 } 112 113 for j := range wrap { 114 if wrap[j] != test.Expected[j] { 115 t.Error("Slice element does not match:") 116 t.Logf(" Test: %d (%s)", i, t.Name()) 117 t.Logf(" Prompt: '%s'", test.Prompt) 118 t.Logf(" Line: '%s'", test.Line) 119 t.Logf(" Width: %d", test.TermWidth) 120 t.Logf(" Expected: %s", test.Expected[j]) 121 t.Logf(" Actual: %s", wrap[j]) 122 t.Logf(" len(exp): %d", len(test.Expected)) 123 t.Logf(" len(act): %d", len(wrap)) 124 t.Logf(" Slice exp:'%s'", fmt.Sprint(test.Expected)) 125 t.Logf(" Slice act:'%s'", fmt.Sprint(wrap)) 126 t.Logf(" Slice j e: %s", json.LazyLogging(test.Expected)) 127 t.Logf(" Slice j a: %s", json.LazyLogging(wrap)) 128 } 129 } 130 } 131 } 132 133 func TestLineWrapCell(t *testing.T) { 134 type ExpectedT struct { 135 X, Y int 136 } 137 138 type TestLineWrapPosT struct { 139 Prompt string 140 Line string 141 TermWidth int 142 Expected ExpectedT 143 } 144 145 tests := []TestLineWrapPosT{ 146 { 147 Prompt: "12345", 148 Line: "", 149 TermWidth: 10, 150 Expected: ExpectedT{5 + 0, 0}, 151 }, 152 ///// 153 { 154 Prompt: "12345", 155 Line: "123", 156 TermWidth: 10, 157 Expected: ExpectedT{5 + 3, 0}, 158 }, 159 { 160 Prompt: "12345", 161 Line: "1234", 162 TermWidth: 10, 163 Expected: ExpectedT{5 + 4, 0}, 164 }, 165 { 166 Prompt: "12345", 167 Line: "12345", 168 TermWidth: 10, 169 Expected: ExpectedT{10, 0}, 170 }, 171 { 172 Prompt: "12345", 173 Line: "123456", 174 TermWidth: 10, 175 Expected: ExpectedT{5 + 1, 1}, 176 }, 177 { 178 Prompt: "foobar", 179 Line: "1234567890", 180 TermWidth: 80, 181 Expected: ExpectedT{6 + 10, 0}, 182 }, 183 { 184 Prompt: "foobar", 185 Line: "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 186 TermWidth: 85, 187 Expected: ExpectedT{6 + 1, 1}, 188 }, 189 { 190 Prompt: "foobar", 191 Line: "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 192 TermWidth: 86, 193 Expected: ExpectedT{86, 0}, 194 }, 195 { 196 Prompt: "foobar", 197 Line: "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 198 TermWidth: 87, 199 Expected: ExpectedT{86, 0}, 200 }, 201 { 202 Prompt: "foobar", 203 Line: "123456789012345678901234567890", 204 TermWidth: 20, 205 //Expected: []string{"12345678901234", "56789012345678", "90"}, 206 Expected: ExpectedT{6 + 2, 2}, 207 }, 208 { // 10 209 Prompt: "foobar", 210 Line: "1234567890", 211 TermWidth: 4, 212 //Expected: []string{"1234", "5678", "90"}, 213 Expected: ExpectedT{0 + 2, 2}, 214 }, 215 { 216 Prompt: "foobar", 217 Line: "1234567890", 218 TermWidth: 5, 219 //Expected: []string{"12345", "67890"}, 220 Expected: ExpectedT{5, 1}, 221 }, 222 { 223 Prompt: "foobar", 224 Line: "1234567890", 225 TermWidth: 6, 226 //Expected: []string{"123456", "7890"}, 227 Expected: ExpectedT{0 + 4, 1}, 228 }, 229 { 230 Prompt: "foobar", 231 Line: "1234567890", 232 TermWidth: 7, 233 //Expected: []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}, 234 Expected: ExpectedT{7, 9}, 235 }, 236 { 237 Prompt: "foobar", 238 Line: "1234567890", 239 TermWidth: 8, 240 //Expected: []string{"12", "34", "56", "78", "90"}, 241 Expected: ExpectedT{6 + 2, 4}, 242 }, 243 ///// 244 { 245 Prompt: "foobar", 246 Line: "使用再生纸", 247 TermWidth: 8, 248 //Expected: []string{"12", "34", "56", "78", "90"}, 249 Expected: ExpectedT{6 + 2, 4}, 250 }, 251 { 252 Prompt: "foo", 253 Line: "使用 再生纸", 254 TermWidth: 8, 255 //Expected: []string{"12", "34", "56", "78", "90"}, 256 Expected: ExpectedT{X: 5, Y: 2}, 257 }, 258 { 259 Prompt: "foo", 260 Line: "使用 再生纸 使用 再生", 261 TermWidth: 8, 262 //Expected: []string{"12", "34", "56", "78", "90"}, 263 Expected: ExpectedT{X: 5, Y: 4}, 264 }, 265 { 266 Prompt: "使用", 267 Line: "使用再生纸使用再生", 268 TermWidth: 8, 269 //Expected: []string{"12", "34", "56", "78", "90"}, 270 Expected: ExpectedT{X: 6, Y: 4}, 271 }, 272 } 273 274 count.Tests(t, len(tests)) 275 for i, test := range tests { 276 promptLen := runewidth.StringWidth(test.Prompt) 277 x, y := lineWrapCell(promptLen, []rune(test.Line), test.TermWidth) 278 279 if (test.Expected.X != x) || (test.Expected.Y != y) { 280 t.Error("X or Y does not match:") 281 t.Logf(" Test: %d (%s)", i, t.Name()) 282 t.Logf(" Prompt: '%s'", test.Prompt) 283 t.Logf(" Prompt len %d", promptLen) 284 t.Logf(" Line: '%s'", test.Line) 285 t.Logf(" Width: %d", test.TermWidth) 286 t.Logf(" Expected X:%d", test.Expected.X) 287 t.Logf(" Actual X:%d", x) 288 t.Logf(" Expected Y:%d", test.Expected.Y) 289 t.Logf(" Actual Y:%d", y) 290 } 291 292 } 293 }