Skip to content

Commit 8860afb

Browse files
committed
IsBsonType helpers and new IsStream constraint
1 parent df783f9 commit 8860afb

File tree

6 files changed

+88
-23
lines changed

6 files changed

+88
-23
lines changed

tests/UnifiedSpecTests/Constraint/IsBsonType.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
use MongoDB\Model\BSONArray;
2222
use MongoDB\Model\BSONDocument;
2323
use PHPUnit\Framework\Constraint\Constraint;
24+
use PHPUnit\Framework\Constraint\LogicalOr;
2425
use RuntimeException;
2526
use Symfony\Bridge\PhpUnit\ConstraintTrait;
2627
use function array_keys;
28+
use function array_map;
2729
use function count;
2830
use function is_array;
2931
use function is_bool;
@@ -76,6 +78,22 @@ public function __construct(string $type)
7678
$this->type = $type;
7779
}
7880

81+
public static function any() : LogicalOr
82+
{
83+
return self::anyOf(...array_keys(self::$knownTypes));
84+
}
85+
86+
public static function anyOf(string ...$types) : Constraint
87+
{
88+
if (count($types) === 1) {
89+
return new self(...$types);
90+
}
91+
92+
return LogicalOr::fromConstraints(...array_map(function ($type) {
93+
return new self($type);
94+
}, $types));
95+
}
96+
7997
private function doMatches($other) : bool
8098
{
8199
switch ($this->type) {

tests/UnifiedSpecTests/Constraint/IsBsonTypeTest.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
use MongoDB\Model\BSONArray;
1616
use MongoDB\Model\BSONDocument;
1717
use MongoDB\Tests\TestCase;
18+
use PHPUnit\Framework\Constraint\Constraint;
1819
use PHPUnit\Framework\ExpectationFailedException;
1920
use stdClass;
21+
use function fopen;
2022
use function MongoDB\BSON\fromJSON;
2123
use function MongoDB\BSON\toPHP;
2224
use function unserialize;
@@ -29,9 +31,7 @@ class IsBsonTypeTest extends TestCase
2931
*/
3032
public function testConstraint($type, $value)
3133
{
32-
$c = new IsBsonType($type);
33-
34-
$this->assertTrue($c->evaluate($value, '', true));
34+
$this->assertResult(true, new IsBsonType($type), $value, $this->dataName() . ' is ' . $type);
3535
}
3636

3737
public function provideTypes()
@@ -69,6 +69,28 @@ public function provideTypes()
6969
];
7070
}
7171

72+
/**
73+
* @dataProvider provideTypes
74+
*/
75+
public function testAny($type, $value)
76+
{
77+
$this->assertResult(true, IsBsonType::any(), $value, $this->dataName() . ' is a BSON type');
78+
}
79+
80+
public function testAnyExcludesStream()
81+
{
82+
$this->assertResult(false, IsBsonType::any(), fopen('php://temp', 'w+b'), 'stream is not a BSON type');
83+
}
84+
85+
public function testAnyOf()
86+
{
87+
$c = IsBsonType::anyOf('double', 'int');
88+
89+
$this->assertResult(true, $c, 1, 'int is double or int');
90+
$this->assertResult(true, $c, 1.4, 'int is double or int');
91+
$this->assertResult(false, $c, 'foo', 'string is not double or int');
92+
}
93+
7294
public function testErrorMessage()
7395
{
7496
$c = new IsBsonType('string');
@@ -129,7 +151,7 @@ public function testTypeJavascriptWithScope()
129151
$this->assertResult(false, $c, new Javascript('foo = 1;'), 'javascript is not javascriptWithScope');
130152
}
131153

132-
private function assertResult($expected, IsBsonType $constraint, $value, $message)
154+
private function assertResult($expected, Constraint $constraint, $value, string $message = '')
133155
{
134156
$this->assertSame($expected, $constraint->evaluate($value, '', true), $message);
135157
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\UnifiedSpecTests\Constraint;
4+
5+
use PHPUnit\Framework\Constraint\Constraint;
6+
use Symfony\Bridge\PhpUnit\ConstraintTrait;
7+
use function get_resource_type;
8+
use function is_resource;
9+
10+
final class IsStream extends Constraint
11+
{
12+
use ConstraintTrait;
13+
14+
private function doMatches($other) : bool
15+
{
16+
return is_resource($other) && get_resource_type($other) === 'stream';
17+
}
18+
19+
private function doToString() : string
20+
{
21+
return 'is a stream';
22+
}
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\UnifiedSpecTests\Constraint;
4+
5+
use MongoDB\Tests\TestCase;
6+
use function fopen;
7+
8+
class IsStreamTest extends TestCase
9+
{
10+
public function testConstraint()
11+
{
12+
$c = new IsStream();
13+
14+
$this->assertTrue($c->evaluate(fopen('php://temp', 'w+b'), '', true));
15+
$this->assertFalse($c->evaluate(1, '', true));
16+
$this->assertFalse($c->evaluate('foo', '', true));
17+
}
18+
}

tests/UnifiedSpecTests/Constraint/Matches.php

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use MongoDB\Model\BSONDocument;
1111
use MongoDB\Tests\UnifiedSpecTests\EntityMap;
1212
use PHPUnit\Framework\Constraint\Constraint;
13-
use PHPUnit\Framework\Constraint\LogicalOr;
1413
use PHPUnit\Framework\ExpectationFailedException;
1514
use RuntimeException;
1615
use SebastianBergmann\Comparator\ComparisonFailure;
@@ -24,14 +23,11 @@
2423
use function containsOnly;
2524
use function count;
2625
use function get_class;
27-
use function get_resource_type;
2826
use function gettype;
2927
use function hex2bin;
3028
use function implode;
3129
use function is_array;
3230
use function is_object;
33-
use function is_resource;
34-
use function is_string;
3531
use function isInstanceOf;
3632
use function isType;
3733
use function logicalAnd;
@@ -244,14 +240,7 @@ private function assertMatchesOperator(BSONDocument $operator, $actual, string $
244240
'$$type requires string or string[]'
245241
);
246242

247-
$types = (array) $operator['$$type'];
248-
$constraints = [];
249-
250-
foreach ($types as $type) {
251-
$constraints[] = new IsBsonType($type);
252-
}
253-
254-
$constraint = LogicalOr::fromConstraints(...$constraints);
243+
$constraint = IsBsonType::anyOf(...(array) $operator['$$type']);
255244

256245
if (! $constraint->evaluate($actual, '', true)) {
257246
self::failAt(sprintf('%s is not an expected BSON type: %s', $this->exporter()->shortenedExport($actual), implode(', ', $types)), $keyPath);
@@ -275,10 +264,7 @@ private function assertMatchesOperator(BSONDocument $operator, $actual, string $
275264
if ($name === '$$matchesHexBytes') {
276265
assertInternalType('string', $operator['$$matchesHexBytes'], '$$matchesHexBytes requires string');
277266
assertRegExp('/^([0-9a-fA-F]{2})*$/', $operator['$$matchesHexBytes'], '$$matchesHexBytes requires pairs of hex chars');
278-
279-
if (! is_resource($actual) || get_resource_type($actual) != "stream") {
280-
self::failAt(sprintf('%s is not a stream', $this->exporter()->shortenedExport($actual)), $keyPath);
281-
}
267+
assertThat($actual, new IsStream());
282268

283269
if (stream_get_contents($actual, -1, 0) !== hex2bin($operator['$$matchesHexBytes'])) {
284270
self::failAt(sprintf('%s does not match expected hex bytes: %s', $this->exporter()->shortenedExport($actual), $operator['$$matchesHexBytes']), $keyPath);

tests/UnifiedSpecTests/Constraint/MatchesTest.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,10 @@ public function testOperatorMatchesHexBytes()
108108
$c = new Matches(['$$matchesHexBytes' => 'DEADBEEF']);
109109
$this->assertResult(true, $c, $stream1, 'value matches hex bytes (root-level)');
110110
$this->assertResult(false, $c, $stream2, 'value does not match hex bytes (root-level)');
111-
$this->assertResult(false, $c, 1, 'value is not a stream');
112111

113112
$c = new Matches(['x' => ['$$matchesHexBytes' => '90ABCDEF']]);
114113
$this->assertResult(true, $c, ['x' => $stream2], 'value matches hex bytes (embedded)');
115114
$this->assertResult(false, $c, ['x' => $stream1], 'value does not match hex bytes (embedded)');
116-
$this->assertResult(false, $c, ['x' => 1], 'value is not a stream');
117115
}
118116

119117
public function testOperatorUnsetOrMatches()
@@ -303,7 +301,7 @@ public function operatorErrorMessageProvider()
303301
];
304302
}
305303

306-
private function assertResult($expected, Matches $constraint, $value, $message)
304+
private function assertResult($expected, Matches $constraint, $value, string $message = '')
307305
{
308306
$this->assertSame($expected, $constraint->evaluate($value, '', true), $message);
309307
}

0 commit comments

Comments
 (0)