Skip to content

Commit ff5ea9e

Browse files
authored
test: strengthen is_some+unwrap assertions (MPI cycle 2) (#1452)
## Summary Multi-perspective improvement cycle (2026-08-03), Test Auditor–led. - **Test integrity:** Replaced 27 `assert!(x.is_some())` + `x.unwrap()` pairs with `.expect(...)` / `expect(...).field` so failures surface the assertion message instead of a bare unwrap panic. Touches types, pipeline, config, diagnostics, resolve, parser snapshots, and CVC5 shell tests. - **Docs:** `docs/CRATES-IO.md` documents the dual-version packaging footgun when monorepo shared crates (for example `rowan`) diverge from crates.io (lesson from #1451). ## Test plan - [x] `cargo test -p assura-pipeline --lib --locked` - [x] `cargo test -p assura-config --lib --locked` - [x] `cargo test -p assura-diagnostics --lib --locked` - [x] `cargo test -p assura-types --lib --locked` - [x] `cargo test -p assura-resolve --lib --locked` - [x] `cargo test -p assura-parser --test snapshots --locked` - [x] `bash scripts/guards.sh` - [ ] CI green ## Not in this PR - Release PR **#1450** (0.4.1) is open and CONFLICTING after #1451. Needs maintainer re-sync and **explicit** approval before merge (publishes crates). - Human launch issues #1410 / #1411 / #1396; blocked #436. --------- Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
1 parent 1c235f1 commit ff5ea9e

13 files changed

Lines changed: 93 additions & 55 deletions

File tree

crates/assura-config/src/lib_tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,7 @@ fn load_project_config_reads_valid_toml() {
718718
.unwrap();
719719

720720
let result = load_project_config(dir.path(), find_root_here);
721-
assert!(result.is_some(), "should parse valid assura.toml");
722-
let (config, root) = result.unwrap();
721+
let (config, root) = result.expect("should parse valid assura.toml");
723722
assert_eq!(config.package.name, "test-proj");
724723
assert_eq!(config.package.version, "1.0.0");
725724
assert_eq!(config.verify.layer, 2);

crates/assura-diagnostics/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,10 @@ mod tests {
402402
fn test_explain_all_catalog_codes() {
403403
let catalog = error_catalog();
404404
for entry in &catalog {
405-
let found = explain(entry.code);
406-
assert!(found.is_some(), "should find {}", entry.code);
407-
assert_eq!(found.unwrap().code, entry.code);
405+
let found = explain(entry.code).unwrap_or_else(|| {
406+
panic!("should find {}", entry.code);
407+
});
408+
assert_eq!(found.code, entry.code);
408409
}
409410
}
410411

crates/assura-parser/tests/snapshots.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,7 @@ fn recovery_multiple_contracts_one_broken() {
469469
"#,
470470
);
471471
// Parser should recover from Bad and still parse AlsoGood
472-
assert!(ast.is_some(), "expected AST despite one broken contract");
473-
let sf = ast.unwrap();
472+
let sf = ast.expect("expected AST despite one broken contract");
474473
// Should have at least 2 contract declarations (Good and AlsoGood)
475474
let contract_count = sf
476475
.decls

crates/assura-pipeline/src/lib_tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,7 @@ fn compile_full_produces_codegen_output() {
639639
"unexpected errors: {:?}",
640640
output.diagnostics
641641
);
642-
assert!(output.generated.is_some(), "codegen should produce output");
643-
let generated = output.generated.unwrap();
642+
let generated = output.generated.expect("codegen should produce output");
644643
assert!(
645644
!generated.files.is_empty(),
646645
"generated project should have files"

crates/assura-resolve/src/resolve_tests.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -879,8 +879,10 @@ type Outer {
879879
.expect("Outer scope not found");
880880
// Int is in root scope; lookup from Outer scope should find it
881881
let int_sym = table.lookup("Int", outer_scope);
882-
assert!(int_sym.is_some(), "Int should be found via scope chain");
883-
assert_eq!(int_sym.unwrap().kind, SymbolKind::BuiltinType);
882+
assert_eq!(
883+
int_sym.expect("Int should be found via scope chain").kind,
884+
SymbolKind::BuiltinType
885+
);
884886
// Nonexistent name should return None
885887
let missing = table.lookup("DoesNotExist", outer_scope);
886888
assert!(missing.is_none(), "missing name should return None");

crates/assura-smt/src/tests_cvc5_shell.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,7 @@ fn shell_old_ident_encoding() {
511511
let inner = Spanned::no_span(Expr::Ident("x".into()));
512512
let result = encode_old_smtlib(&inner, expr_to_smtlib);
513513
// old(x) for an ident should produce the old snapshot name
514-
assert!(result.is_some(), "old(x) should encode");
515-
let smt = result.unwrap();
514+
let smt = result.expect("old(x) should encode");
516515
assert!(
517516
smt.contains("old"),
518517
"old(x) should contain 'old' in the name, got: {smt}"

crates/assura-types/src/tests/domain_checkers/fixed_width.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ fn fixed_width_u8_overflow_add() {
6363
// U8 + U8: 255 + 255 = 510 > 255 -> overflow
6464
let checker = FixedWidthChecker::new();
6565
let err = checker.check_arithmetic_overflow(&AstBinOp::Add, &Type::U8, &Type::U8, &(0..1));
66-
assert!(err.is_some(), "U8 + U8 should detect potential overflow");
67-
let e = err.unwrap();
66+
let e = err.expect("U8 + U8 should detect potential overflow");
6867
assert_eq!(e.code, "A10101");
6968
assert!(e.message.contains("checked_add"));
7069
}
@@ -74,8 +73,10 @@ fn fixed_width_i8_overflow_add() {
7473
// I8 + I8: 127 + 127 = 254 > 127 -> overflow
7574
let checker = FixedWidthChecker::new();
7675
let err = checker.check_arithmetic_overflow(&AstBinOp::Add, &Type::I8, &Type::I8, &(0..1));
77-
assert!(err.is_some(), "I8 + I8 should detect potential overflow");
78-
assert_eq!(err.unwrap().code, "A10101");
76+
assert_eq!(
77+
err.expect("I8 + I8 should detect potential overflow").code,
78+
"A10101"
79+
);
7980
}
8081

8182
#[test]
@@ -92,17 +93,18 @@ fn fixed_width_mul_overflow() {
9293
// U8 * U8: 255 * 255 = 65025 > 255 -> overflow
9394
let checker = FixedWidthChecker::new();
9495
let err = checker.check_arithmetic_overflow(&AstBinOp::Mul, &Type::U8, &Type::U8, &(0..1));
95-
assert!(err.is_some(), "U8 * U8 should detect potential overflow");
96-
let e = err.unwrap();
96+
let e = err.expect("U8 * U8 should detect potential overflow");
9797
assert!(e.message.contains("checked_mul"));
9898
}
9999

100100
#[test]
101101
fn fixed_width_narrowing_cast_u32_to_u16() {
102102
// U32 -> U16: max 4294967295 > 65535 -> unsafe
103103
let err = FixedWidthChecker::check_cast_safety(&Type::U32, &Type::U16, &(0..1));
104-
assert!(err.is_some(), "U32 -> U16 should be unsafe narrowing");
105-
assert_eq!(err.unwrap().code, "A10102");
104+
assert_eq!(
105+
err.expect("U32 -> U16 should be unsafe narrowing").code,
106+
"A10102"
107+
);
106108
}
107109

108110
#[test]
@@ -121,8 +123,10 @@ fn fixed_width_signed_unsigned_comparison() {
121123
&Type::U32,
122124
&(0..1),
123125
);
124-
assert!(err.is_some(), "I32 vs U32 comparison should warn");
125-
assert_eq!(err.unwrap().code, "A10103");
126+
assert_eq!(
127+
err.expect("I32 vs U32 comparison should warn").code,
128+
"A10103"
129+
);
126130
}
127131

128132
#[test]
@@ -141,8 +145,10 @@ fn fixed_width_same_signedness_ok() {
141145
fn fixed_width_division_by_zero() {
142146
let rhs = Spanned::no_span(AstExpr::Literal(AstLit::Int("0".into())));
143147
let err = FixedWidthChecker::check_division_by_zero(&AstBinOp::Div, &rhs, &Type::U32, &(0..1));
144-
assert!(err.is_some(), "division by literal 0 should be flagged");
145-
assert_eq!(err.unwrap().code, "A10104");
148+
assert_eq!(
149+
err.expect("division by literal 0 should be flagged").code,
150+
"A10104"
151+
);
146152
}
147153

148154
#[test]
@@ -181,8 +187,10 @@ fn fixed_width_cast_i32_to_u32() {
181187
// I32 -> U32: signed-to-unsigned, range [-2^31, 2^31-1] does not
182188
// fit in [0, 2^32-1] because of negative values -> unsafe
183189
let err = FixedWidthChecker::check_cast_safety(&Type::I32, &Type::U32, &(0..1));
184-
assert!(err.is_some(), "I32 -> U32 cast should be unsafe");
185-
assert_eq!(err.unwrap().code, "A10102");
190+
assert_eq!(
191+
err.expect("I32 -> U32 cast should be unsafe").code,
192+
"A10102"
193+
);
186194
}
187195

188196
#[test]
@@ -222,8 +230,7 @@ fn fixed_width_check_binop_combined() {
222230
fn fixed_width_modulo_by_zero() {
223231
let rhs = Spanned::no_span(AstExpr::Literal(AstLit::Int("0".into())));
224232
let err = FixedWidthChecker::check_division_by_zero(&AstBinOp::Mod, &rhs, &Type::I32, &(0..1));
225-
assert!(err.is_some(), "modulo by zero should be flagged");
226-
let e = err.unwrap();
233+
let e = err.expect("modulo by zero should be flagged");
227234
assert_eq!(e.code, "A10104");
228235
assert!(e.message.contains("modulo"));
229236
}
@@ -233,8 +240,10 @@ fn fixed_width_sub_overflow_unsigned() {
233240
// U8 - U8: 0 - 255 = -255 < 0 -> overflow (underflow)
234241
let checker = FixedWidthChecker::new();
235242
let err = checker.check_arithmetic_overflow(&AstBinOp::Sub, &Type::U8, &Type::U8, &(0..1));
236-
assert!(err.is_some(), "U8 - U8 should detect potential underflow");
237-
assert_eq!(err.unwrap().code, "A10101");
243+
assert_eq!(
244+
err.expect("U8 - U8 should detect potential underflow").code,
245+
"A10101"
246+
);
238247
}
239248

240249
#[test]

crates/assura-types/src/tests/domain_checkers/remaining.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,8 +1648,11 @@ fn error_propagation_dc_swallow_a12001() {
16481648
},
16491649
);
16501650
let err = checker.validate_catch("CRITICAL_ERROR", ErrorAction::Swallow, 0..10);
1651-
assert!(err.is_some(), "swallowing must_propagate error should fail");
1652-
assert_eq!(err.unwrap().code, "A12001");
1651+
assert_eq!(
1652+
err.expect("swallowing must_propagate error should fail")
1653+
.code,
1654+
"A12001"
1655+
);
16531656
}
16541657

16551658
// InterfaceChecker: missing method triggers A13001

crates/assura-types/src/tests/integration/domain.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,10 @@ fn circular_buffer_check_index_wired() {
389389
checker.declare("buf".into(), 4);
390390
// Index 0 on empty buffer: check_index should flag it
391391
let err = checker.check_index("buf", 5, &(0..1));
392-
assert!(err.is_some(), "index 5 on capacity-4 buffer should error");
393-
assert_eq!(err.unwrap().code, "A23001");
392+
assert_eq!(
393+
err.expect("index 5 on capacity-4 buffer should error").code,
394+
"A23001"
395+
);
394396
}
395397

396398
// =========================================================================
@@ -622,8 +624,10 @@ fn resource_limit_unbounded_detected() {
622624
let checker = ResourceLimitChecker::new();
623625
// No limit declared for "cpu"
624626
let err = checker.check_unbounded("cpu");
625-
assert!(err.is_some(), "unbounded resource should be detected");
626-
assert_eq!(err.unwrap().code, "A46002");
627+
assert_eq!(
628+
err.expect("unbounded resource should be detected").code,
629+
"A46002"
630+
);
627631
}
628632

629633
#[test]
@@ -836,17 +840,21 @@ fn ulp_bound_violation_detected() {
836840
let mut checker = NumericalPrecisionChecker::new();
837841
checker.declare("y".into(), 64, 1.0, 0..1);
838842
let err = checker.check_ulp_bound("y", 2.5);
839-
assert!(err.is_some(), "ULP 2.5 > min 1.0 should trigger A42002");
840-
assert_eq!(err.unwrap().code, "A42002");
843+
assert_eq!(
844+
err.expect("ULP 2.5 > min 1.0 should trigger A42002").code,
845+
"A42002"
846+
);
841847
}
842848

843849
#[test]
844850
fn cancellation_detected() {
845851
let mut checker = NumericalPrecisionChecker::new();
846852
checker.declare("z".into(), 64, 1.0, 0..1);
847853
let err = checker.check_cancellation("z", 0.99999);
848-
assert!(err.is_some(), "ratio 0.99999 should trigger A42003");
849-
assert_eq!(err.unwrap().code, "A42003");
854+
assert_eq!(
855+
err.expect("ratio 0.99999 should trigger A42003").code,
856+
"A42003"
857+
);
850858
}
851859

852860
#[test]

crates/assura-types/src/tests/interactions.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,8 +1386,11 @@ fn test_error_propagation_must_propagate_swallow_rejected() {
13861386

13871387
// Swallowing a must_propagate error should produce A12001
13881388
let err = checker.validate_catch("SQLITE_CORRUPT", ErrorAction::Swallow, 0..10);
1389-
assert!(err.is_some(), "swallowing must_propagate error should fail");
1390-
assert_eq!(err.unwrap().code, "A12001");
1389+
assert_eq!(
1390+
err.expect("swallowing must_propagate error should fail")
1391+
.code,
1392+
"A12001"
1393+
);
13911394

13921395
// Propagating is fine
13931396
let err = checker.validate_catch("SQLITE_CORRUPT", ErrorAction::Propagate, 0..10);
@@ -1425,8 +1428,10 @@ fn test_error_propagation_must_not_mask() {
14251428
ErrorAction::TranslateTo("SQLITE_OK".into()),
14261429
0..10,
14271430
);
1428-
assert!(err.is_some(), "forbidden translation should fail");
1429-
assert_eq!(err.unwrap().code, "A12002");
1431+
assert_eq!(
1432+
err.expect("forbidden translation should fail").code,
1433+
"A12002"
1434+
);
14301435

14311436
// Allowed translation should pass
14321437
let err = checker.validate_catch(
@@ -1450,8 +1455,10 @@ fn test_error_propagation_must_check() {
14501455

14511456
// Unchecked call to must_check function -> A12003
14521457
let err = checker.validate_unchecked_call("sqlite3_reset", 0..10);
1453-
assert!(err.is_some(), "unchecked must_check call should fail");
1454-
assert_eq!(err.unwrap().code, "A12003");
1458+
assert_eq!(
1459+
err.expect("unchecked must_check call should fail").code,
1460+
"A12003"
1461+
);
14551462

14561463
// Non-must_check function is fine
14571464
let err = checker.validate_unchecked_call("sqlite3_open", 0..10);

0 commit comments

Comments
 (0)