vxx2 / vlib / v3 / tests / fn_nil_context_test.v
157 lines · 138 sloc · 3.42 KB · 288feee4702b35beadb4037d02b96b5c8674156b
Raw
1import os
2
3const vexe = @VEXE
4const tests_dir = os.dir(@FILE)
5const v3_dir = os.dir(tests_dir)
6const vlib_dir = os.dir(v3_dir)
7const v3_src = os.join_path(v3_dir, 'v3.v')
8
9fn build_v3() string {
10 v3_bin := os.join_path(os.temp_dir(), 'v3_fn_nil_context_test')
11 build :=
12 os.execute('${vexe} -gc none -path "${vlib_dir}|@vlib|@vmodules" -o ${v3_bin} ${v3_src}')
13 assert build.exit_code == 0, build.output
14 return v3_bin
15}
16
17fn run_good(v3_bin string, name string, src string) string {
18 good_src := os.join_path(os.temp_dir(), 'v3_${name}.v')
19 os.write_file(good_src, src) or { panic(err) }
20 good_bin := os.join_path(os.temp_dir(), 'v3_${name}')
21 compile := os.execute('${v3_bin} ${good_src} -b c -o ${good_bin}')
22 assert compile.exit_code == 0, '${name}: compile failed: ${compile.output}'
23 assert !compile.output.contains('C compilation failed'), '${name}: C compilation failed: ${compile.output}'
24 run := os.execute(good_bin)
25 assert run.exit_code == 0, '${name}: run failed: ${run.output}'
26 return run.output.trim_space()
27}
28
29fn run_bad(v3_bin string, name string, src string, expected string) {
30 bad_src := os.join_path(os.temp_dir(), 'v3_${name}.v')
31 os.write_file(bad_src, src) or { panic(err) }
32 bad_bin := os.join_path(os.temp_dir(), 'v3_${name}')
33 result := os.execute('${v3_bin} ${bad_src} -b c -o ${bad_bin}')
34 assert result.exit_code != 0
35 assert result.output.contains(expected), '${name}: missing `${expected}` in ${result.output}'
36 assert !result.output.contains('C compilation failed')
37}
38
39fn test_unsafe_nil_contextually_matches_fn_fields() {
40 v3_bin := build_v3()
41 default_out := run_good(v3_bin, 'fn_nil_default', 'struct S {
42 f fn (int) ! = unsafe { nil }
43}
44
45fn main() {
46 _ := S{}
47 println(int_str(1))
48}
49')
50 assert default_out == '1'
51 alias_out := run_good(v3_bin, 'fn_alias_nil_field_init', 'type Callback = fn (data voidptr)
52
53struct S {
54 f Callback
55}
56
57fn main() {
58 _ := S{
59 f: unsafe { nil }
60 }
61 println(int_str(2))
62}
63')
64 assert alias_out == '2'
65 run_bad(v3_bin, 'fn_field_rejects_voidptr_variable', 'struct S {
66 f fn (int) !
67}
68
69fn main() {
70 v := unsafe { nil }
71 _ := S{
72 f: v
73 }
74}
75',
76 'cannot initialize field `f` with `&void`; expected `fn(int) !void`')
77 run_bad(v3_bin, 'fn_field_rejects_non_nil_unsafe_pointer', 'struct S {
78 f fn (int) !
79}
80
81fn main() {
82 _ := S{
83 f: unsafe { &int(0) }
84 }
85}
86',
87 'cannot initialize field `f` with `&int`; expected `fn(int) !void`')
88 run_bad(v3_bin, 'fn_field_rejects_voidptr_zero', 'struct S {
89 f fn (int) !
90}
91
92fn main() {
93 _ := S{
94 f: voidptr(0)
95 }
96}
97',
98 'cannot initialize field `f` with `&void`; expected `fn(int) !void`')
99 run_bad(v3_bin, 'fn_field_rejects_integer_zero', 'struct S {
100 f fn (int) !
101}
102
103fn main() {
104 _ := S{
105 f: 0
106 }
107}
108',
109 'cannot initialize field `f` with `int`; expected `fn(int) !void`')
110 run_bad(v3_bin, 'fn_field_rejects_wrong_arity', 'fn no_args() ! {
111 return
112}
113
114struct S {
115 f fn (int) !
116}
117
118fn main() {
119 _ := S{
120 f: no_args
121 }
122}
123',
124 'cannot initialize field `f` with `fn() !void`; expected `fn(int) !void`')
125 run_bad(v3_bin, 'fn_field_rejects_wrong_return', 'fn returns_int(i int) !int {
126 return i
127}
128
129struct S {
130 f fn (int) !
131}
132
133fn main() {
134 _ := S{
135 f: returns_int
136 }
137}
138',
139 'cannot initialize field `f` with `fn(int) !int`; expected `fn(int) !void`')
140 run_bad(v3_bin, 'fn_alias_field_rejects_wrong_arity', 'type Callback = fn (int) !
141
142fn no_args() ! {
143 return
144}
145
146struct S {
147 f Callback
148}
149
150fn main() {
151 _ := S{
152 f: no_args
153 }
154}
155',
156 'cannot initialize field `f` with `fn() !void`; expected `Callback`')
157}
158