Skip to content

Commit d8898ce

Browse files
authored
Use BSON round-trip to normalize pipelines for comparison (mongodb#13)
* Use BSON round-trip to normalize pipelines for comparison * Use Canonical Extended JSON * Fix $regex comparison
1 parent 6f260f9 commit d8898ce

File tree

8 files changed

+41
-53
lines changed

8 files changed

+41
-53
lines changed

generator/config/query/regex.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ tests:
2020
-
2121
$match:
2222
sku:
23-
# Should be nested in $regex
24-
$regularExpression:
25-
pattern: '789$'
26-
options: ''
23+
$regex:
24+
$regularExpression:
25+
pattern: '789$'
26+
options: ''
2727
-
2828
name: 'Perform Case-Insensitive Regular Expression Match'
2929
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/regex/#perform-case-insensitive-regular-expression-match'
3030
pipeline:
3131
-
3232
$match:
3333
sku:
34-
# Should be nested in $regex
35-
$regularExpression:
36-
pattern: '^ABC'
37-
options: 'i'
34+
$regex:
35+
$regularExpression:
36+
pattern: '^ABC'
37+
options: 'i'

generator/src/OperatorTestGenerator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace MongoDB\CodeGenerator;
66

7+
use MongoDB\BSON\Document;
78
use MongoDB\Builder\Pipeline;
89
use MongoDB\CodeGenerator\Definition\GeneratorDefinition;
910
use MongoDB\CodeGenerator\Definition\OperatorDefinition;
@@ -16,6 +17,7 @@
1617
use Throwable;
1718

1819
use function basename;
20+
use function json_decode;
1921
use function json_encode;
2022
use function ksort;
2123
use function sprintf;
@@ -81,7 +83,9 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition
8183
$testName = 'test' . str_replace([' ', '-'], '', ucwords(str_replace('$', '', $test->name)));
8284
$caseName = str_replace([' ', '-'], '', ucwords(str_replace('$', '', $operator->name . ' ' . $test->name)));
8385

84-
$case = $dataEnum->addCase($caseName, new Literal('<<<\'JSON\'' . "\n" . json_encode($test->pipeline, JSON_PRETTY_PRINT) . "\n" . 'JSON'));
86+
$json = Document::fromPHP(['pipeline' => $test->pipeline])->toCanonicalExtendedJSON();
87+
$json = json_encode(json_decode($json)->pipeline, JSON_PRETTY_PRINT);
88+
$case = $dataEnum->addCase($caseName, new Literal('<<<\'JSON\'' . "\n" . $json . "\n" . 'JSON'));
8589
$case->setComment($test->name);
8690
if ($test->link) {
8791
$case->addComment('');

src/Builder/Type/OutputWindow.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
*/
2626
class OutputWindow implements WindowInterface
2727
{
28-
public const ENCODE = Encode::Object;
29-
3028
/**
3129
* Function used to initialize the state. The init function receives its arguments from the initArgs array expression.
3230
* You can specify the function definition as either BSON type Code or String.

tests/Builder/Accumulator/Pipelines.php

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/Builder/BuilderEncoderTest.php

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace MongoDB\Tests\Builder;
66

77
use Generator;
8+
use MongoDB\BSON\Document;
89
use MongoDB\Builder\Accumulator;
910
use MongoDB\Builder\BuilderEncoder;
1011
use MongoDB\Builder\Expression;
@@ -15,10 +16,7 @@
1516
use MongoDB\Builder\Variable;
1617
use PHPUnit\Framework\TestCase;
1718

18-
use function array_is_list;
1919
use function array_merge;
20-
use function array_walk;
21-
use function is_array;
2220
use function MongoDB\object;
2321
use function var_export;
2422

@@ -342,26 +340,11 @@ private static function assertSamePipeline(array $expected, Pipeline $pipeline):
342340
$codec = new BuilderEncoder();
343341
$actual = $codec->encode($pipeline);
344342

345-
self::objectify($expected);
343+
// Normalize with BSON round-trip
344+
// BSON Documents doesn't support top-level arrays.
345+
$actual = Document::fromPHP(['root' => $actual])->toCanonicalExtendedJSON();
346+
$expected = Document::fromPHP(['root' => $expected])->toCanonicalExtendedJSON();
346347

347-
self::assertEquals($expected, $actual, var_export($actual, true));
348-
}
349-
350-
/**
351-
* Recursively convert associative arrays to objects.
352-
*
353-
* @param array<mixed> $array
354-
*/
355-
private static function objectify(array &$array): void
356-
{
357-
array_walk($array, function (&$value): void {
358-
if (is_array($value)) {
359-
self::objectify($value);
360-
361-
if (! array_is_list($value)) {
362-
$value = (object) $value;
363-
}
364-
}
365-
});
348+
self::assertJsonStringEqualsJsonString($expected, $actual, var_export($actual, true));
366349
}
367350
}

tests/Builder/PipelineTestCase.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
namespace MongoDB\Tests\Builder;
66

77
use BackedEnum;
8+
use MongoDB\BSON\Document;
89
use MongoDB\Builder\BuilderEncoder;
910
use MongoDB\Builder\Pipeline;
1011
use PHPUnit\Framework\TestCase;
1112

12-
use function MongoDB\BSON\fromJSON;
13-
use function MongoDB\BSON\toPHP;
14-
use function var_export;
15-
16-
class PipelineTestCase extends TestCase
13+
abstract class PipelineTestCase extends TestCase
1714
{
1815
final public static function assertSamePipeline(string|BackedEnum $expectedJson, Pipeline $pipeline): void
1916
{
@@ -22,11 +19,13 @@ final public static function assertSamePipeline(string|BackedEnum $expectedJson,
2219
}
2320

2421
// BSON Documents doesn't support top-level arrays.
25-
$expected = toPHP(fromJSON('{"root":' . $expectedJson . '}'))->root;
22+
$expected = '{"pipeline":' . $expectedJson . '}';
2623

2724
$codec = new BuilderEncoder();
2825
$actual = $codec->encode($pipeline);
26+
// Normalize with BSON round-trip
27+
$actual = Document::fromPHP(['pipeline' => $actual])->toCanonicalExtendedJSON();
2928

30-
self::assertEquals($expected, $actual, var_export($actual, true));
29+
self::assertJsonStringEqualsJsonString($expected, $actual);
3130
}
3231
}

tests/Builder/Query/Pipelines.php

Lines changed: 10 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/Builder/Query/RegexOperatorTest.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
namespace MongoDB\Tests\Builder\Query;
66

7-
use MongoDB\BSON\Regex;
87
use MongoDB\Builder\Pipeline;
8+
use MongoDB\Builder\Query;
99
use MongoDB\Builder\Stage;
1010
use MongoDB\Tests\Builder\PipelineTestCase;
1111

@@ -18,8 +18,7 @@ public function testPerformALIKEMatch(): void
1818
{
1919
$pipeline = new Pipeline(
2020
Stage::match(
21-
// sku: \MongoDB\Builder\Query::regex('789$', ''),
22-
sku: new Regex('789$', ''),
21+
sku: Query::regex('789$', ''),
2322
),
2423
);
2524

@@ -30,8 +29,7 @@ public function testPerformCaseInsensitiveRegularExpressionMatch(): void
3029
{
3130
$pipeline = new Pipeline(
3231
Stage::match(
33-
// sku: \MongoDB\Builder\Query::regex('^ABC', 'i'),
34-
sku: new Regex('^ABC', 'i'),
32+
sku: Query::regex('^ABC', 'i'),
3533
),
3634
);
3735

0 commit comments

Comments
 (0)