1" Tests for diff mode
2source shared.vim
3source screendump.vim
4source check.vim
5
6func Test_diff_fold_sync()
7  enew!
8  let g:update_count = 0
9  au DiffUpdated * let g:update_count += 1
10
11  let l = range(50)
12  call setline(1, l)
13  diffthis
14  let winone = win_getid()
15  new
16  let l[25] = 'diff'
17  call setline(1, l)
18  diffthis
19  let wintwo = win_getid()
20  " line 15 is inside the closed fold
21  call assert_equal(19, foldclosedend(10))
22  call win_gotoid(winone)
23  call assert_equal(19, foldclosedend(10))
24  " open the fold
25  normal zv
26  call assert_equal(-1, foldclosedend(10))
27  " fold in other window must have opened too
28  call win_gotoid(wintwo)
29  call assert_equal(-1, foldclosedend(10))
30
31  " cursor position is in sync
32  normal 23G
33  call win_gotoid(winone)
34  call assert_equal(23, getcurpos()[1])
35
36  call assert_equal(1, g:update_count)
37  au! DiffUpdated
38
39  windo diffoff
40  close!
41  set nomodified
42endfunc
43
44func Test_vert_split()
45  set diffopt=filler
46  call Common_vert_split()
47  set diffopt&
48endfunc
49
50func Test_vert_split_internal()
51  set diffopt=internal,filler
52  call Common_vert_split()
53  set diffopt&
54endfunc
55
56func Common_vert_split()
57  " Disable the title to avoid xterm keeping the wrong one.
58  set notitle noicon
59  new
60  let l = ['1 aa', '2 bb', '3 cc', '4 dd', '5 ee']
61  call setline(1, l)
62  w! Xtest
63  normal dd
64  $
65  put
66  normal kkrXoxxx
67  w! Xtest2
68  file Nop
69  normal ggoyyyjjjozzzz
70  set foldmethod=marker foldcolumn=4
71  call assert_equal(0, &diff)
72  call assert_equal('marker', &foldmethod)
73  call assert_equal(4, &foldcolumn)
74  call assert_equal(0, &scrollbind)
75  call assert_equal(0, &cursorbind)
76  call assert_equal(1, &wrap)
77
78  vert diffsplit Xtest
79  vert diffsplit Xtest2
80  call assert_equal(1, &diff)
81  call assert_equal('diff', &foldmethod)
82  call assert_equal(2, &foldcolumn)
83  call assert_equal(1, &scrollbind)
84  call assert_equal(1, &cursorbind)
85  call assert_equal(0, &wrap)
86
87  let diff_fdm = &fdm
88  let diff_fdc = &fdc
89  " repeat entering diff mode here to see if this saves the wrong settings
90  diffthis
91  " jump to second window for a moment to have filler line appear at start of
92  " first window
93  wincmd w
94  normal gg
95  wincmd p
96  normal gg
97  call assert_equal(2, winline())
98  normal j
99  call assert_equal(4, winline())
100  normal j
101  call assert_equal(5, winline())
102  normal j
103  call assert_equal(6, winline())
104  normal j
105  call assert_equal(8, winline())
106  normal j
107  call assert_equal(9, winline())
108
109  wincmd w
110  normal gg
111  call assert_equal(1, winline())
112  normal j
113  call assert_equal(2, winline())
114  normal j
115  call assert_equal(4, winline())
116  normal j
117  call assert_equal(5, winline())
118  normal j
119  call assert_equal(8, winline())
120
121  wincmd w
122  normal gg
123  call assert_equal(2, winline())
124  normal j
125  call assert_equal(3, winline())
126  normal j
127  call assert_equal(4, winline())
128  normal j
129  call assert_equal(5, winline())
130  normal j
131  call assert_equal(6, winline())
132  normal j
133  call assert_equal(7, winline())
134  normal j
135  call assert_equal(8, winline())
136
137  " Test diffoff
138  diffoff!
139  1wincmd 2
140  let &diff = 1
141  let &fdm = diff_fdm
142  let &fdc = diff_fdc
143  4wincmd w
144  diffoff!
145  1wincmd w
146  call assert_equal(0, &diff)
147  call assert_equal('marker', &foldmethod)
148  call assert_equal(4, &foldcolumn)
149  call assert_equal(0, &scrollbind)
150  call assert_equal(0, &cursorbind)
151  call assert_equal(1, &wrap)
152
153  wincmd w
154  call assert_equal(0, &diff)
155  call assert_equal('marker', &foldmethod)
156  call assert_equal(4, &foldcolumn)
157  call assert_equal(0, &scrollbind)
158  call assert_equal(0, &cursorbind)
159  call assert_equal(1, &wrap)
160
161  wincmd w
162  call assert_equal(0, &diff)
163  call assert_equal('marker', &foldmethod)
164  call assert_equal(4, &foldcolumn)
165  call assert_equal(0, &scrollbind)
166  call assert_equal(0, &cursorbind)
167  call assert_equal(1, &wrap)
168
169  call delete('Xtest')
170  call delete('Xtest2')
171  windo bw!
172endfunc
173
174func Test_filler_lines()
175  " Test that diffing shows correct filler lines
176  enew!
177  put =range(4,10)
178  1d _
179  vnew
180  put =range(1,10)
181  1d _
182  windo diffthis
183  wincmd h
184  call assert_equal(1, line('w0'))
185  unlet! diff_fdm diff_fdc
186  windo diffoff
187  bwipe!
188  enew!
189endfunc
190
191func Test_diffget_diffput()
192  enew!
193  let l = range(50)
194  call setline(1, l)
195  call assert_fails('diffget', 'E99:')
196  diffthis
197  call assert_fails('diffget', 'E100:')
198  new
199  let l[10] = 'one'
200  let l[20] = 'two'
201  let l[30] = 'three'
202  let l[40] = 'four'
203  call setline(1, l)
204  diffthis
205  call assert_equal('one', getline(11))
206  11diffget
207  call assert_equal('10', getline(11))
208  21diffput
209  wincmd w
210  call assert_equal('two', getline(21))
211  normal 31Gdo
212  call assert_equal('three', getline(31))
213  call assert_equal('40', getline(41))
214  normal 41Gdp
215  wincmd w
216  call assert_equal('40', getline(41))
217  new
218  diffthis
219  call assert_fails('diffget', 'E101:')
220
221  windo diffoff
222  %bwipe!
223endfunc
224
225" Test putting two changes from one buffer to another
226func Test_diffput_two()
227  new a
228  let win_a = win_getid()
229  call setline(1, range(1, 10))
230  diffthis
231  new b
232  let win_b = win_getid()
233  call setline(1, range(1, 10))
234  8del
235  5del
236  diffthis
237  call win_gotoid(win_a)
238  %diffput
239  call win_gotoid(win_b)
240  call assert_equal(map(range(1, 10), 'string(v:val)'), getline(1, '$'))
241  bwipe! a
242  bwipe! b
243endfunc
244
245func Test_diffget_diffput_completion()
246  new Xdiff1 | diffthis
247  new Xdiff2 | diffthis
248  new Xdiff3 | diffthis
249  new Xdiff4
250
251  " :diffput and :diffget completes names of buffers which
252  " are in diff mode and which are different then current buffer.
253  b Xdiff1
254  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
255  call assert_equal('"diffput Xdiff2 Xdiff3', @:)
256  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
257  call assert_equal('"diffget Xdiff2 Xdiff3', @:)
258  call assert_equal(['Xdiff2', 'Xdiff3'], getcompletion('', 'diff_buffer'))
259
260  b Xdiff2
261  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
262  call assert_equal('"diffput Xdiff1 Xdiff3', @:)
263  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
264  call assert_equal('"diffget Xdiff1 Xdiff3', @:)
265  call assert_equal(['Xdiff1', 'Xdiff3'], getcompletion('', 'diff_buffer'))
266
267  b Xdiff3
268  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
269  call assert_equal('"diffput Xdiff1 Xdiff2', @:)
270  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
271  call assert_equal('"diffget Xdiff1 Xdiff2', @:)
272  call assert_equal(['Xdiff1', 'Xdiff2'], getcompletion('', 'diff_buffer'))
273
274  " No completion when in Xdiff4, it's not in diff mode.
275  b Xdiff4
276  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
277  call assert_equal('"diffput ', @:)
278  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
279  call assert_equal('"diffget ', @:)
280  call assert_equal([], getcompletion('', 'diff_buffer'))
281
282  %bwipe
283endfunc
284
285func Test_dp_do_buffer()
286  e! one
287  let bn1=bufnr('%')
288  let l = range(60)
289  call setline(1, l)
290  diffthis
291
292  new two
293  let l[10] = 'one'
294  let l[20] = 'two'
295  let l[30] = 'three'
296  let l[40] = 'four'
297  let l[50] = 'five'
298  call setline(1, l)
299  diffthis
300
301  " dp and do with invalid buffer number.
302  11
303  call assert_fails('norm 99999dp', 'E102:')
304  call assert_fails('norm 99999do', 'E102:')
305  call assert_fails('diffput non_existing_buffer', 'E94:')
306  call assert_fails('diffget non_existing_buffer', 'E94:')
307
308  " dp and do with valid buffer number.
309  call assert_equal('one', getline('.'))
310  exe 'norm ' . bn1 . 'do'
311  call assert_equal('10', getline('.'))
312  21
313  call assert_equal('two', getline('.'))
314  diffget one
315  call assert_equal('20', getline('.'))
316
317  31
318  exe 'norm ' . bn1 . 'dp'
319  41
320  diffput one
321  wincmd w
322  31
323  call assert_equal('three', getline('.'))
324  41
325  call assert_equal('four', getline('.'))
326
327  " dp and do with buffer number which is not in diff mode.
328  new not_in_diff_mode
329  let bn3=bufnr('%')
330  wincmd w
331  51
332  call assert_fails('exe "norm" . bn3 . "dp"', 'E103:')
333  call assert_fails('exe "norm" . bn3 . "do"', 'E103:')
334  call assert_fails('diffput not_in_diff_mode', 'E94:')
335  call assert_fails('diffget not_in_diff_mode', 'E94:')
336
337  windo diffoff
338  %bwipe!
339endfunc
340
341func Test_do_lastline()
342  e! one
343  call setline(1, ['1','2','3','4','5','6'])
344  diffthis
345
346  new two
347  call setline(1, ['2','4','5'])
348  diffthis
349
350  1
351  norm dp]c
352  norm dp]c
353  wincmd w
354  call assert_equal(4, line('$'))
355  norm G
356  norm do
357  call assert_equal(3, line('$'))
358
359  windo diffoff
360  %bwipe!
361endfunc
362
363func Test_diffoff()
364  enew!
365  call setline(1, ['Two', 'Three'])
366  redraw
367  let normattr = screenattr(1, 1)
368  diffthis
369  botright vert new
370  call setline(1, ['One', '', 'Two', 'Three'])
371  diffthis
372  redraw
373  call assert_notequal(normattr, 1->screenattr(1))
374  diffoff!
375  redraw
376  call assert_equal(normattr, screenattr(1, 1))
377  bwipe!
378  bwipe!
379endfunc
380
381func Common_icase_test()
382  edit one
383  call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve'])
384  redraw
385  let normattr = screenattr(1, 1)
386  diffthis
387
388  botright vert new two
389  call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE'])
390  diffthis
391
392  redraw
393  call assert_equal(normattr, screenattr(1, 1))
394  call assert_equal(normattr, screenattr(2, 1))
395  call assert_notequal(normattr, screenattr(3, 1))
396  call assert_equal(normattr, screenattr(4, 1))
397
398  let dtextattr = screenattr(5, 3)
399  call assert_notequal(dtextattr, screenattr(5, 1))
400  call assert_notequal(dtextattr, screenattr(5, 5))
401
402  diffoff!
403  %bwipe!
404endfunc
405
406func Test_diffopt_icase()
407  set diffopt=icase,foldcolumn:0
408  call Common_icase_test()
409  set diffopt&
410endfunc
411
412func Test_diffopt_icase_internal()
413  set diffopt=icase,foldcolumn:0,internal
414  call Common_icase_test()
415  set diffopt&
416endfunc
417
418func Common_iwhite_test()
419  edit one
420  " Difference in trailing spaces and amount of spaces should be ignored,
421  " but not other space differences.
422  call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four'])
423  redraw
424  let normattr = screenattr(1, 1)
425  diffthis
426
427  botright vert new two
428  call setline(1, ["One\t ", "Two\t ", 'Three', 'one   two', 'onetwo', ' Four'])
429  diffthis
430
431  redraw
432  call assert_equal(normattr, screenattr(1, 1))
433  call assert_equal(normattr, screenattr(2, 1))
434  call assert_equal(normattr, screenattr(3, 1))
435  call assert_equal(normattr, screenattr(4, 1))
436  call assert_notequal(normattr, screenattr(5, 1))
437  call assert_notequal(normattr, screenattr(6, 1))
438
439  diffoff!
440  %bwipe!
441endfunc
442
443func Test_diffopt_iwhite()
444  set diffopt=iwhite,foldcolumn:0
445  call Common_iwhite_test()
446  set diffopt&
447endfunc
448
449func Test_diffopt_iwhite_internal()
450  set diffopt=internal,iwhite,foldcolumn:0
451  call Common_iwhite_test()
452  set diffopt&
453endfunc
454
455func Test_diffopt_context()
456  enew!
457  call setline(1, ['1', '2', '3', '4', '5', '6', '7'])
458  diffthis
459  new
460  call setline(1, ['1', '2', '3', '4', '5x', '6', '7'])
461  diffthis
462
463  set diffopt=context:2
464  call assert_equal('+--  2 lines: 1', foldtextresult(1))
465  set diffopt=internal,context:2
466  call assert_equal('+--  2 lines: 1', foldtextresult(1))
467
468  set diffopt=context:1
469  call assert_equal('+--  3 lines: 1', foldtextresult(1))
470  set diffopt=internal,context:1
471  call assert_equal('+--  3 lines: 1', foldtextresult(1))
472
473  diffoff!
474  %bwipe!
475  set diffopt&
476endfunc
477
478func Test_diffopt_horizontal()
479  set diffopt=internal,horizontal
480  diffsplit
481
482  call assert_equal(&columns, winwidth(1))
483  call assert_equal(&columns, winwidth(2))
484  call assert_equal(&lines, winheight(1) + winheight(2) + 3)
485  call assert_inrange(0, 1, winheight(1) - winheight(2))
486
487  set diffopt&
488  diffoff!
489  %bwipe
490endfunc
491
492func Test_diffopt_vertical()
493  set diffopt=internal,vertical
494  diffsplit
495
496  call assert_equal(&lines - 2, winheight(1))
497  call assert_equal(&lines - 2, winheight(2))
498  call assert_equal(&columns, winwidth(1) + winwidth(2) + 1)
499  call assert_inrange(0, 1, winwidth(1) - winwidth(2))
500
501  set diffopt&
502  diffoff!
503  %bwipe
504endfunc
505
506func Test_diffopt_hiddenoff()
507  set diffopt=internal,filler,foldcolumn:0,hiddenoff
508  e! one
509  call setline(1, ['Two', 'Three'])
510  redraw
511  let normattr = screenattr(1, 1)
512  diffthis
513  botright vert new two
514  call setline(1, ['One', 'Four'])
515  diffthis
516  redraw
517  call assert_notequal(normattr, screenattr(1, 1))
518  set hidden
519  close
520  redraw
521  " should not diffing with hidden buffer two while 'hiddenoff' is enabled
522  call assert_equal(normattr, screenattr(1, 1))
523
524  bwipe!
525  bwipe!
526  set hidden& diffopt&
527endfunc
528
529func Test_diffoff_hidden()
530  set diffopt=internal,filler,foldcolumn:0
531  e! one
532  call setline(1, ['Two', 'Three'])
533  redraw
534  let normattr = screenattr(1, 1)
535  diffthis
536  botright vert new two
537  call setline(1, ['One', 'Four'])
538  diffthis
539  redraw
540  call assert_notequal(normattr, screenattr(1, 1))
541  set hidden
542  close
543  redraw
544  " diffing with hidden buffer two
545  call assert_notequal(normattr, screenattr(1, 1))
546  diffoff
547  redraw
548  call assert_equal(normattr, screenattr(1, 1))
549  diffthis
550  redraw
551  " still diffing with hidden buffer two
552  call assert_notequal(normattr, screenattr(1, 1))
553  diffoff!
554  redraw
555  call assert_equal(normattr, screenattr(1, 1))
556  diffthis
557  redraw
558  " no longer diffing with hidden buffer two
559  call assert_equal(normattr, screenattr(1, 1))
560
561  bwipe!
562  bwipe!
563  set hidden& diffopt&
564endfunc
565
566func Test_setting_cursor()
567  new Xtest1
568  put =range(1,90)
569  wq
570  new Xtest2
571  put =range(1,100)
572  wq
573
574  tabe Xtest2
575  $
576  diffsp Xtest1
577  tabclose
578
579  call delete('Xtest1')
580  call delete('Xtest2')
581endfunc
582
583func Test_diff_move_to()
584  new
585  call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
586  diffthis
587  vnew
588  call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
589  diffthis
590  norm ]c
591  call assert_equal(2, line('.'))
592  norm 3]c
593  call assert_equal(9, line('.'))
594  norm 10]c
595  call assert_equal(11, line('.'))
596  norm [c
597  call assert_equal(9, line('.'))
598  norm 2[c
599  call assert_equal(5, line('.'))
600  norm 10[c
601  call assert_equal(2, line('.'))
602  %bwipe!
603endfunc
604
605func Test_diffexpr()
606  if !executable('diff')
607    return
608  endif
609
610  func DiffExpr()
611    " Prepent some text to check diff type detection
612    call writefile(['warning', '  message'], v:fname_out)
613    silent exe '!diff ' . v:fname_in . ' ' . v:fname_new . '>>' . v:fname_out
614  endfunc
615  set diffexpr=DiffExpr()
616  set diffopt=foldcolumn:0
617
618  enew!
619  call setline(1, ['one', 'two', 'three'])
620  redraw
621  let normattr = screenattr(1, 1)
622  diffthis
623
624  botright vert new
625  call setline(1, ['one', 'two', 'three.'])
626  diffthis
627
628  redraw
629  call assert_equal(normattr, screenattr(1, 1))
630  call assert_equal(normattr, screenattr(2, 1))
631  call assert_notequal(normattr, screenattr(3, 1))
632
633  diffoff!
634  %bwipe!
635  set diffexpr& diffopt&
636endfunc
637
638func Test_diffpatch()
639  " The patch program on MS-Windows may fail or hang.
640  if !executable('patch') || !has('unix')
641    return
642  endif
643  new
644  insert
645***************
646*** 1,3 ****
647  1
648! 2
649  3
650--- 1,4 ----
651  1
652! 2x
653  3
654+ 4
655.
656  saveas! Xpatch
657  bwipe!
658  new
659  call assert_fails('diffpatch Xpatch', 'E816:')
660
661  for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
662    call setline(1, ['1', '2', '3'])
663    if name != 'Xpatch'
664      call rename('Xpatch', name)
665    endif
666    exe 'diffpatch ' . escape(name, '$')
667    call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
668    if name != 'Xpatch'
669      call rename(name, 'Xpatch')
670    endif
671    bwipe!
672  endfor
673
674  call delete('Xpatch')
675  bwipe!
676endfunc
677
678func Test_diff_too_many_buffers()
679  for i in range(1, 8)
680    exe "new Xtest" . i
681    diffthis
682  endfor
683  new Xtest9
684  call assert_fails('diffthis', 'E96:')
685  %bwipe!
686endfunc
687
688func Test_diff_nomodifiable()
689  new
690  call setline(1, [1, 2, 3, 4])
691  setl nomodifiable
692  diffthis
693  vnew
694  call setline(1, ['1x', 2, 3, 3, 4])
695  diffthis
696  call assert_fails('norm dp', 'E793:')
697  setl nomodifiable
698  call assert_fails('norm do', 'E21:')
699  %bwipe!
700endfunc
701
702func Test_diff_hlID()
703  new
704  call setline(1, [1, 2, 3])
705  diffthis
706  vnew
707  call setline(1, ['1x', 2, 'x', 3])
708  diffthis
709  redraw
710
711  call diff_hlID(-1, 1)->synIDattr("name")->assert_equal("")
712
713  call diff_hlID(1, 1)->synIDattr("name")->assert_equal("DiffChange")
714  call diff_hlID(1, 2)->synIDattr("name")->assert_equal("DiffText")
715  call diff_hlID(2, 1)->synIDattr("name")->assert_equal("")
716  call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd")
717  eval 4->diff_hlID(1)->synIDattr("name")->assert_equal("")
718
719  wincmd w
720  call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange")
721  call assert_equal(synIDattr(diff_hlID(2, 1), "name"), "")
722  call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "")
723
724  %bwipe!
725endfunc
726
727func Test_diff_filler()
728  new
729  call setline(1, [1, 2, 3, 'x', 4])
730  diffthis
731  vnew
732  call setline(1, [1, 2, 'y', 'y', 3, 4])
733  diffthis
734  redraw
735
736  call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'v:val->diff_filler()'))
737  wincmd w
738  call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)'))
739
740  %bwipe!
741endfunc
742
743func Test_diff_lastline()
744  enew!
745  only!
746  call setline(1, ['This is a ', 'line with five ', 'rows'])
747  diffthis
748  botright vert new
749  call setline(1, ['This is', 'a line with ', 'four rows'])
750  diffthis
751  1
752  call feedkeys("Je a\<CR>", 'tx')
753  call feedkeys("Je a\<CR>", 'tx')
754  let w1lines = winline()
755  wincmd w
756  $
757  let w2lines = winline()
758  call assert_equal(w2lines, w1lines)
759  bwipe!
760  bwipe!
761endfunc
762
763func WriteDiffFiles(buf, list1, list2)
764  call writefile(a:list1, 'Xfile1')
765  call writefile(a:list2, 'Xfile2')
766  if a:buf
767    call term_sendkeys(a:buf, ":checktime\<CR>")
768  endif
769endfunc
770
771" Verify a screendump with both the internal and external diff.
772func VerifyBoth(buf, dumpfile, extra)
773  " trailing : for leaving the cursor on the command line
774  for cmd in [":set diffopt=filler" . a:extra . "\<CR>:", ":set diffopt+=internal\<CR>:"]
775    call term_sendkeys(a:buf, cmd)
776    if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external')
777      break " don't let the next iteration overwrite the "failed" file.
778    endif
779  endfor
780endfunc
781
782" Verify a screendump with the internal diff only.
783func VerifyInternal(buf, dumpfile, extra)
784  call term_sendkeys(a:buf, ":diffupdate!\<CR>")
785  " trailing : for leaving the cursor on the command line
786  call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\<CR>:")
787  call term_wait(a:buf)
788  call VerifyScreenDump(a:buf, a:dumpfile, {})
789endfunc
790
791func Test_diff_screen()
792  CheckScreendump
793  CheckFeature menu
794
795  " clean up already existing swap files, just in case
796  call delete('.Xfile1.swp')
797  call delete('.Xfile2.swp')
798
799  " Test 1: Add a line in beginning of file 2
800  call WriteDiffFiles(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
801  let buf = RunVimInTerminal('-d Xfile1 Xfile2', {})
802  " Set autoread mode, so that Vim won't complain once we re-write the test
803  " files
804  call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
805
806  call VerifyBoth(buf, 'Test_diff_01', '')
807
808  " Test 2: Add a line in beginning of file 1
809  call WriteDiffFiles(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
810  call VerifyBoth(buf, 'Test_diff_02', '')
811
812  " Test 3: Add a line at the end of file 2
813  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
814  call VerifyBoth(buf, 'Test_diff_03', '')
815
816  " Test 4: Add a line at the end of file 1
817  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
818  call VerifyBoth(buf, 'Test_diff_04', '')
819
820  " Test 5: Add a line in the middle of file 2, remove on at the end of file 1
821  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10])
822  call VerifyBoth(buf, 'Test_diff_05', '')
823
824  " Test 6: Add a line in the middle of file 1, remove on at the end of file 2
825  call WriteDiffFiles(buf, [1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
826  call VerifyBoth(buf, 'Test_diff_06', '')
827
828  " Variants on test 6 with different context settings
829  call term_sendkeys(buf, ":set diffopt+=context:2\<cr>")
830  call VerifyScreenDump(buf, 'Test_diff_06.2', {})
831  call term_sendkeys(buf, ":set diffopt-=context:2\<cr>")
832  call term_sendkeys(buf, ":set diffopt+=context:1\<cr>")
833  call VerifyScreenDump(buf, 'Test_diff_06.1', {})
834  call term_sendkeys(buf, ":set diffopt-=context:1\<cr>")
835  call term_sendkeys(buf, ":set diffopt+=context:0\<cr>")
836  call VerifyScreenDump(buf, 'Test_diff_06.0', {})
837  call term_sendkeys(buf, ":set diffopt-=context:0\<cr>")
838
839  " Test 7 - 9: Test normal/patience/histogram diff algorithm
840  call WriteDiffFiles(buf, ['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{',
841      \ '    int i;', '    for(i = 0; i < 10; i++)', '    {', '        printf("Your answer is: ");',
842      \ '        printf("%d\n", foo);', '    }', '}', '', 'int fact(int n)', '{', '    if(n > 1)', '    {',
843      \ '        return fact(n-1) * n;', '    }', '    return 1;', '}', '', 'int main(int argc, char **argv)',
844      \ '{', '    frobnitz(fact(10));', '}'],
845      \ ['#include <stdio.h>', '', 'int fib(int n)', '{', '    if(n > 2)', '    {',
846      \ '        return fib(n-1) + fib(n-2);', '    }', '    return 1;', '}', '', '// Frobs foo heartily',
847      \ 'int frobnitz(int foo)', '{', '    int i;', '    for(i = 0; i < 10; i++)', '    {',
848      \ '        printf("%d\n", foo);', '    }', '}', '',
849      \ 'int main(int argc, char **argv)', '{', '    frobnitz(fib(10));', '}'])
850  call term_sendkeys(buf, ":diffupdate!\<cr>")
851  call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
852  call VerifyScreenDump(buf, 'Test_diff_07', {})
853
854  call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>")
855  call VerifyScreenDump(buf, 'Test_diff_08', {})
856
857  call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>")
858  call VerifyScreenDump(buf, 'Test_diff_09', {})
859
860  " Test 10-11: normal/indent-heuristic
861  call term_sendkeys(buf, ":set diffopt&vim\<cr>")
862  call WriteDiffFiles(buf, ['', '  def finalize(values)', '', '    values.each do |v|', '      v.finalize', '    end'],
863      \ ['', '  def finalize(values)', '', '    values.each do |v|', '      v.prepare', '    end', '',
864      \ '    values.each do |v|', '      v.finalize', '    end'])
865  call term_sendkeys(buf, ":diffupdate!\<cr>")
866  call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
867  call VerifyScreenDump(buf, 'Test_diff_10', {})
868
869  " Leave trailing : at commandline!
870  call term_sendkeys(buf, ":set diffopt+=indent-heuristic\<cr>:\<cr>")
871  call VerifyScreenDump(buf, 'Test_diff_11', {}, 'one')
872  " shouldn't matter, if indent-algorithm comes before or after the algorithm
873  call term_sendkeys(buf, ":set diffopt&\<cr>")
874  call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\<cr>:\<cr>")
875  call VerifyScreenDump(buf, 'Test_diff_11', {}, 'two')
876  call term_sendkeys(buf, ":set diffopt&\<cr>")
877  call term_sendkeys(buf, ":set diffopt+=algorithm:patience,indent-heuristic\<cr>:\<cr>")
878  call VerifyScreenDump(buf, 'Test_diff_11', {}, 'three')
879
880  " Test 12: diff the same file
881  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
882  call VerifyBoth(buf, 'Test_diff_12', '')
883
884  " Test 13: diff an empty file
885  call WriteDiffFiles(buf, [], [])
886  call VerifyBoth(buf, 'Test_diff_13', '')
887
888  " Test 14: test diffopt+=icase
889  call WriteDiffFiles(buf, ['a', 'b', 'cd'], ['A', 'b', 'cDe'])
890  call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase")
891
892  " Test 15-16: test diffopt+=iwhite
893  call WriteDiffFiles(buf, ['int main()', '{', '   printf("Hello, World!");', '   return 0;', '}'],
894      \ ['int main()', '{', '   if (0)', '   {', '      printf("Hello, World!");', '      return 0;', '   }', '}'])
895  call term_sendkeys(buf, ":diffupdate!\<cr>")
896  call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>")
897  call VerifyScreenDump(buf, 'Test_diff_15', {})
898  call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
899  call VerifyScreenDump(buf, 'Test_diff_16', {})
900
901  " Test 17: test diffopt+=iblank
902  call WriteDiffFiles(buf, ['a', ' ', 'cd', 'ef', 'xxx'], ['a', 'cd', '', 'ef', 'yyy'])
903  call VerifyInternal(buf, 'Test_diff_17', " diffopt+=iblank")
904
905  " Test 18: test diffopt+=iblank,iwhite / iwhiteall / iwhiteeol
906  call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhite")
907  call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteall")
908  call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteeol")
909
910  " Test 19: test diffopt+=iwhiteeol
911  call WriteDiffFiles(buf, ['a ', 'x', 'cd', 'ef', 'xx  xx', 'foo', 'bar'], ['a', 'x', 'c d', ' ef', 'xx xx', 'foo', '', 'bar'])
912  call VerifyInternal(buf, 'Test_diff_19', " diffopt+=iwhiteeol")
913
914  " Test 19: test diffopt+=iwhiteall
915  call VerifyInternal(buf, 'Test_diff_20', " diffopt+=iwhiteall")
916
917  " clean up
918  call StopVimInTerminal(buf)
919  call delete('Xfile1')
920  call delete('Xfile2')
921endfunc
922
923func Test_diff_with_cursorline()
924  CheckScreendump
925
926  call writefile([
927	\ 'hi CursorLine ctermbg=red ctermfg=white',
928	\ 'set cursorline',
929	\ 'call setline(1, ["foo","foo","foo","bar"])',
930	\ 'vnew',
931	\ 'call setline(1, ["bee","foo","foo","baz"])',
932	\ 'windo diffthis',
933	\ '2wincmd w',
934	\ ], 'Xtest_diff_cursorline')
935  let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {})
936
937  call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {})
938  call term_sendkeys(buf, "j")
939  call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {})
940  call term_sendkeys(buf, "j")
941  call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {})
942
943  " clean up
944  call StopVimInTerminal(buf)
945  call delete('Xtest_diff_cursorline')
946endfunc
947
948func Test_diff_with_syntax()
949  CheckScreendump
950
951  let lines =<< trim END
952  	void doNothing() {
953	   int x = 0;
954	   char *s = "hello";
955	   return 5;
956	}
957  END
958  call writefile(lines, 'Xprogram1.c')
959  let lines =<< trim END
960  	void doSomething() {
961	   int x = 0;
962	   char *s = "there";
963	   return 5;
964	}
965  END
966  call writefile(lines, 'Xprogram2.c')
967
968  let lines =<< trim END
969  	edit Xprogram1.c
970	diffsplit Xprogram2.c
971  END
972  call writefile(lines, 'Xtest_diff_syntax')
973  let buf = RunVimInTerminal('-S Xtest_diff_syntax', {})
974
975  call VerifyScreenDump(buf, 'Test_diff_syntax_1', {})
976
977  " clean up
978  call StopVimInTerminal(buf)
979  call delete('Xtest_diff_syntax')
980  call delete('Xprogram1.c')
981  call delete('Xprogram2.c')
982endfunc
983
984func Test_diff_of_diff()
985  CheckScreendump
986  CheckFeature rightleft
987
988  call writefile([
989	\ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])',
990	\ 'vnew',
991	\ 'call setline(1, ["aa","bb","cc"])',
992	\ 'windo diffthis',
993	\ '1wincmd w',
994	\ 'setlocal number',
995	\ ], 'Xtest_diff_diff')
996  let buf = RunVimInTerminal('-S Xtest_diff_diff', {})
997
998  call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {})
999
1000  call term_sendkeys(buf, ":set rightleft\<cr>")
1001  call VerifyScreenDump(buf, 'Test_diff_of_diff_02', {})
1002
1003  " clean up
1004  call StopVimInTerminal(buf)
1005  call delete('Xtest_diff_diff')
1006endfunc
1007
1008func CloseoffSetup()
1009  enew
1010  call setline(1, ['one', 'two', 'three'])
1011  diffthis
1012  new
1013  call setline(1, ['one', 'tow', 'three'])
1014  diffthis
1015  call assert_equal(1, &diff)
1016  only!
1017endfunc
1018
1019func Test_diff_closeoff()
1020  " "closeoff" included by default: last diff win gets 'diff' reset'
1021  call CloseoffSetup()
1022  call assert_equal(0, &diff)
1023  enew!
1024
1025  " "closeoff" excluded: last diff win keeps 'diff' set'
1026  set diffopt-=closeoff
1027  call CloseoffSetup()
1028  call assert_equal(1, &diff)
1029  diffoff!
1030  enew!
1031endfunc
1032
1033func Test_diff_maintains_change_mark()
1034  enew!
1035  call setline(1, ['a', 'b', 'c', 'd'])
1036  diffthis
1037  new
1038  call setline(1, ['a', 'b', 'c', 'e'])
1039  " Set '[ and '] marks
1040  2,3yank
1041  call assert_equal([2, 3], [line("'["), line("']")])
1042  " Verify they aren't affected by the implicit diff
1043  diffthis
1044  call assert_equal([2, 3], [line("'["), line("']")])
1045  " Verify they aren't affected by an explicit diff
1046  diffupdate
1047  call assert_equal([2, 3], [line("'["), line("']")])
1048  bwipe!
1049  bwipe!
1050endfunc
1051