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