Skip to content

S002 Edge Cases

IDScenarioExpected Behavior
S002-EC-001coveragePercent is exactly 0.0 and min is 0minimum-coverage MUST pass (0.0 >= 0 is true)
S002-EC-002coveragePercent is exactly 100.0 and min is 100minimum-coverage MUST pass
S002-EC-003No test file exists but minimum-coverage rule is activeminimum-coverage evaluates with coveragePercent from context (may be 0.0); result depends on min threshold. Rule does not skip.
S002-EC-004totalExecutableLines is 0 for matched-coverage rulematched-coverage MUST return RuleResult::pass('-') (skip) to avoid division by zero
S002-EC-005Required parameter min is missing from minimum-coverage configRuleRegistry::resolve() MUST throw InvalidArgumentException with message containing "requires parameter 'min'"
S002-EC-006Structure has rules: [] (empty array)test-exists MUST still be auto-prepended; the resolved list contains exactly one rule
S002-EC-007Same rule listed twice in config (e.g. [test-exists, test-exists])Both entries resolve independently; the rule evaluates twice. Auto-prepend logic checks only the user's list, so test-exists is not added a third time.
S002-EC-008min parameter provided as a string like "eighty"RuleRegistry MUST throw InvalidArgumentException because "eighty" is not numeric
S002-EC-009coveragePercent is 79.999 and min is 80minimum-coverage MUST fail (79.999 < 80 is true). Floating-point comparison uses native PHP >= operator.
S002-EC-010Test file exists but testContent is null (unreadable)enforce-coverage-link MUST return RuleResult::pass('-') (skip) because it checks testContent === null
S002-EC-011A plugin registers a rule with name "test-exists" (same as built-in)The plugin rule replaces the built-in rule in the registry (last-write-wins per S002-FR-004.e). All subsequent evaluations use the plugin's implementation.
S002-EC-012PHPUnit XML coverage loaded but lineCoverage is empty for a filematched-coverage counts 0 matched lines, resulting in 0% matched coverage. If min is set, the rule fails; if not, it passes with "0%".