@@ -58,7 +58,7 @@ public function testAssertHasFailsWhenNestedPropMissing()
5858 $ assert ->has ('example.another ' );
5959 }
6060
61- public function testAssertCountItemsInProp ()
61+ public function testAssertHasCountItemsInProp ()
6262 {
6363 $ assert = AssertableJson::fromArray ([
6464 'bar ' => [
@@ -70,7 +70,7 @@ public function testAssertCountItemsInProp()
7070 $ assert ->has ('bar ' , 2 );
7171 }
7272
73- public function testAssertCountFailsWhenAmountOfItemsDoesNotMatch ()
73+ public function testAssertHasCountFailsWhenAmountOfItemsDoesNotMatch ()
7474 {
7575 $ assert = AssertableJson::fromArray ([
7676 'bar ' => [
@@ -85,7 +85,7 @@ public function testAssertCountFailsWhenAmountOfItemsDoesNotMatch()
8585 $ assert ->has ('bar ' , 1 );
8686 }
8787
88- public function testAssertCountFailsWhenPropMissing ()
88+ public function testAssertHasCountFailsWhenPropMissing ()
8989 {
9090 $ assert = AssertableJson::fromArray ([
9191 'bar ' => [
@@ -111,6 +111,90 @@ public function testAssertHasFailsWhenSecondArgumentUnsupportedType()
111111 $ assert ->has ('bar ' , 'invalid ' );
112112 }
113113
114+ public function testAssertHasOnlyCounts ()
115+ {
116+ $ assert = AssertableJson::fromArray ([
117+ 'foo ' ,
118+ 'bar ' ,
119+ 'baz ' ,
120+ ]);
121+
122+ $ assert ->has (3 );
123+ }
124+
125+ public function testAssertHasOnlyCountFails ()
126+ {
127+ $ assert = AssertableJson::fromArray ([
128+ 'foo ' ,
129+ 'bar ' ,
130+ 'baz ' ,
131+ ]);
132+
133+ $ this ->expectException (AssertionFailedError::class);
134+ $ this ->expectExceptionMessage ('Root level does not have the expected size. ' );
135+
136+ $ assert ->has (2 );
137+ }
138+
139+ public function testAssertHasOnlyCountFailsScoped ()
140+ {
141+ $ assert = AssertableJson::fromArray ([
142+ 'bar ' => [
143+ 'baz ' => 'example ' ,
144+ 'prop ' => 'value ' ,
145+ ],
146+ ]);
147+
148+ $ this ->expectException (AssertionFailedError::class);
149+ $ this ->expectExceptionMessage ('Property [bar] does not have the expected size. ' );
150+
151+ $ assert ->has ('bar ' , function ($ bar ) {
152+ $ bar ->has (3 );
153+ });
154+ }
155+
156+ public function testAssertCount ()
157+ {
158+ $ assert = AssertableJson::fromArray ([
159+ 'foo ' ,
160+ 'bar ' ,
161+ 'baz ' ,
162+ ]);
163+
164+ $ assert ->count (3 );
165+ }
166+
167+ public function testAssertCountFails ()
168+ {
169+ $ assert = AssertableJson::fromArray ([
170+ 'foo ' ,
171+ 'bar ' ,
172+ 'baz ' ,
173+ ]);
174+
175+ $ this ->expectException (AssertionFailedError::class);
176+ $ this ->expectExceptionMessage ('Root level does not have the expected size. ' );
177+
178+ $ assert ->count (2 );
179+ }
180+
181+ public function testAssertCountFailsScoped ()
182+ {
183+ $ assert = AssertableJson::fromArray ([
184+ 'bar ' => [
185+ 'baz ' => 'example ' ,
186+ 'prop ' => 'value ' ,
187+ ],
188+ ]);
189+
190+ $ this ->expectException (AssertionFailedError::class);
191+ $ this ->expectExceptionMessage ('Property [bar] does not have the expected size. ' );
192+
193+ $ assert ->has ('bar ' , function ($ bar ) {
194+ $ bar ->count (3 );
195+ });
196+ }
197+
114198 public function testAssertMissing ()
115199 {
116200 $ assert = AssertableJson::fromArray ([
@@ -421,7 +505,7 @@ public function testScopeShorthandFailsWhenAssertingZeroItems()
421505 ]);
422506
423507 $ this ->expectException (AssertionFailedError::class);
424- $ this ->expectExceptionMessage ('Cannot scope directly onto the first entry of property [bar] when asserting that it has a size of 0 . ' );
508+ $ this ->expectExceptionMessage ('Property [bar] does not have the expected size. ' );
425509
426510 $ assert ->has ('bar ' , 0 , function (AssertableJson $ item ) {
427511 $ item ->where ('key ' , 'first ' );
@@ -445,6 +529,64 @@ public function testScopeShorthandFailsWhenAmountOfItemsDoesNotMatch()
445529 });
446530 }
447531
532+ public function testFirstScope ()
533+ {
534+ $ assert = AssertableJson::fromArray ([
535+ 'foo ' => [
536+ 'key ' => 'first ' ,
537+ ],
538+ 'bar ' => [
539+ 'key ' => 'second ' ,
540+ ],
541+ ]);
542+
543+ $ assert ->first (function (AssertableJson $ item ) {
544+ $ item ->where ('key ' , 'first ' );
545+ });
546+ }
547+
548+ public function testFirstScopeFailsWhenNoProps ()
549+ {
550+ $ assert = AssertableJson::fromArray ([]);
551+
552+ $ this ->expectException (AssertionFailedError::class);
553+ $ this ->expectExceptionMessage ('Cannot scope directly onto the first element of the root level because it is empty. ' );
554+
555+ $ assert ->first (function (AssertableJson $ item ) {
556+ //
557+ });
558+ }
559+
560+ public function testFirstNestedScopeFailsWhenNoProps ()
561+ {
562+ $ assert = AssertableJson::fromArray ([
563+ 'foo ' => [],
564+ ]);
565+
566+ $ this ->expectException (AssertionFailedError::class);
567+ $ this ->expectExceptionMessage ('Cannot scope directly onto the first element of property [foo] because it is empty. ' );
568+
569+ $ assert ->has ('foo ' , function (AssertableJson $ assert ) {
570+ $ assert ->first (function (AssertableJson $ item ) {
571+ //
572+ });
573+ });
574+ }
575+
576+ public function testFirstScopeFailsWhenPropSingleValue ()
577+ {
578+ $ assert = AssertableJson::fromArray ([
579+ 'foo ' => 'bar ' ,
580+ ]);
581+
582+ $ this ->expectException (AssertionFailedError::class);
583+ $ this ->expectExceptionMessage ('Property [foo] is not scopeable. ' );
584+
585+ $ assert ->first (function (AssertableJson $ item ) {
586+ //
587+ });
588+ }
589+
448590 public function testFailsWhenNotInteractingWithAllPropsInScope ()
449591 {
450592 $ assert = AssertableJson::fromArray ([
0 commit comments