1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

tests: support VTEST_ONLY_FN=*test_sincos* ./v test . and ./v test -run-only test_sin .

This commit is contained in:
Delyan Angelov
2021-12-20 17:22:02 +02:00
parent 5f0160bf11
commit 68ada041e6
4 changed files with 117 additions and 15 deletions

View File

@ -19,6 +19,10 @@ pub const hide_oks = os.getenv('VTEST_HIDE_OK') == '1'
pub const fail_fast = os.getenv('VTEST_FAIL_FAST') == '1'
pub const test_only = os.getenv('VTEST_ONLY').split_any(',')
pub const test_only_fn = os.getenv('VTEST_ONLY_FN').split_any(',')
pub const is_node_present = os.execute('node --version').exit_code == 0
pub const all_processes = os.execute('ps ax').output.split_any('\r\n')

View File

@ -5,6 +5,13 @@ import os.cmdline
import testing
import v.pref
struct Context {
mut:
verbose bool
fail_fast bool
run_only []string
}
fn main() {
args := os.args.clone()
if os.args.last() == 'test' {
@ -14,7 +21,11 @@ fn main() {
args_to_executable := args[1..]
mut args_before := cmdline.options_before(args_to_executable, ['test'])
mut args_after := cmdline.options_after(args_to_executable, ['test'])
fail_fast := extract_flag('-fail-fast', mut args_after, testing.fail_fast)
mut ctx := Context{}
ctx.fail_fast = extract_flag_bool('-fail-fast', mut args_after, testing.fail_fast)
ctx.verbose = extract_flag_bool('-v', mut args_after, false)
ctx.run_only = extract_flag_string_array('-run-only', mut args_after, testing.test_only_fn)
os.setenv('VTEST_ONLY_FN', ctx.run_only.join(','), true)
if args_after == ['v'] {
eprintln('`v test v` has been deprecated.')
eprintln('Use `v test-all` instead.')
@ -24,21 +35,25 @@ fn main() {
backend := if backend_pos == -1 { '.c' } else { args_before[backend_pos + 1] } // this giant mess because closures are not implemented
mut ts := testing.new_test_session(args_before.join(' '), true)
ts.fail_fast = fail_fast
ts.fail_fast = ctx.fail_fast
for targ in args_after {
if os.is_dir(targ) {
// Fetch all tests from the directory
files, skip_files := should_test_dir(targ.trim_right(os.path_separator), backend)
files, skip_files := ctx.should_test_dir(targ.trim_right(os.path_separator),
backend)
ts.files << files
ts.skip_files << skip_files
continue
} else if os.exists(targ) {
match should_test(targ, backend) {
match ctx.should_test(targ, backend) {
.test {
ts.files << targ
continue
}
.skip {
if ctx.run_only.len > 0 {
continue
}
ts.files << targ
ts.skip_files << targ
continue
@ -71,7 +86,7 @@ fn show_usage() {
println('')
}
pub fn should_test_dir(path string, backend string) ([]string, []string) { // return is (files, skip_files)
pub fn (mut ctx Context) should_test_dir(path string, backend string) ([]string, []string) { // return is (files, skip_files)
mut files := os.ls(path) or { return []string{}, []string{} }
mut local_path_separator := os.path_separator
if path.ends_with(os.path_separator) {
@ -85,15 +100,18 @@ pub fn should_test_dir(path string, backend string) ([]string, []string) { // re
if file == 'testdata' {
continue
}
ret_files, ret_skip_files := should_test_dir(p, backend)
ret_files, ret_skip_files := ctx.should_test_dir(p, backend)
res_files << ret_files
skip_files << ret_skip_files
} else if os.exists(p) {
match should_test(p, backend) {
match ctx.should_test(p, backend) {
.test {
res_files << p
}
.skip {
if ctx.run_only.len > 0 {
continue
}
res_files << p
skip_files << p
}
@ -110,7 +128,7 @@ enum ShouldTestStatus {
ignore // just ignore the file, so it will not be printed at all in the list of tests
}
fn should_test(path string, backend string) ShouldTestStatus {
fn (mut ctx Context) should_test(path string, backend string) ShouldTestStatus {
if path.ends_with('mysql_orm_test.v') {
testing.find_started_process('mysqld') or { return .skip }
}
@ -126,11 +144,11 @@ fn should_test(path string, backend string) ShouldTestStatus {
}
}
if path.ends_with('_test.v') {
return .test
return ctx.should_test_when_it_contains_matching_fns(path, backend)
}
if path.ends_with('_test.js.v') {
if testing.is_node_present {
return .test
return ctx.should_test_when_it_contains_matching_fns(path, backend)
}
return .skip
}
@ -141,13 +159,21 @@ fn should_test(path string, backend string) ShouldTestStatus {
backend_arg := path.all_before_last('.v').all_after_last('.')
arch := pref.arch_from_string(backend_arg) or { pref.Arch._auto }
if arch == pref.get_host_arch() {
return .test
return ctx.should_test_when_it_contains_matching_fns(path, backend)
} else if arch == ._auto {
if backend_arg == 'c' { // .c.v
return if backend == 'c' { ShouldTestStatus.test } else { ShouldTestStatus.skip }
return if backend == 'c' {
ctx.should_test_when_it_contains_matching_fns(path, backend)
} else {
ShouldTestStatus.skip
}
}
if backend_arg == 'js' {
return if backend == 'js' { ShouldTestStatus.test } else { ShouldTestStatus.skip }
return if backend == 'js' {
ctx.should_test_when_it_contains_matching_fns(path, backend)
} else {
ShouldTestStatus.skip
}
}
} else {
return .skip
@ -156,7 +182,33 @@ fn should_test(path string, backend string) ShouldTestStatus {
return .ignore
}
fn extract_flag(flag_name string, mut after []string, flag_default bool) bool {
fn (mut ctx Context) should_test_when_it_contains_matching_fns(path string, backend string) ShouldTestStatus {
if ctx.run_only.len == 0 {
// no filters set, so just compile and test
return .test
}
lines := os.read_lines(path) or { return .ignore }
for line in lines {
if line.match_glob('fn test_*') || line.match_glob('pub fn test_*') {
tname := line.replace_each(['pub fn ', '', 'fn ', '']).all_before('(')
for pattern in ctx.run_only {
mut pat := pattern.clone()
if pat.contains('.') {
pat = pat.all_after_last('.')
}
if tname.match_glob(pat) {
if ctx.verbose {
println('> compiling path: $path, since test fn `$tname` matches glob pattern `$pat`')
}
return .test
}
}
}
}
return .ignore
}
fn extract_flag_bool(flag_name string, mut after []string, flag_default bool) bool {
mut res := flag_default
orig_after := after.clone() // workaround for after.filter() codegen bug, when `mut after []string`
matches_after := orig_after.filter(it != flag_name)
@ -166,3 +218,16 @@ fn extract_flag(flag_name string, mut after []string, flag_default bool) bool {
}
return res
}
fn extract_flag_string_array(flag_name string, mut after []string, flag_default []string) []string {
mut res := flag_default.clone()
mut found := after.index(flag_name)
if found > -1 {
if found + 1 < after.len {
res = after[found + 1].split_any(',')
after.delete(found)
}
after.delete(found)
}
return res
}