summaryrefslogtreecommitdiffstats
path: root/runtime/indent/testdir/runtest.vim
blob: fa4e16e3810c668d5e4f6375e8200c61b61fb4be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
" Runs all the indent tests for which there is no .out file.
"
" Current directory must be runtime/indent.

" Only do this with the +eval feature
if 1

set nocp
filetype indent on
syn on
set nowrapscan
set report=9999
set modeline
set debug=throw

au! SwapExists * call HandleSwapExists()
func HandleSwapExists()
  " Ignore finding a swap file for the test input and output, the user might be
  " editing them and that's OK.
  if expand('<afile>') =~ '.*\.\(in\|out\|fail\|ok\)'
    let v:swapchoice = 'e'
  endif
endfunc

let failed_count = 0
for fname in glob('testdir/*.in', 1, 1)
  let root = substitute(fname, '\.in', '', '')

  " Execute the test if the .out file does not exist of when the .in file is
  " newer.
  let in_time = getftime(fname)
  let out_time = getftime(root . '.out')
  if out_time < 0 || in_time > out_time
    call delete(root . '.fail')
    call delete(root . '.out')

    set sw& ts& filetype=
    exe 'split ' . fname

    let did_some = 0
    let failed = 0
    let end = 1
    while 1
      " Indent all the lines between "START_INDENT" and "END_INDENT"
      exe end
      let start = search('\<START_INDENT\>')
      let end = search('\<END_INDENT\>')
      if start <= 0 || end <= 0 || end <= start
	if did_some == 0
	  call append(0, 'ERROR: START_INDENT and/or END_INDENT not found')
	  let failed = 1
	endif
	break
      else
	let did_some = 1

	" Execute all commands marked with INDENT_EXE and find any pattern.
	let lnum = start
	let pattern = ''
	let at = ''
	while 1
	  exe lnum + 1
	  let lnum_exe = search('\<INDENT_EXE\>')
	  exe lnum + 1
	  let indent_at = search('\<INDENT_\(AT\|NEXT\|PREV\)\>')
	  if lnum_exe > 0 && lnum_exe < end && (indent_at <= 0 || lnum_exe < indent_at)
	    exe substitute(getline(lnum_exe), '.*INDENT_EXE', '', '')
	    let lnum = lnum_exe
	    let start = lnum
	  elseif indent_at > 0 && indent_at < end
	    if pattern != ''
	      call append(indent_at, 'ERROR: duplicate pattern')
	      let failed = 1
	      break
	    endif
	    let text = getline(indent_at)
	    let pattern = substitute(text, '.*INDENT_\S*\s*', '', '')
	    let at = substitute(text, '.*INDENT_\(\S*\).*', '\1', '')
	    let lnum = indent_at
	    let start = lnum
	  else
	    break
	  endif
	endwhile

	exe start + 1
	if pattern == ''
	  try
	    exe 'normal =' . (end - 1) . 'G'
	  catch
	    call append(indent_at, 'ERROR: ' . v:exception)
	    let failed = 1
	  endtry
	else
	  let lnum = search(pattern)
	  if lnum <= 0
	    call append(indent_at, 'ERROR: pattern not found: ' . pattern)
	    let failed = 1
	    break
	  endif
	  if at == 'AT'
	    exe lnum
	  elseif at == 'NEXT'
	    exe lnum + 1
	  else
	    exe lnum - 1
	  endif
	  try
	    normal ==
	  catch
	    call append(indent_at, 'ERROR: ' . v:exception)
	    let failed = 1
	  endtry
	endif
      endif
    endwhile

    if !failed
      " Check the resulting text equals the .ok file.
      if getline(1, '$') != readfile(root . '.ok')
	let failed = 1
      endif
    endif

    if failed
      let failed_count += 1
      exe 'write ' . root . '.fail'
      echoerr 'Test ' . fname . ' FAILED!'
    else
      exe 'write ' . root . '.out'
      echo "Test " . fname . " OK\n"
    endif

    quit!  " close the indented file
  endif
endfor

" Matching "if 1" at the start.
endif

if failed_count > 0
  " have make report an error
  cquit
endif
qall!