blob: 9029ea58f5b5d7261889d8b0830dceb0d1623411 [file] [log] [blame]
Hirohito Higashi74f0a772025-06-23 21:42:36 +02001" Tests for the ":uniq" command.
2
Hirohito Higashi74f0a772025-06-23 21:42:36 +02003" Tests for the ":uniq" command.
4func Test_uniq_cmd()
5 let tests = [
6 \ {
7 \ 'name' : 'Alphabetical uniq #1',
8 \ 'cmd' : '%uniq',
9 \ 'input' : [
10 \ 'abc',
11 \ 'ab',
12 \ 'a',
13 \ 'a321',
14 \ 'a123',
15 \ 'a123',
16 \ 'a123',
17 \ 'a123',
18 \ 'a122',
19 \ 'a123',
20 \ 'b321',
21 \ 'c123d',
22 \ ' 123b',
23 \ 'c321d',
24 \ 'b322b',
25 \ 'b321',
26 \ 'b321b'
27 \ ],
28 \ 'expected' : [
29 \ 'abc',
30 \ 'ab',
31 \ 'a',
32 \ 'a321',
33 \ 'a123',
34 \ 'a122',
35 \ 'a123',
36 \ 'b321',
37 \ 'c123d',
38 \ ' 123b',
39 \ 'c321d',
40 \ 'b322b',
41 \ 'b321',
42 \ 'b321b'
43 \ ]
44 \ },
45 \ {
46 \ 'name' : 'Alphabetical uniq #2',
47 \ 'cmd' : '%uniq',
48 \ 'input' : [
49 \ 'abc',
50 \ 'abc',
51 \ 'abc',
52 \ 'ab',
53 \ 'a',
54 \ 'a321',
55 \ 'a122',
56 \ 'b321',
57 \ 'a123',
58 \ 'a123',
59 \ 'c123d',
60 \ ' 123b',
61 \ 'c321d',
62 \ 'b322b',
63 \ 'b321',
64 \ 'b321b'
65 \ ],
66 \ 'expected' : [
67 \ 'abc',
68 \ 'ab',
69 \ 'a',
70 \ 'a321',
71 \ 'a122',
72 \ 'b321',
73 \ 'a123',
74 \ 'c123d',
75 \ ' 123b',
76 \ 'c321d',
77 \ 'b322b',
78 \ 'b321',
79 \ 'b321b'
80 \ ]
81 \ },
82 \ {
83 \ 'name' : 'alphabetical, uniqed input',
84 \ 'cmd' : 'uniq',
85 \ 'input' : [
86 \ 'a',
87 \ 'b',
88 \ 'c',
89 \ ],
90 \ 'expected' : [
91 \ 'a',
92 \ 'b',
93 \ 'c',
94 \ ]
95 \ },
96 \ {
97 \ 'name' : 'alphabetical, uniqed input, unique at end',
98 \ 'cmd' : 'uniq',
99 \ 'input' : [
100 \ 'aa',
101 \ 'bb',
102 \ 'cc',
103 \ 'cc',
104 \ ],
105 \ 'expected' : [
106 \ 'aa',
107 \ 'bb',
108 \ 'cc',
109 \ ]
110 \ },
111 \ {
112 \ 'name' : 'uniq one line buffer',
113 \ 'cmd' : 'uniq',
114 \ 'input' : [
115 \ 'single line'
116 \ ],
117 \ 'expected' : [
118 \ 'single line'
119 \ ]
120 \ },
121 \ {
122 \ 'name' : 'uniq ignoring case',
123 \ 'cmd' : '%uniq i',
124 \ 'input' : [
125 \ 'BB',
126 \ 'Cc',
127 \ 'cc',
128 \ 'Cc',
129 \ 'aa'
130 \ ],
131 \ 'expected' : [
132 \ 'BB',
133 \ 'Cc',
134 \ 'aa'
135 \ ]
136 \ },
137 \ {
138 \ 'name' : 'uniq not uniqued #1',
139 \ 'cmd' : '%uniq!',
140 \ 'input' : [
141 \ 'aa',
142 \ 'cc',
143 \ 'cc',
144 \ 'cc',
145 \ 'bb',
146 \ 'aa',
147 \ 'yyy',
148 \ 'yyy',
149 \ 'zz'
150 \ ],
151 \ 'expected' : [
152 \ 'cc',
153 \ 'yyy',
154 \ ]
155 \ },
156 \ {
157 \ 'name' : 'uniq not uniqued #2',
158 \ 'cmd' : '%uniq!',
159 \ 'input' : [
160 \ 'aa',
161 \ 'aa',
162 \ 'bb',
163 \ 'cc',
164 \ 'cc',
165 \ 'cc',
166 \ 'yyy',
167 \ 'yyy',
168 \ 'zz'
169 \ ],
170 \ 'expected' : [
171 \ 'aa',
172 \ 'cc',
173 \ 'yyy',
174 \ ]
175 \ },
176 \ {
177 \ 'name' : 'uniq not uniqued ("u" is ignored)',
178 \ 'cmd' : '%uniq! u',
179 \ 'input' : [
180 \ 'aa',
181 \ 'cc',
182 \ 'cc',
183 \ 'cc',
184 \ 'bb',
185 \ 'aa',
186 \ 'yyy',
187 \ 'yyy',
188 \ 'zz'
189 \ ],
190 \ 'expected' : [
191 \ 'cc',
192 \ 'yyy',
193 \ ]
194 \ },
195 \ {
196 \ 'name' : 'uniq not uniqued, ignoring case',
197 \ 'cmd' : '%uniq! i',
198 \ 'input' : [
199 \ 'aa',
200 \ 'cc',
201 \ 'cc',
202 \ 'Cc',
203 \ 'bb',
204 \ 'aa',
205 \ 'yyy',
206 \ 'yyy',
207 \ 'zz'
208 \ ],
209 \ 'expected' : [
210 \ 'cc',
211 \ 'yyy',
212 \ ]
213 \ },
214 \ {
215 \ 'name' : 'uniq only unique #1',
216 \ 'cmd' : '%uniq u',
217 \ 'input' : [
218 \ 'aa',
219 \ 'cc',
220 \ 'cc',
221 \ 'cc',
222 \ 'bb',
223 \ 'aa',
224 \ 'yyy',
225 \ 'yyy',
226 \ 'zz'
227 \ ],
228 \ 'expected' : [
229 \ 'aa',
230 \ 'bb',
231 \ 'aa',
232 \ 'zz'
233 \ ]
234 \ },
235 \ {
236 \ 'name' : 'uniq only unique #2',
237 \ 'cmd' : '%uniq u',
238 \ 'input' : [
239 \ 'aa',
240 \ 'aa',
241 \ 'bb',
242 \ 'cc',
243 \ 'cc',
244 \ 'cc',
245 \ 'yyy',
246 \ 'yyy',
247 \ 'zz'
248 \ ],
249 \ 'expected' : [
250 \ 'bb',
251 \ 'zz'
252 \ ]
253 \ },
254 \ {
255 \ 'name' : 'uniq only unique, ignoring case',
256 \ 'cmd' : '%uniq ui',
257 \ 'input' : [
258 \ 'aa',
259 \ 'cc',
260 \ 'Cc',
261 \ 'cc',
262 \ 'bb',
263 \ 'aa',
264 \ 'yyy',
265 \ 'yyy',
266 \ 'zz'
267 \ ],
268 \ 'expected' : [
269 \ 'aa',
270 \ 'bb',
271 \ 'aa',
272 \ 'zz'
273 \ ]
274 \ },
275 \ {
276 \ 'name' : 'uniq on first 2 charscters',
277 \ 'cmd' : '%uniq r /^../',
278 \ 'input' : [
279 \ 'aa',
280 \ 'cc',
281 \ 'cc1',
282 \ 'cc2',
283 \ 'bb',
284 \ 'aa',
285 \ 'yyy',
286 \ 'yyy2',
287 \ 'zz'
288 \ ],
289 \ 'expected' : [
290 \ 'aa',
291 \ 'cc',
292 \ 'bb',
293 \ 'aa',
294 \ 'yyy',
295 \ 'zz'
296 \ ]
297 \ },
298 \ {
299 \ 'name' : 'uniq on after 2 charscters',
300 \ 'cmd' : '%uniq /^../',
301 \ 'input' : [
302 \ '11aa',
303 \ '11cc',
304 \ '13cc',
305 \ '13cc',
306 \ '13bb',
307 \ '13aa',
308 \ '12yyy',
309 \ '11yyy',
310 \ '11zz'
311 \ ],
312 \ 'expected' : [
313 \ '11aa',
314 \ '11cc',
315 \ '13bb',
316 \ '13aa',
317 \ '12yyy',
318 \ '11zz'
319 \ ]
320 \ },
321 \ {
322 \ 'name' : 'uniq on first 2 charscters, not uniqued',
323 \ 'cmd' : '%uniq! r /^../',
324 \ 'input' : [
325 \ 'aa',
326 \ 'cc',
327 \ 'cc1',
328 \ 'cc2',
329 \ 'bb',
330 \ 'aa',
331 \ 'yyy',
332 \ 'yyy2',
333 \ 'zz'
334 \ ],
335 \ 'expected' : [
336 \ 'cc',
337 \ 'yyy'
338 \ ]
339 \ },
340 \ {
341 \ 'name' : 'uniq on after 2 charscters, not uniqued',
342 \ 'cmd' : '%uniq! /^../',
343 \ 'input' : [
344 \ '11aa',
345 \ '11cc',
346 \ '13cc',
347 \ '13cc',
348 \ '13bb',
349 \ '13aa',
350 \ '12yyy',
351 \ '11yyy',
352 \ '11zz'
353 \ ],
354 \ 'expected' : [
355 \ '11cc',
356 \ '12yyy'
357 \ ]
358 \ },
359 \ {
360 \ 'name' : 'uniq on first 2 charscters, only unique',
361 \ 'cmd' : '%uniq ru /^../',
362 \ 'input' : [
363 \ 'aa',
364 \ 'cc',
365 \ 'cc1',
366 \ 'cc2',
367 \ 'bb',
368 \ 'aa',
369 \ 'yyy',
370 \ 'yyy2',
371 \ 'zz'
372 \ ],
373 \ 'expected' : [
374 \ 'aa',
375 \ 'bb',
376 \ 'aa',
377 \ 'zz'
378 \ ]
379 \ },
380 \ {
381 \ 'name' : 'uniq on after 2 charscters, only unique',
382 \ 'cmd' : '%uniq u /^../',
383 \ 'input' : [
384 \ '11aa',
385 \ '11cc',
386 \ '13cc',
387 \ '13cc',
388 \ '13bb',
389 \ '13aa',
390 \ '12yyy',
391 \ '11yyy',
392 \ '11zz'
393 \ ],
394 \ 'expected' : [
395 \ '11aa',
396 \ '13bb',
397 \ '13aa',
398 \ '11zz'
399 \ ]
400 \ }
401 \ ]
402
403 " This does not appear to work correctly on Mac.
404 if !has('mac')
405 if v:collate =~? '^\(en\|fr\)_ca.utf-\?8$'
406 " en_CA.utf-8 uniqs capitals before lower case
407 " 'Œ' is omitted because it can uniq before or after 'œ'
408 let tests += [
409 \ {
410 \ 'name' : 'uniq with locale ' .. v:collate,
411 \ 'cmd' : '%uniq l',
412 \ 'input' : [
413 \ 'A',
414 \ 'a',
415 \ 'À',
416 \ 'à',
417 \ 'E',
418 \ 'e',
419 \ 'É',
420 \ 'é',
421 \ 'È',
422 \ 'è',
423 \ 'O',
424 \ 'o',
425 \ 'Ô',
426 \ 'ô',
427 \ 'œ',
428 \ 'Z',
429 \ 'z'
430 \ ],
431 \ 'expected' : [
432 \ 'A',
433 \ 'a',
434 \ 'À',
435 \ 'à',
436 \ 'E',
437 \ 'e',
438 \ 'É',
439 \ 'é',
440 \ 'È',
441 \ 'è',
442 \ 'O',
443 \ 'o',
444 \ 'Ô',
445 \ 'ô',
446 \ 'œ',
447 \ 'Z',
448 \ 'z'
449 \ ]
450 \ },
451 \ ]
452 elseif v:collate =~? '^\(en\|es\|de\|fr\|it\|nl\).*\.utf-\?8$'
453 " With these locales, the accentuated letters are ordered
454 " similarly to the non-accentuated letters.
455 let tests += [
456 \ {
457 \ 'name' : 'uniq with locale ' .. v:collate,
458 \ 'cmd' : '%uniq li',
459 \ 'input' : [
460 \ 'A',
461 \ 'À',
462 \ 'a',
463 \ 'à',
464 \ 'à',
465 \ 'E',
466 \ 'È',
467 \ 'É',
468 \ 'o',
469 \ 'O',
470 \ 'Ô',
471 \ 'e',
472 \ 'è',
473 \ 'é',
474 \ 'ô',
475 \ 'Œ',
476 \ 'œ',
477 \ 'z',
478 \ 'Z'
479 \ ],
480 \ 'expected' : [
481 \ 'A',
482 \ 'À',
483 \ 'a',
484 \ 'à',
485 \ 'E',
486 \ 'È',
487 \ 'É',
488 \ 'o',
489 \ 'O',
490 \ 'Ô',
491 \ 'e',
492 \ 'è',
493 \ 'é',
494 \ 'ô',
495 \ 'Œ',
496 \ 'œ',
497 \ 'z',
498 \ 'Z'
499 \ ]
500 \ },
501 \ ]
502 endif
503 endif
504
505 for t in tests
506 enew!
507 call append(0, t.input)
508 $delete _
509 setlocal nomodified
510 execute t.cmd
511
512 call assert_equal(t.expected, getline(1, '$'), t.name)
513
514 " Previously, the ":uniq" command would set 'modified' even if the buffer
515 " contents did not change. Here, we check that this problem is fixed.
516 if t.input == t.expected
517 call assert_false(&modified, t.name . ': &mod is not correct')
518 else
519 call assert_true(&modified, t.name . ': &mod is not correct')
520 endif
521 endfor
522
523 " Needs at least two lines for this test
524 call setline(1, ['line1', 'line2'])
525 call assert_fails('uniq no', 'E475:')
526 call assert_fails('uniq c', 'E475:')
527 call assert_fails('uniq #pat%', 'E654:')
528 call assert_fails('uniq /\%(/', 'E53:')
529 call assert_fails('333uniq', 'E16:')
530 call assert_fails('1,999uniq', 'E16:')
531
532 enew!
533endfunc
534
535func Test_uniq_cmd_report()
536 enew!
537 call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
538 $delete _
539 setlocal nomodified
540 let res = execute('%uniq')
541
542 call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0'))
543 call assert_match("6 fewer lines", res)
544 enew!
545 call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
546 $delete _
547 setlocal nomodified report=10
548 let res = execute('%uniq')
549
550 call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0'))
551 call assert_equal("", res)
552 enew!
553 call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
554 $delete _
555 setl report&vim
556 setlocal nomodified
557 let res = execute('1g/^/%uniq')
558
559 call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0'))
560 " the output comes from the :g command, not from the :uniq
561 call assert_match("6 fewer lines", res)
562 enew!
563endfunc
564
565" Test for a :uniq command followed by another command
566func Test_uniq_followed_by_cmd()
567 new
568 let var = ''
569 call setline(1, ['cc', 'aa', 'bb'])
570 %uniq | let var = "uniqcmdtest"
571 call assert_equal(var, "uniqcmdtest")
572 call assert_equal(['cc', 'aa', 'bb'], getline(1, '$'))
573 " Test for :uniq followed by a comment
574 call setline(1, ['3b', '3b', '3b', '1c', '2a'])
575 %uniq " uniq alphabetically
576 call assert_equal(['3b', '1c', '2a'], getline(1, '$'))
577 bw!
578endfunc
579
580" Test for retaining marks across a :uniq
581func Test_uniq_with_marks()
582 new
583 call setline(1, ['cc', 'cc', 'aa', 'bb', 'bb', 'bb', 'bb'])
584 call setpos("'c", [0, 1, 0, 0])
585 call setpos("'a", [0, 4, 0, 0])
586 call setpos("'b", [0, 7, 0, 0])
587 %uniq
588 call assert_equal(['cc', 'aa', 'bb'], getline(1, '$'))
589 call assert_equal(1, line("'c"))
590 call assert_equal(0, line("'a"))
591 call assert_equal(0, line("'b"))
592 bw!
593endfunc
594
595" Test for undo after a :uniq
596func Test_uniq_undo()
597 new
598 let li = ['cc', 'cc', 'aa', 'bb', 'bb', 'bb', 'bb', 'aa']
599 call writefile(li, 'XfileUniq', 'D')
600 edit XfileUniq
601 uniq
602 call assert_equal(['cc', 'aa', 'bb', 'aa'], getline(1, '$'))
603 call assert_true(&modified)
604 undo
605 call assert_equal(li, getline(1, '$'))
606 call assert_false(&modified)
607 bw!
608endfunc
609
610" vim: shiftwidth=2 sts=2 expandtab