Skip to content

Commit a2a8f65

Browse files
authored
Fix test discovery for ingots where lib.fe has no tests (argotorg#1304)
`run_tests_ingot` checked only the root module (lib.fe) for #[test] functions before deciding whether to run tests. If lib.fe had no tests, the entire ingot was skipped with "No tests found" even when sibling modules contained tests. Replace `has_test_functions(db, root_mod)` with a new `ingot_has_test_functions(db, ingot)` that checks all modules in the ingot via `Ingot::all_funcs`. Add a regression test with an ingot fixture whose lib.fe exports a helper but has no tests, while a sibling module contains the only test.
1 parent cdb38ee commit a2a8f65

5 files changed

Lines changed: 47 additions & 1 deletion

File tree

crates/fe/src/test/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use colored::Colorize;
2121
use common::{
2222
InputDb,
2323
config::{Config, WorkspaceMemberSelection},
24+
ingot::Ingot,
2425
};
2526
use contract_harness::{CallGasProfile, EvmTraceOptions, ExecutionOptions, RuntimeInstance};
2627
use driver::DriverDataBase;
@@ -1266,7 +1267,7 @@ fn run_tests_ingot(
12661267
}
12671268

12681269
let root_mod = ingot.root_mod(db);
1269-
if !has_test_functions(db, root_mod) {
1270+
if !ingot_has_test_functions(db, ingot) {
12701271
return Vec::new();
12711272
}
12721273

@@ -1748,6 +1749,15 @@ fn has_test_functions(db: &DriverDataBase, top_mod: TopLevelMod<'_>) -> bool {
17481749
})
17491750
}
17501751

1752+
/// Like [`has_test_functions`] but checks all modules in the ingot, not just one.
1753+
fn ingot_has_test_functions(db: &DriverDataBase, ingot: Ingot<'_>) -> bool {
1754+
ingot.all_funcs(db).iter().any(|func| {
1755+
ItemKind::from(*func)
1756+
.attrs(db)
1757+
.is_some_and(|attrs| attrs.has_attr(db, "test"))
1758+
})
1759+
}
1760+
17511761
fn create_run_report_staging() -> Result<ReportStaging, String> {
17521762
create_report_staging_root("target/fe-test-report-staging", "fe-test-report")
17531763
}

crates/fe/tests/cli_output.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,26 @@ fn test_cli_test_workspace_ingot_missing_member_is_error() {
918918
);
919919
}
920920

921+
/// Regression test: `fe test` must discover tests in non-root modules of an
922+
/// ingot even when `lib.fe` itself contains no `#[test]` functions.
923+
#[test]
924+
fn test_cli_test_ingot_discovers_tests_in_non_root_modules() {
925+
let fixture_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
926+
.join("tests/fixtures/fe_test_runner/ingot_tests_in_non_root_module");
927+
let fixture_dir_str = fixture_dir.to_str().expect("fixture dir utf8");
928+
929+
let (output, exit_code) = run_fe_main(&["test", fixture_dir_str]);
930+
assert_eq!(exit_code, 0, "fe test failed:\n{output}");
931+
assert!(
932+
output.contains("test test_add"),
933+
"expected test_add to be discovered, got:\n{output}"
934+
);
935+
assert!(
936+
output.contains("1 passed"),
937+
"expected 1 passed test, got:\n{output}"
938+
);
939+
}
940+
921941
#[test]
922942
fn test_cli_test_repo_core_ingot_without_tests_is_ok() {
923943
let project_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[ingot]
2+
name = "ingot_tests_in_non_root_module"
3+
version = "0.1.0"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use std::evm::{Evm, assert}
2+
use ingot::add
3+
4+
#[test]
5+
fn test_add() uses (evm: mut Evm) {
6+
assert(add(2, 3) == 5)
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Root module with no #[test] functions.
2+
// Tests live only in the sibling module (helper.fe).
3+
4+
pub fn add(a: u256, b: u256) -> u256 {
5+
a + b
6+
}

0 commit comments

Comments
 (0)