12
12
namespace Symfony \Component \Validator \Test ;
13
13
14
14
use PHPUnit \Framework \Assert ;
15
+ use PHPUnit \Framework \Constraint \IsIdentical ;
16
+ use PHPUnit \Framework \Constraint \IsInstanceOf ;
17
+ use PHPUnit \Framework \Constraint \IsNull ;
18
+ use PHPUnit \Framework \Constraint \LogicalOr ;
19
+ use PHPUnit \Framework \ExpectationFailedException ;
15
20
use PHPUnit \Framework \TestCase ;
16
21
use Symfony \Component \Validator \Constraint ;
17
22
use Symfony \Component \Validator \Constraints \NotNull ;
23
+ use Symfony \Component \Validator \Constraints \Valid ;
18
24
use Symfony \Component \Validator \ConstraintValidatorInterface ;
19
25
use Symfony \Component \Validator \ConstraintViolation ;
20
26
use Symfony \Component \Validator \Context \ExecutionContext ;
21
27
use Symfony \Component \Validator \Context \ExecutionContextInterface ;
22
28
use Symfony \Component \Validator \Mapping \ClassMetadata ;
23
29
use Symfony \Component \Validator \Mapping \PropertyMetadata ;
30
+ use Symfony \Component \Validator \Validator \ContextualValidatorInterface ;
24
31
use Symfony \Contracts \Translation \TranslatorInterface ;
25
32
26
33
/**
@@ -99,7 +106,6 @@ protected function createContext()
99
106
$ translator = $ this ->getMockBuilder (TranslatorInterface::class)->getMock ();
100
107
$ translator ->expects ($ this ->any ())->method ('trans ' )->willReturnArgument (0 );
101
108
$ validator = $ this ->getMockBuilder ('Symfony\Component\Validator\Validator\ValidatorInterface ' )->getMock ();
102
- $ contextualValidator = $ this ->getMockBuilder ('Symfony\Component\Validator\Validator\ContextualValidatorInterface ' )->getMock ();
103
109
104
110
$ context = new ExecutionContext ($ validator , $ this ->root , $ translator );
105
111
$ context ->setGroup ($ this ->group );
@@ -109,7 +115,7 @@ protected function createContext()
109
115
$ validator ->expects ($ this ->any ())
110
116
->method ('inContext ' )
111
117
->with ($ context )
112
- ->willReturn ($ contextualValidator );
118
+ ->willReturn (new AssertingContextualValidator () );
113
119
114
120
return $ context ;
115
121
}
@@ -162,23 +168,18 @@ protected function setPropertyPath($propertyPath)
162
168
protected function expectNoValidate ()
163
169
{
164
170
$ validator = $ this ->context ->getValidator ()->inContext ($ this ->context );
165
- $ validator ->expects ($ this ->never ())
166
- ->method ('atPath ' );
167
- $ validator ->expects ($ this ->never ())
168
- ->method ('validate ' );
171
+ $ validator ->expectNoValidate ();
169
172
}
170
173
171
174
protected function expectValidateAt ($ i , $ propertyPath , $ value , $ group )
172
175
{
173
176
$ validator = $ this ->context ->getValidator ()->inContext ($ this ->context );
174
- $ validator ->expects ($ this ->at (2 * $ i ))
175
- ->method ('atPath ' )
176
- ->with ($ propertyPath )
177
- ->willReturn ($ validator );
178
- $ validator ->expects ($ this ->at (2 * $ i + 1 ))
179
- ->method ('validate ' )
180
- ->with ($ value , $ this ->logicalOr (null , [], $ this ->isInstanceOf ('\Symfony\Component\Validator\Constraints\Valid ' )), $ group )
181
- ->willReturn ($ validator );
177
+ $ validator ->expectValidation ($ i , $ propertyPath , $ value , $ group , function ($ passedConstraints ) {
178
+ $ expectedConstraints = new LogicalOr ();
179
+ $ expectedConstraints ->setConstraints ([new IsNull (), new IsIdentical ([]), new IsInstanceOf (Valid::class)]);
180
+
181
+ Assert::assertThat ($ passedConstraints , $ expectedConstraints );
182
+ });
182
183
}
183
184
184
185
protected function expectValidateValue (int $ i , $ value , array $ constraints = [], $ group = null )
@@ -193,14 +194,9 @@ protected function expectValidateValue(int $i, $value, array $constraints = [],
193
194
protected function expectValidateValueAt ($ i , $ propertyPath , $ value , $ constraints , $ group = null )
194
195
{
195
196
$ contextualValidator = $ this ->context ->getValidator ()->inContext ($ this ->context );
196
- $ contextualValidator ->expects ($ this ->at (2 * $ i ))
197
- ->method ('atPath ' )
198
- ->with ($ propertyPath )
199
- ->willReturn ($ contextualValidator );
200
- $ contextualValidator ->expects ($ this ->at (2 * $ i + 1 ))
201
- ->method ('validate ' )
202
- ->with ($ value , $ constraints , $ group )
203
- ->willReturn ($ contextualValidator );
197
+ $ contextualValidator ->expectValidation ($ i , $ propertyPath , $ value , $ group , function ($ passedConstraints ) use ($ constraints ) {
198
+ Assert::assertEquals ($ constraints , $ passedConstraints );
199
+ });
204
200
}
205
201
206
202
protected function expectViolationsAt ($ i , $ value , Constraint $ constraint )
@@ -372,3 +368,63 @@ private function getViolation(): ConstraintViolation
372
368
);
373
369
}
374
370
}
371
+
372
+ class AssertingContextualValidator implements ContextualValidatorInterface
373
+ {
374
+ private $ expectNoValidate = false ;
375
+ private $ atPathCalls = -1 ;
376
+ private $ expectedAtPath = [];
377
+ private $ validateCalls = -1 ;
378
+ private $ expectedValidate = [];
379
+
380
+ public function atPath ($ path )
381
+ {
382
+ Assert::assertFalse ($ this ->expectNoValidate , 'No validation calls have been expected. ' );
383
+
384
+ if (!isset ($ this ->expectedAtPath [++$ this ->atPathCalls ])) {
385
+ throw new ExpectationFailedException (sprintf ('Validation for property path "%s" was not expected. ' , $ path ));
386
+ }
387
+
388
+ Assert::assertSame ($ this ->expectedAtPath [$ this ->atPathCalls ], $ path );
389
+
390
+ return $ this ;
391
+ }
392
+
393
+ public function validate ($ value , $ constraints = null , $ groups = null )
394
+ {
395
+ Assert::assertFalse ($ this ->expectNoValidate , 'No validation calls have been expected. ' );
396
+
397
+ list ($ expectedValue , $ expectedGroup , $ expectedConstraints ) = $ this ->expectedValidate [++$ this ->validateCalls ];
398
+
399
+ Assert::assertSame ($ expectedValue , $ value );
400
+ $ expectedConstraints ($ constraints );
401
+ Assert::assertSame ($ expectedGroup , $ groups );
402
+
403
+ return $ this ;
404
+ }
405
+
406
+ public function validateProperty ($ object , $ propertyName , $ groups = null )
407
+ {
408
+ return $ this ;
409
+ }
410
+
411
+ public function validatePropertyValue ($ objectOrClass , $ propertyName , $ value , $ groups = null )
412
+ {
413
+ return $ this ;
414
+ }
415
+
416
+ public function getViolations ()
417
+ {
418
+ }
419
+
420
+ public function expectNoValidate ()
421
+ {
422
+ $ this ->expectNoValidate = true ;
423
+ }
424
+
425
+ public function expectValidation ($ call , $ propertyPath , $ value , $ group , $ constraints )
426
+ {
427
+ $ this ->expectedAtPath [$ call ] = $ propertyPath ;
428
+ $ this ->expectedValidate [$ call ] = [$ value , $ group , $ constraints ];
429
+ }
430
+ }
0 commit comments