checker: add check against `fn test_opt() ?{}`

pull/6892/head
Delyan Angelov 2020-11-20 13:32:46 +02:00
parent 9871d24929
commit 3c4b87bfec
7 changed files with 98 additions and 30 deletions

View File

@ -4505,17 +4505,22 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
} }
} }
// TODO c.pref.is_vet // TODO c.pref.is_vet
if node.language == .v && !node.is_method && node.params.len == 0 && node.return_type == table.void_type_idx && if node.language == .v && !node.is_method && node.params.len == 0 && node.name.after('.').starts_with('test_') {
node.name.after('.').starts_with('test_') && !c.file.path.ends_with('_test.v') { if !c.file.path.ends_with('_test.v') {
// simple heuristic // simple heuristic
for st in node.stmts { for st in node.stmts {
if st is ast.AssertStmt { if st is ast.AssertStmt {
c.warn('tests will not be run because filename does not end with `_test.v`', c.warn('tests will not be run, because filename does not end with `_test.v`',
node.pos) node.pos)
break break
} }
} }
} }
// eprintln('> node.name: $node.name | node.return_type: $node.return_type')
if node.return_type != table.void_type_idx {
c.error('test functions should not return anything', node.pos)
}
}
c.expected_type = table.void_type c.expected_type = table.void_type
c.cur_fn = node c.cur_fn = node
// Add return if `fn(...) ? {...}` have no return at end // Add return if `fn(...) ? {...}` have no return at end

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/test_functions_should_not_return_test.vv:9:1: error: test functions should not return anything
7 |
8 | // should be disallowed:
9 | fn test_returning_int() int {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 |
11 | }
vlib/v/checker/tests/test_functions_should_not_return_test.vv:14:1: error: test functions should not return anything
12 |
13 | // should be disallowed:
14 | fn test_returning_opt() ? {
| ~~~~~~~~~~~~~~~~~~~~~~~~~
15 | }

View File

@ -0,0 +1,15 @@
// ordinary functions can return whatever they like,
// since they are not called by V's testing system
// in the generated main():
fn abc() int {
return 1
}
// should be disallowed:
fn test_returning_int() int {
}
// should be disallowed:
fn test_returning_opt() ? {
}

View File

@ -8,7 +8,7 @@ fn test_vexe_is_set() {
assert vexe != '' assert vexe != ''
} }
fn test_pipe_to_v_run() ? { fn pipe_to_v_run() ? {
cat_cmd := if os.user_os() == 'windows' { 'type' } else { 'cat' } cat_cmd := if os.user_os() == 'windows' { 'type' } else { 'cat' }
tmp_v_file := os.join_path(os.temp_dir(), 'generated_piped_program.v') tmp_v_file := os.join_path(os.temp_dir(), 'generated_piped_program.v')
os.write_file(tmp_v_file, 'println(1 + 3)\nprintln("hello")\n') ? os.write_file(tmp_v_file, 'println(1 + 3)\nprintln("hello")\n') ?
@ -21,3 +21,9 @@ fn test_pipe_to_v_run() ? {
os.rm(tmp_v_file) os.rm(tmp_v_file)
assert !os.exists(tmp_v_file) assert !os.exists(tmp_v_file)
} }
fn test_pipe_to_v_run() {
pipe_to_v_run() or {
panic(err)
}
}

View File

@ -23,9 +23,7 @@ fn test_double_ptr() {
(*p) = &j (*p) = &j
assert x == &j assert x == &j
} }
// ///////
/////////
mut x := &int(0) mut x := &int(0)
unsafe { unsafe {
mut p := &x mut p := &x
@ -60,7 +58,7 @@ fn test_if_expr_unsafe() {
assert *p == 4 assert *p == 4
} }
fn test_unsafe_if_stmt() int { fn unsafe_if_stmt() int {
i := 4 i := 4
unsafe { unsafe {
if true { if true {
@ -70,6 +68,11 @@ fn test_unsafe_if_stmt() int {
return i return i
} }
fn test_unsafe_if_stmt() {
x := unsafe_if_stmt()
assert x == 4
}
fn test_map_address_index() { fn test_map_address_index() {
mut m := { mut m := {
'one': 1 'one': 1

View File

@ -14,7 +14,7 @@ fn check_cache_entry_fpath_invariants(x string, extension string) {
assert a[1][0..2] == a[0] assert a[1][0..2] == a[0]
} }
fn testsuite_begin() ? { fn testsuite_begin() {
os.setenv('VCACHE', vcache_folder, true) os.setenv('VCACHE', vcache_folder, true)
// eprintln('testsuite_begin, vcache_folder = $vcache_folder') // eprintln('testsuite_begin, vcache_folder = $vcache_folder')
os.rmdir_all(vcache_folder) os.rmdir_all(vcache_folder)
@ -22,41 +22,62 @@ fn testsuite_begin() ? {
assert os.is_dir(vcache_folder) assert os.is_dir(vcache_folder)
} }
fn test_save_and_load() ? { fn test_save_and_load() {
mut cm := vcache.new_cache_manager([]) mut cm := vcache.new_cache_manager([])
x := cm.save('.txt', 'first/cache/entry', 'hello') ? x := cm.save('.txt', 'first/cache/entry', 'hello') or {
assert false
''
}
check_cache_entry_fpath_invariants(x, '.txt') check_cache_entry_fpath_invariants(x, '.txt')
} }
fn test_different_options_should_produce_different_cache_entries_for_same_key_and_content() ? { fn test_different_options_should_produce_different_cache_entries_for_same_key_and_content() {
mut cm1 := vcache.new_cache_manager([]) mut cm1 := vcache.new_cache_manager([])
mut cm2 := vcache.new_cache_manager(['-cc tcc']) mut cm2 := vcache.new_cache_manager(['-cc tcc'])
mut cm3 := vcache.new_cache_manager(['-cc gcc']) mut cm3 := vcache.new_cache_manager(['-cc gcc'])
x := cm1.save('.txt', 'first/cache/entry', 'hello') ? x := cm1.save('.txt', 'first/cache/entry', 'hello') or {
y := cm2.save('.txt', 'first/cache/entry', 'hello') ? assert false
z := cm3.save('.txt', 'first/cache/entry', 'hello') ? ''
}
y := cm2.save('.txt', 'first/cache/entry', 'hello') or {
assert false
''
}
z := cm3.save('.txt', 'first/cache/entry', 'hello') or {
assert false
''
}
check_cache_entry_fpath_invariants(x, '.txt') check_cache_entry_fpath_invariants(x, '.txt')
check_cache_entry_fpath_invariants(y, '.txt') check_cache_entry_fpath_invariants(y, '.txt')
check_cache_entry_fpath_invariants(z, '.txt') check_cache_entry_fpath_invariants(z, '.txt')
} }
fn test_exists() ? { fn test_exists() {
mut cm := vcache.new_cache_manager([]) mut cm := vcache.new_cache_manager([])
cm.exists('.o', 'abc') or { cm.exists('.o', 'abc') or {
assert true assert true
} }
// //
x := cm.save('.x', 'abc', '') ? x := cm.save('.x', 'abc', '') or {
assert false
''
}
cm.exists('.o', 'abc') or { cm.exists('.o', 'abc') or {
assert true assert true
} }
// //
y := cm.save('.o', 'zbc', '') ? y := cm.save('.o', 'zbc', '') or {
assert false
''
}
cm.exists('.o', 'abc') or { cm.exists('.o', 'abc') or {
assert true assert true
} }
// //
z := cm.save('.o', 'abc', '') ? z := cm.save('.o', 'abc', '') or {
assert false
''
}
cm.exists('.o', 'abc') or { cm.exists('.o', 'abc') or {
assert false assert false
} }
@ -69,11 +90,14 @@ fn test_exists() ? {
assert y != z assert y != z
} }
fn test_readme_exists_and_is_readable() ? { fn test_readme_exists_and_is_readable() {
vcache.new_cache_manager([]) vcache.new_cache_manager([])
freadme := os.join_path(vcache_folder, 'README.md') freadme := os.join_path(vcache_folder, 'README.md')
assert os.is_file(freadme) assert os.is_file(freadme)
x := os.read_file(freadme) ? x := os.read_file(freadme) or {
assert false
''
}
assert x.len > 0 assert x.len > 0
assert x.starts_with('This folder contains cached build artifacts') assert x.starts_with('This folder contains cached build artifacts')
} }

View File

@ -2,10 +2,12 @@ import x.websocket
import time import time
// Tests with external ws & wss servers // Tests with external ws & wss servers
fn test_ws() ? { fn test_ws() {
go start_server() go start_server()
time.sleep_ms(100) time.sleep_ms(100)
ws_test('ws://localhost:30000')? ws_test('ws://localhost:30000') or {
assert false
}
} }
fn start_server() ? { fn start_server() ? {
@ -20,7 +22,7 @@ fn start_server() ? {
return false return false
} }
return true return true
})? }) ?
s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? {
// payload := if msg.payload.len == 0 { '' } else { string(msg.payload, msg.payload.len) } // payload := if msg.payload.len == 0 { '' } else { string(msg.payload, msg.payload.len) }
// println('server client ($ws.id) got message: opcode: $msg.opcode, payload: $payload') // println('server client ($ws.id) got message: opcode: $msg.opcode, payload: $payload')
@ -38,7 +40,7 @@ fn start_server() ? {
fn ws_test(uri string) ? { fn ws_test(uri string) ? {
eprintln('connecting to $uri ...') eprintln('connecting to $uri ...')
mut ws := websocket.new_client(uri)? mut ws := websocket.new_client(uri) ?
ws.on_open(fn (mut ws websocket.Client) ? { ws.on_open(fn (mut ws websocket.Client) ? {
println('open!') println('open!')
ws.pong() ws.pong()