v2 / vlib / v / tests / comptime / comptime_for_test.v
115 lines · 105 sloc · 2.3 KB · 682db6685219d63d808fda329fb16224a682394e
Raw
1struct App {
2 Inner
3 a string
4 b string
5mut:
6 c int
7 d f32
8pub:
9 e f32
10 f u64
11pub mut:
12 g string
13 h u8
14}
15
16struct Inner {}
17
18@['foo/bar/three']
19fn (mut app App) run() {
20}
21
22@['attr2']
23fn (mut app App) method2() {
24}
25
26fn (mut app App) int_method1() int {
27 return 0
28}
29
30fn (mut app App) int_method2() int {
31 return 1
32}
33
34fn (mut app App) string_arg(x string) {
35}
36
37fn no_lines(s string) string {
38 return s.replace('\n', ' ')
39}
40
41fn test_comptime_for() {
42 println(@FN)
43 methods := ['run', 'method2', 'int_method1', 'int_method2', 'string_arg']
44 $for method in App.methods {
45 // ensure each method is scoped under a new block in the generated code
46 x := ' method: ${method.name} | ' + no_lines('${method}')
47 println(x)
48 assert method.name in methods
49 }
50}
51
52fn test_comptime_for_with_if() {
53 println(@FN)
54 mut methods_found := map[string]int{}
55 $for method in App.methods {
56 println(' method: ' + no_lines('${method}'))
57 $if method.typ is fn () {
58 methods_found['fn()'] += 1
59 assert method.name in ['run', 'method2']
60 }
61 $if method.typ is fn () int {
62 methods_found['fn() int'] += 1
63 }
64 $if method.return_type is int {
65 assert method.name in ['int_method1', 'int_method2']
66 }
67 $if method.typ is fn (string) {
68 methods_found['fn(string)'] += 1
69 }
70 $if method.args[0].typ is string {
71 assert method.name == 'string_arg'
72 }
73 }
74 assert methods_found['fn()'] == 2
75 assert methods_found['fn() int'] == 2
76 assert methods_found['fn(string)'] == 1
77}
78
79fn test_comptime_for_fields() {
80 println(@FN)
81 mut fields_found := 0
82 $for field in App.fields {
83 println(' field: ${field.name} | ' + no_lines('${field}'))
84 $if field.typ is string {
85 assert field.name in ['a', 'b', 'g']
86 }
87 $if field.typ is f32 {
88 assert field.name in ['d', 'e']
89 }
90 if field.is_mut {
91 assert field.name in ['c', 'd', 'g', 'h', 'Inner']
92 }
93 if field.is_pub {
94 assert field.name in ['e', 'f', 'g', 'h', 'Inner']
95 }
96 if field.is_pub && field.is_mut {
97 assert field.name in ['g', 'h', 'Inner']
98 }
99 if field.is_embed {
100 assert field.name == 'Inner'
101 }
102 if field.name == 'f' {
103 assert sizeof(field) == 8
104 assert isreftype(field) == false
105 assert typeof(field).name == 'u64'
106 fields_found++
107 }
108 if field.name == 'g' {
109 assert typeof(field).name == 'string'
110 assert isreftype(field) == true
111 fields_found++
112 }
113 }
114 assert fields_found == 2
115}
116