Summary
The library-level suppression tests never exercise a mixed marker that lists a valid metric and an unknown metric (e.g. suppress(cyclomatic, no_such_metric)), so the "unknown identifier voids the entire marker" contract is untested at the library boundary — a regression that silently honored only the valid part would pass the whole suite.
Location
tests/suppression_test.rs:257-279 (unknown_metric_in_marker_has_no_effect)
- companion gap in the unit test
src/suppression.rs:666 (native_unknown_metric_errors)
Evidence
parse_metric_list voids the whole marker on the first unknown token via ?:
// src/suppression.rs:459-461
let metric: Metric = name
.parse()
.map_err(|_| SuppressionError::UnknownMetric(name.to_owned()))?;
So suppress(cyclomatic, no_such_metric) returns Err(UnknownMetric) for the entire marker — the valid cyclomatic is dropped too. This is the documented hard contract (big-code-analysis-book/src/commands/suppression.md: an unknown identifier "warns and voids the entire marker").
Every existing test uses a marker whose only metric is unknown:
unknown_metric_in_marker_has_no_effect (lib integration, line 269): # bca: suppress(no_such_metric) → asserts fine.suppressed.is_empty().
native_unknown_metric_errors (unit, line 667): // bca: suppress(no_such_metric) → asserts the error variant.
With a single unknown token, is_empty() (or Err) holds under both the current "void whole marker" behavior and a hypothetical "skip unknown token, keep the rest" behavior. The two are indistinguishable until a marker mixes a valid metric with an unknown one — which no test does (rg 'suppress\(' ... confirms no mixed case anywhere in tests/, src/suppression.rs, or big-code-analysis-cli/tests/).
This is the library-side twin of #896 (which is scoped to the CLI stderr + exit-code surface through bca check); #896 even cites these two tests as covering only is_empty() / the error variant. The mixed-marker voiding gap is not addressed by #896.
Expected Behavior
A test should pin that suppress(cyclomatic, no_such_metric) produces an empty scope on the enclosing function — i.e. the valid cyclomatic is not honored — proving the unknown token voids the whole marker rather than being dropped in isolation.
Actual Behavior
No test distinguishes voiding from partial-honor. Swapping ? for continue in parse_metric_list (skip unknown, keep valid) would silently widen suppression on a typo and pass the entire test suite — the most dangerous failure mode, since a misspelled metric would still silence the correctly-spelled one beside it.
Impact
The void-on-typo guarantee is the safety property that prevents a typo from silently silencing a real violation. The data-structure half of that guarantee is unverified at the library level; a regression ships unnoticed.
Summary
The library-level suppression tests never exercise a mixed marker that lists a valid metric and an unknown metric (e.g.
suppress(cyclomatic, no_such_metric)), so the "unknown identifier voids the entire marker" contract is untested at the library boundary — a regression that silently honored only the valid part would pass the whole suite.Location
tests/suppression_test.rs:257-279(unknown_metric_in_marker_has_no_effect)src/suppression.rs:666(native_unknown_metric_errors)Evidence
parse_metric_listvoids the whole marker on the first unknown token via?:So
suppress(cyclomatic, no_such_metric)returnsErr(UnknownMetric)for the entire marker — the validcyclomaticis dropped too. This is the documented hard contract (big-code-analysis-book/src/commands/suppression.md: an unknown identifier "warns and voids the entire marker").Every existing test uses a marker whose only metric is unknown:
unknown_metric_in_marker_has_no_effect(lib integration, line 269):# bca: suppress(no_such_metric)→ assertsfine.suppressed.is_empty().native_unknown_metric_errors(unit, line 667):// bca: suppress(no_such_metric)→ asserts the error variant.With a single unknown token,
is_empty()(orErr) holds under both the current "void whole marker" behavior and a hypothetical "skip unknown token, keep the rest" behavior. The two are indistinguishable until a marker mixes a valid metric with an unknown one — which no test does (rg 'suppress\(' ...confirms no mixed case anywhere intests/,src/suppression.rs, orbig-code-analysis-cli/tests/).This is the library-side twin of #896 (which is scoped to the CLI stderr + exit-code surface through
bca check); #896 even cites these two tests as covering onlyis_empty()/ the error variant. The mixed-marker voiding gap is not addressed by #896.Expected Behavior
A test should pin that
suppress(cyclomatic, no_such_metric)produces an empty scope on the enclosing function — i.e. the validcyclomaticis not honored — proving the unknown token voids the whole marker rather than being dropped in isolation.Actual Behavior
No test distinguishes voiding from partial-honor. Swapping
?forcontinueinparse_metric_list(skip unknown, keep valid) would silently widen suppression on a typo and pass the entire test suite — the most dangerous failure mode, since a misspelled metric would still silence the correctly-spelled one beside it.Impact
The void-on-typo guarantee is the safety property that prevents a typo from silently silencing a real violation. The data-structure half of that guarantee is unverified at the library level; a regression ships unnoticed.