Skip to content

tests(suppression): mixed valid+unknown marker voiding contract untested at lib level #948

@dekobon

Description

@dekobon

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions