Skip to content

Property-based tests + CONTRIBUTING.md#55

Merged
mmucklo merged 1 commit intomasterfrom
quality/property-tests
Apr 20, 2026
Merged

Property-based tests + CONTRIBUTING.md#55
mmucklo merged 1 commit intomasterfrom
quality/property-tests

Conversation

@mmucklo
Copy link
Copy Markdown
Owner

@mmucklo mmucklo commented Apr 17, 2026

Summary

Adds property-based (randomized invariant) testing and a contributor guide. Stacks on top of PR #54 (test-strengthening).

Property-based tests

10 randomized invariants, 200 iterations each, using native PHPUnit + mt_rand (no external dependency). Deterministic via SEED envvar for failure reproduction.

Property Invariant
No-crash (parseSingle) Every byte string yields a ParsedEmailAddress; never an exception
No-crash (parseMultiple) Same for multi-address mode
Determinism parse(x) == parse(x) for all x
Reason + code consistency invalid=true ⇔ both invalidReason and invalidReasonCode non-null
Severity Every invalid address has a non-null ValidationSeverity
Stringable (string) $parsed === simpleAddress when valid, '' when invalid
toArray round-trip parseSingle(x)->toArray() === parse(x, false) for all x
Valid round-trip Synthesized atext@label.tld parses; reparsing simpleAddress yields the same simpleAddress
All presets All four factory presets (rfc5321/rfc6531/rfc5322/rfc2822) never crash on arbitrary input

Finding: no bugs or crashes across 2000+ random inputs including arbitrary byte sequences (NUL, control chars, invalid UTF-8). The parser is robust to malformed input.

CONTRIBUTING.md

Developer guide covering: dev setup, all 7 composer scripts, adding test cases via testspec.yml, code-style rules, PHPStan level 8, PR conventions, RFC citation requirements, issue template.

Numbers

Test plan

  • composer ci passes
  • Property tests pass with default (time-based) seed
  • Deterministic reproduction works: SEED=12345 composer test produces identical results
  • CONTRIBUTING.md reviewed for accuracy against current composer scripts

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.21%. Comparing base (97ad7ac) to head (c059328).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             master      #55      +/-   ##
============================================
+ Coverage     90.88%   93.21%   +2.33%     
  Complexity      382      382              
============================================
  Files             6        6              
  Lines           987      987              
============================================
+ Hits            897      920      +23     
+ Misses           90       67      -23     

see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Property-based tests (tests/PropertyTest.php):
10 randomized invariant checks, 200 iterations each, across the full
parseSingle / parseMultiple / parseStream / toArray / Stringable API.
No external dependency — uses native PHPUnit + mt_rand with a SEED
envvar for deterministic reproduction. 84 total tests / 3,279 total
assertions after this change.

Invariants tested:
1. parseSingle never throws on arbitrary byte strings.
2. parseMultiple never throws on arbitrary byte strings.
3. Determinism: same input always yields same toArray() output.
4. invalid ⇔ both invalidReason and invalidReasonCode are non-null.
5. Every invalid address has a non-null ValidationSeverity.
6. Stringable: (string) $parsed === simpleAddress when valid, '' when invalid.
7. toArray() matches the legacy parse(…, false) output exactly.
8. Synthesized valid addresses round-trip via parseSingle($parsed->simpleAddress).
9. All four factory presets never crash on arbitrary input.
10. (Bonus) ParseErrorCode enum exhaustive severity mapping is verified.

Finding: no bugs or crashes found across 2000+ random inputs including
arbitrary byte sequences (NUL, control chars, invalid UTF-8), confirming
the parser's robustness to malformed input.

CONTRIBUTING.md:
Developer guide covering: git clone → composer install, all 7 composer
scripts (test, test:coverage, infect, bench, stan, cs:check, cs:fix, ci),
adding tests via testspec.yml, code-style rules, PHPStan level 8
expectations, PR conventions, RFC citation requirements, and issue
reporting template.

ROADMAP updates:
- Property-based testing flipped to [x] with implementation details.
- CONTRIBUTING.md flipped to [x].

PHPStan baseline regenerated (13 entries, +1 from PropertyTest.php
untyped array access).
@mmucklo mmucklo force-pushed the quality/property-tests branch from f003530 to c059328 Compare April 20, 2026 04:37
@mmucklo mmucklo merged commit 217bfcc into master Apr 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant