|
16 | 16 | use MongoDB\Tests\CommandObserver;
|
17 | 17 | use function array_filter;
|
18 | 18 | use function call_user_func;
|
| 19 | +use function is_scalar; |
| 20 | +use function json_encode; |
19 | 21 | use function strchr;
|
| 22 | +use function usort; |
20 | 23 | use function version_compare;
|
21 | 24 |
|
22 | 25 | /**
|
@@ -170,6 +173,88 @@ function (array $event) {
|
170 | 173 | );
|
171 | 174 | }
|
172 | 175 |
|
| 176 | + /** |
| 177 | + * @dataProvider provideTypeMapOptionsAndExpectedDocuments |
| 178 | + */ |
| 179 | + public function testDistinctWithTypeMap(array $typeMap, array $expectedDocuments) |
| 180 | + { |
| 181 | + $bulkWrite = new BulkWrite(['ordered' => true]); |
| 182 | + $bulkWrite->insert([ |
| 183 | + 'x' => (object) ['foo' => 'bar'], |
| 184 | + ]); |
| 185 | + $bulkWrite->insert(['x' => 4]); |
| 186 | + $bulkWrite->insert([ |
| 187 | + 'x' => (object) ['foo' => ['foo' => 'bar']], |
| 188 | + ]); |
| 189 | + $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite); |
| 190 | + |
| 191 | + $values = $this->collection->withOptions(['typeMap' => $typeMap])->distinct('x'); |
| 192 | + |
| 193 | + /* This sort callable sorts all scalars to the front of the list. All |
| 194 | + * non-scalar values are sorted by running json_encode on them and |
| 195 | + * comparing their string representations. |
| 196 | + */ |
| 197 | + $sort = function ($a, $b) { |
| 198 | + if (is_scalar($a) && ! is_scalar($b)) { |
| 199 | + return -1; |
| 200 | + } |
| 201 | + |
| 202 | + if (! is_scalar($a)) { |
| 203 | + if (is_scalar($b)) { |
| 204 | + return 1; |
| 205 | + } |
| 206 | + |
| 207 | + $a = json_encode($a); |
| 208 | + $b = json_encode($b); |
| 209 | + } |
| 210 | + |
| 211 | + return $a < $b ? -1 : 1; |
| 212 | + }; |
| 213 | + |
| 214 | + usort($expectedDocuments, $sort); |
| 215 | + usort($values, $sort); |
| 216 | + |
| 217 | + $this->assertEquals($expectedDocuments, $values); |
| 218 | + } |
| 219 | + |
| 220 | + public function provideTypeMapOptionsAndExpectedDocuments() |
| 221 | + { |
| 222 | + return [ |
| 223 | + 'No type map' => [ |
| 224 | + ['root' => 'array', 'document' => 'array'], |
| 225 | + [ |
| 226 | + ['foo' => 'bar'], |
| 227 | + 4, |
| 228 | + ['foo' => ['foo' => 'bar']], |
| 229 | + ], |
| 230 | + ], |
| 231 | + 'array/array' => [ |
| 232 | + ['root' => 'array', 'document' => 'array'], |
| 233 | + [ |
| 234 | + ['foo' => 'bar'], |
| 235 | + 4, |
| 236 | + ['foo' => ['foo' => 'bar']], |
| 237 | + ], |
| 238 | + ], |
| 239 | + 'object/array' => [ |
| 240 | + ['root' => 'object', 'document' => 'array'], |
| 241 | + [ |
| 242 | + (object) ['foo' => 'bar'], |
| 243 | + 4, |
| 244 | + (object) ['foo' => ['foo' => 'bar']], |
| 245 | + ], |
| 246 | + ], |
| 247 | + 'array/stdClass' => [ |
| 248 | + ['root' => 'array', 'document' => 'stdClass'], |
| 249 | + [ |
| 250 | + ['foo' => 'bar'], |
| 251 | + 4, |
| 252 | + ['foo' => (object) ['foo' => 'bar']], |
| 253 | + ], |
| 254 | + ], |
| 255 | + ]; |
| 256 | + } |
| 257 | + |
173 | 258 | public function testDrop()
|
174 | 259 | {
|
175 | 260 | $writeResult = $this->collection->insertOne(['x' => 1]);
|
|
0 commit comments