Expect API
The expect() API provides a Jest/Pest-style fluent interface for assertions, ideal for testing and validation with a natural, readable syntax.
Installation
Section titled “Installation”use function Cline\Assert\expect;Core Expectations
Section titled “Core Expectations”Value Equality
Section titled “Value Equality”expect(42)->toBe(42);expect('hello')->toBe('hello');expect($result)->toEqual(42);expect(42)->toStrictEqual(42);Null Checks
Section titled “Null Checks”expect(null)->toBeNull();expect($value)->not->toBeNull();expect('hello')->toBeDefined();expect(null)->toBeUndefined();expect(null)->toBeNullable('string');Boolean Checks
Section titled “Boolean Checks”expect(true)->toBeTrue();expect(false)->toBeFalse();expect(1)->toBeTruthy();expect(0)->toBeFalsy();Empty Checks
Section titled “Empty Checks”expect('')->toBeEmpty();expect([])->toBeEmpty();expect('hello')->not->toBeEmpty();Type Expectations
Section titled “Type Expectations”expect($value)->toBeString();expect($count)->toBeInt();expect($price)->toBeFloat();expect($active)->toBeBool();expect($items)->toBeArray();expect($user)->toBeObject();expect($callback)->toBeCallable();expect($collection)->toBeIterable();expect($number)->toBeNumeric();Numeric Comparisons
Section titled “Numeric Comparisons”expect(10)->toBeGreaterThan(5);expect(10)->toBeGreaterThanOrEqual(10);expect(5)->toBeLessThan(10);expect(5)->toBeLessThanOrEqual(5);expect(5)->toBeBetween(1, 10);expect(3.14159)->toEqualWithDelta(3.14, 0.01);expect(42)->toBePositive();expect(-10)->toBeNegative();expect(4)->toBeEven();expect(7)->toBeOdd();expect(10)->toBeDivisibleBy(5);String Expectations
Section titled “String Expectations”expect('hello world')->toStartWith('hello');expect('hello world')->toEndWith('world');expect('hello world')->toContain('lo wo');expect('test@example.com')->toMatch('/^.+@.+\..+$/');expect('hello')->toHaveLength(5);expect('abc')->toBeAlpha();expect('abc123')->toBeAlphaNumeric();expect('hello_world')->toBeSnakeCase();expect('hello-world')->toBeKebabCase();expect('helloWorld')->toBeCamelCase();Collection Expectations
Section titled “Collection Expectations”expect([1, 2, 3])->toHaveCount(3);expect(['name' => 'John'])->toHaveKey('name');expect(['a' => 1, 'b' => 2])->toHaveKeys(['a', 'b']);expect([1, 2, 3])->toContain(2);expect(2)->toBeIn([1, 2, 3]);expect([3, 2, 1])->toEqualCanonicalizing([1, 2, 3]);expect([1, 2])->toBeSubsetOf([1, 2, 3, 4, 5]);expect([1, 2, 3])->toHaveUniqueValues();expect([1, 2, 3])->toBeSorted();Object Expectations
Section titled “Object Expectations”expect($user)->toHaveProperty('name');expect($user)->toHaveProperties(['name', 'email']);expect($user)->toHaveMethod('save');expect($iterator)->toBeInstanceOf(ArrayIterator::class);expect($obj)->toMatchObject(['name' => 'John']);Format Validations
Section titled “Format Validations”expect('test@example.com')->toBeEmail();expect('https://example.com')->toBeUrl();expect('550e8400-e29b-41d4-a716-446655440000')->toBeUuid();expect('{"key": "value"}')->toBeJson();expect('2024-01-15')->toBeValidDate('Y-m-d');File System Expectations
Section titled “File System Expectations”expect('/path/to/file.txt')->toBeFile();expect('/path/to/file.txt')->toBeReadableFile();expect('/path/to/directory')->toBeReadableDirectory();expect('/path/to/directory')->toBeWritableDirectory();Exception Expectations
Section titled “Exception Expectations”expect(fn() => throw new RuntimeException())->toThrow();expect(fn() => throw new InvalidArgumentException()) ->toThrow(InvalidArgumentException::class);expect(fn() => throw new Exception('Custom error')) ->toThrow(Exception::class, 'Custom error');expect(fn() => $user->save())->not->toThrow();Date/Time Expectations
Section titled “Date/Time Expectations”expect('2024-01-01')->toBeBefore('2024-12-31');expect('2024-12-31')->toBeAfter('2024-01-01');expect(date('Y-m-d'))->toBeToday();Performance Expectations
Section titled “Performance Expectations”$fastOperation = fn () => 1 + 1;expect($fastOperation)->toCompleteWithin(100); // millisecondsNegation Modifier
Section titled “Negation Modifier”Use ->not to negate any expectation:
expect(42)->not->toBe(43);expect('hello')->not->toBeNull();expect([])->not->toBeEmpty();expect(42)->not->toBeString();Each Modifier
Section titled “Each Modifier”Apply expectations to each element in a collection:
expect([1, 2, 3])->each->toBeInt();expect(['a', 'b', 'c'])->each->toBeString();expect([1, 2, 3])->each->not->toBeString();
expect(['a' => 1, 'b' => 2])->each(function($expectation, $key) { $expectation->toBeInt(); expect($key)->toBeString();});And Modifier
Section titled “And Modifier”Chain multiple values in a single expression:
expect($user)->toHaveProperty('email') ->and($admin)->toHaveProperty('email') ->and($guest)->not->toHaveProperty('email');Conditional Modifiers
Section titled “Conditional Modifiers”When Modifier
Section titled “When Modifier”expect($user)->when( $isAdmin, fn($exp) => $exp->toHaveProperty('adminLevel'));Unless Modifier
Section titled “Unless Modifier”expect($user)->unless( $isGuest, fn($exp) => $exp->toHaveProperty('subscription'));Sequence Modifier
Section titled “Sequence Modifier”Apply different expectations to each element in order:
expect([1, 'test', 3.14])->sequence( fn($e) => $e->toBeInt(), fn($e) => $e->toBeString(), fn($e) => $e->toBeFloat());JSON Modifier
Section titled “JSON Modifier”Parse JSON and continue chaining:
expect('{"name":"John","age":30}') ->json() ->toHaveKey('name') ->toHaveKey('age');Custom Validation
Section titled “Custom Validation”toSatisfy()
Section titled “toSatisfy()”expect($age)->toSatisfy(fn($v) => $v > 18);expect($user)->toSatisfy(function($u) { return $u->age > 18 && $u->verified === true;});toMatchSchema()
Section titled “toMatchSchema()”expect($user)->toMatchSchema([ 'type' => 'object', 'properties' => [ 'name' => ['type' => 'string'], 'age' => ['type' => 'integer', 'minimum' => 0], ], 'required' => ['name', 'email'],]);Asymmetric Matchers
Section titled “Asymmetric Matchers”Match partial patterns without requiring exact equality:
expect(['name' => 'John', 'age' => 30])->toEqual([ 'name' => expect()->any('string'), 'age' => expect()->any('int'),]);
expect(['id' => 123, 'data' => 'test'])->toEqual([ 'id' => expect()->anything(), 'data' => expect()->anything(),]);
expect(['message' => 'Error: Invalid input'])->toEqual([ 'message' => expect()->stringContaining('Error'),]);
expect(['a' => 1, 'b' => 2, 'c' => 3])->toEqual( expect()->arrayContaining(['a' => 1, 'c' => 3]));Soft Assertions
Section titled “Soft Assertions”Collect multiple assertion failures before throwing:
expect(5)->soft->toBeGreaterThan(10);expect('hello')->soft->toBeInt();expect([])->soft->toHaveCount(5);
Expectation::assertSoft(); // Throws with all 3 errorsOR Operator
Section titled “OR Operator”Value must match at least one group:
expect($value) ->or ->toBeString() ->or ->toBeInt() ->or ->toBeNull();
expect($input) ->or ->toBeString() ->toHaveLength(10) ->or ->toBeInt() ->toBePositive();XOR Operator
Section titled “XOR Operator”Exactly one group must pass:
expect($configValue) ->xor ->toBeBoolean() ->xor ->toBeString() ->xor ->toBeNumeric();Snapshot Testing
Section titled “Snapshot Testing”use Cline\Assert\Snapshots\SnapshotManager;
SnapshotManager::setSnapshotDirectory('__snapshots__');
expect($data)->toMatchSnapshot('user-data');expect($data)->toMatchInlineSnapshot($expected);Debugging Helpers
Section titled “Debugging Helpers”expect($data)->dd();expect($data)->ddWhen($isDebug);expect($data)->ddUnless($isProduction);expect($data)->ray();Next Steps
Section titled “Next Steps”- Getting Started - Basic assertion concepts
- Assertion Chains - Fluent API usage
- Custom Assertions - Create custom rules