tests: make `fn test_fn() ? { return error(fail) }` count as a fail

pull/10328/head
Delyan Angelov 2021-06-02 19:14:37 +03:00
parent a368800b26
commit 5400a765a4
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 22 additions and 6 deletions

View File

@ -4869,8 +4869,17 @@ fn (mut g Gen) return_stmt(node ast.Return) {
if fn_return_is_optional {
optional_none := node.exprs[0] is ast.None
ftyp := g.typ(node.types[0])
mut is_regular_option := ftyp in ['Option2', 'Option']
mut is_regular_option := ftyp == 'Option'
if optional_none || is_regular_option || node.types[0] == ast.error_type_idx {
if !isnil(g.fn_decl) && g.fn_decl.is_test {
test_error_var := g.new_tmp_var()
g.write('$ret_typ $test_error_var = ')
g.gen_optional_error(g.fn_decl.return_type, node.exprs[0])
g.writeln(';')
g.write_defer_stmts_when_needed()
g.gen_failing_return_error_for_test_fn(node, test_error_var)
return
}
if use_tmp_var {
g.write('$ret_typ $tmpvar = ')
} else {
@ -4993,7 +5002,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
node.types[0].has_flag(.optional)
}
}
if fn_return_is_optional && !expr_type_is_opt && return_sym.name !in ['Option2', 'Option'] {
if fn_return_is_optional && !expr_type_is_opt && return_sym.name != 'Option' {
styp := g.base_type(g.fn_decl.return_type)
g.writeln('$ret_typ $tmpvar;')
g.write('opt_ok(&($styp[]) { ')
@ -5173,9 +5182,6 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, expr ast.Expr, typ
// Initialize more complex consts in `void _vinit/2{}`
// (C doesn't allow init expressions that can't be resolved at compile time).
mut styp := g.typ(typ)
if styp == 'Option2' {
styp = 'IError'
}
cname := '_const_$name'
g.definitions.writeln('$styp $cname; // inited later')
if cname == '_const_os__args' {
@ -5587,7 +5593,7 @@ fn (mut g Gen) write_init_function() {
}
const (
builtins = ['string', 'array', 'DenseArray', 'map', 'Error', 'IError', 'Option2', 'Option']
builtins = ['string', 'array', 'DenseArray', 'map', 'Error', 'IError', 'Option']
)
fn (mut g Gen) write_builtin_types() {

View File

@ -162,6 +162,16 @@ pub fn (mut g Gen) gen_failing_error_propagation_for_test_fn(or_block ast.OrExpr
g.writeln('\tlongjmp(g_jump_buffer, 1);')
}
pub fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return, cvar_name string) {
// in test_() functions, a `return error('something')` is sugar for
// `or { err := error('something') cb_propagate_test_error(@LINE, @FILE, @MOD, @FN, err.msg) return err }`
// and the test is considered failed
paline, pafile, pamod, pafn := g.panic_debug_info(return_stmt.pos)
g.writeln('\tmain__cb_propagate_test_error($paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), *(${cvar_name}.err.msg) );')
g.writeln('\tg_test_fails++;')
g.writeln('\tlongjmp(g_jump_buffer, 1);')
}
pub fn (mut g Gen) gen_c_main_for_tests() {
main_fn_start_pos := g.out.len
g.writeln('')