v2 / vlib / v / tests / vls / goto_def_test.v
315 lines · 305 sloc · 8.65 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
1import os
2import term
3import v.util.diff
4
5const vroot = @VMODROOT
6const test_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'goto_def_test_data.vv')
7const mod1_text_file = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_mod1', 'sample.v')
8
9struct TestCase {
10 name string
11 line int
12 col int
13 expected string
14 description string
15}
16
17const test_cases = [
18 // test_local_struct() tests
19 TestCase{
20 name: 'method_call'
21 line: 17
22 col: 13
23 expected: '${test_file}:10:20'
24 description: 'Go to method definition from method call'
25 },
26 TestCase{
27 name: 'struct_init'
28 line: 20
29 col: 13
30 expected: '${test_file}:6:7'
31 description: 'Go to struct definition from StructInit'
32 },
33 TestCase{
34 name: 'struct_init_field_name'
35 line: 15
36 col: 28
37 expected: '${test_file}:7:1'
38 description: 'Go to field definition from field name in struct initialization'
39 },
40 TestCase{
41 name: 'field_access'
42 line: 21
43 col: 21
44 expected: '${test_file}:7:1'
45 description: 'Go to field definition from field access'
46 },
47 TestCase{
48 name: 'variable_reference'
49 line: 23
50 col: 17
51 expected: '${test_file}:15:6'
52 description: 'Go to variable definition from reference'
53 },
54 TestCase{
55 name: 'field_access_via_variable'
56 line: 26
57 col: 17
58 expected: '${test_file}:7:1'
59 description: 'Go to field definition from obj.value'
60 },
61 TestCase{
62 name: 'method_receiver_type'
63 line: 10
64 col: 8
65 expected: '${test_file}:6:7'
66 description: 'Go to struct definition from method receiver type (LocalStruct)'
67 },
68 TestCase{
69 name: 'method_return_type_builtin'
70 line: 10
71 col: 33
72 expected: os.join_path(vroot, 'vlib', 'builtin', 'string.v') + ':45:11'
73 description: 'Builtin return type (string) jumps to builtin string definition'
74 },
75 // test_deep_struct() tests
76 TestCase{
77 name: 'nested_struct_st'
78 line: 49
79 col: 22
80 expected: '${test_file}:38:1'
81 description: 'Go to nested anonymous struct field definition (deep.st)'
82 },
83 TestCase{
84 name: 'nested_struct_sstt'
85 line: 49
86 col: 25
87 expected: '${test_file}:39:2'
88 description: 'Go to deeply nested anonymous struct field definition (deep.st.sstt)'
89 },
90 TestCase{
91 name: 'nested_struct_l2'
92 line: 49
93 col: 30
94 expected: '${test_file}:40:3'
95 description: 'Go to deeply nested struct field definition (deep.st.sstt.l2)'
96 },
97 TestCase{
98 name: 'embedded_struct_field'
99 line: 52
100 col: 23
101 expected: '${test_file}:37:1'
102 description: 'Go to embedded struct field declaration (deep.LocalStruct)'
103 },
104 TestCase{
105 name: 'embedded_field_to_type'
106 line: 37
107 col: 2
108 expected: '${test_file}:6:7'
109 description: 'Go to struct type definition from embedded field declaration'
110 },
111 TestCase{
112 name: 'deep_2_nested_sstt_in_init'
113 line: 58
114 col: 21
115 expected: '${test_file}:39:2'
116 description: 'Go to field definition from deep.st.sstt in struct init'
117 },
118 TestCase{
119 name: 'deep_2_nested_l1_in_init'
120 line: 60
121 col: 16
122 expected: '${test_file}:42:2'
123 description: 'Go to field definition from deep.st.l1 in struct init'
124 },
125 // test_local_enum() tests
126 TestCase{
127 name: 'enum_value_qualified'
128 line: 72
129 col: 18
130 expected: '${test_file}:66:1'
131 description: 'Go to enum value definition (qualified form: LocalEnum.first)'
132 },
133 TestCase{
134 name: 'enum_value_short_form'
135 line: 75
136 col: 3
137 expected: '${test_file}:67:1'
138 description: 'Go to enum value definition (short form: .second in match)'
139 },
140 // test_local_alias() tests
141 TestCase{
142 name: 'type_alias_cast'
143 line: 83
144 col: 13
145 expected: '${test_file}:80:5'
146 description: 'Go to type alias definition in cast expression'
147 },
148 TestCase{
149 name: 'type_alias_rhs_type'
150 line: 80
151 col: 19
152 expected: os.join_path(vroot, 'vlib', 'builtin', 'string.v') + ':45:11'
153 description: 'Go to builtin type definition from type alias RHS'
154 },
155 // test_local_sum() tests
156 TestCase{
157 name: 'sum_type_cast'
158 line: 99
159 col: 13
160 expected: '${test_file}:86:5'
161 description: 'Go to sum type definition in cast expression'
162 },
163 TestCase{
164 name: 'user_sum_type_rhs_type_a'
165 line: 96
166 col: 18
167 expected: '${test_file}:88:7'
168 description: 'Go to TypeA definition from UserSum type RHS'
169 },
170 TestCase{
171 name: 'user_sum_type_rhs_type_b'
172 line: 96
173 col: 26
174 expected: '${test_file}:92:7'
175 description: 'Go to TypeB definition from UserSum type RHS'
176 },
177 // test_match_enum() tests
178 TestCase{
179 name: 'match_enum_short_form'
180 line: 115
181 col: 3
182 expected: '${test_file}:107:1'
183 description: 'Go to enum value definition in match expression (short form .completion)'
184 },
185 TestCase{
186 name: 'match_enum_variable'
187 line: 114
188 col: 22
189 expected: '${test_file}:113:1'
190 description: 'Go to variable definition from match expression condition'
191 },
192 // test_imported_enum() tests
193 TestCase{
194 name: 'imported_enum_value'
195 line: 129
196 col: 25
197 expected: '${mod1_text_file}:25:1'
198 description: 'Go to imported enum value definition'
199 },
200 // test_operator_overload() tests
201 TestCase{
202 name: 'operator_receiver_type'
203 line: 137
204 col: 8
205 expected: '${test_file}:133:7'
206 description: 'Go to struct definition from operator overload receiver type'
207 },
208 TestCase{
209 name: 'operator_param_type'
210 line: 137
211 col: 22
212 expected: '${test_file}:133:7'
213 description: 'Go to struct definition from operator overload parameter type'
214 },
215 TestCase{
216 name: 'operator_return_type'
217 line: 137
218 col: 33
219 expected: '${test_file}:133:7'
220 description: 'Go to struct definition from operator overload return type'
221 },
222 TestCase{
223 name: 'struct_init_field_in_params_left'
224 line: 138
225 col: 23
226 expected: '${test_file}:137:4'
227 description: 'Go to param definition from struct init variable (left fn param)'
228 },
229 TestCase{
230 name: 'struct_init_field_in_params_right'
231 line: 138
232 col: 31
233 expected: '${test_file}:137:19'
234 description: 'Go to param definition from struct init variable (right fn param)'
235 },
236 TestCase{
237 name: 'field_selector_in_struct_init'
238 line: 138
239 col: 25
240 expected: '${test_file}:134:1'
241 description: 'Go to field definition from selector expression in struct init value (a.val)'
242 },
243 // test_function_params() tests
244 TestCase{
245 name: 'function_param_type'
246 line: 141
247 col: 24
248 expected: '${test_file}:133:7'
249 description: 'Go to struct definition from function parameter type'
250 },
251 // test_array_field_types() tests
252 TestCase{
253 name: 'array_elem_type_in_struct_field'
254 line: 150
255 col: 10
256 expected: '${test_file}:145:7'
257 description: 'Go to element type definition from array type in struct field ([]ArrayElemStruct)'
258 },
259 TestCase{
260 name: 'fixed_array_elem_type_in_struct_field'
261 line: 151
262 col: 17
263 expected: '${test_file}:145:7'
264 description: 'Go to element type definition from fixed array type in struct field ([5]ArrayElemStruct)'
265 },
266]
267
268fn test_goto_definition() {
269 mut total_errors := 0
270 mut passed := 0
271
272 for tc in test_cases {
273 cmd := 'v -w -check -json-errors -nocolor -vls-mode -line-info "${test_file}:${tc.line}:gd^${tc.col}" ${os.quoted_path(test_file)}'
274 res := os.execute(cmd)
275
276 if res.exit_code < 0 {
277 println('${term.red('FAIL')} ${tc.name}: Command failed to execute')
278 println(' Command: ${cmd}')
279 total_errors++
280 continue
281 }
282
283 res_output := $if windows {
284 res.output.replace('\r\n', '\n').trim_space()
285 } $else {
286 res.output.trim_space()
287 }
288
289 if tc.expected != res_output {
290 println('${term.red('FAIL')} ${tc.name}')
291 println(' Description: ${tc.description}')
292 println(' Line ${tc.line}, Column ${tc.col}')
293 if diff_ := diff.compare_text(tc.expected, res_output) {
294 println(' Difference:')
295 println(diff_)
296 } else {
297 println(' Expected: ${tc.expected}')
298 println(' Got: ${res_output}')
299 }
300 total_errors++
301 } else {
302 println('${term.green('OK ')} ${tc.name}: ${tc.description}')
303 passed++
304 }
305 }
306
307 println('')
308 println('${term.header('Summary:', '=')}')
309 println('Passed: ${passed}/${test_cases.len}')
310 if total_errors > 0 {
311 println('${term.red('Failed:')} ${total_errors}')
312 }
313
314 assert total_errors == 0, 'Some tests failed'
315}
316