Skip to content
This repository was archived by the owner on Feb 28, 2025. It is now read-only.

Commit 320cc26

Browse files
authored
PHPLIB-1336 Add tests on Evaluation Query Operators (#24)
1 parent 3caabb0 commit 320cc26

File tree

16 files changed

+729
-14
lines changed

16 files changed

+729
-14
lines changed

generator/config/query/jsonSchema.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,29 @@ arguments:
1111
name: schema
1212
type:
1313
- object
14+
tests:
15+
-
16+
name: 'Example'
17+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/jsonSchema/#syntax'
18+
pipeline:
19+
-
20+
$match:
21+
$jsonSchema:
22+
required:
23+
- 'name'
24+
- 'major'
25+
- 'gpa'
26+
- 'address'
27+
properties:
28+
name:
29+
bsonType: 'string'
30+
description: 'must be a string and is required'
31+
address:
32+
bsonType: 'object'
33+
required:
34+
- 'zipcode'
35+
properties:
36+
street:
37+
bsonType: 'string'
38+
zipcode:
39+
bsonType: 'string'

generator/config/query/mod.yaml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,33 @@ arguments:
1010
-
1111
name: divisor
1212
type:
13-
- int
13+
- number
1414
-
1515
name: remainder
1616
type:
17-
- int
17+
- number
18+
tests:
19+
-
20+
name: 'Use $mod to Select Documents'
21+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/mod/#use--mod-to-select-documents'
22+
pipeline:
23+
-
24+
$match:
25+
qty:
26+
$mod: [4, 0]
27+
-
28+
name: 'Floating Point Arguments'
29+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/mod/#floating-point-arguments'
30+
pipeline:
31+
-
32+
$match:
33+
qty:
34+
$mod: [4.0, 0]
35+
-
36+
$match:
37+
qty:
38+
$mod: [4.5, 0]
39+
-
40+
$match:
41+
qty:
42+
$mod: [4.99, 0]

generator/config/query/text.yaml

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: $text
33
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/'
44
type:
55
- query
6-
encode: object
6+
encode: dollar_object
77
description: |
88
Performs text search.
99
arguments:
@@ -36,3 +36,77 @@ arguments:
3636
description: |
3737
A boolean flag to enable or disable diacritic sensitive search against version 3 text indexes. Defaults to false; i.e. the search defers to the diacritic insensitivity of the text index.
3838
Text searches against earlier versions of the text index are inherently diacritic sensitive and cannot be diacritic insensitive. As such, the $diacriticSensitive option has no effect with earlier versions of the text index.
39+
tests:
40+
-
41+
name: 'Search for a Single Word'
42+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#search-for-a-single-word'
43+
pipeline:
44+
-
45+
$match:
46+
$text:
47+
$search: 'coffee'
48+
-
49+
name: 'Match Any of the Search Terms'
50+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#search-for-a-single-word'
51+
pipeline:
52+
-
53+
$match:
54+
$text:
55+
$search: 'bake coffee cake'
56+
-
57+
name: 'Search a Different Language'
58+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#search-a-different-language'
59+
pipeline:
60+
-
61+
$match:
62+
$text:
63+
$search: 'leche'
64+
$language: 'es'
65+
-
66+
name: 'Case and Diacritic Insensitive Search'
67+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#case-and-diacritic-insensitive-search'
68+
pipeline:
69+
-
70+
$match:
71+
$text:
72+
$search: 'сы́рники CAFÉS'
73+
-
74+
name: 'Perform Case Sensitive Search'
75+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#perform-case-sensitive-search'
76+
pipeline:
77+
-
78+
$match:
79+
$text:
80+
$search: 'Coffee'
81+
$caseSensitive: true
82+
-
83+
$match:
84+
$text:
85+
$search: '\"Café Con Leche\"'
86+
$caseSensitive: true
87+
-
88+
name: 'Diacritic Sensitive Search'
89+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#perform-case-sensitive-search'
90+
pipeline:
91+
-
92+
$match:
93+
$text:
94+
$search: 'CAFÉ'
95+
$diacriticSensitive: true
96+
-
97+
name: 'Text Search Score Examples'
98+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/text/#perform-case-sensitive-search'
99+
pipeline:
100+
-
101+
$match:
102+
$text:
103+
$search: 'CAFÉ'
104+
$diacriticSensitive: true
105+
score:
106+
$meta: 'textScore'
107+
-
108+
$sort:
109+
score:
110+
$meta: 'textScore'
111+
-
112+
$limit: 5

generator/config/query/where.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,21 @@ arguments:
1111
name: function
1212
type:
1313
- javascript
14+
tests:
15+
-
16+
name: 'Example'
17+
link: 'https://www.mongodb.com/docs/manual/reference/operator/query/where/#example'
18+
pipeline:
19+
-
20+
$match:
21+
$where: 'function() { return hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994" }'
22+
-
23+
$match:
24+
$expr:
25+
$function:
26+
body: |-
27+
function(name) {
28+
return hex_md5(name) == "9b53e667f30cd329dca1ec9e6a83e994";
29+
}
30+
args: ['$name']
31+
lang: 'js'

generator/config/schema.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"enum": [
6161
"array",
6262
"object",
63+
"dollar_object",
6364
"single",
6465
"group"
6566
]

generator/src/Definition/OperatorDefinition.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function __construct(
3838
'single' => Encode::Single,
3939
'array' => Encode::Array,
4040
'object' => Encode::Object,
41+
'dollar_object' => Encode::DollarObject,
4142
'group' => Encode::Group,
4243
default => throw new UnexpectedValueException(sprintf('Unexpected "encode" value for operator "%s". Got "%s"', $name, $encode)),
4344
};

src/Builder/BuilderEncoder.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public function encode($value): stdClass|array|string
111111
case Encode::Object:
112112
return $this->encodeAsObject($value);
113113

114+
case Encode::DollarObject:
115+
return $this->encodeAsDollarObject($value);
116+
114117
case Encode::Group:
115118
assert($value instanceof GroupStage);
116119

@@ -170,6 +173,21 @@ private function encodeAsObject(OperatorInterface $value): stdClass
170173
return $this->wrap($value, $result);
171174
}
172175

176+
private function encodeAsDollarObject(OperatorInterface $value): stdClass
177+
{
178+
$result = new stdClass();
179+
foreach (get_object_vars($value) as $key => $val) {
180+
// Skip optional arguments. If they have a default value, it is resolved by the server.
181+
if ($val === Optional::Undefined) {
182+
continue;
183+
}
184+
185+
$result->{'$' . $key} = $this->recursiveEncode($val);
186+
}
187+
188+
return $this->wrap($value, $result);
189+
}
190+
173191
/**
174192
* Get the unique property of the operator as value
175193
*/

src/Builder/Query/FactoryTrait.php

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

src/Builder/Query/ModOperator.php

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

src/Builder/Query/TextOperator.php

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

src/Builder/Type/Encode.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ enum Encode
2323
*/
2424
case Object;
2525

26+
/**
27+
* Parameters are encoded as an object with keys matching the parameter names prefixed with a dollar sign ($)
28+
*/
29+
case DollarObject;
30+
2631
/**
2732
* Get the single parameter value
2833
*/
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MongoDB\Tests\Builder\Query;
6+
7+
use MongoDB\Builder\Pipeline;
8+
use MongoDB\Builder\Query;
9+
use MongoDB\Builder\Stage;
10+
use MongoDB\Tests\Builder\PipelineTestCase;
11+
12+
use function MongoDB\object;
13+
14+
/**
15+
* Test $jsonSchema query
16+
*/
17+
class JsonSchemaOperatorTest extends PipelineTestCase
18+
{
19+
public function testExample(): void
20+
{
21+
$pipeline = new Pipeline(
22+
Stage::match(
23+
Query::jsonSchema(object(
24+
required: ['name', 'major', 'gpa', 'address'],
25+
properties: object(
26+
name: object(
27+
bsonType: 'string',
28+
description: 'must be a string and is required',
29+
),
30+
address: object(
31+
bsonType: 'object',
32+
required: ['zipcode'],
33+
properties: object(
34+
zipcode: object(bsonType: 'string'),
35+
street: object(bsonType: 'string'),
36+
),
37+
),
38+
),
39+
)),
40+
),
41+
);
42+
43+
$this->assertSamePipeline(Pipelines::JsonSchemaExample, $pipeline);
44+
}
45+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MongoDB\Tests\Builder\Query;
6+
7+
use MongoDB\Builder\Pipeline;
8+
use MongoDB\Builder\Query;
9+
use MongoDB\Builder\Stage;
10+
use MongoDB\Tests\Builder\PipelineTestCase;
11+
12+
/**
13+
* Test $mod query
14+
*/
15+
class ModOperatorTest extends PipelineTestCase
16+
{
17+
public function testFloatingPointArguments(): void
18+
{
19+
$pipeline = new Pipeline(
20+
Stage::match(
21+
qty: Query::mod(4.0, 0),
22+
),
23+
Stage::match(
24+
qty: Query::mod(4.5, 0),
25+
),
26+
Stage::match(
27+
qty: Query::mod(4.99, 0),
28+
),
29+
);
30+
31+
$this->assertSamePipeline(Pipelines::ModFloatingPointArguments, $pipeline);
32+
}
33+
34+
public function testUseModToSelectDocuments(): void
35+
{
36+
$pipeline = new Pipeline(
37+
Stage::match(
38+
qty: Query::mod(4, 0),
39+
),
40+
);
41+
42+
$this->assertSamePipeline(Pipelines::ModUseModToSelectDocuments, $pipeline);
43+
}
44+
}

0 commit comments

Comments
 (0)