Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eris Laravel Package

giorgiosironi/eris

Eris brings QuickCheck-style property-based testing to PHP and PHPUnit. Define properties, generate many random inputs, and find minimal counterexamples automatically. Works with PHP 8.1–8.4 and PHPUnit 10–13.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev giorgiosironi/eris
    

    Ensure your phpunit.xml supports PHPUnit 10.x–13.x and PHP 8.1–8.4.

  2. First Test: Create a test class extending PHPUnit\Framework\TestCase and use the TestTrait:

    use Eris\Generators;
    use Eris\TestTrait;
    
    class MyTest extends \PHPUnit\Framework\TestCase
    {
        use TestTrait;
    
        public function testExample()
        {
            $this->forAll(Generators::nat()) // Natural numbers
                ->then(fn(int $n) => $this->assertGreaterThan(0, $n));
        }
    }
    
  3. Run Tests:

    vendor/bin/phpunit --testdox
    

Key First Use Cases

  • Validate edge cases: Test sorting algorithms with random inputs.
  • Verify invariants: Ensure collections maintain properties (e.g., uniqueness).
  • Debug regressions: Shrink failing inputs to minimal reproducible cases.

Implementation Patterns

Core Workflow

  1. Define Generators: Use Generators::* static methods (e.g., Generators::string(), Generators::array()).

    $generator = Generators::tuple(
        Generators::int(),
        Generators::string(Generators::printableCharacter())
    );
    
  2. Compose Properties: Chain generators with forAll() and assertions:

    $this->forAll($generator)
        ->then(fn([int $a, string $b]) => $this->assertTrue(strlen($b) > 0));
    
  3. Custom Constraints: Use suchThat() to filter inputs:

    $this->forAll(Generators::int()->suchThat(fn(int $n) => $n % 2 === 0))
        ->then(fn(int $n) => $this->assertTrue($n % 2 === 0));
    

Integration Tips

  • PHPUnit Annotations: Control test behavior via annotations:

    /**
     * @eris-repeat 100
     * @eris-duration 5s
     */
    public function testPerformance() { ... }
    
  • Listeners: Hook into test execution for logging or metrics:

    $this->hook(Listener\collectFrequencies('output.json'));
    
  • Shrinking: Enable deterministic shrinking for minimal failing inputs:

    $this->forAll($generator)->shrink()->then(...);
    

Common Patterns

Use Case Generator Example Test Example
Random Strings Generators::string(Generators::char()) $this->assertTrue(is_string($s));
Nested Structures Generators::array(Generators::int()) $this->assertCount(10, $arr);
Date/Time Generators::date('2020-01-01', '+1 day') $this->assertInstanceOf(DateTime::class, $d);
Regex Matching Generators::regex('/^[A-Za-z]+$/') $this->assertMatchesRegularExpression(...);

Gotchas and Tips

Pitfalls

  1. Shrinking Behavior:

    • Shrinking may not always reduce inputs to the "simplest" form (e.g., strings may shrink to empty).
    • Fix: Use ->shrink() explicitly and inspect outputs with ERIS_ORIGINAL_INPUT=1.
  2. Generator Size:

    • Large sizes (e.g., Generators::string()->size(1000)) can slow tests.
    • Tip: Limit sizes or use ->limitTo(100) for performance.
  3. PHPUnit 10+:

    • Annotations like @eris-method may conflict with PHPUnit’s new attributes.
    • Workaround: Use ->hook(Listener\...) instead of annotations.
  4. Floating-Point Precision:

    • Floating-point generators (Generators::float()) may produce edge cases (e.g., NaN).
    • Tip: Use ->suchThat(fn(float $f) => is_finite($f)).
  5. Deterministic Seeds:

    • Set ERIS_SEED=42 for reproducible runs, but avoid in CI to catch edge cases.

Debugging Tips

  • Inspect Generated Values:

    $this->forAll($generator)
        ->then(fn($value) => $this->assertTrue(/* ... */))
        ->hook(Listener\log('debug.log'));
    
  • Custom Shrinkers: Override shrinking for complex types:

    Generators::custom(
        fn(GeneratedValueOptions $options) => new MyType(...),
        fn(MyType $value) => [$value->getSimplerRepresentation()]
    );
    
  • Performance:

    • Use ->ratio(0.1) to reduce test iterations for quick feedback.
    • Cache generated samples with ->sample(100)->shrink().

Extension Points

  1. Custom Generators: Implement GeneratorInterface for domain-specific types:

    class UserGenerator implements GeneratorInterface {
        public function generate(GeneratedValueOptions $options): GeneratedValue {
            return new GeneratedValueSingle(new User(...));
        }
    }
    
  2. Listeners: Extend ListenerInterface to log or analyze test runs:

    class MyListener implements ListenerInterface {
        public function onAttempt(Attempt $attempt) {
            // Custom logic
        }
    }
    
  3. Annotations: For PHPUnit <10, use TestTrait annotations. For PHPUnit 10+, migrate to ->hook() or attributes.

Config Quirks

  • Randomness: Defaults to mt_rand(). Override globally:

    Eris\Facade::setRandomness('rand');
    
  • Shrinking Limits: Disable with ->disableShrinking() or set a time limit:

    $this->forAll($generator)->shrink()->timeLimit(1000);
    
  • PHPUnit Integration: Ensure TestTrait is used in test classes, not traits or base classes.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony