v / cmd / tools / vtest_test.v
139 lines · 127 sloc · 5.38 KB · 221f83d0e9311f7c6df79c88c6b5f73c9f639131
Raw
1import os
2import encoding.txtar
3
4const vexe = @VEXE
5const vroot = os.dir(vexe)
6const tpath = os.join_path(os.vtmp_dir(), 'vtest_folder')
7const tpath_passing = os.join_path(tpath, 'passing')
8const tpath_impure = os.join_path(tpath, 'impure')
9const tpath_js_runtime_error = os.join_path(tpath, 'js_runtime_error')
10const tpath_partial = os.join_path(tpath, 'partial')
11const mytest_exe = os.join_path(tpath, 'mytest.exe')
12
13fn testsuite_end() {
14 os.rmdir_all(tpath) or {}
15}
16
17fn testsuite_begin() {
18 os.setenv('VFLAGS', '', true)
19 os.setenv('VCOLORS', 'never', true)
20 os.setenv('VJOBS', '2', true)
21 os.setenv('VTEST_HIDE_OK', '0', true)
22 os.rmdir_all(tpath) or {}
23 os.mkdir_all(tpath)!
24
25 txtar.parse('Some known test files to make sure `v test` and `v -stats test` work:
26-- passing/1_test.v --
27fn test_abc() { assert true; assert true; assert true }
28fn test_def() { assert 2 * 2 == 4 }
29-- passing/2_test.v --
30fn test_xyz() { assert 1 == 2 - 1 }
31fn test_abc() { assert 10 == 2 * 5 }
32-- impure/warning_test.v --
33fn test_warning() {
34 C.printf(c"")
35}
36-- js_runtime_error/runtime_error_test.js.v --
37fn test_runtime_error() {
38 JS.eval("(()=>{ throw new TypeError(`boom`) })()".str)
39}
40-- partial/passing_test.v --
41fn test_xyz() { assert 3 == 10 - 7 }
42fn test_def() { assert 10 == 100 / 10 }
43-- partial/failing_test.v --
44fn test_xyz() { assert 5 == 7, "oh no" }
45').unpack_to(tpath)!
46 assert os.exists(os.join_path(tpath, 'passing/1_test.v'))
47 assert os.exists(os.join_path(tpath, 'passing/2_test.v'))
48 assert os.exists(os.join_path(tpath, 'impure/warning_test.v'))
49 assert os.exists(os.join_path(tpath, 'js_runtime_error/runtime_error_test.js.v'))
50 assert os.exists(os.join_path(tpath, 'partial/passing_test.v'))
51 assert os.exists(os.join_path(tpath, 'partial/failing_test.v'))
52}
53
54fn test_vtest_executable_compiles() {
55 os.chdir(vroot)!
56 os.execute_or_exit('${os.quoted_path(vexe)} -o ${tpath}/mytest.exe cmd/tools/vtest.v')
57 assert os.exists(mytest_exe), 'executable file: `${mytest_exe}` should exist'
58}
59
60fn test_with_several_test_files() {
61 res := os.execute_or_exit('${os.quoted_path(mytest_exe)} test ${os.quoted_path(tpath_passing)}')
62 assert !res.output.contains('1 assert'), res.output
63 assert !res.output.contains('3 asserts'), res.output
64 assert res.output.contains('2 passed, 2 total'), res.output
65 assert res.output.count('OK') == 2, res.output
66 assert res.output.contains('on 2 parallel jobs'), res.output
67}
68
69fn test_with_stats_and_several_test_files() {
70 // There should be more OKs here, since the output will have the inner OKs for each individual test fn:
71 res :=
72 os.execute_or_exit('${os.quoted_path(mytest_exe)} -stats test ${os.quoted_path(tpath_passing)}')
73 assert res.output.contains('1 assert'), res.output
74 assert res.output.contains('3 asserts'), res.output
75 assert res.output.contains('2 passed, 2 total'), res.output
76 assert res.output.count('OK') == 6, res.output
77 run_1 := '1_test.v\n OK'
78 run_2 := '2_test.v\n OK'
79 summary_1 := 'Summary for running V tests in "1_test.v"'
80 summary_2 := 'Summary for running V tests in "2_test.v"'
81 run_1_idx := res.output.index(run_1) or { -1 }
82 run_2_idx := res.output.index(run_2) or { -1 }
83 summary_1_idx := res.output.index(summary_1) or { -1 }
84 summary_2_idx := res.output.index(summary_2) or { -1 }
85 assert run_1_idx != -1, res.output
86 assert run_2_idx != -1, res.output
87 assert summary_1_idx != -1, res.output
88 assert summary_2_idx != -1, res.output
89 assert run_1_idx < summary_1_idx, res.output
90 assert run_2_idx < summary_2_idx, res.output
91 assert summary_1_idx < run_2_idx || summary_2_idx < run_1_idx, res.output
92}
93
94fn test_partial_failure() {
95 res := os.execute('${os.quoted_path(mytest_exe)} test ${os.quoted_path(tpath_partial)}')
96 assert res.exit_code == 1
97 assert res.output.contains('assert 5 == 7'), res.output
98 assert res.output.contains(' 1 failed, 1 passed, 2 total'), res.output
99 assert res.output.contains('To reproduce just failure'), res.output
100}
101
102fn test_run_only_reports_filtered_failures() {
103 failing_test_path := os.join_path(tpath_partial, 'failing_test.v')
104 res :=
105 os.execute('${os.quoted_path(mytest_exe)} test -run-only test_xyz ${os.quoted_path(failing_test_path)}')
106 assert res.exit_code == 1
107 assert res.output.contains('assert 5 == 7'), res.output
108 assert res.output.contains(' 1 failed, 1 total'), res.output
109}
110
111fn test_wimpure_v_warnings_are_shown_for_test_files() {
112 res :=
113 os.execute_or_exit('${os.quoted_path(mytest_exe)} -Wimpure-v test ${os.quoted_path(tpath_impure)}')
114 assert res.output.contains('warning_test.v'), res.output
115 assert res.output.contains('warning: C code will not be allowed in pure .v files'), res.output
116}
117
118fn test_js_runtime_errors_are_shown_for_js_tests() {
119 if @CCOMPILER.contains('musl') || os.getenv('VFLAGS').contains('musl')
120 || os.getenv('V_CI_MUSL') == '1' {
121 return
122 }
123 if os.execute('node --version').exit_code != 0 {
124 return
125 }
126 res :=
127 os.execute('${os.quoted_path(mytest_exe)} test ${os.quoted_path(tpath_js_runtime_error)}')
128 assert res.exit_code == 1, res.output
129 assert res.output.contains('runtime_error_test.js.v'), res.output
130 assert res.output.contains('TypeError: boom'), res.output
131}
132
133fn test_with_stats_and_partial_failure() {
134 res := os.execute('${os.quoted_path(mytest_exe)} -stats test ${os.quoted_path(tpath_partial)}')
135 assert res.exit_code == 1
136 assert res.output.contains('assert 5 == 7'), res.output
137 assert res.output.contains(' 1 failed, 1 passed, 2 total'), res.output
138 assert res.output.contains('To reproduce just failure'), res.output
139}
140