Skip to content

Commit 311c2ba

Browse files
authored
Relax parameter types to allow filters like "array:empty" in JsonType (#107)
* Relax parameter types to allow filters like "array:empty" * Verify that the "array:empty" filter is case-insensitive * Add "array:empty" filter to the documentation
1 parent 727823a commit 311c2ba

File tree

4 files changed

+19
-11
lines changed

4 files changed

+19
-11
lines changed

Diff for: src/Codeception/Module/REST.php

+1
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,7 @@ public function dontSeeResponseContainsJson(array $json = []): void
13011301
*
13021302
* Here is the list of possible filters:
13031303
*
1304+
* * `array:empty` - check that value is an empty array
13041305
* * `integer:>{val}` - checks that integer is greater than {val} (works with float and string types too).
13051306
* * `integer:<{val}` - checks that integer is lower than {val} (works with float and string types too).
13061307
* * `string:url` - checks that value is valid url.

Diff for: src/Codeception/Util/JsonType.php

+6-5
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
*
1515
* ```php
1616
* <?php
17-
* $jsonType = new JsonType(['name' => 'davert', 'id' => 1]);
17+
* $jsonType = new JsonType(['name' => 'davert', 'id' => 1, 'data' => []]);
1818
* $jsonType->matches([
1919
* 'name' => 'string:!empty',
2020
* 'id' => 'integer:>0|string:>0',
21+
* 'data' => 'array:empty',
2122
* ]); // => true
2223
*
2324
* $jsonType->matches([
@@ -170,7 +171,7 @@ protected function typeComparison(array $data, array $jsonType): string|bool
170171
return $regexes[1][$pos];
171172
}, $filter);
172173

173-
$matched = $matched && $this->matchFilter($filter, (string)$data[$key]);
174+
$matched = $matched && $this->matchFilter($filter, $data[$key]);
174175
}
175176

176177
if ($matched) {
@@ -186,7 +187,7 @@ protected function typeComparison(array $data, array $jsonType): string|bool
186187
return true;
187188
}
188189

189-
protected function matchFilter(string $filter, string $value)
190+
protected function matchFilter(string $filter, mixed $value)
190191
{
191192
$filter = trim($filter);
192193
if (str_starts_with($filter, '!')) {
@@ -206,7 +207,7 @@ protected function matchFilter(string $filter, string $value)
206207
}
207208

208209
if (str_starts_with($filter, '=')) {
209-
return $value === substr($filter, 1);
210+
return (string) $value === substr($filter, 1);
210211
}
211212

212213
if ($filter === 'url') {
@@ -232,7 +233,7 @@ protected function matchFilter(string $filter, string $value)
232233
}
233234

234235
if (preg_match('#^regex\((.*?)\)$#', $filter, $matches)) {
235-
return preg_match($matches[1], $value);
236+
return preg_match($matches[1], (string) $value);
236237
}
237238

238239
if (preg_match('#^>=(-?[\d\.]+)$#', $filter, $matches)) {

Diff for: tests/unit/Codeception/Module/RestTest.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,10 @@ public function testApplicationJsonSubtypeIncludesObjectSerialized()
500500

501501
public function testJsonTypeMatches()
502502
{
503-
$this->setStubResponse('{"xxx": "yyy", "user_id": 1}');
504-
$this->module->seeResponseMatchesJsonType(['xxx' => 'string', 'user_id' => 'integer:<10']);
505-
$this->module->dontSeeResponseMatchesJsonType(['xxx' => 'integer', 'user_id' => 'integer:<10']);
503+
$this->setStubResponse('{"xxx": "yyy", "user_id": 1, "empty_array": [], "non_empty_array": ["foo"]}');
504+
$this->module->seeResponseMatchesJsonType(['xxx' => 'string', 'user_id' => 'integer:<10', 'empty_array' => 'array:empty', 'non_empty_array' => 'array:!empty']);
505+
$this->module->dontSeeResponseMatchesJsonType(['xxx' => 'integer', 'user_id' => 'integer:<10', 'empty_array' => 'array:empty', 'non_empty_array' => 'array:!empty']);
506+
$this->module->dontSeeResponseMatchesJsonType(['xxx' => 'string', 'user_id' => 'integer:<10', 'empty_array' => 'array:!empty', 'non_empty_array' => 'array:!empty']);
506507
}
507508

508509
public function testJsonTypeMatchesWithJsonPath()

Diff for: tests/unit/Codeception/Util/JsonTypeTest.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@ final class JsonTypeTest extends Unit
1515
'name' => 'string|null', // http://codeception.com/docs/modules/REST#seeResponseMatchesJsonType
1616
'user' => [
1717
'url' => 'String:url'
18-
]
18+
],
19+
'empty_array' => 'array',
1920
];
2021

2122
protected array $data = [
2223
'id' => 11,
2324
'retweeted' => false,
2425
'in_reply_to_screen_name' => null,
2526
'name' => null,
26-
'user' => ['url' => 'http://davert.com']
27+
'user' => ['url' => 'http://davert.com'],
28+
'empty_array' => [],
2729
];
2830

2931
protected function _after()
@@ -135,10 +137,11 @@ public function testEmailFilter()
135137

136138
public function testNegativeFilters()
137139
{
138-
$jsonType = new JsonType(['name' => 'davert', 'id' => 1]);
140+
$jsonType = new JsonType(['name' => 'davert', 'id' => 1, 'data' => ['foo']]);
139141
$this->assertTrue($jsonType->matches([
140142
'name' => 'string:!date|string:!empty',
141143
'id' => 'integer:!=0',
144+
'data' => 'array:!empty',
142145
]));
143146
}
144147

@@ -167,6 +170,8 @@ public function testArray()
167170
$this->types['user'] = 'array';
168171
$jsonType = new JsonType($this->data);
169172
$this->assertTrue($jsonType->matches($this->types));
173+
$this->assertTrue($jsonType->matches(['empty_array' => 'array:empty']));
174+
$this->assertTrue($jsonType->matches(['empty_array' => 'Array:empty']));
170175
}
171176

172177
public function testNull()

0 commit comments

Comments
 (0)