vxx2 / vlib / v3 / tests / veb_implicit_ctx_test.v
63 lines · 54 sloc · 1.62 KB · 7a89e581dace12716ed47d2e665fd337d9820870
Raw
1import os
2
3const vexe = @VEXE
4const tests_dir = os.dir(@FILE)
5const v3_dir = os.dir(tests_dir)
6const v3_src = os.join_path(v3_dir, 'v3.v')
7
8fn build_v3() string {
9 v3_bin := os.join_path(os.temp_dir(), 'v3_veb_ctx_test')
10 build := os.execute('${vexe} -o ${v3_bin} ${v3_src}')
11 assert build.exit_code == 0, build.output
12 return v3_bin
13}
14
15// A `veb.Result` method that receives the implicit `Context` parameter can be
16// called by another handler without passing ctx explicitly. The call must
17// type-check (not report a missing argument) and forward the enclosing `ctx`,
18// not a zero/default value.
19fn test_veb_implicit_ctx_forwarded_at_call_site() {
20 v3_bin := build_v3()
21 src := '
22import veb
23
24pub struct Context {
25 veb.Context
26}
27
28pub struct App {
29mut:
30 n int
31}
32
33pub fn (app &App) index() veb.Result {
34 app.show(5)
35 return app.helper()
36}
37
38pub fn (app &App) helper() veb.Result {
39 return veb.Result{}
40}
41
42pub fn (app &App) show(id int) veb.Result {
43 return veb.Result{}
44}
45
46fn main() {
47 mut app := &App{}
48 _ := app
49}
50'
51 src_file := os.join_path(os.temp_dir(), 'v3_veb_ctx.v')
52 os.write_file(src_file, src) or { panic(err) }
53 c_out := os.join_path(os.temp_dir(), 'v3_veb_ctx.c')
54 os.rm(c_out) or {}
55 compile := os.execute('${v3_bin} ${src_file} -o ${c_out}')
56 assert compile.exit_code == 0, compile.output
57 c_code := os.read_file(c_out) or { '' }
58 // No-arg delegation forwards the enclosing ctx in the ctx slot.
59 assert c_code.contains('App__helper(app, ctx)'), c_code
60 // Delegation that also passes a real argument keeps ctx at its slot,
61 // so the explicit argument still lines up with its parameter.
62 assert c_code.contains('App__show(app, ctx, 5)'), c_code
63}
64