/
githubmirror
/
framework
Обзор
Документация
Войти
/
githubmirror
/
framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
13.x
tests/Testing/Fluent/AssertTest.php
1 596 строк
43 KB
Lucas Michot
Simplify remaining exception expectations (#61058)
05 авг 2026, 20:23
Не верифицирован
05 авг 2026, 20:23
6051a06
Код
Авторство
О чём код?
<?php namespace Illuminate\Tests\Testing\Fluent; use Illuminate\Support\Collection; use Illuminate\Testing\Fluent\AssertableJson; use Illuminate\Tests\Testing\Stubs\ArrayableStubObject; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; use RuntimeException; use TypeError; class AssertTest extends TestCase { public function testAssertHas() { $assert = AssertableJson::fromArray([ 'prop' => 'value', ]); $assert->has('prop'); } public function testAssertHasFailsWhenPropMissing() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [prop] does not exist.')); $assert->has('prop'); } public function testAssertHasNestedProp() { $assert = AssertableJson::fromArray([ 'example' => [ 'nested' => 'nested-value', ], ]); $assert->has('example.nested'); } public function testAssertHasFailsWhenNestedPropMissing() { $assert = AssertableJson::fromArray([ 'example' => [ 'nested' => 'nested-value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [example.another] does not exist.')); $assert->has('example.another'); } public function testAssertHasCountItemsInProp() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $assert->has('bar', 2); } public function testAssertHasCountFailsWhenAmountOfItemsDoesNotMatch() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not have the expected size.')); $assert->has('bar', 1); } public function testAssertHasCountFailsWhenPropMissing() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->has('baz', 1); } public function testAssertHasFailsWhenSecondArgumentUnsupportedType() { $assert = AssertableJson::fromArray([ 'bar' => 'baz', ]); $this->expectException(TypeError::class); $assert->has('bar', 'invalid'); } public function testAssertHasOnlyCounts() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $assert->has(3); } public function testAssertHasOnlyCountFails() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Root level does not have the expected size.')); $assert->has(2); } public function testAssertHasOnlyCountFailsScoped() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not have the expected size.')); $assert->has('bar', function ($bar) { $bar->has(3); }); } public function testAssertHasWithWhereNotDoesNotFail() { $assert = AssertableJson::fromArray([ 'data' => [ [ 'id' => 1, 'name' => 'Taylor', ], [ 'id' => 2, 'name' => 'Nuno', ], ], ]); $assert->has('data', function ($bar) { $bar->has(2) ->each(fn ($json) => $json->whereNot('id', 3)->etc()); }); } public function testAssertHasWithWhereNotFails() { $assert = AssertableJson::fromArray([ 'data' => [ [ 'id' => 1, 'name' => 'Taylor', ], [ 'id' => 2, 'name' => 'Mateus', ], ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [data.1.id] contains a value that should be missing: [id, 2]')); $assert->has('data', function ($bar) { $bar->has(2) ->each(fn ($json) => $json->whereNot('id', 2)->etc()); }); } public function testAssertHasWithWhereNotDoesNotFailClosure() { $assert = AssertableJson::fromArray([ 'data' => [ [ 'id' => 1, 'name' => 'Taylor', ], [ 'id' => 2, 'name' => 'Mateus', ], ], ]); $assert->has('data', function ($bar) { $bar->has(2) ->each(fn ($json) => $json->whereNot('id', fn ($value) => $value === 3)->etc()); }); } public function testAssertHasWithWhereNotFailsClosure() { $assert = AssertableJson::fromArray([ 'data' => [ [ 'id' => 1, 'name' => 'Taylor', ], [ 'id' => 2, 'name' => 'Mateus', ], ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [data.1.id] was marked as invalid using a closure.')); $assert->has('data', function ($bar) { $bar->has(2) ->each(fn ($json) => $json->whereNot('id', fn ($value) => $value === 2)->etc()); }); } public function testAssertCount() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $assert->count(3); } public function testAssertCountFails() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Root level does not have the expected size.')); $assert->count(2); } public function testAssertCountFailsScoped() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not have the expected size.')); $assert->has('bar', function ($bar) { $bar->count(3); }); } public function testAssertBetween() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $assert->countBetween(1, 3); } public function testAssertBetweenFails() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Root level size is not less than or equal to [2].')); $assert->countBetween(1, 2); } public function testAssertBetweenLowestValueFails() { $assert = AssertableJson::fromArray([ 'foo', 'bar', 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Root level size is not greater than or equal to [4].')); $assert->countBetween(4, 3); } public function testAssertBetweenFailsScoped() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', 'foo' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] size is not less than or equal to [2].')); $assert->has('bar', function (AssertableJson $bar) { $bar->countBetween(1, 2); }); } public function testAssertMissing() { $assert = AssertableJson::fromArray([ 'foo' => [ 'bar' => true, ], ]); $assert->missing('foo.baz'); } public function testAssertMissingFailsWhenPropExists() { $assert = AssertableJson::fromArray([ 'prop' => 'value', 'foo' => [ 'bar' => true, ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo.bar] was found while it was expected to be missing.')); $assert->missing('foo.bar'); } public function testAssertMissingAll() { $assert = AssertableJson::fromArray([ 'baz' => 'foo', ]); $assert->missingAll([ 'foo', 'bar', ]); } public function testAssertMissingAllFailsWhenAtLeastOnePropExists() { $assert = AssertableJson::fromArray([ 'baz' => 'foo', ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] was found while it was expected to be missing.')); $assert->missingAll([ 'bar', 'baz', ]); } public function testAssertMissingAllAcceptsMultipleArgumentsInsteadOfArray() { $assert = AssertableJson::fromArray([ 'baz' => 'foo', ]); $assert->missingAll('foo', 'bar'); $this->expectExceptionObject(new AssertionFailedError('Property [baz] was found while it was expected to be missing.')); $assert->missingAll('bar', 'baz'); } public function testAssertWhereMatchesValue() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $assert->where('bar', 'value'); } public function testAssertWhereFailsWhenDoesNotMatchValue() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not match the expected value.')); $assert->where('bar', 'invalid'); } public function testAssertWhereFailsWhenMissing() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->where('baz', 'invalid'); } public function testAssertWhereFailsWhenMatchingLoosely() { $assert = AssertableJson::fromArray([ 'bar' => 1, ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not match the expected value.')); $assert->where('bar', true); } public function testAssertWhereUsingClosure() { $assert = AssertableJson::fromArray([ 'bar' => 'baz', ]); $assert->where('bar', function ($value) { return $value === 'baz'; }); } public function testAssertWhereFailsWhenDoesNotMatchValueUsingClosure() { $assert = AssertableJson::fromArray([ 'bar' => 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] was marked as invalid using a closure.')); $assert->where('bar', function ($value) { return $value === 'invalid'; }); } public function testAssertWhereClosureArrayValuesAreAutomaticallyCastedToCollections() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'foo', 'example' => 'value', ], ]); $assert->where('bar', function ($value) { $this->assertInstanceOf(Collection::class, $value); return $value->count() === 2; }); } public function testAssertWhereMatchesValueUsingArrayable() { $stub = ArrayableStubObject::make(['foo' => 'bar']); $assert = AssertableJson::fromArray([ 'bar' => $stub->toArray(), ]); $assert->where('bar', $stub); } public function testAssertWhereMatchesValueUsingArrayableWhenSortedDifferently() { $assert = AssertableJson::fromArray([ 'data' => [ 'status' => 200, 'user' => [ 'id' => 1, 'name' => 'Taylor', ], ], ]); $assert->where('data', [ 'user' => [ 'name' => 'Taylor', 'id' => 1, ], 'status' => 200, ]); } public function testAssertWhereFailsWhenDoesNotMatchValueUsingArrayable() { $assert = AssertableJson::fromArray([ 'bar' => ['id' => 1, 'name' => 'Example'], 'baz' => [ 'id' => 1, 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', 'email_verified_at' => '2021-01-22T10:34:42.000000Z', 'created_at' => '2021-01-22T10:34:42.000000Z', 'updated_at' => '2021-01-22T10:34:42.000000Z', ], ]); $assert ->where('bar', ArrayableStubObject::make(['name' => 'Example', 'id' => 1])) ->where('baz', [ 'name' => 'Taylor Otwell', 'email' => 'taylor@laravel.com', 'id' => 1, 'email_verified_at' => '2021-01-22T10:34:42.000000Z', 'updated_at' => '2021-01-22T10:34:42.000000Z', 'created_at' => '2021-01-22T10:34:42.000000Z', ]); } public function testAssertWhereUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'bar' => BackedEnum::test->value, ]); $assert->where('bar', BackedEnum::test); $assert = AssertableJson::fromArray([ 'bar' => BackedEnum::test_empty->value, ]); $assert->where('bar', BackedEnum::test_empty); } public function testAssertWhereFailsUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'bar' => BackedEnum::test->value, ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not match the expected value.')); $assert->where('bar', BackedEnum::test_empty); } public function testAssertWhereNullMatchesValue() { $assert = AssertableJson::fromArray([ 'bar' => null, ]); $assert->whereNull('bar'); } public function testAssertWhereNullFailsWhenNotNull() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] should be null.')); $assert->whereNull('bar'); } public function testAssertWhereNullFailsWhenMissing() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->whereNull('baz'); } public function testAssertWhereNotNullMatchesValue() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $assert->whereNotNull('bar'); } public function testAssertWhereNotNullFailsWhenNull() { $assert = AssertableJson::fromArray([ 'bar' => null, ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] should not be null.')); $assert->whereNotNull('bar'); } public function testAssertWhereNotNullFailsWhenMissing() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->whereNotNull('baz'); } public function testAssertWhereContainsFailsWithEmptyValue() { $assert = AssertableJson::fromArray([]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] does not contain [1].')); $assert->whereContains('foo', ['1']); } public function testAssertWhereContainsFailsWithMissingValue() { $assert = AssertableJson::fromArray([ 'foo' => ['bar', 'baz'], ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] does not contain [invalid].')); $assert->whereContains('foo', ['bar', 'baz', 'invalid']); } public function testAssertWhereContainsFailsWithMissingNestedValue() { $assert = AssertableJson::fromArray([ ['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4], ]); $this->expectExceptionObject(new AssertionFailedError('Property [id] does not contain [5].')); $assert->whereContains('id', [1, 2, 3, 4, 5]); } public function testAssertWhereContainsFailsWhenDoesNotMatchType() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] does not contain [1].')); $assert->whereContains('foo', ['1']); } public function testAssertWhereContainsFailsWhenDoesNotSatisfyClosure() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] does not contain a value that passes the truth test within the given closure.')); $assert->whereContains('foo', [function ($actual) { return $actual === 5; }]); } public function testAssertWhereContainsFailsWhenHavingExpectedValueButDoesNotSatisfyClosure() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] does not contain a value that passes the truth test within the given closure.')); $assert->whereContains('foo', [1, function ($actual) { return $actual === 5; }]); } public function testAssertWhereContainsFailsWhenSatisfiesClosureButDoesNotHaveExpectedValue() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] does not contain [5].')); $assert->whereContains('foo', [5, function ($actual) { return $actual === 1; }]); } public function testAssertWhereContainsWithNestedValue() { $assert = AssertableJson::fromArray([ ['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4], ]); $assert->whereContains('id', 1); $assert->whereContains('id', [1, 2, 3, 4]); $assert->whereContains('id', [4, 3, 2, 1]); } public function testAssertWhereContainsWithMatchingType() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $assert->whereContains('foo', 1); $assert->whereContains('foo', [1]); } public function testAssertWhereContainsWithNullValue() { $assert = AssertableJson::fromArray([ 'foo' => null, ]); $assert->whereContains('foo', null); $assert->whereContains('foo', [null]); } public function testAssertWhereContainsWithOutOfOrderMatchingType() { $assert = AssertableJson::fromArray([ 'foo' => [4, 1, 7, 3], ]); $assert->whereContains('foo', [1, 7, 4, 3]); } public function testAssertWhereContainsWithOutOfOrderNestedMatchingType() { $assert = AssertableJson::fromArray([ ['bar' => 5], ['baz' => 4], ['zal' => 8], ]); $assert->whereContains('baz', 4); } public function testAssertWhereContainsWithClosure() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $assert->whereContains('foo', function ($actual) { return $actual % 3 === 0; }); } public function testAssertWhereContainsWithNestedClosure() { $assert = AssertableJson::fromArray([ 'foo' => 1, 'bar' => 2, 'baz' => 3, ]); $assert->whereContains('baz', function ($actual) { return $actual % 3 === 0; }); } public function testAssertWhereContainsWithMultipleClosure() { $assert = AssertableJson::fromArray([ 'foo' => [1, 2, 3, 4], ]); $assert->whereContains('foo', [ function ($actual) { return $actual % 3 === 0; }, function ($actual) { return $actual % 2 === 0; }, ]); } public function testAssertWhereContainsWithNullExpectation() { $assert = AssertableJson::fromArray([ 'foo' => 1, ]); $assert->whereContains('foo', null); } public function testAssertWhereContainsUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'bar' => [BackedEnum::test->value], ]); $assert->whereContains('bar', BackedEnum::test); $assert = AssertableJson::fromArray([ 'bar' => [BackedEnum::test_empty->value], ]); $assert->whereContains('bar', BackedEnum::test_empty); } public function testAssertWhereContainsFailsUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'bar' => [BackedEnum::test_empty->value], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not contain [test].')); $assert->whereContains('bar', BackedEnum::test); } public function testAssertNestedWhereMatchesValue() { $assert = AssertableJson::fromArray([ 'example' => [ 'nested' => 'nested-value', ], ]); $assert->where('example.nested', 'nested-value'); } public function testAssertNestedWhereFailsWhenDoesNotMatchValue() { $assert = AssertableJson::fromArray([ 'example' => [ 'nested' => 'nested-value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [example.nested] does not match the expected value.')); $assert->where('example.nested', 'another-value'); } public function testAssertNestedWhereUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'example' => [ 'nested' => BackedEnum::test->value, ], ]); $assert->where('example.nested', BackedEnum::test); } public function testAssertNestedWhereFailsUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'example' => [ 'nested' => BackedEnum::test_empty->value, ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [example.nested] does not match the expected value.')); $assert->where('example.nested', BackedEnum::test); } public function testAssertWhereDoesNotMatchValue() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $assert->whereNot('bar', 'different_value'); } public function testAssertWhereNotFailsWhenMatchingValue() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] contains a value that should be missing: [bar, value]')); $assert->whereNot('bar', 'value'); } public function testAssertWhereNotFailsWhenNotMissing() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->whereNot('baz', 'value'); } public function testAssertWhereNotUsingClosure() { $assert = AssertableJson::fromArray([ 'bar' => 'baz', ]); $assert->whereNot('bar', function ($value) { return $value === 'foo'; }); } public function testAssertWhereNotFailsWhenMatchesValueUsingClosure() { $assert = AssertableJson::fromArray([ 'bar' => 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] was marked as invalid using a closure.')); $assert->whereNot('bar', function ($value) { return $value === 'baz'; }); } public function testAssertWhereNotUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'bar' => BackedEnum::test->value, ]); $assert->whereNot('bar', BackedEnum::test_empty); } public function testAssertWhereNotFailsUsingBackedEnum() { $assert = AssertableJson::fromArray([ 'bar' => BackedEnum::test->value, ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] contains a value that should be missing: [bar, test]')); $assert->whereNot('bar', BackedEnum::test); } public function testScope() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $called = false; $assert->has('bar', function (AssertableJson $assert) use (&$called) { $called = true; $assert ->where('baz', 'example') ->where('prop', 'value'); }); $this->assertTrue($called, 'The scoped query was never actually called.'); } public function testScopeFailsWhenPropMissing() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->has('baz', function (AssertableJson $item) { $item->where('baz', 'example'); }); } public function testScopeFailsWhenPropSingleValue() { $assert = AssertableJson::fromArray([ 'bar' => 'value', ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] is not scopeable.')); $assert->has('bar', function (AssertableJson $item) { // }); } public function testScopeShorthand() { $assert = AssertableJson::fromArray([ 'bar' => [ ['key' => 'first'], ['key' => 'second'], ], ]); $called = false; $assert->has('bar', 2, function (AssertableJson $item) use (&$called) { $item->where('key', 'first'); $called = true; }); $this->assertTrue($called, 'The scoped query was never actually called.'); } public function testScopeShorthandWithoutCount() { $assert = AssertableJson::fromArray([ 'bar' => [ ['key' => 'first'], ['key' => 'second'], ], ]); $called = false; $assert->has('bar', null, function (AssertableJson $item) use (&$called) { $item->where('key', 'first'); $called = true; }); $this->assertTrue($called, 'The scoped query was never actually called.'); } public function testScopeShorthandFailsWhenAssertingZeroItems() { $assert = AssertableJson::fromArray([ 'bar' => [ ['key' => 'first'], ['key' => 'second'], ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not have the expected size.')); $assert->has('bar', 0, function (AssertableJson $item) { $item->where('key', 'first'); }); } public function testScopeShorthandFailsWhenAmountOfItemsDoesNotMatch() { $assert = AssertableJson::fromArray([ 'bar' => [ ['key' => 'first'], ['key' => 'second'], ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [bar] does not have the expected size.')); $assert->has('bar', 1, function (AssertableJson $item) { $item->where('key', 'first'); }); } public function testScopeShorthandFailsWhenAssertingEmptyArray() { $assert = AssertableJson::fromArray([ 'bar' => [], ]); $this->expectExceptionObject(new AssertionFailedError('Cannot scope directly onto the first element of property [bar] because it is empty.')); $assert->has('bar', 0, function (AssertableJson $item) { $item->where('key', 'first'); }); } public function testScopeShorthandFailsWhenAssertingEmptyArrayWithoutCount() { $assert = AssertableJson::fromArray([ 'bar' => [], ]); $this->expectExceptionObject(new AssertionFailedError('Cannot scope directly onto the first element of property [bar] because it is empty.')); $assert->has('bar', null, function (AssertableJson $item) { $item->where('key', 'first'); }); } public function testScopeShorthandFailsWhenSecondArgumentUnsupportedType() { $assert = AssertableJson::fromArray([ 'bar' => [ ['key' => 'first'], ['key' => 'second'], ], ]); $this->expectException(TypeError::class); $assert->has('bar', 'invalid', function (AssertableJson $item) { $item->where('key', 'first'); }); } public function testFirstScope() { $assert = AssertableJson::fromArray([ 'foo' => [ 'key' => 'first', ], 'bar' => [ 'key' => 'second', ], ]); $assert->first(function (AssertableJson $item) { $item->where('key', 'first'); }); } public function testFirstScopeFailsWhenNoProps() { $assert = AssertableJson::fromArray([]); $this->expectExceptionObject(new AssertionFailedError('Cannot scope directly onto the first element of the root level because it is empty.')); $assert->first(function (AssertableJson $item) { // }); } public function testFirstNestedScopeFailsWhenNoProps() { $assert = AssertableJson::fromArray([ 'foo' => [], ]); $this->expectExceptionObject(new AssertionFailedError('Cannot scope directly onto the first element of property [foo] because it is empty.')); $assert->has('foo', function (AssertableJson $assert) { $assert->first(function (AssertableJson $item) { // }); }); } public function testFirstScopeFailsWhenPropSingleValue() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] is not scopeable.')); $assert->first(function (AssertableJson $item) { // }); } public function testEachScope() { $assert = AssertableJson::fromArray([ 'foo' => [ 'key' => 'first', ], 'bar' => [ 'key' => 'second', ], ]); $assert->each(function (AssertableJson $item) { $item->whereType('key', 'string'); }); } public function testEachScopeFailsWhenNoProps() { $assert = AssertableJson::fromArray([]); $this->expectExceptionObject(new AssertionFailedError('Cannot scope directly onto each element of the root level because it is empty.')); $assert->each(function (AssertableJson $item) { // }); } public function testEachNestedScopeFailsWhenNoProps() { $assert = AssertableJson::fromArray([ 'foo' => [], ]); $this->expectExceptionObject(new AssertionFailedError('Cannot scope directly onto each element of property [foo] because it is empty.')); $assert->has('foo', function (AssertableJson $assert) { $assert->each(function (AssertableJson $item) { // }); }); } public function testEachScopeFailsWhenPropSingleValue() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] is not scopeable.')); $assert->each(function (AssertableJson $item) { // }); } public function testFailsWhenNotInteractingWithAllPropsInScope() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Unexpected properties were found in scope [bar].')); $assert->has('bar', function (AssertableJson $item) { $item->where('baz', 'example'); }); } public function testDisableInteractionCheckForCurrentScope() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $assert->has('bar', function (AssertableJson $item) { $item->etc(); }); } public function testCannotDisableInteractionCheckForDifferentScopes() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => [ 'foo' => 'bar', 'example' => 'value', ], 'prop' => 'value', ], ]); $this->expectExceptionObject(new AssertionFailedError('Unexpected properties were found in scope [bar.baz].')); $assert->has('bar', function (AssertableJson $item) { $item ->etc() ->has('baz', function (AssertableJson $item) { // }); }); } public function testTopLevelPropInteractionDisabledByDefault() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', 'bar' => 'baz', ]); $assert->has('foo'); } public function testTopLevelInteractionEnabledWhenInteractedFlagSet() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', 'bar' => 'baz', ]); $this->expectExceptionObject(new AssertionFailedError('Unexpected properties were found on the root level.')); $assert ->has('foo') ->interacted(); } public function testAssertWhereAllMatchesValues() { $assert = AssertableJson::fromArray([ 'foo' => [ 'bar' => 'value', 'example' => ['hello' => 'world'], ], 'baz' => 'another', ]); $assert->whereAll([ 'foo.bar' => 'value', 'foo.example' => ArrayableStubObject::make(['hello' => 'world']), 'baz' => function ($value) { return $value === 'another'; }, ]); } public function testAssertWhereAllFailsWhenAtLeastOnePropDoesNotMatchValue() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', 'baz' => 'example', ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] was marked as invalid using a closure.')); $assert->whereAll([ 'foo' => 'bar', 'baz' => function ($value) { return $value === 'foo'; }, ]); } public function testAssertWhereTypeString() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $assert->whereType('foo', 'string'); } public function testAssertWhereTypeInteger() { $assert = AssertableJson::fromArray([ 'foo' => 123, ]); $assert->whereType('foo', 'integer'); } public function testAssertWhereTypeBoolean() { $assert = AssertableJson::fromArray([ 'foo' => true, ]); $assert->whereType('foo', 'boolean'); } public function testAssertWhereTypeDouble() { $assert = AssertableJson::fromArray([ 'foo' => 12.3, ]); $assert->whereType('foo', 'double'); } public function testAssertWhereTypeArray() { $assert = AssertableJson::fromArray([ 'foo' => ['bar', 'baz'], 'bar' => ['foo' => 'baz'], ]); $assert->whereType('foo', 'array'); $assert->whereType('bar', 'array'); } public function testAssertWhereTypeNull() { $assert = AssertableJson::fromArray([ 'foo' => null, ]); $assert->whereType('foo', 'null'); } public function testAssertWhereAllType() { $assert = AssertableJson::fromArray([ 'one' => 'foo', 'two' => 123, 'three' => true, 'four' => 12.3, 'five' => ['foo', 'bar'], 'six' => ['foo' => 'bar'], 'seven' => null, ]); $assert->whereAllType([ 'one' => 'string', 'two' => 'integer', 'three' => 'boolean', 'four' => 'double', 'five' => 'array', 'six' => 'array', 'seven' => 'null', ]); } public function testAssertWhereTypeWhenWrongTypeIsGiven() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] is not of expected type [integer].')); $assert->whereType('foo', 'integer'); } public function testAssertWhereTypeWithUnionTypes() { $firstAssert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $secondAssert = AssertableJson::fromArray([ 'foo' => null, ]); $firstAssert->whereType('foo', ['string', 'null']); $secondAssert->whereType('foo', ['string', 'null']); } public function testAssertWhereTypeWhenWrongUnionTypeIsGiven() { $assert = AssertableJson::fromArray([ 'foo' => 123, ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] is not of expected type [string|null].')); $assert->whereType('foo', ['string', 'null']); } public function testAssertWhereTypeWithPipeInUnionType() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $assert->whereType('foo', 'string|null'); } public function testAssertWhereTypeWithPipeInWrongUnionType() { $assert = AssertableJson::fromArray([ 'foo' => 'bar', ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo] is not of expected type [integer|null].')); $assert->whereType('foo', 'integer|null'); } public function testAssertHasAll() { $assert = AssertableJson::fromArray([ 'foo' => [ 'bar' => 'value', 'example' => ['hello' => 'world'], ], 'baz' => 'another', ]); $assert->hasAll([ 'foo.bar', 'foo.example', 'baz', ]); } public function testAssertHasAllFailsWhenAtLeastOnePropMissing() { $assert = AssertableJson::fromArray([ 'foo' => [ 'bar' => 'value', 'example' => ['hello' => 'world'], ], 'baz' => 'another', ]); $this->expectExceptionObject(new AssertionFailedError('Property [foo.baz] does not exist.')); $assert->hasAll([ 'foo.bar', 'foo.baz', 'baz', ]); } public function testAssertHasAllAcceptsMultipleArgumentsInsteadOfArray() { $assert = AssertableJson::fromArray([ 'foo' => [ 'bar' => 'value', 'example' => ['hello' => 'world'], ], 'baz' => 'another', ]); $assert->hasAll('foo.bar', 'foo.example', 'baz'); $this->expectExceptionObject(new AssertionFailedError('Property [foo.baz] does not exist.')); $assert->hasAll('foo.bar', 'foo.baz', 'baz'); } public function testAssertCountMultipleProps() { $assert = AssertableJson::fromArray([ 'bar' => [ 'key' => 'value', 'prop' => 'example', ], 'baz' => [ 'another' => 'value', ], ]); $assert->hasAll([ 'bar' => 2, 'baz' => 1, ]); } public function testAssertCountMultiplePropsFailsWhenPropMissing() { $assert = AssertableJson::fromArray([ 'bar' => [ 'key' => 'value', 'prop' => 'example', ], ]); $this->expectExceptionObject(new AssertionFailedError('Property [baz] does not exist.')); $assert->hasAll([ 'bar' => 2, 'baz' => 1, ]); } public function testMacroable() { AssertableJson::macro('myCustomMacro', function () { throw new RuntimeException('My Custom Macro was called!'); }); $this->expectExceptionObject(new RuntimeException('My Custom Macro was called!')); $assert = AssertableJson::fromArray(['foo' => 'bar']); $assert->myCustomMacro(); } public function testTappable() { $assert = AssertableJson::fromArray([ 'bar' => [ 'baz' => 'example', 'prop' => 'value', ], ]); $called = false; $assert->has('bar', function (AssertableJson $assert) use (&$called) { $assert->etc(); $assert->tap(function (AssertableJson $assert) use (&$called) { $called = true; }); }); $this->assertTrue($called, 'The scoped query was never actually called.'); } }