v / cmd / tools / test_if_v_test_system_works.v
145 lines · 129 sloc · 4.71 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
1module main
2
3// This program verifies that `v test` propagates errors
4// and that it exits with code 1, when at least 1 FAIL happen.
5import os
6import rand
7import time
8
9const vexe = os.quoted_path(get_vexe_path())
10const vroot = os.dir(vexe)
11const tdir = new_tdir()
12
13fn get_vexe_path() string {
14 env_vexe := os.getenv('VEXE')
15 if env_vexe != '' {
16 return env_vexe
17 }
18 me := os.executable()
19 eprintln('me: ${me}')
20 mut vexe_ := os.join_path(os.dir(os.dir(os.dir(me))), 'v')
21 if os.user_os() == 'windows' {
22 vexe_ += '.exe'
23 }
24 return vexe_
25}
26
27fn new_tdir() string {
28 dir := os.join_path(os.vtmp_dir(), rand.ulid())
29 os.rmdir_all(dir) or {}
30 os.mkdir_all(dir) or { panic(err) }
31 at_exit(cleanup_tdir) or {}
32 return dir
33}
34
35fn cleanup_tdir() {
36 println('... removing tdir: ${tdir}')
37 os.rmdir_all(tdir) or { eprintln(err) }
38}
39
40type MyResult = string
41
42@[noreturn]
43fn (result MyResult) fail(reason string) {
44 eprintln('> ${reason}, but it does not. Result:\n${result}')
45 exit(1)
46}
47
48fn (result MyResult) has(sub string) MyResult {
49 if !result.contains(sub) {
50 result.fail(' result should have the substring `${sub}`')
51 }
52 return result
53}
54
55fn (result MyResult) matches(gpattern string) MyResult {
56 if !result.match_glob(gpattern) {
57 result.fail('result should match the glob pattern `${gpattern}`')
58 }
59 return result
60}
61
62fn create_test(tname string, tcontent string) !string {
63 tpath := os.join_path(tdir, tname)
64 os.write_file(tpath, tcontent)!
65 eprintln('>>>>>>>> tpath: ${tpath} | tcontent: ${tcontent}')
66 return os.quoted_path(tpath)
67}
68
69fn check_assert_continues_works() ! {
70 os.chdir(tdir)!
71 create_test('assert_continues_option_works_test.v',
72 'fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false }')!
73 result := check_fail('${vexe} -assert continues assert_continues_option_works_test.v')
74 result.has('assert_continues_option_works_test.v:1: fn test_fail1')
75 result.has('assert_continues_option_works_test.v:2: fn test_fail1')
76 result.has('assert_continues_option_works_test.v:3: fn test_fail1')
77 result.has('assert_continues_option_works_test.v:5: fn test_fail2')
78 result.has('> assert 2 == 4').has('> assert 2 == 1').has('> assert 2 == 0')
79 // Check if a test function, tagged with [assert_continues], has the same behaviour, without needing additional options
80 create_test('assert_continues_tag_works_test.v',
81 '@[assert_continues]fn test_fail1() { assert 2==4\nassert 2==1\nassert 2==0 }\nfn test_ok(){ assert true }\nfn test_fail2() { assert false\n assert false }')!
82 tag_res := check_fail('${vexe} assert_continues_tag_works_test.v')
83 tag_res.has('assert_continues_tag_works_test.v:1: fn test_fail1')
84 tag_res.has('assert_continues_tag_works_test.v:2: fn test_fail1')
85 tag_res.has('assert_continues_tag_works_test.v:3: fn test_fail1')
86 tag_res.has('assert_continues_tag_works_test.v:5: fn test_fail2')
87 if tag_res.contains('assert_continues_tag_works_test.v:6: fn test_fail2') {
88 exit(1)
89 }
90}
91
92fn check_ok(cmd string) MyResult {
93 println('> check_ok cmd: ${cmd}')
94 res := os.execute(cmd)
95 if res.exit_code != 0 {
96 eprintln('> check_ok failed.\n${res.output}')
97 exit(1)
98 }
99 return res.output
100}
101
102fn check_fail(cmd string) MyResult {
103 println('> check_fail cmd: ${cmd}')
104 res := os.execute(cmd)
105 if res.exit_code == 0 {
106 eprintln('> check_fail succeeded, but it should have failed.\n${res.output}')
107 exit(1)
108 }
109 return res.output
110}
111
112fn main() {
113 defer {
114 os.chdir(os.wd_at_startup) or {}
115 }
116 unbuffer_stdout()
117 spawn fn () {
118 time.sleep(120 * time.second)
119 eprintln('>>> exiting due to an expired watchdog timer <<<')
120 exit(1)
121 }()
122 println('> vroot: ${vroot} | vexe: ${vexe} | tdir: ${tdir}')
123 os.setenv('VTEST_HIDE_OK', '0', true)
124 ok_fpath := create_test('a_single_ok_test.v', 'fn test_ok(){ assert true }')!
125 if check_ok('${vexe} ${ok_fpath}') != '' {
126 exit(1)
127 }
128 check_ok('${vexe} test ${ok_fpath}').matches('*OK*a_single_ok_test.v*')
129 check_ok('${vexe} test "${tdir}"').matches('*OK*a_single_ok_test.v*')
130 check_ok('${vexe} -stats test "${tdir}"').matches('*OK*a_single_ok_test.v*')
131
132 fail_fpath := create_test('a_single_failing_test.v', 'fn test_fail(){ assert 1 == 2 }')!
133 check_fail('${vexe} ${fail_fpath}').has('> assert 1 == 2').has('a_single_failing_test.v:1: fn test_fail')
134 check_fail('${vexe} test ${fail_fpath}').has('> assert 1 == 2').has('a_single_failing_test.v:1: fn test_fail')
135 check_fail('${vexe} test "${tdir}"').has('> assert 1 == 2')
136 check_fail('${vexe} -stats test "${tdir}"').has('> assert 1 == 2')
137 rel_dir := os.join_path(tdir, rand.ulid())
138 os.mkdir(rel_dir)!
139 os.chdir(rel_dir)!
140 relative_path := '..' + os.path_separator + 'a_single_ok_test.v'
141 check_ok('${vexe} test ${os.quoted_path(relative_path)}').has('OK').has('a_single_ok_test.v')
142
143 check_assert_continues_works()!
144 println('> all done')
145}
146