Skip to content

Commit 9b9387f

Browse files
committed
Move rule existence check from ReflectorMetaSource to MetaResolver
1 parent f6aa863 commit 9b9387f

File tree

5 files changed

+78
-69
lines changed

5 files changed

+78
-69
lines changed

src/Meta/Compile/FieldCompileMeta.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
final class FieldCompileMeta extends NodeCompileMeta
99
{
1010

11-
private RuleCompileMeta $rule;
11+
private ?RuleCompileMeta $rule;
1212

1313
private ClassStructure $class;
1414

@@ -18,7 +18,7 @@ public function __construct(
1818
array $callbacks,
1919
array $docs,
2020
array $modifiers,
21-
RuleCompileMeta $rule,
21+
?RuleCompileMeta $rule,
2222
PropertyStructure $property
2323
)
2424
{
@@ -31,7 +31,7 @@ public function __construct(
3131
$this->property = $property;
3232
}
3333

34-
public function getRule(): RuleCompileMeta
34+
public function getRule(): ?RuleCompileMeta
3535
{
3636
return $this->rule;
3737
}

src/Meta/MetaResolver.php

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,18 @@ private function resolveFieldsMeta(ReflectionClass $rootClass, CompileMeta $meta
197197
$sourceName = $meta->getSourceName();
198198
foreach ($meta->getFields() as $fieldMetas) {
199199
$this->checkFieldInvariance($rootClass, $fieldMetas, $sourceName);
200+
$firstFieldMeta = $fieldMetas[0];
201+
$ruleMeta = $firstFieldMeta->getRule();
202+
203+
if ($ruleMeta === null) {
204+
$this->throwFieldHasNoRule($rootClass, $meta, $firstFieldMeta);
205+
}
206+
200207
foreach ($fieldMetas as $fieldMeta) {
201208
$resolved = $this->resolveFieldMeta(
202209
$rootClass,
203210
$fieldMeta,
211+
$ruleMeta,
204212
$this->getDefaultValue($fieldMeta),
205213
);
206214

@@ -212,6 +220,30 @@ private function resolveFieldsMeta(ReflectionClass $rootClass, CompileMeta $meta
212220
return $fields;
213221
}
214222

223+
/**
224+
* @param ReflectionClass<MappedObject> $rootClass
225+
* @return never
226+
*/
227+
private function throwFieldHasNoRule(
228+
ReflectionClass $rootClass,
229+
CompileMeta $meta,
230+
FieldCompileMeta $firstFieldMeta
231+
): void
232+
{
233+
$propertyName = $this->getRelativePropertyName($firstFieldMeta->getProperty(), $rootClass);
234+
235+
$message = Message::create()
236+
->withContext("Resolving metadata of mapped object '{$rootClass->getName()}'.")
237+
->withProblem(
238+
"Property '$propertyName' has some mapped object definition"
239+
. " (in {$meta->getSourceName()}), but no rule definition.",
240+
)
241+
->withSolution('Either remove the definition or add a rule definition.');
242+
243+
throw InvalidArgument::create()
244+
->withMessage($message);
245+
}
246+
215247
/**
216248
* @param ReflectionClass<MappedObject> $rootClass
217249
* @param list<FieldCompileMeta> $resolvedGroup
@@ -258,11 +290,12 @@ private function propertyNameToFieldName(FieldRuntimeMeta $fieldMeta)
258290
*/
259291
private function resolveFieldMeta(
260292
ReflectionClass $rootClass,
261-
FieldCompileMeta $meta,
293+
FieldCompileMeta $fieldMeta,
294+
RuleCompileMeta $ruleMeta,
262295
DefaultValueMeta $defaultValue
263296
): FieldRuntimeMeta
264297
{
265-
$fieldStructure = $meta->getProperty();
298+
$fieldStructure = $fieldMeta->getProperty();
266299
$reflector = $fieldStructure->getContextReflector();
267300

268301
if ($reflector->isStatic()) {
@@ -285,13 +318,10 @@ private function resolveFieldMeta(
285318
$context = new MetaFieldContext($this->loader, $this, $defaultValue);
286319

287320
return new FieldRuntimeMeta(
288-
$this->resolveCallbacksMeta($meta, $context, $reflector),
289-
$this->resolveDocsMeta($meta, $context),
290-
$this->resolveFieldModifiersMeta($meta, $context),
291-
$this->resolveRuleMeta(
292-
$meta->getRule(),
293-
$context,
294-
),
321+
$this->resolveCallbacksMeta($fieldMeta, $context, $reflector),
322+
$this->resolveDocsMeta($fieldMeta, $context),
323+
$this->resolveFieldModifiersMeta($fieldMeta, $context),
324+
$this->resolveRuleMeta($ruleMeta, $context),
295325
$defaultValue,
296326
PhpPropertyMeta::from($reflector),
297327
);

src/Meta/Source/ReflectorMetaSource.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,21 +183,6 @@ private function loadPropertiesMeta(ReflectionClass $rootClass, StructureGroup $
183183
continue;
184184
}
185185

186-
if ($rule === null) {
187-
$propertyName = $this->getRelativePropertyName($propertyStructure, $rootClass);
188-
189-
$message = Message::create()
190-
->withContext("Resolving metadata of mapped object '{$rootClass->getName()}'.")
191-
->withProblem(
192-
"Property '$propertyName' has some mapped object definition"
193-
. " (in {$this->getSourceName()}), but no rule definition.",
194-
)
195-
->withSolution('Either remove the definition or add a rule definition.');
196-
197-
throw InvalidArgument::create()
198-
->withMessage($message);
199-
}
200-
201186
$resolvedGroup[] = new FieldCompileMeta(
202187
$callbacks,
203188
$docs,

tests/Unit/Meta/MetaResolverTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldNameIdenticalWithAnotherPropertyNameVO;
1616
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldNamesFromTraitVO;
1717
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldTraitMetaInvalidScopeRootVO;
18+
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleChildVO;
19+
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleVO;
1820
use Tests\Orisai\ObjectMapper\Doubles\Invalid\MultipleIdenticalFieldNamesVO;
1921
use Tests\Orisai\ObjectMapper\Doubles\Invalid\StaticMappedPropertyVO;
2022
use Tests\Orisai\ObjectMapper\Doubles\Invalid\VariantFieldChildVO;
@@ -161,6 +163,40 @@ public function testFieldInvarianceFullName(): void
161163
$this->metaLoader->load(VariantFieldChildVO::class);
162164
}
163165

166+
public function testFieldWithNoRuleRelativeName(): void
167+
{
168+
$this->expectException(InvalidArgument::class);
169+
$this->expectExceptionMessage(
170+
<<<'MSG'
171+
Context: Resolving metadata of mapped object
172+
'Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleVO'.
173+
Problem: Property '$field' has some mapped object definition (in annotation),
174+
but no rule definition.
175+
Solution: Either remove the definition or add a rule definition.
176+
MSG,
177+
);
178+
179+
$this->metaLoader->load(FieldWithNoRuleVO::class);
180+
}
181+
182+
public function testFieldWithNoRuleAbsoluteName(): void
183+
{
184+
$this->expectException(InvalidArgument::class);
185+
$this->expectExceptionMessage(
186+
<<<'MSG'
187+
Context: Resolving metadata of mapped object
188+
'Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleChildVO'.
189+
Problem: Property
190+
'Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleVO->$field'
191+
has some mapped object definition (in annotation), but no rule
192+
definition.
193+
Solution: Either remove the definition or add a rule definition.
194+
MSG,
195+
);
196+
197+
$this->metaLoader->load(FieldWithNoRuleChildVO::class);
198+
}
199+
164200
public function testMultipleIdenticalFieldNames(): void
165201
{
166202
$this->expectException(InvalidState::class);

tests/Unit/Meta/Source/ReflectorMetaSourceTest.php

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
use ReflectionClass;
1616
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithMultipleRulesChildVO;
1717
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithMultipleRulesVO;
18-
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleChildVO;
19-
use Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleVO;
2018
use Tests\Orisai\ObjectMapper\Doubles\Invalid\RuleAboveClassChildVO;
2119
use Tests\Orisai\ObjectMapper\Doubles\Invalid\RuleAboveClassVO;
2220
use Tests\Orisai\ObjectMapper\Doubles\Invalid\UnsupportedClassDefinitionVO;
@@ -159,44 +157,4 @@ public function testFieldWithMultipleRulesAbsoluteName(): void
159157
$this->source->load($reflector, $group);
160158
}
161159

162-
public function testFieldWithNoRuleRelativeName(): void
163-
{
164-
$reflector = new ReflectionClass(FieldWithNoRuleVO::class);
165-
$group = $this->createStructureGroup($reflector);
166-
167-
$this->expectException(InvalidArgument::class);
168-
$this->expectExceptionMessage(
169-
<<<'MSG'
170-
Context: Resolving metadata of mapped object
171-
'Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleVO'.
172-
Problem: Property '$field' has some mapped object definition (in annotation),
173-
but no rule definition.
174-
Solution: Either remove the definition or add a rule definition.
175-
MSG,
176-
);
177-
178-
$this->source->load($reflector, $group);
179-
}
180-
181-
public function testFieldWithNoRuleAbsoluteName(): void
182-
{
183-
$reflector = new ReflectionClass(FieldWithNoRuleChildVO::class);
184-
$group = $this->createStructureGroup($reflector);
185-
186-
$this->expectException(InvalidArgument::class);
187-
$this->expectExceptionMessage(
188-
<<<'MSG'
189-
Context: Resolving metadata of mapped object
190-
'Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleChildVO'.
191-
Problem: Property
192-
'Tests\Orisai\ObjectMapper\Doubles\Invalid\FieldWithNoRuleVO->$field'
193-
has some mapped object definition (in annotation), but no rule
194-
definition.
195-
Solution: Either remove the definition or add a rule definition.
196-
MSG,
197-
);
198-
199-
$this->source->load($reflector, $group);
200-
}
201-
202160
}

0 commit comments

Comments
 (0)