1
+ local help_message = [[ test-runner [...options] [...test_files] [-- [...busted_options]
2
+
3
+ Run tests using neotest-busted from the commandline. Options given after '--'
4
+ are forwarded to busted.
5
+
6
+ Usage:
7
+
8
+ -h, --help Show this help message.
9
+ ]]
10
+
11
+ --- @class ParsedArgs
12
+ --- @field help boolean
13
+ --- @field paths string[]
14
+ --- @field busted_args string[]
15
+
1
16
--- @enum Color
2
17
local Color = {
3
18
Red = 31 ,
@@ -32,93 +47,127 @@ local level_options = {
32
47
color = Color .White ,
33
48
hl_group = " MoreMsg" ,
34
49
},
50
+ [vim .log .levels .OFF ] = {
51
+ name = " " ,
52
+ color = Color .Reset ,
53
+ hl_group = " " ,
54
+ },
35
55
}
36
56
57
+ local function is_windows ()
58
+ if jit then
59
+ return not vim .tbl_contains ({ " linux" , " osx" , " bsd" , " posix" , " other" }, jit .os :lower ())
60
+ else
61
+ return package.config :sub (1 , 1 ) == " \\ "
62
+ end
63
+ end
64
+
65
+ local _is_windows = is_windows ()
66
+
37
67
local function is_headless ()
38
68
return # vim .api .nvim_list_uis () == 0
39
69
end
40
70
41
71
--- @param color integer
42
72
--- @return string
43
73
local function color_code (color )
74
+ if _is_windows then
75
+ return " "
76
+ end
77
+
44
78
return (" \x1b [%dm" ):format (color )
45
79
end
46
80
47
81
--- @param message string
48
82
--- @param level vim.log.levels ?
49
83
local function print_level (message , level )
50
- local options = level_options [level ] or level_options [vim .log .levels .ERROR ]
84
+ local _level = level or vim .log .levels .OFF
85
+ local options = level_options [_level ]
86
+ local prefix = " "
51
87
52
88
if is_headless () then
53
- io.stderr : write (
54
- (" %s%s%s: %s \n " ):format (
89
+ if _level ~= vim . log . levels . OFF then
90
+ prefix = (" %s%s%s: " ):format (
55
91
color_code (options .color ),
56
92
options .name ,
57
- color_code (Color .Reset ),
58
- message
93
+ color_code (Color .Reset )
59
94
)
60
- )
95
+ end
96
+
97
+ io.stderr :write ((" %s%s\n " ):format (prefix , message ))
61
98
else
99
+ if _level ~= vim .log .levels .OFF then
100
+ prefix = (" [neotest-busted:%s]: " ):format (options .name )
101
+ end
102
+
62
103
vim .api .nvim_echo ({
63
- { ( " [neotest-busted:%s]: " ): format ( options . name ) , options .hl_group },
104
+ { prefix , options .hl_group },
64
105
{ message },
65
106
}, true , {})
66
107
end
67
108
end
68
109
69
110
--- @return string ?
70
111
local function find_minimal_init ()
71
- -- NOTE: Do not use util.glob as we haven't loaded neotest-busted at this point
72
112
local glob_matches = vim .fn .glob (" **/minimal_init.lua" , false , true )
73
113
74
114
if # glob_matches == 0 then
75
- print_level (" Could not find minimal_init.lua" )
115
+ print_level (" Could not find minimal_init.lua" , vim . log . levels . ERROR )
76
116
return
77
117
end
78
118
79
119
return glob_matches [1 ]
80
120
end
81
121
82
- --- @param module_name string
83
- --- @return any
84
- local function require_checked (module_name )
85
- local ok , module_or_error = pcall (require , module_name )
86
-
87
- if not ok then
88
- return nil
122
+ --- @return ParsedArgs
123
+ local function parse_args ()
124
+ local parsed_args = {
125
+ help = false ,
126
+ paths = {},
127
+ busted_args = {},
128
+ }
129
+
130
+ -- Start from the third argument to skip busted executable and "--ignore-lua" flag
131
+ -- TODO: Should we just use them instead of skipping them?
132
+ for idx = 3 , # _G .arg do
133
+ local arg = _G .arg [idx ]
134
+
135
+ if arg == " -h" or arg == " --help" then
136
+ parsed_args .help = true
137
+ elseif arg == " --" then
138
+ vim .list_extend (parsed_args .busted_args , _G .arg , idx + 1 )
139
+ break
140
+ else
141
+ table.insert (parsed_args .paths , arg )
142
+ end
89
143
end
90
144
91
- return module_or_error
92
- end
93
-
94
- --- @return string[]
95
- local function parse_args ()
96
- return vim .list_slice (_G .arg , 1 )
145
+ return parsed_args
97
146
end
98
147
99
148
--- @return string[]
100
149
local function collect_tests ()
101
150
local tests = {}
102
151
local util = require (" neotest-busted.util" )
103
152
104
- vim .list_extend (tests , util .glob (" ./test/**/*_spec.lua" ))
105
- vim .list_extend (tests , util .glob (" ./tests/**/*_spec.lua" ))
106
- vim .list_extend (tests , util .glob (" ./spec/**/*_spec.lua" ))
153
+ -- TODO: Support other test file patterns (via .busted)
154
+ vim .list_extend (tests , util .glob (" test/**/*_spec.lua" ))
155
+ vim .list_extend (tests , util .glob (" tests/**/*_spec.lua" ))
156
+ vim .list_extend (tests , util .glob (" spec/**/*_spec.lua" ))
107
157
108
158
return tests
109
159
end
110
160
111
161
local function run ()
112
162
if not is_headless () then
113
- print_level (" Script must be run from the command line" )
163
+ print_level (" Script must be run from the command line" , vim . log . levels . ERROR )
114
164
return
115
165
end
116
166
117
- local paths = parse_args ()
118
167
local minimal_init = find_minimal_init ()
119
168
120
169
if not minimal_init then
121
- print_level (" Could not find a minimal_init.lua file" )
170
+ print_level (" Could not find a minimal_init.lua file" , vim . log . levels . ERROR )
122
171
return
123
172
end
124
173
@@ -135,25 +184,33 @@ local function run()
135
184
return
136
185
end
137
186
138
- if # paths == 0 then
139
- paths = collect_tests ()
187
+ local parsed_args = parse_args ()
188
+
189
+ if parsed_args .help then
190
+ print_level (help_message )
191
+ return
140
192
end
141
193
142
- local busted = adapter_or_error .create_test_command (nil , paths , {}, {
194
+ local paths = # parsed_args .paths > 0 and parsed_args .paths or collect_tests ()
195
+
196
+ local test_command = adapter_or_error .create_test_command (nil , paths , {}, {
143
197
busted_output_handler = " utfTerminal" ,
144
198
busted_output_handler_options = { " --color" },
199
+ -- If we don't add --ignore-lua the subsequent busted command (run via
200
+ -- neovim) will use the .busted config file and use the 'lua' option
201
+ -- again for running the tests (this script) which will cause an
202
+ -- infinite process spawning loop
203
+ busted_arguments = vim .list_extend ({ " --ignore-lua" }, parsed_args .busted_args ),
145
204
})
146
205
147
- if not busted then
148
- print_level (" Could not find a busted executable" )
206
+ if not test_command then
207
+ print_level (" Could not find a busted executable" , vim . log . levels . ERROR )
149
208
return
150
209
end
151
210
152
- local command = vim .list_extend ({ busted .nvim_command }, busted .arguments )
211
+ local command = vim .list_extend ({ test_command .nvim_command }, test_command .arguments )
153
212
154
- io.stdout :write (
155
- vim .fn .system (table.concat (vim .tbl_map (vim .fn .shellescape , command ), " " ))
156
- )
213
+ io.stdout :write (vim .fn .system (table.concat (vim .tbl_map (vim .fn .shellescape , command ), " " )))
157
214
end
158
215
159
216
run ()
0 commit comments