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

Phpunit Iterable Assertions Laravel Package

loophp/phpunit-iterable-assertions

PHPUnit helper assertions for iterables. Adds convenient, fluent checks for arrays and Traversables to simplify and clarify test expectations when working with generators, collections, and other iterable data sources.

View on GitHub
Deep Wiki
Context7
## Getting Started
This package, **`loophp/phpunit-iterable-assertions`**, extends PHPUnit with assertions for testing iterables (arrays, collections, generators, etc.). To get started:

1. **Installation**:
   ```bash
   composer require --dev loophp/phpunit-iterable-assertions

Requires PHP 8.1+ (updated in v1.0.4).

  1. Basic Usage: Add the trait to your test class and use assertions like:

    use Loophp\IterableAssertions\Assertions;
    
    class MyTest extends TestCase
    {
        use Assertions;
    
        public function testIterableContains()
        {
            $collection = collect([1, 2, 3]);
            $this->assertContainsOnly(1, $collection); // Checks if 1 exists
            $this->assertContainsAll([1, 3], $collection); // Checks if all values exist
        }
    }
    
  2. Key Assertions:

    • assertContainsOnly($value, $iterable)
    • assertContainsAll($values, $iterable)
    • assertDoesNotContain($value, $iterable)
    • assertIsIterable($iterable)
    • assertIsEmpty($iterable)
    • assertHasKey($key, $iterable)
    • assertHasKeys($keys, $iterable)

    Full list: Package Documentation.


Implementation Patterns

Workflows

  1. Testing Collections: Useful for Laravel Eloquent collections or custom iterables:

    $users = User::all();
    $this->assertContainsOnly('admin@example.com', $users->pluck('email'));
    
  2. API Response Validation: Validate array responses from APIs:

    $response = $this->get('/api/users');
    $this->assertContainsAll(['id', 'name'], $response->json());
    
  3. Generator/Iterator Testing: Test lazy-loaded data (e.g., streams, generators):

    $generator = function () { yield 1; yield 2; };
    $this->assertContainsOnly(1, $generator());
    

Integration Tips

  • Laravel Collections: Pair with Laravel’s collect() for fluent assertions:

    $this->assertHasKeys(['id', 'name'], collect($users)->first());
    
  • Data Providers: Use for parameterized tests:

    public function testMultipleValuesProvider()
    {
        $provider = [[1, 2], [3, 4]];
        foreach ($provider as $values) {
            $this->assertContainsAll($values, [1, 2, 3, 4]);
        }
    }
    
  • Custom Matchers: Extend assertions for domain-specific logic:

    $this->assertCustom($customMatcher, $iterable);
    

Gotchas and Tips

Pitfalls

  1. PHP 8.1 Requirement:

    • Breaking Change: v1.0.4 drops support for PHP <8.1. Update your environment or use ^0.9 for older PHP versions.
    • Fix: Run composer require loophp/phpunit-iterable-assertions:^0.9 if stuck on PHP 7.4/8.0.
  2. Strict Typing:

    • Assertions may throw TypeError if $iterable isn’t actually iterable (e.g., passing a string to assertIsIterable()).
    • Tip: Use assertIsIterable() first to validate:
      $this->assertIsIterable($data);
      $this->assertContainsOnly(1, $data);
      
  3. Performance with Large Iterables:

    • Some assertions (e.g., assertContainsAll) may traverse the entire iterable. Use sparingly for huge datasets.
    • Tip: Pre-filter iterables or use assertContainsOnly for single-value checks.
  4. Key-Based Assertions:

    • assertHasKey() and assertHasKeys() work with array-accessible iterables (e.g., ArrayObject, stdClass with __get). Generators or plain arrays without keys will fail.
    • Tip: Convert to an array first if needed:
      $this->assertHasKeys(['id'], (array) $generator());
      

Debugging

  • Assertion Failures: Use var_dump($iterable) or Laravel’s dd() to inspect the structure before asserting. Example:

    dd($iterable); // Debug iterable structure
    $this->assertContainsAll([1, 2], $iterable);
    
  • Custom Error Messages: Pass a custom message to assertions for clearer failures:

    $this->assertContainsOnly(
        1,
        $iterable,
        'Expected iterable to contain value `1` for user IDs.'
    );
    

Extension Points

  1. Custom Assertions: Extend the trait or create a wrapper:

    trait CustomIterableAssertions
    {
        protected function assertIsNonEmptyArray($iterable)
        {
            $this->assertIsIterable($iterable);
            $this->assertNotEmpty($iterable);
            $this->assertIsArray($iterable);
        }
    }
    
  2. Integration with Laravel: Create a test helper for common use cases:

    // tests/TestHelpers.php
    use Loophp\IterableAssertions\Assertions;
    
    if (!class_exists('TestHelpers')) {
        class TestHelpers
        {
            use Assertions;
    
            public static function assertApiResponseHasKeys(array $keys, $response)
            {
                self::assertContainsAll($keys, array_keys($response->json()));
            }
        }
    }
    
  3. CI/CD Compatibility:

    • The package now uses Renovate for dependency updates (added in v1.0.4), reducing manual maintenance.
    • Tip: If using GitHub Actions, ensure your workflows are updated to the latest actions (e.g., actions/checkout@v4).

---
**Note**: The release primarily includes dependency updates and a **PHP 8.1 requirement**, which may require action if your project uses older PHP versions. No new features were added.
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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager