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

Commit 6efa8bd

Browse files
committed
Improve tests and refactor generator
1 parent 31d537c commit 6efa8bd

File tree

3 files changed

+52
-51
lines changed

3 files changed

+52
-51
lines changed

generator/src/FluentStageFactoryGenerator.php

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828
use MongoDB\Model\BSONArray;
2929
use Nette\PhpGenerator\ClassType;
3030
use Nette\PhpGenerator\Method;
31+
use Nette\PhpGenerator\Parameter;
3132
use Nette\PhpGenerator\PhpNamespace;
3233
use Nette\PhpGenerator\TraitType;
33-
use RuntimeException;
34+
use ReflectionClass;
3435
use stdClass;
35-
use Throwable;
3636

3737
use function array_key_last;
3838
use function array_map;
@@ -42,15 +42,11 @@
4242

4343
/**
4444
* Generates a fluent factory class for aggregation pipeline stages.
45-
* The method definition is based on the manually edited static class
46-
* that imports the stage factory trait.
45+
* The method definition is based on all the public static methods
46+
* of the Stage class.
4747
*/
4848
class FluentStageFactoryGenerator extends OperatorGenerator
4949
{
50-
/**
51-
* All public of this class are duplicated as instance methods of the
52-
* fluent factory class.
53-
*/
5450
private const FACTORY_CLASS = Stage::class;
5551

5652
public function generate(GeneratorDefinition $definition): void
@@ -98,37 +94,37 @@ private function createFluentFactoryClass(GeneratorDefinition $definition): PhpN
9894

9995
$staticFactory = ClassType::from(self::FACTORY_CLASS);
10096
assert($staticFactory instanceof ClassType);
97+
98+
// Import the methods customized in the factory class
10199
foreach ($staticFactory->getMethods() as $method) {
102100
if (! $method->isPublic()) {
103101
continue;
104102
}
105103

106-
try {
107-
$this->addMethod($method, $namespace, $class);
108-
} catch (Throwable $e) {
109-
throw new RuntimeException(sprintf('Failed to generate class for operator "%s"', $operator->name), 0, $e);
110-
}
104+
$this->addMethod($method, $class);
111105
}
112106

113-
$staticFactory = TraitType::from(Stage\FactoryTrait::class);
114-
assert($staticFactory instanceof TraitType);
115-
foreach ($staticFactory->getMethods() as $method) {
116-
if (! $method->isPublic()) {
117-
continue;
118-
}
119-
120-
try {
121-
$this->addMethod($method, $namespace, $class);
122-
} catch (Throwable $e) {
123-
throw new RuntimeException(sprintf('Failed to generate class for operator "%s"', $operator->name), 0, $e);
107+
// Import the other methods provided by the generated trait
108+
foreach ($staticFactory->getTraits() as $trait) {
109+
$staticFactory = TraitType::from($trait->getName());
110+
assert($staticFactory instanceof TraitType);
111+
foreach ($staticFactory->getMethods() as $method) {
112+
$this->addMethod($method, $class);
124113
}
125114
}
126115

127116
return $namespace;
128117
}
129118

130-
private function addMethod(Method $factoryMethod, PhpNamespace $namespace, ClassType $class): void
119+
private function addMethod(Method $factoryMethod, ClassType $class): void
131120
{
121+
// Non-public methods are not part of the API
122+
if (! $factoryMethod->isPublic()) {
123+
return;
124+
}
125+
126+
// Some methods can be overridden in the class, so we skip them
127+
// when importing the methods provided by the trait.
132128
if ($class->hasMethod($factoryMethod->getName())) {
133129
return;
134130
}
@@ -139,7 +135,7 @@ private function addMethod(Method $factoryMethod, PhpNamespace $namespace, Class
139135
$method->setParameters($factoryMethod->getParameters());
140136

141137
$args = array_map(
142-
fn ($param) => '$' . $param->getName(),
138+
fn (Parameter $param): string => '$' . $param->getName(),
143139
$factoryMethod->getParameters(),
144140
);
145141

@@ -155,9 +151,9 @@ private function addMethod(Method $factoryMethod, PhpNamespace $namespace, Class
155151
156152
return $this;
157153
PHP,
158-
'Stage',
154+
(new ReflectionClass(self::FACTORY_CLASS))->getShortName(),
159155
$factoryMethod->getName(),
160-
implode(',', $args),
156+
implode(', ', $args),
161157
));
162158
}
163159
}

src/Builder/Stage/FluentFactory.php

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

tests/Builder/FluentPipelineFactoryTest.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
namespace MongoDB\Tests\Builder;
66

7-
use MongoDB\Builder\Pipeline;
87
use MongoDB\Builder\Query;
98
use MongoDB\Builder\Stage\FluentFactory;
109
use MongoDB\Builder\Type\Sort;
11-
use PHPUnit\Framework\TestCase;
1210

13-
class FluentPipelineFactoryTest extends TestCase
11+
class FluentPipelineFactoryTest extends PipelineTestCase
1412
{
1513
public function testFluentPipelineFactory(): void
1614
{
@@ -20,7 +18,14 @@ public function testFluentPipelineFactory(): void
2018
->sort(x: Sort::Asc)
2119
->getPipeline();
2220

23-
$this->assertInstanceof(Pipeline::class, $pipeline);
24-
$this->assertCount(3, $pipeline->getIterator());
21+
$expected = <<<'json'
22+
[
23+
{"$match": {"x": {"$eq": {"$numberInt": "1"}}}},
24+
{"$project": {"_id": false, "x": true}},
25+
{"$sort": {"x": {"$numberInt": "1"}}}
26+
]
27+
json;
28+
29+
$this->assertSamePipeline($expected, $pipeline);
2530
}
2631
}

0 commit comments

Comments
 (0)