mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
testing: support for internal module testing
This commit is contained in:
parent
3a2c46a1ce
commit
1cd5fab21d
@ -506,24 +506,22 @@ pub fn (v mut V) generate_main() {
|
||||
if v.table.main_exists() {
|
||||
verror('test files cannot have function `main`')
|
||||
}
|
||||
if !v.table.has_at_least_one_test_fn() {
|
||||
test_fn_names := v.table.all_test_function_names()
|
||||
if test_fn_names.len == 0 {
|
||||
verror('test files need to have at least one test function')
|
||||
}
|
||||
|
||||
// Generate a C `main`, which calls every single test function
|
||||
v.gen_main_start(false)
|
||||
|
||||
if v.pref.is_stats {
|
||||
cgen.genln('BenchedTests bt = main__start_testing();')
|
||||
}
|
||||
|
||||
for _, f in v.table.fns {
|
||||
if f.name.starts_with('main__test_') {
|
||||
if v.pref.is_stats {
|
||||
cgen.genln('BenchedTests_testing_step_start(&bt, tos3("$f.name"));') }
|
||||
cgen.genln('$f.name ();')
|
||||
for tfname in test_fn_names {
|
||||
if v.pref.is_stats { cgen.genln('BenchedTests_testing_step_start(&bt, tos3("$tfname"));') }
|
||||
cgen.genln('$tfname ();')
|
||||
if v.pref.is_stats { cgen.genln('BenchedTests_testing_step_end(&bt);') }
|
||||
}
|
||||
}
|
||||
if v.pref.is_stats { cgen.genln('BenchedTests_end_testing(&bt);') }
|
||||
v.gen_main_end('return g_test_fails > 0')
|
||||
}
|
||||
@ -766,17 +764,25 @@ pub fn (v &V) get_user_files() []string {
|
||||
user_files << filepath.join(preludes_path,'tests_with_stats.v')
|
||||
}
|
||||
|
||||
is_test := dir.ends_with('_test.v')
|
||||
mut is_internal_module_test := false
|
||||
if is_test {
|
||||
tcontent := os.read_file( dir ) or { panic('$dir does not exist') }
|
||||
if tcontent.contains('module ') && !tcontent.contains('module main') {
|
||||
is_internal_module_test = true
|
||||
}
|
||||
}
|
||||
if is_internal_module_test {
|
||||
// v volt/slack_test.v: compile all .v files to get the environment
|
||||
// I need to implement user packages! TODO
|
||||
is_test_with_imports := dir.ends_with('_test.v') &&
|
||||
(dir.contains('${os.path_separator}volt') ||
|
||||
dir.contains('${os.path_separator}c2volt'))// TODO
|
||||
if is_test_with_imports {
|
||||
user_files << dir
|
||||
if pos := dir.last_index(os.path_separator) {
|
||||
dir = dir[..pos] + os.path_separator// TODO why is this needed
|
||||
single_test_v_file := os.realpath(dir)
|
||||
if v.pref.is_verbose {
|
||||
v.log('> Compiling an internal module _test.v file $single_test_v_file .')
|
||||
v.log('> That brings in all other ordinary .v files in the same module too .')
|
||||
}
|
||||
user_files << single_test_v_file
|
||||
dir = os.basedir( single_test_v_file )
|
||||
}
|
||||
|
||||
if dir.ends_with('.v') || dir.ends_with('.vsh') {
|
||||
single_v_file := dir
|
||||
// Just compile one file and get parent dir
|
||||
|
@ -19,7 +19,7 @@ fn cb_assertion_failed(filename string, line int, sourceline string, funcname st
|
||||
else { true }
|
||||
}
|
||||
final_filename := if use_relative_paths { filename } else { os.realpath( filename ) }
|
||||
final_funcname := funcname.replace('main__','')
|
||||
final_funcname := funcname.replace('main__','').replace('__','.')
|
||||
|
||||
mut fail_message := 'FAILED assertion'
|
||||
if color_on { fail_message = term.bold(term.red(fail_message)) }
|
||||
|
@ -34,7 +34,7 @@ fn start_testing() BenchedTests {
|
||||
|
||||
// Called before each test_ function, defined in file_test.v
|
||||
fn (b mut BenchedTests) testing_step_start(stepfunc string) {
|
||||
b.step_func_name = stepfunc.replace('main__','')
|
||||
b.step_func_name = stepfunc.replace('main__','').replace('__','.')
|
||||
b.oks = C.g_test_oks
|
||||
b.fails = C.g_test_fails
|
||||
b.bench.step()
|
||||
|
@ -778,13 +778,14 @@ fn (t &Table) main_exists() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
fn (t &Table) has_at_least_one_test_fn() bool {
|
||||
fn (t &Table) all_test_function_names() []string {
|
||||
mut res := []string
|
||||
for _, f in t.fns {
|
||||
if f.name.starts_with('main__test_') {
|
||||
return true
|
||||
if f.name.contains('__test_') {
|
||||
res << f.name
|
||||
}
|
||||
}
|
||||
return false
|
||||
return res
|
||||
}
|
||||
|
||||
fn (t &Table) find_const(name string) ?Var {
|
||||
|
@ -0,0 +1,16 @@
|
||||
module amodule
|
||||
|
||||
// This tests whether _test.v files can be *internal* to a
|
||||
// module, and thus have access to its guts.
|
||||
|
||||
// NB: the function test_private_isub() is defined both here
|
||||
// and inside internal_module_test.v . That is done on purpose,
|
||||
// with the goal of ensuring that _test.v files are compiled
|
||||
// *independently* from each other.
|
||||
//
|
||||
// _test.v files should *only* import all the other normal .v
|
||||
// files from the same folder, NOT other _test.v files from it.
|
||||
|
||||
fn test_private_isub(){
|
||||
assert private_isub(7,5) == 2
|
||||
}
|
16
vlib/compiler/tests/modules/amodule/internal_module_test.v
Normal file
16
vlib/compiler/tests/modules/amodule/internal_module_test.v
Normal file
@ -0,0 +1,16 @@
|
||||
module amodule
|
||||
|
||||
// this tests whether _test.v files can be *internal*
|
||||
// to a module, and thus have access to its guts.
|
||||
|
||||
fn test_iadd(){
|
||||
assert iadd(10, 20) == 30
|
||||
}
|
||||
|
||||
fn test_imul(){
|
||||
assert imul(5,8) == 40
|
||||
}
|
||||
|
||||
fn test_private_isub(){
|
||||
assert private_isub(10,6) == 4
|
||||
}
|
15
vlib/compiler/tests/modules/amodule/module.v
Normal file
15
vlib/compiler/tests/modules/amodule/module.v
Normal file
@ -0,0 +1,15 @@
|
||||
module amodule
|
||||
|
||||
pub fn iadd(x int, y int) int {
|
||||
return x + y
|
||||
}
|
||||
|
||||
pub fn imul(x int, y int) int {
|
||||
return x * y
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
fn private_isub(x int, y int) int {
|
||||
return x - y
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
module main
|
||||
|
||||
import os
|
||||
import compiler.tests.repl.runner
|
||||
import benchmark
|
||||
|
Loading…
Reference in New Issue
Block a user