forked from exercism/vimscript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate.vim
115 lines (103 loc) · 3.14 KB
/
generate.vim
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
"
" This Vim script fetches the canonical test data for an
" exercise from GitHub and converts it to a Vader file.
"
" :source %
" :Generate word-count
"
if get(g:, 'loaded_netrwPlugin') != 0
echoerr 'This generator script needs the netrw plugin to be loaded.'
finish
elseif !exists('*json_decode')
echoerr 'The function json_decode() is not available. This generator script needs a newer Vim version.'
finish
endif
function! s:data_url(slug) abort
return printf('https://raw.githubusercontent.com/exercism/problem-specifications/master/exercises/%s/canonical-data.json', a:slug)
endfunction
function! s:generate_header(data)
call append(0, [
\ '"',
\ '" Version: '. a:data.version,
\ '"',
\ ])
endfunction
function! s:generate_variable(name, value)
let value = a:value
if type(a:value) == type('')
let value = '"'. value .'"'
endif
call append(line('$'), printf(' let g:%s = %s', a:name, value))
endfunction
function! s:generate_assert(test, arguments) abort
let funcname = toupper(a:test.property[0]) . a:test.property[1:]
if type(a:test.expected) == type({}) && has_key(a:test.expected, 'error')
call s:generate_variable('expected', a:test.expected.error)
call append(line('$'),
\ printf(' AssertThrows call %s(%s)', funcname, join(a:arguments, ', ')))
call append(line('$'), ' AssertEqual g:expected, g:vader_exception')
else
call s:generate_variable('expected', a:test.expected)
call append(line('$'),
\ printf(' AssertEqual g:expected, %s(%s)', funcname, join(a:arguments, ', ')))
endif
call append(line('$'), '')
endfunction
function! s:generate_tests(tests) abort
for test in a:tests
if has_key(test, 'cases')
call s:generate_tests(test.cases)
else
let arguments = []
call append(line('$'), printf('Execute (%s):', test.description))
for [arg, val] in sort(items(test.input))
call s:generate_variable(arg, val)
let arguments += ['g:'.arg]
endfor
call s:generate_assert(test, arguments)
endif
endfor
if empty(getline(line('$')))
silent $delete _
endif
endfunction
function! s:replace_types() abort
silent %substitute/v:true/1/eg
silent %substitute/v:false/0/eg
silent %substitute/v:null/''/eg
endfunction
function! s:generate(slug) abort
execute 'silent edit' s:data_url(a:slug)
if getline(1) ==# '404: Not Found'
silent bwipeout!
redraw!
echomsg '404: Not Found'
return
elseif line2byte('$') == -1
silent bwipeout!
echomsg 'Got empty buffer. Have you disabled the netrw plugin?'
return
endif
%yank x
try
let data = json_decode(substitute(@x, '\\', '\\\\', 'g'))
catch
redraw
echohl ErrorMsg
echomsg 'JSON decoding failed.'
echomsg 'Trying again without backslash escaping.'
echomsg 'Check escaping in the generated tests!'
echohl None
call input('[press any key]')
let data = json_decode(@x)
endtry
bwipeout!
enew!
setfiletype vader
call s:generate_header(data)
call s:generate_tests(data.cases)
call s:replace_types()
set nomodified
redraw!
endfunction
command! -nargs=1 Generate call s:generate(<f-args>)