Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 422893b

Browse filesBrowse files
committed
feature #60105 [JsonPath] Add JsonPathAssertionsTrait and related constraints (alexandre-daubois)
This PR was merged into the 7.3 branch. Discussion ---------- [JsonPath] Add `JsonPathAssertionsTrait` and related constraints | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT Let's leverage JsonPath in test cases. I propose to add a new trait to ease testing JSON strings against JsonPath: ```php use PHPUnit\Framework\TestCase; use Symfony\Component\JsonPath\Test\JsonPathAssertionsTrait; class MyApiTest extends TestCase { use JsonPathAssertionsTrait; public function testItFetchesAllUsers(): void { $json = self::fetchUserCollection(); $this->assertJsonPathCount(3, '$.users[*]', $json); $this->assertJsonPathSame(['Melchior'], '$.users[0].username', $json); $this->assertJsonPathEquals(['30'], '$.users[0].age', $json, 'should return the age as string or int'); } public function testItFetchesOneUser(): void { $json = self::fetchOneUser(); $this->assertJsonPathSame(['Melchior'], '$.user.username', $json); $this->assertJsonPathEquals(['30'], '$.user.age', $json, 'should return the age as string or int'); } /** * Hard-coded for the example, but in a real integration test, you would actually make the API call! */ private static function fetchUserCollection(): string { // Simulate fetching JSON data from an API return <<<JSON { "users": [ { "username": "Melchior", "age": 30 }, { "username": "Gaspard", "age": 50 }, { "username": "Balthazar", "age": 55 } ] } JSON; } private static function fetchOneUser(): string { // Simulate fetching JSON data from an API return <<<JSON { "user": { "username": "Melchior", "age": 30 } } JSON; } } ``` Commits ------- 60cba45 [JsonPath] Add `JsonPathAssertionsTrait` and related constraints
2 parents c11519a + 60cba45 commit 422893b
Copy full SHA for 422893b

File tree

Expand file treeCollapse file tree

9 files changed

+557
-0
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+557
-0
lines changed
+80Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Assert;
15+
use PHPUnit\Framework\ExpectationFailedException;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
trait JsonPathAssertionsTrait
24+
{
25+
/**
26+
* @throws ExpectationFailedException
27+
*/
28+
final public static function assertJsonPathEquals(mixed $expectedValue, JsonPath|string $jsonPath, string $json, string $message = ''): void
29+
{
30+
Assert::assertThat($expectedValue, new JsonPathEquals($jsonPath, $json), $message);
31+
}
32+
33+
/**
34+
* @throws ExpectationFailedException
35+
*/
36+
final public static function assertJsonPathNotEquals(mixed $expectedValue, JsonPath|string $jsonPath, string $json, string $message = ''): void
37+
{
38+
Assert::assertThat($expectedValue, new JsonPathNotEquals($jsonPath, $json), $message);
39+
}
40+
41+
/**
42+
* @throws ExpectationFailedException
43+
*/
44+
final public static function assertJsonPathCount(int $expectedCount, JsonPath|string $jsonPath, string $json, string $message = ''): void
45+
{
46+
Assert::assertThat($expectedCount, new JsonPathCount($jsonPath, $json), $message);
47+
}
48+
49+
/**
50+
* @throws ExpectationFailedException
51+
*/
52+
final public static function assertJsonPathSame(mixed $expectedValue, JsonPath|string $jsonPath, string $json, string $message = ''): void
53+
{
54+
Assert::assertThat($expectedValue, new JsonPathSame($jsonPath, $json), $message);
55+
}
56+
57+
/**
58+
* @throws ExpectationFailedException
59+
*/
60+
final public static function assertJsonPathNotSame(mixed $expectedValue, JsonPath|string $jsonPath, string $json, string $message = ''): void
61+
{
62+
Assert::assertThat($expectedValue, new JsonPathNotSame($jsonPath, $json), $message);
63+
}
64+
65+
/**
66+
* @throws ExpectationFailedException
67+
*/
68+
final public static function assertJsonPathContains(mixed $expectedValue, JsonPath|string $jsonPath, string $json, bool $strict = true, string $message = ''): void
69+
{
70+
Assert::assertThat($expectedValue, new JsonPathContains($jsonPath, $json, $strict), $message);
71+
}
72+
73+
/**
74+
* @throws ExpectationFailedException
75+
*/
76+
final public static function assertJsonPathNotContains(mixed $expectedValue, JsonPath|string $jsonPath, string $json, bool $strict = true, string $message = ''): void
77+
{
78+
Assert::assertThat($expectedValue, new JsonPathNotContains($jsonPath, $json, $strict), $message);
79+
}
80+
}
+43Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathContains extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
private bool $strict = true,
29+
) {
30+
}
31+
32+
public function toString(): string
33+
{
34+
return \sprintf('is found in elements at JSON path "%s"', $this->jsonPath);
35+
}
36+
37+
protected function matches(mixed $other): bool
38+
{
39+
$result = (new JsonCrawler($this->json))->find($this->jsonPath);
40+
41+
return \in_array($other, $result, $this->strict);
42+
}
43+
}
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathCount extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
) {
29+
}
30+
31+
public function toString(): string
32+
{
33+
return \sprintf('matches expected count of JSON path "%s"', $this->jsonPath);
34+
}
35+
36+
protected function matches(mixed $other): bool
37+
{
38+
return $other === \count((new JsonCrawler($this->json))->find($this->jsonPath));
39+
}
40+
}
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathEquals extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
) {
29+
}
30+
31+
public function toString(): string
32+
{
33+
return \sprintf('equals JSON path "%s" result', $this->jsonPath);
34+
}
35+
36+
protected function matches(mixed $other): bool
37+
{
38+
return (new JsonCrawler($this->json))->find($this->jsonPath) == $other;
39+
}
40+
}
+43Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathNotContains extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
private bool $strict = true,
29+
) {
30+
}
31+
32+
public function toString(): string
33+
{
34+
return \sprintf('is not found in elements at JSON path "%s"', $this->jsonPath);
35+
}
36+
37+
protected function matches(mixed $other): bool
38+
{
39+
$result = (new JsonCrawler($this->json))->find($this->jsonPath);
40+
41+
return !\in_array($other, $result, $this->strict);
42+
}
43+
}
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathNotEquals extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
) {
29+
}
30+
31+
public function toString(): string
32+
{
33+
return \sprintf('does not equal JSON path "%s" result', $this->jsonPath);
34+
}
35+
36+
protected function matches(mixed $other): bool
37+
{
38+
return (new JsonCrawler($this->json))->find($this->jsonPath) != $other;
39+
}
40+
}
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathNotSame extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
) {
29+
}
30+
31+
public function toString(): string
32+
{
33+
return \sprintf('is not identical to JSON path "%s" result', $this->jsonPath);
34+
}
35+
36+
protected function matches(mixed $other): bool
37+
{
38+
return (new JsonCrawler($this->json))->find($this->jsonPath) !== $other;
39+
}
40+
}
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\JsonPath\Test;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\JsonPath\JsonCrawler;
16+
use Symfony\Component\JsonPath\JsonPath;
17+
18+
/**
19+
* @author Alexandre Daubois <alex.daubois@gmail.com>
20+
*
21+
* @experimental
22+
*/
23+
class JsonPathSame extends Constraint
24+
{
25+
public function __construct(
26+
private JsonPath|string $jsonPath,
27+
private string $json,
28+
) {
29+
}
30+
31+
public function toString(): string
32+
{
33+
return \sprintf('is identical to JSON path "%s" result', $this->jsonPath);
34+
}
35+
36+
protected function matches(mixed $other): bool
37+
{
38+
return (new JsonCrawler($this->json))->find($this->jsonPath) === $other;
39+
}
40+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.