mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
tools: add tests for vcomplete (#16587)
This commit is contained in:
parent
e35f5f290e
commit
5fc7b6d3d6
239
cmd/tools/vcomplete_test.v
Normal file
239
cmd/tools/vcomplete_test.v
Normal file
@ -0,0 +1,239 @@
|
||||
import os
|
||||
|
||||
const vexe = @VEXE
|
||||
|
||||
const tfolder = os.join_path(os.vtmp_dir(), 'v', 'vcomplete_test')
|
||||
|
||||
enum Shell {
|
||||
bash
|
||||
fish
|
||||
zsh
|
||||
powershell
|
||||
}
|
||||
|
||||
fn string_to_shell(shell string) !Shell {
|
||||
return match shell {
|
||||
'bash' {
|
||||
.bash
|
||||
}
|
||||
'fish' {
|
||||
.fish
|
||||
}
|
||||
'zsh' {
|
||||
.zsh
|
||||
}
|
||||
'powershell' {
|
||||
.powershell
|
||||
}
|
||||
else {
|
||||
error('${shell} is not supported')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn testsuite_begin() {
|
||||
os.mkdir_all(tfolder) or {}
|
||||
}
|
||||
|
||||
fn testsuite_end() {
|
||||
os.rmdir_all(tfolder) or {}
|
||||
}
|
||||
|
||||
fn detect_shell() Shell {
|
||||
forced_shell := os.getenv('VTEST_VCOMPLETE_SHELL')
|
||||
if forced_shell != '' {
|
||||
return string_to_shell(forced_shell) or { panic(err) }
|
||||
}
|
||||
$if linux || macos {
|
||||
return .bash
|
||||
}
|
||||
$if windows {
|
||||
return .powershell
|
||||
}
|
||||
return .bash
|
||||
}
|
||||
|
||||
struct CompleteTestCase {
|
||||
shell Shell = detect_shell()
|
||||
structure []string
|
||||
completes map[string][]string
|
||||
}
|
||||
|
||||
const test_cases = [
|
||||
CompleteTestCase{
|
||||
// Tests the completion of "v complet<tab>" *completeception*
|
||||
structure: [] // no test folders
|
||||
completes: {
|
||||
'v complet': ['complete']
|
||||
}
|
||||
},
|
||||
CompleteTestCase{
|
||||
// Tests the completion of "v ru<tab>"
|
||||
structure: [] // no test folders
|
||||
completes: {
|
||||
'v ru': ['run']
|
||||
}
|
||||
},
|
||||
CompleteTestCase{
|
||||
// Tests with one sub-folder in test root
|
||||
// vfmt off
|
||||
structure: [
|
||||
os.join_path('examples', 'ex1'), // Empty dir
|
||||
os.join_path('examples', 'ex2'), // Two files
|
||||
os.join_path('examples', 'ex2', 'ex2_0.v'),
|
||||
os.join_path('examples', 'ex2', 'ex2_1.v'),
|
||||
os.join_path('examples', 'ex3'), // One file
|
||||
os.join_path('examples', 'ex3', 'ex3.v')
|
||||
]
|
||||
// vfmt on
|
||||
completes: {
|
||||
'v run e': ['examples/']
|
||||
'v run': ['examples/']
|
||||
'v run ': ['examples/']
|
||||
'v run examples/': ['ex1', 'ex2', 'ex3']
|
||||
'v run examples/ex': ['examples/ex1/', 'examples/ex2/', 'examples/ex3/']
|
||||
'v run examples/ex1': ['examples/ex1/']
|
||||
'v run examples/ex1/': []
|
||||
'v run examples/ex2/': ['ex2_0.v', 'ex2_1.v']
|
||||
'v run examples/ex3/': ['examples/ex3/ex3.v']
|
||||
'v run examples/ex3/ex3.v': ['examples/ex3/ex3.v']
|
||||
'v examp': ['examples/']
|
||||
'v examples/f': []
|
||||
'v examples/': ['ex1', 'ex2', 'ex3']
|
||||
'v examples/ex': ['examples/ex1/', 'examples/ex2/', 'examples/ex3/']
|
||||
'v examples/ex1': ['examples/ex1/']
|
||||
'v examples/ex1/': []
|
||||
'v examples/ex2/': ['ex2_0.v', 'ex2_1.v']
|
||||
'v examples/ex3/': ['examples/ex3/ex3.v']
|
||||
'v examples/ex3/ex3.v': ['examples/ex3/ex3.v']
|
||||
}
|
||||
},
|
||||
CompleteTestCase{
|
||||
// Tests with two sub-folder in test root
|
||||
// vfmt off
|
||||
structure: [
|
||||
os.join_path('sub0', 'ex1'), // Empty dir
|
||||
os.join_path('sub0', 'ex2'), // Two files
|
||||
os.join_path('sub0', 'ex2', 'ex2_0.v'),
|
||||
os.join_path('sub0', 'ex2', 'ex2_1.v'),
|
||||
os.join_path('sub0', 'ex3'), // One file
|
||||
os.join_path('sub0', 'ex3', 'ex3.v'),
|
||||
os.join_path('sub1', 'vex1'),
|
||||
os.join_path('sub1', 'vex2'),
|
||||
os.join_path('sub1', 'vex3'),
|
||||
os.join_path('sub1', 'vex3', 'vex3.v')
|
||||
]
|
||||
// vfmt on
|
||||
completes: {
|
||||
// sub0
|
||||
'v run ./': ['sub0/', 'sub1/']
|
||||
'v run ./s': ['./sub0/', './sub1/']
|
||||
'v run': ['sub0/', 'sub1/']
|
||||
'v run ': ['sub0/', 'sub1/']
|
||||
'v run sub0/': ['ex1', 'ex2', 'ex3']
|
||||
'v run sub0/ex': ['sub0/ex1/', 'sub0/ex2/', 'sub0/ex3/']
|
||||
'v run sub0/ex1': ['sub0/ex1/']
|
||||
'v run sub0/ex1/': []
|
||||
'v run sub0/ex2/': ['ex2_0.v', 'ex2_1.v']
|
||||
'v run sub0/ex3/': ['sub0/ex3/ex3.v']
|
||||
'v run sub0/ex3/ex3.v': ['sub0/ex3/ex3.v']
|
||||
'v su': ['sub0/', 'sub1/']
|
||||
'v sub': ['sub0/', 'sub1/']
|
||||
'v sub0/f': []
|
||||
'v sub0/': ['ex1', 'ex2', 'ex3']
|
||||
'v sub0/ex': ['sub0/ex1/', 'sub0/ex2/', 'sub0/ex3/']
|
||||
'v sub0/ex1': ['sub0/ex1/']
|
||||
'v sub0/ex1/': []
|
||||
'v sub0/ex2/': ['ex2_0.v', 'ex2_1.v']
|
||||
'v sub0/ex3/': ['sub0/ex3/ex3.v']
|
||||
'v sub0/ex3/ex3.v': ['sub0/ex3/ex3.v']
|
||||
// sub1
|
||||
'v run sub1/': ['vex1', 'vex2', 'vex3']
|
||||
'v sub1/vex1/': []
|
||||
'v sub1/vex2/': []
|
||||
'v sub1/vex3/': ['sub1/vex3/vex3.v']
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
fn run_individual_test(case CompleteTestCase) ! {
|
||||
// Clean plate
|
||||
os.rmdir_all(tfolder) or {}
|
||||
os.mkdir_all(tfolder) or {}
|
||||
// Work relative to the test dir
|
||||
os.chdir(tfolder) or { panic(err) }
|
||||
for relative_path in case.structure {
|
||||
path := os.join_path(tfolder, relative_path)
|
||||
rel_parts := relative_path.split(os.path_separator)
|
||||
if rel_parts.last().contains('.') {
|
||||
// Make the containing dir
|
||||
os.mkdir_all(os.dir(path)) or { panic(err) }
|
||||
// Create empty file
|
||||
mut f := os.create(path) or { panic(err) }
|
||||
f.close()
|
||||
} else {
|
||||
os.mkdir_all(path) or { panic(err) }
|
||||
}
|
||||
}
|
||||
for complete, expected in case.completes {
|
||||
mut pre_strip := ''
|
||||
mut post_strip := ''
|
||||
mut complete_command := '${vexe} complete'
|
||||
match case.shell {
|
||||
.bash {
|
||||
pre_strip = "COMPREPLY+=('"
|
||||
post_strip = "')"
|
||||
complete_command += ' bash'
|
||||
}
|
||||
.fish {
|
||||
complete_command += ' fish'
|
||||
}
|
||||
.zsh {
|
||||
pre_strip = 'compadd -U -S"" -- \''
|
||||
post_strip = "';"
|
||||
complete_command += ' zsh'
|
||||
}
|
||||
.powershell {
|
||||
complete_command += ' powershell'
|
||||
}
|
||||
}
|
||||
|
||||
mut normalized_complete := complete
|
||||
if case.shell == .powershell {
|
||||
normalized_complete = normalized_complete.replace('/', '\\')
|
||||
}
|
||||
complete_command += ' ${normalized_complete}'
|
||||
res := os.execute('${complete_command}')
|
||||
mut lines := res.output.split('\n')
|
||||
for mut line in lines {
|
||||
if case.shell == .powershell {
|
||||
line = line.replace('\r', '')
|
||||
line = line.all_after('.\\')
|
||||
}
|
||||
line = line.trim_string_left(pre_strip).trim_string_right(post_strip)
|
||||
}
|
||||
lines = lines.filter(it != '')
|
||||
lines.sort()
|
||||
mut sorted_expected := expected.clone()
|
||||
if case.shell == .powershell {
|
||||
sorted_expected = sorted_expected.map(fn (path string) string {
|
||||
mut normalized_path := path.replace('/', '\\')
|
||||
normalized_path = normalized_path.all_after('.\\')
|
||||
return normalized_path
|
||||
})
|
||||
}
|
||||
sorted_expected.sort()
|
||||
// eprintln('${complete} ${lines} vs ${sorted_expected}') // kept for easier debugging
|
||||
|
||||
assert lines.len == sorted_expected.len
|
||||
for i, line in lines {
|
||||
assert line == sorted_expected[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_all_complete_cases() {
|
||||
for case in test_cases {
|
||||
run_individual_test(case)!
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user