From 82dad350a9662763cb5662669412ed4bcf7064f4 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 26 Feb 2026 21:13:27 +0300 Subject: [PATCH] checker: fix confusing error message when test file gets an invalid name (fixes #15642) --- vlib/v/checker/checker.v | 20 ++++++++++++++++++-- vlib/v/checker/tests/test_invalid_name.out | 6 ++++++ vlib/v/checker/tests/test_invalid_name.vv | 5 +++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/test_invalid_name.out create mode 100644 vlib/v/checker/tests/test_invalid_name.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 473faaad3..cd085c9ea 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -439,6 +439,8 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) { mut has_main_mod_file := false mut has_no_main_mod_file := false mut has_main_fn := false + mut invalid_test_file_name := '' + mut invalid_test_file_pos := token.Pos{} // Determine the project directory when using -line-info mut project_dir := '' if c.pref.is_vls && c.pref.line_info != '' { @@ -472,6 +474,10 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) { has_main_fn = true } } + if invalid_test_file_name == '' && is_likely_invalid_test_file_name(file) { + invalid_test_file_name = file.path_base + invalid_test_file_pos = file.mod.pos + } c.timers.show('checker_check ${file.path}') } if has_main_mod_file && !has_main_fn && files_from_main_module.len > 0 { @@ -569,13 +575,23 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) { return } if !has_main_mod_file { - c.error('project must include a `main` module or be a shared library (compile with `v -shared`)', - token.Pos{}) + if invalid_test_file_name != '' { + c.add_error_detail('Test files should have names ending with `_test.v`.') + c.error('invalid test file name `${invalid_test_file_name}`', invalid_test_file_pos) + } else { + c.error('project must include a `main` module or be a shared library (compile with `v -shared`)', + token.Pos{}) + } } else if !has_main_fn && !c.pref.is_o { c.error('function `main` must be declared in the main module', token.Pos{}) } } +fn is_likely_invalid_test_file_name(file &ast.File) bool { + return !file.is_test && (file.path_base.ends_with('.v') || file.path_base.ends_with('.vv')) + && file.path_base.starts_with('test_') +} + fn (mut c Checker) stmts_has_main_fn(stmts []ast.Stmt) bool { mut has_main_fn := false for stmt in stmts { diff --git a/vlib/v/checker/tests/test_invalid_name.out b/vlib/v/checker/tests/test_invalid_name.out new file mode 100644 index 000000000..f05f7cddd --- /dev/null +++ b/vlib/v/checker/tests/test_invalid_name.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/test_invalid_name.vv:1:1: error: invalid test file name `test_invalid_name.vv` + 1 | module custom + | ~~~~~~~~~~~~~ + 2 | + 3 | fn test_result() { +Details: Test files should have names ending with `_test.v`. diff --git a/vlib/v/checker/tests/test_invalid_name.vv b/vlib/v/checker/tests/test_invalid_name.vv new file mode 100644 index 000000000..36275664d --- /dev/null +++ b/vlib/v/checker/tests/test_invalid_name.vv @@ -0,0 +1,5 @@ +module custom + +fn test_result() { + println('whatever') +} -- 2.39.5