v / vlib / v2 / pref / pref_test.v
392 lines · 342 sloc · 16.71 KB · e8810a671233f1d2072d70ab8e17c3b1dad5e1e5
Raw
1module pref
2
3import os
4
5fn test_source_files_from_args_skips_os_option_value() {
6 files := source_files_from_args(['-b', 'x64', '-os', 'windows', '-o', 'app', 'main.v'])
7 assert files == ['main.v']
8}
9
10fn test_source_files_from_args_skips_fhooks_option_value() {
11 files := source_files_from_args(['-freestanding', '-fhooks', 'output,panic', '-o', 'app',
12 'main.v'])
13 assert files == ['main.v']
14}
15
16fn test_new_preferences_from_args_defaults_to_host_target() {
17 prefs := new_preferences_from_args(['main.v'])
18 assert prefs.target_os == normalize_target_os_name(os.user_os())
19 assert prefs.normalized_target_os() == normalize_target_os_name(os.user_os())
20 assert !prefs.is_cross_target()
21 assert !prefs.is_freestanding()
22 assert 'cross' !in prefs.user_defines
23 assert 'freestanding' !in prefs.user_defines
24 assert prefs.explicit_user_defines.len == 0
25}
26
27fn test_new_preferences_from_args_parses_macos_tiny_opt_out() {
28 default_prefs := new_preferences_from_args(['-b', 'x64', '-os', 'macos', 'main.v'])
29 assert default_prefs.macos_tiny
30
31 opt_out_prefs :=
32 new_preferences_from_args(['-b', 'x64', '-no-mos-tiny', '-os', 'macos', 'main.v'])
33 assert !opt_out_prefs.macos_tiny
34}
35
36fn test_macos_tiny_opt_out_requires_macos_target() {
37 validate_macos_tiny_flag_contract(['-no-mos-tiny'], 'macos')!
38
39 for target in ['linux', 'windows', 'cross', 'none'] {
40 mut got_error := false
41 validate_macos_tiny_flag_contract(['-no-mos-tiny'], target) or {
42 got_error = true
43 assert err.msg().contains('-no-mos-tiny requires a macOS target')
44 }
45 assert got_error, '-no-mos-tiny was accepted for target ${target}'
46 }
47}
48
49fn test_macos_tiny_opt_out_rejection_has_cli_error_prefix() {
50 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_pref_macos_tiny_error_${os.getpid()}')
51 os.rmdir_all(tmp_dir) or {}
52 os.mkdir_all(tmp_dir) or { panic(err) }
53 defer {
54 os.rmdir_all(tmp_dir) or {}
55 }
56 source_path := os.join_path(tmp_dir, 'main.v')
57 os.write_file(source_path,
58 "import v2.pref\n\nfn main() {\n\tpref.new_preferences_from_args(['-no-mos-tiny', '-os', 'linux', 'main.v'])\n}\n") or {
59 panic(err)
60 }
61 vlib_path := os.join_path(os.dir(@VEXE), 'vlib')
62 res :=
63 os.execute('${os.quoted_path(@VEXE)} -path "${vlib_path}|@vlib|@vmodules" run ${os.quoted_path(source_path)}')
64 assert res.exit_code == 1, res.output
65 assert res.output.contains('error: -no-mos-tiny requires a macOS target'), res.output
66}
67
68fn test_new_preferences_from_args_parses_target_os() {
69 linux_prefs := new_preferences_from_args(['-os', 'linux', 'main.v'])
70 assert linux_prefs.target_os == 'linux'
71 assert linux_prefs.normalized_target_os() == 'linux'
72 assert !linux_prefs.is_cross_target()
73
74 windows_prefs := new_preferences_from_args(['-os', 'windows', 'main.v'])
75 assert windows_prefs.target_os == 'windows'
76 assert windows_prefs.normalized_target_os() == 'windows'
77
78 termux_prefs := new_preferences_from_args(['-os', 'termux', 'main.v'])
79 assert termux_prefs.target_os == 'termux'
80 assert termux_prefs.normalized_target_os() == 'termux'
81 assert comptime_flag_value(&termux_prefs, 'termux')
82}
83
84fn test_new_preferences_from_args_normalizes_macos_target_aliases() {
85 macos_prefs := new_preferences_from_args(['-os', 'macos', 'main.v'])
86 assert macos_prefs.target_os == 'macos'
87 assert macos_prefs.normalized_target_os() == 'macos'
88
89 darwin_prefs := new_preferences_from_args(['-os', 'darwin', 'main.v'])
90 assert darwin_prefs.target_os == 'macos'
91 assert darwin_prefs.normalized_target_os() == 'macos'
92
93 mac_prefs := new_preferences_from_args(['-os', 'mac', 'main.v'])
94 assert mac_prefs.target_os == 'macos'
95 assert mac_prefs.normalized_target_os() == 'macos'
96}
97
98fn test_new_preferences_from_args_cross_is_not_concrete_os() {
99 prefs := new_preferences_from_args(['-os', 'cross', 'main.v'])
100 assert prefs.target_os == 'cross'
101 assert prefs.normalized_target_os() == 'cross'
102 assert prefs.is_cross_target()
103 assert 'cross' in prefs.user_defines
104 assert 'cross' !in prefs.explicit_user_defines
105 assert comptime_flag_value(&prefs, 'cross')
106 assert !comptime_optional_flag_value(&prefs, 'cross')
107 assert !comptime_flag_value(&prefs, 'linux')
108 assert !comptime_flag_value(&prefs, 'macos')
109 assert !comptime_flag_value(&prefs, 'darwin')
110 assert !comptime_flag_value(&prefs, 'windows')
111}
112
113fn test_new_preferences_from_args_freestanding_is_distinct_from_cross() {
114 prefs := new_preferences_from_args(['-freestanding', '-os', 'linux', 'main.v'])
115 assert prefs.is_freestanding()
116 assert !prefs.is_cross_target()
117 assert prefs.normalized_target_os() == 'linux'
118 assert comptime_flag_value(&prefs, 'freestanding')
119 assert comptime_flag_value(&prefs, 'linux')
120 assert !comptime_flag_value(&prefs, 'cross')
121 assert 'freestanding' in prefs.user_defines
122 assert 'freestanding' !in prefs.explicit_user_defines
123 assert !comptime_optional_flag_value(&prefs, 'freestanding')
124}
125
126fn test_new_preferences_from_args_accepts_freestanding_none_target() {
127 prefs := new_preferences_from_args(['-freestanding', '-os', 'none', 'main.v'])
128 assert prefs.is_freestanding()
129 assert !prefs.is_cross_target()
130 assert prefs.target_os == 'none'
131 assert prefs.normalized_target_os() == 'none'
132 assert prefs.source_filter_target_os() == 'none'
133 assert !prefs.can_compile_cleanc_locally()
134 assert comptime_flag_value(&prefs, 'freestanding')
135 assert comptime_flag_value(&prefs, 'none')
136 assert !comptime_optional_flag_value(&prefs, 'none')
137 assert !comptime_flag_value(&prefs, 'cross')
138 assert !comptime_flag_value(&prefs, 'linux')
139 assert !comptime_flag_value(&prefs, 'macos')
140 assert !comptime_flag_value(&prefs, 'windows')
141}
142
143fn test_can_compile_cleanc_locally_follows_target_contract() {
144 host := normalize_target_os_name(os.user_os())
145 host_prefs := new_preferences_from_args(['-os', host, 'main.v'])
146 assert host_prefs.can_compile_cleanc_locally()
147
148 cross_prefs := new_preferences_from_args(['-os', 'cross', 'main.v'])
149 assert cross_prefs.can_compile_cleanc_locally()
150 assert cross_prefs.source_filter_target_os() == host
151
152 freestanding_prefs := new_preferences_from_args(['-freestanding', '-os', host, 'main.v'])
153 assert !freestanding_prefs.can_compile_cleanc_locally()
154 assert freestanding_prefs.source_filter_target_os() == host
155
156 non_host := if host == 'windows' { 'linux' } else { 'windows' }
157 non_host_prefs := new_preferences_from_args(['-os', non_host, 'main.v'])
158 assert !non_host_prefs.can_compile_cleanc_locally()
159 assert non_host_prefs.source_filter_target_os() == non_host
160}
161
162fn test_can_run_target_binary_locally_follows_effective_target() {
163 host := normalize_target_os_name(os.user_os())
164 host_prefs := new_preferences_from_args(['-os', host, 'main.v'])
165 assert host_prefs.can_run_target_binary_locally()
166
167 cross_prefs := new_preferences_from_args(['-os', 'cross', 'main.v'])
168 assert cross_prefs.can_run_target_binary_locally()
169
170 native_cross_prefs := new_preferences_from_args(['-b', 'x64', '-os', 'cross', 'main.v'])
171 assert native_cross_prefs.backend == .x64
172 assert !native_cross_prefs.can_run_target_binary_locally()
173
174 freestanding_prefs := new_preferences_from_args(['-freestanding', '-os', host, 'main.v'])
175 assert !freestanding_prefs.can_run_target_binary_locally()
176
177 mut native_freestanding_prefs := new_preferences_from_args(['-b', 'x64', '-freestanding', '-os',
178 host, 'main.v'])
179 native_freestanding_prefs.backend = .x64
180 assert !native_freestanding_prefs.can_run_target_binary_locally()
181
182 non_host := if host == 'windows' { 'linux' } else { 'windows' }
183 non_host_prefs := new_preferences_from_args(['-os', non_host, 'main.v'])
184 assert !non_host_prefs.can_run_target_binary_locally()
185
186 mut native_non_host_prefs := new_preferences_from_args(['-b', 'x64', '-os', non_host, 'main.v'])
187 native_non_host_prefs.backend = .x64
188 assert !native_non_host_prefs.can_run_target_binary_locally()
189}
190
191fn test_new_preferences_from_args_parses_freestanding_hooks() {
192 prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'output,panic', '-os', 'linux',
193 'main.v'])
194 assert prefs.is_freestanding()
195 assert !prefs.skip_builtin
196 assert prefs.freestanding_hook_list() == ['output', 'panic']
197 assert prefs.has_freestanding_hooks()
198 assert prefs.has_freestanding_hook('output')
199 assert prefs.has_freestanding_hook('panic')
200 assert !prefs.has_freestanding_hook('alloc')
201 assert 'freestanding_hooks' in prefs.user_defines
202 assert 'freestanding_output' in prefs.user_defines
203 assert 'freestanding_hooks_output' in prefs.user_defines
204 assert 'freestanding_panic' in prefs.user_defines
205 assert 'freestanding_hooks_panic' in prefs.user_defines
206 assert 'freestanding_alloc' !in prefs.user_defines
207 assert 'freestanding_hooks_alloc' !in prefs.user_defines
208 assert prefs.explicit_user_defines.len == 0
209 assert comptime_flag_value(&prefs, 'freestanding_hooks')
210 assert comptime_flag_value(&prefs, 'freestanding_output')
211 assert comptime_flag_value(&prefs, 'freestanding_panic')
212 assert !comptime_flag_value(&prefs, 'freestanding_alloc')
213}
214
215fn test_new_preferences_from_args_uses_implicit_skip_builtin_only_without_freestanding_hooks() {
216 prefs := new_preferences_from_args(['-freestanding', '-os', 'linux', 'main.v'])
217 assert prefs.is_freestanding()
218 assert prefs.skip_builtin
219 assert !prefs.has_freestanding_hooks()
220
221 hook_prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'output', '-os', 'linux',
222 'main.v'])
223 assert hook_prefs.is_freestanding()
224 assert hook_prefs.has_freestanding_hook('output')
225 assert !hook_prefs.skip_builtin
226
227 explicit_hook_prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'output',
228 '--skip-builtin', '-os', 'linux', 'main.v'])
229 assert explicit_hook_prefs.has_freestanding_hook('output')
230 assert explicit_hook_prefs.skip_builtin
231}
232
233fn test_freestanding_hook_defines_do_not_grant_hook_capabilities() {
234 prefs := new_preferences_from_args(['-freestanding', '-d', 'freestanding_output', '-d',
235 'freestanding_panic', '-d', 'freestanding_alloc', 'main.v'])
236 assert prefs.is_freestanding()
237 assert !prefs.has_freestanding_hooks()
238 assert !prefs.has_freestanding_hook('output')
239 assert !prefs.has_freestanding_hook('panic')
240 assert !prefs.has_freestanding_hook('alloc')
241 assert 'freestanding_output' in prefs.user_defines
242 assert 'freestanding_panic' in prefs.user_defines
243 assert 'freestanding_alloc' in prefs.user_defines
244 assert prefs.explicit_user_defines == ['freestanding_output', 'freestanding_panic',
245 'freestanding_alloc']
246 assert comptime_flag_value(&prefs, 'freestanding_output')
247 assert comptime_flag_value(&prefs, 'freestanding_panic')
248 assert comptime_flag_value(&prefs, 'freestanding_alloc')
249}
250
251fn test_new_preferences_from_args_expands_minimal_freestanding_hooks() {
252 prefs := new_preferences_from_args(['-freestanding', '-fhooks', 'minimal', 'main.v'])
253 assert prefs.freestanding_hook_list() == ['output', 'panic', 'alloc']
254 assert prefs.has_freestanding_hook('output')
255 assert prefs.has_freestanding_hook('panic')
256 assert prefs.has_freestanding_hook('alloc')
257 assert comptime_flag_value(&prefs, 'freestanding_output')
258 assert comptime_flag_value(&prefs, 'freestanding_panic')
259 assert comptime_flag_value(&prefs, 'freestanding_alloc')
260}
261
262fn test_new_preferences_using_options_accepts_target_os_and_freestanding() {
263 prefs := new_preferences_using_options(['--cleanc', '--os-windows', '--freestanding'])
264 assert prefs.backend == .cleanc
265 assert prefs.target_os == 'windows'
266 assert prefs.normalized_target_os() == 'windows'
267 assert !prefs.is_cross_target()
268 assert prefs.is_freestanding()
269 assert comptime_flag_value(&prefs, 'windows')
270 assert comptime_flag_value(&prefs, 'freestanding')
271 assert 'freestanding' in prefs.user_defines
272 assert 'freestanding' !in prefs.explicit_user_defines
273
274 termux_prefs := new_preferences_using_options(['--cleanc', '--os-termux'])
275 assert termux_prefs.backend == .cleanc
276 assert termux_prefs.target_os == 'termux'
277 assert termux_prefs.normalized_target_os() == 'termux'
278 assert comptime_flag_value(&termux_prefs, 'termux')
279 assert !comptime_flag_value(&termux_prefs, 'android')
280}
281
282fn test_new_preferences_using_options_accepts_freestanding_hooks() {
283 prefs := new_preferences_using_options(['--cleanc', '--os-linux', '--freestanding',
284 '--fhooks-output,alloc'])
285 assert prefs.is_freestanding()
286 assert prefs.freestanding_hook_list() == ['output', 'alloc']
287 assert prefs.has_freestanding_hook('output')
288 assert prefs.has_freestanding_hook('alloc')
289 assert !prefs.has_freestanding_hook('panic')
290 assert comptime_flag_value(&prefs, 'freestanding_output')
291 assert comptime_flag_value(&prefs, 'freestanding_alloc')
292 assert !comptime_flag_value(&prefs, 'freestanding_panic')
293}
294
295fn test_new_preferences_using_options_accepts_freestanding_none_target() {
296 prefs := new_preferences_using_options(['--cleanc', '--freestanding', '--os-none'])
297 assert prefs.is_freestanding()
298 assert !prefs.is_cross_target()
299 assert prefs.target_os == 'none'
300 assert prefs.source_filter_target_os() == 'none'
301 assert !prefs.can_compile_cleanc_locally()
302}
303
304fn test_new_preferences_using_options_accepts_cross_target() {
305 prefs := new_preferences_using_options(['--cleanc', '--os-cross'])
306 assert prefs.target_os == 'cross'
307 assert prefs.is_cross_target()
308 assert 'cross' in prefs.user_defines
309 assert 'cross' !in prefs.explicit_user_defines
310 assert comptime_flag_value(&prefs, 'cross')
311 assert !comptime_optional_flag_value(&prefs, 'cross')
312 assert !comptime_flag_value(&prefs, 'linux')
313 assert !comptime_flag_value(&prefs, 'macos')
314 assert !comptime_flag_value(&prefs, 'windows')
315}
316
317fn test_new_preferences_from_args_accepted_targets_match_comptime_flags() {
318 for target in ['linux', 'macos', 'darwin', 'mac', 'windows', 'freebsd', 'openbsd', 'netbsd',
319 'dragonfly', 'android', 'termux', 'ios', 'solaris', 'qnx', 'serenity', 'plan9', 'vinix'] {
320 prefs := new_preferences_from_args(['-os', target, 'main.v'])
321 flag_name := match target {
322 'darwin', 'mac' { 'macos' }
323 else { prefs.normalized_target_os() }
324 }
325
326 assert comptime_flag_value(&prefs, flag_name), '${target} should match ${flag_name}'
327 }
328}
329
330fn test_cross_and_freestanding_still_allow_user_defines() {
331 mut prefs := new_preferences()
332 prefs.user_defines = ['cross', 'freestanding']
333 prefs.explicit_user_defines = ['cross', 'freestanding']
334 assert comptime_flag_value(&prefs, 'cross')
335 assert comptime_flag_value(&prefs, 'freestanding')
336 assert comptime_optional_flag_value(&prefs, 'cross')
337 assert comptime_optional_flag_value(&prefs, 'freestanding')
338}
339
340fn test_explicit_user_defines_are_separate_from_synthesized_defines() {
341 cross_prefs := new_preferences_from_args(['-os', 'cross', '-d', 'cross', 'main.v'])
342 assert 'cross' in cross_prefs.user_defines
343 assert 'cross' in cross_prefs.explicit_user_defines
344 assert comptime_optional_flag_value(&cross_prefs, 'cross')
345
346 free_prefs := new_preferences_from_args(['-freestanding', '-d', 'freestanding', 'main.v'])
347 assert 'freestanding' in free_prefs.user_defines
348 assert 'freestanding' in free_prefs.explicit_user_defines
349 assert comptime_optional_flag_value(&free_prefs, 'freestanding')
350
351 none_prefs :=
352 new_preferences_from_args(['-freestanding', '-os', 'none', '-d', 'none', 'main.v'])
353 assert none_prefs.target_os == 'none'
354 assert 'none' in none_prefs.explicit_user_defines
355 assert comptime_optional_flag_value(&none_prefs, 'none')
356
357 bare_prefs := new_preferences_from_args(['-d', 'bare', 'main.v'])
358 assert 'bare' in bare_prefs.explicit_user_defines
359 assert comptime_optional_flag_value(&bare_prefs, 'bare')
360}
361
362fn test_file_suffix_filter_cross_target_contract() {
363 assert !file_has_incompatible_os_suffix('common.v', 'cross')
364 assert file_has_incompatible_os_suffix('platform_linux.v', 'cross')
365 assert file_has_incompatible_os_suffix('platform_macos.v', 'cross')
366 assert file_has_incompatible_os_suffix('platform_darwin.v', 'cross')
367 assert file_has_incompatible_os_suffix('platform_windows.v', 'cross')
368 assert file_has_incompatible_os_suffix('platform_termux.c.v', 'cross')
369 assert !file_has_incompatible_os_suffix('platform_nix.v', 'cross')
370}
371
372fn test_file_suffix_filter_termux_is_selected_only_for_termux_target() {
373 for target in ['linux', 'macos', 'windows', 'android', 'ios', 'freebsd', 'openbsd', 'netbsd',
374 'dragonfly', 'solaris', 'qnx', 'serenity', 'plan9', 'vinix'] {
375 assert file_has_incompatible_os_suffix('platform_termux.c.v', target)
376 }
377 assert !file_has_incompatible_os_suffix('platform_termux.c.v', 'termux')
378 assert !file_has_incompatible_os_suffix('platform_android.c.v', 'termux')
379 assert !file_has_incompatible_os_suffix('platform_android_outside_termux.c.v', 'android')
380 assert file_has_incompatible_os_suffix('platform_android_outside_termux.c.v', 'termux')
381}
382
383fn test_file_suffix_filter_none_target_excludes_all_os_variants() {
384 assert !file_has_incompatible_os_suffix('common.v', 'none')
385 assert file_has_incompatible_os_suffix('platform_linux.v', 'none')
386 assert file_has_incompatible_os_suffix('platform_macos.v', 'none')
387 assert file_has_incompatible_os_suffix('platform_darwin.v', 'none')
388 assert file_has_incompatible_os_suffix('platform_windows.v', 'none')
389 assert file_has_incompatible_os_suffix('platform_nix.v', 'none')
390 assert file_has_incompatible_os_suffix('platform_termux.c.v', 'none')
391 assert file_has_incompatible_os_suffix('platform_bsd.v', 'none')
392}
393