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
|
module main
import os
import os.cmdline
import testing
import v.pref
fn main() {
args := os.args.clone()
if os.args.last() == 'test' {
show_usage()
return
}
args_to_executable := args[1..]
args_before := cmdline.options_before(args_to_executable, ['test'])
args_after := cmdline.options_after(args_to_executable, ['test'])
if args_after.join(' ') == 'v' {
eprintln('`v test v` has been deprecated.')
eprintln('Use `v test-all` instead.')
exit(1)
}
backend_pos := args_before.index('-b')
backend := if backend_pos == -1 { '.c' } else { args_before[backend_pos + 1] } // this giant mess because closures are not implemented
mut ts := testing.new_test_session(args_before.join(' '), true)
for targ in args_after {
if os.is_dir(targ) {
// Fetch all tests from the directory
files, skip_files := should_test_dir(targ.trim_right(os.path_separator), backend)
ts.files << files
ts.skip_files << skip_files
continue
} else if os.exists(targ) {
match should_test(targ, backend) {
.test {
ts.files << targ
continue
}
.skip {
ts.files << targ
ts.skip_files << targ
continue
}
.ignore {}
}
} else {
eprintln('\nUnrecognized test file `$targ`.\n `v test` can only be used with folders and/or _test.v files.\n')
show_usage()
exit(1)
}
}
testing.header('Testing...')
ts.test()
println(ts.benchmark.total_message('all V _test.v files'))
if ts.failed {
exit(1)
}
}
fn show_usage() {
println('Usage:')
println(' A)')
println(' v test folder/ : run all v tests in the given folder.')
println(' v -stats test folder/ : the same, but print more stats.')
println(' B)')
println(' v test file_test.v : run test functions in a given test file.')
println(' v -stats test file_test.v : as above, but with more stats.')
println(' NB: you can also give many and mixed folder/ file_test.v arguments after `v test` .')
println('')
}
pub fn should_test_dir(path string, backend string) ([]string, []string) { // return is (files, skip_files)
mut files := os.ls(path) or { return []string{}, []string{} }
mut local_path_separator := os.path_separator
if path.ends_with(os.path_separator) {
local_path_separator = ''
}
mut res_files := []string{}
mut skip_files := []string{}
for file in files {
p := path + local_path_separator + file
if os.is_dir(p) && !os.is_link(p) {
if file == 'testdata' {
continue
}
ret_files, ret_skip_files := should_test_dir(p, backend)
res_files << ret_files
skip_files << ret_skip_files
} else if os.exists(p) {
match should_test(p, backend) {
.test {
res_files << p
}
.skip {
res_files << p
skip_files << p
}
.ignore {}
}
}
}
return res_files, skip_files
}
enum ShouldTestStatus {
test // do test
skip
ignore
}
fn should_test(path string, backend string) ShouldTestStatus {
if path.ends_with('_test.v') {
return .test
}
if path.ends_with('.v') && path.count('.') == 2 {
if !path.all_before_last('.v').all_before_last('.').ends_with('_test') {
return .ignore
}
backend_arg := path.all_before_last('.v').all_after_last('.')
arch := pref.arch_from_string(backend_arg) or { pref.Arch._auto }
if arch == pref.get_host_arch() {
return .test
} else if arch == ._auto {
if backend_arg == 'c' { // .c.v
return if backend == 'c' { ShouldTestStatus.test } else { ShouldTestStatus.skip }
}
if backend_arg == 'js' {
return if backend == 'js' { ShouldTestStatus.test } else { ShouldTestStatus.skip }
}
} else {
return .skip
}
}
return .ignore
}
|