Skip to content

Commit a33c0f7

Browse files
committed
test(coverage): achieve 100% test coverage — 119 tests, 391 assertions, 47/47 classes
- Add TransformAttributeHandlerTest (12 tests, covers Transform, TransformerConfiguration, TransformationException) - Add EventsAndIntegrationTest (5 tests, covers TransformationStartedEvent, TransformationCompletedEvent, ProcessorBridge) - Expand TransformerEngineTest with CoversClass + 3 new edge-case tests (dot-notation missing key, inline rule object, tuple form) - Expand DateRulesTest with CoversClass + 11 new tests (just now, future, hours, months, years, bad timezone, invalid format, empty string) - Expand DataRulesTest with CoversClass + 3 new tests (empty CSV, non-string passthrough, getName) - Add CoversClass + #[Test] to 12 existing test files via batch script - Fix CoversClass FQCN resolution (absolute backslash prefix for PHP namespace resolution) Coverage: Classes 100.00% (47/47), Methods 100.00% (118/118), Lines 100.00% (401/401)
1 parent e55c7e3 commit a33c0f7

17 files changed

Lines changed: 577 additions & 0 deletions

tests/Conformance/ArchitecturalContractTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
namespace KaririCode\Transformer\Tests\Conformance;
66

7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\Test;
79
use PHPUnit\Framework\TestCase;
810

11+
#[CoversClass(\KaririCode\Transformer\Core\TransformerEngine::class)]
912
final class ArchitecturalContractTest extends TestCase
1013
{
1114
private const RULE_CLASSES = [
@@ -43,6 +46,8 @@ final class ArchitecturalContractTest extends TestCase
4346
\KaririCode\Transformer\Rule\Encoding\HashRule::class,
4447
];
4548

49+
#[Test]
50+
4651
public function testAllRulesAreFinalReadonly(): void
4752
{
4853
foreach (self::RULE_CLASSES as $class) {
@@ -52,6 +57,8 @@ public function testAllRulesAreFinalReadonly(): void
5257
}
5358
}
5459

60+
#[Test]
61+
5562
public function testAllRulesImplementContract(): void
5663
{
5764
foreach (self::RULE_CLASSES as $class) {
@@ -62,6 +69,8 @@ public function testAllRulesImplementContract(): void
6269
}
6370
}
6471

72+
#[Test]
73+
6574
public function testRuleCount(): void
6675
{
6776
$this->assertCount(32, self::RULE_CLASSES);

tests/Conformance/ImmutableStateTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
namespace KaririCode\Transformer\Tests\Conformance;
66

77
use KaririCode\Transformer\Core\TransformationContextImpl;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\Test;
810
use PHPUnit\Framework\TestCase;
911

12+
#[CoversClass(\KaririCode\Transformer\Core\TransformationContextImpl::class)]
1013
final class ImmutableStateTest extends TestCase
1114
{
15+
#[Test]
1216
public function testContextWithFieldReturnsNewInstance(): void
1317
{
1418
$ctx = TransformationContextImpl::create(['a' => 1]);
@@ -18,6 +22,8 @@ public function testContextWithFieldReturnsNewInstance(): void
1822
$this->assertSame('email', $ctx2->getFieldName());
1923
}
2024

25+
#[Test]
26+
2127
public function testContextWithParametersReturnsNewInstance(): void
2228
{
2329
$ctx = TransformationContextImpl::create([]);

tests/Integration/FullPipelineTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
namespace KaririCode\Transformer\Tests\Integration;
66

77
use KaririCode\Transformer\Provider\TransformerServiceProvider;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\Test;
810
use PHPUnit\Framework\TestCase;
911

12+
#[CoversClass(\KaririCode\Transformer\Core\TransformerEngine::class)]
13+
#[CoversClass(\KaririCode\Transformer\Provider\TransformerServiceProvider::class)]
14+
#[CoversClass(\KaririCode\Transformer\Core\InMemoryRuleRegistry::class)]
1015
final class FullPipelineTest extends TestCase
1116
{
17+
#[Test]
1218
public function testAllRulesResolvable(): void
1319
{
1420
$registry = (new TransformerServiceProvider())->createRegistry();
@@ -18,6 +24,8 @@ public function testAllRulesResolvable(): void
1824
}
1925
}
2026

27+
#[Test]
28+
2129
public function testComplexPipeline(): void
2230
{
2331
$engine = (new TransformerServiceProvider())->createEngine();

tests/Unit/Attribute/AttributeTransformerTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66

77
use KaririCode\Transformer\Attribute\Transform;
88
use KaririCode\Transformer\Provider\TransformerServiceProvider;
9+
use PHPUnit\Framework\Attributes\CoversClass;
10+
use PHPUnit\Framework\Attributes\Test;
911
use PHPUnit\Framework\TestCase;
1012

13+
#[CoversClass(\KaririCode\Transformer\Core\AttributeTransformer::class)]
14+
#[CoversClass(\KaririCode\Transformer\Core\TransformAttributeHandler::class)]
1115
final class AttributeTransformerTest extends TestCase
1216
{
17+
#[Test]
1318
public function testTransformDtoViaAttributes(): void
1419
{
1520
$dto = new class {
@@ -31,6 +36,8 @@ public function testTransformDtoViaAttributes(): void
3136
$this->assertTrue($result->wasTransformed());
3237
}
3338

39+
#[Test]
40+
3441
public function testMultipleAttributes(): void
3542
{
3643
$dto = new class {

tests/Unit/Core/InMemoryRuleRegistryTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
use KaririCode\Transformer\Core\InMemoryRuleRegistry;
88
use KaririCode\Transformer\Exception\InvalidRuleException;
99
use KaririCode\Transformer\Rule\String\CamelCaseRule;
10+
use PHPUnit\Framework\Attributes\CoversClass;
11+
use PHPUnit\Framework\Attributes\Test;
1012
use PHPUnit\Framework\TestCase;
1113

14+
#[CoversClass(\KaririCode\Transformer\Core\InMemoryRuleRegistry::class)]
15+
#[CoversClass(\KaririCode\Transformer\Exception\InvalidRuleException::class)]
1216
final class InMemoryRuleRegistryTest extends TestCase
1317
{
18+
#[Test]
1419
public function testRegisterAndResolve(): void
1520
{
1621
$registry = new InMemoryRuleRegistry();
@@ -20,6 +25,8 @@ public function testRegisterAndResolve(): void
2025
$this->assertSame($rule, $registry->resolve('camel'));
2126
}
2227

28+
#[Test]
29+
2330
public function testDuplicateThrows(): void
2431
{
2532
$registry = new InMemoryRuleRegistry();
@@ -28,6 +35,8 @@ public function testDuplicateThrows(): void
2835
$registry->register('camel', new CamelCaseRule());
2936
}
3037

38+
#[Test]
39+
3140
public function testUnknownThrows(): void
3241
{
3342
$this->expectException(InvalidRuleException::class);
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\Transformer\Tests\Unit\Core;
6+
7+
use KaririCode\Transformer\Attribute\Transform;
8+
use KaririCode\Transformer\Configuration\TransformerConfiguration;
9+
use KaririCode\Transformer\Core\TransformAttributeHandler;
10+
use KaririCode\Transformer\Exception\TransformationException;
11+
use PHPUnit\Framework\Attributes\CoversClass;
12+
use PHPUnit\Framework\Attributes\Test;
13+
use PHPUnit\Framework\TestCase;
14+
15+
#[CoversClass(TransformAttributeHandler::class)]
16+
#[CoversClass(Transform::class)]
17+
#[CoversClass(TransformerConfiguration::class)]
18+
#[CoversClass(TransformationException::class)]
19+
final class TransformAttributeHandlerTest extends TestCase
20+
{
21+
#[Test]
22+
public function testHandleAttributeIgnoresNonTransformAttributes(): void
23+
{
24+
$handler = new TransformAttributeHandler();
25+
$result = $handler->handleAttribute('field', new \stdClass(), 'value');
26+
$this->assertNull($result);
27+
$this->assertSame([], $handler->getFieldRules());
28+
}
29+
30+
#[Test]
31+
public function testHandleAttributeCollectsRules(): void
32+
{
33+
$handler = new TransformAttributeHandler();
34+
$attribute = new Transform('camel_case', 'reverse');
35+
36+
$handler->handleAttribute('name', $attribute, 'hello_world');
37+
38+
$this->assertArrayHasKey('name', $handler->getFieldRules());
39+
$this->assertSame(['camel_case', 'reverse'], $handler->getFieldRules()['name']);
40+
}
41+
42+
#[Test]
43+
public function testHandleAttributeMergesMultipleAttributes(): void
44+
{
45+
$handler = new TransformAttributeHandler();
46+
$attr1 = new Transform('snake_case');
47+
$attr2 = new Transform('reverse');
48+
49+
$handler->handleAttribute('name', $attr1, 'Hello World');
50+
$handler->handleAttribute('name', $attr2, 'Hello World');
51+
52+
$this->assertSame(['snake_case', 'reverse'], $handler->getFieldRules()['name']);
53+
}
54+
55+
#[Test]
56+
public function testGetProcessedPropertyValues(): void
57+
{
58+
$handler = new TransformAttributeHandler();
59+
$attr = new Transform('camel_case');
60+
$handler->handleAttribute('field', $attr, 'hello');
61+
62+
$values = $handler->getProcessedPropertyValues();
63+
$this->assertArrayHasKey('field', $values);
64+
}
65+
66+
#[Test]
67+
public function testGetProcessingResultMessagesIsEmpty(): void
68+
{
69+
$handler = new TransformAttributeHandler();
70+
$this->assertSame([], $handler->getProcessingResultMessages());
71+
}
72+
73+
#[Test]
74+
public function testGetProcessingResultErrorsIsEmpty(): void
75+
{
76+
$handler = new TransformAttributeHandler();
77+
$this->assertSame([], $handler->getProcessingResultErrors());
78+
}
79+
80+
#[Test]
81+
public function testSetProcessedValuesAndApplyChanges(): void
82+
{
83+
$object = new class {
84+
public string $name = 'original';
85+
};
86+
87+
$handler = new TransformAttributeHandler();
88+
$handler->setProcessedValues(['name' => 'modified']);
89+
$handler->applyChanges($object);
90+
91+
$this->assertSame('modified', $object->name);
92+
}
93+
94+
#[Test]
95+
public function testApplyChangesSkipsNonExistentProperties(): void
96+
{
97+
$object = new class {};
98+
99+
$handler = new TransformAttributeHandler();
100+
$handler->setProcessedValues(['nonexistent' => 'value']);
101+
102+
// Should not throw, just skip silently
103+
$handler->applyChanges($object);
104+
$this->assertTrue(true); // reached here = no exception
105+
}
106+
107+
// -------------------------------------------------------------------------
108+
// Coverage for Transform, TransformerConfiguration, TransformationException
109+
// -------------------------------------------------------------------------
110+
111+
#[Test]
112+
public function testTransformAttributeConstruction(): void
113+
{
114+
$attr = new Transform('snake_case', ['mask', ['keep_start' => 3]]);
115+
$this->assertSame(['snake_case', ['mask', ['keep_start' => 3]]], $attr->rules);
116+
}
117+
118+
#[Test]
119+
public function testTransformerConfigurationDefaults(): void
120+
{
121+
$config = new TransformerConfiguration();
122+
$this->assertTrue($config->trackTransformations);
123+
$this->assertTrue($config->preserveOriginal);
124+
}
125+
126+
#[Test]
127+
public function testTransformationExceptionFactory(): void
128+
{
129+
$ex = TransformationException::engineError('test error');
130+
$this->assertInstanceOf(TransformationException::class, $ex);
131+
$this->assertStringContainsString('test error', $ex->getMessage());
132+
}
133+
134+
#[Test]
135+
public function testTransformationExceptionWithPrevious(): void
136+
{
137+
$prev = new \RuntimeException('root cause');
138+
$ex = TransformationException::engineError('outer', $prev);
139+
$this->assertSame($prev, $ex->getPrevious());
140+
}
141+
}

tests/Unit/Core/TransformationContextImplTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
namespace KaririCode\Transformer\Tests\Unit\Core;
66

77
use KaririCode\Transformer\Core\TransformationContextImpl;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\Test;
810
use PHPUnit\Framework\TestCase;
911

12+
#[CoversClass(\KaririCode\Transformer\Core\TransformationContextImpl::class)]
1013
final class TransformationContextImplTest extends TestCase
1114
{
15+
#[Test]
1216
public function testCreateReturnsEmptyFieldAndParams(): void
1317
{
1418
$ctx = TransformationContextImpl::create(['a' => 1]);
@@ -17,6 +21,8 @@ public function testCreateReturnsEmptyFieldAndParams(): void
1721
$this->assertSame([], $ctx->getParameters());
1822
}
1923

24+
#[Test]
25+
2026
public function testWithFieldReturnsNewInstance(): void
2127
{
2228
$ctx = TransformationContextImpl::create([]);
@@ -25,6 +31,8 @@ public function testWithFieldReturnsNewInstance(): void
2531
$this->assertSame('name', $ctx2->getFieldName());
2632
}
2733

34+
#[Test]
35+
2836
public function testWithParametersMerges(): void
2937
{
3038
$ctx = TransformationContextImpl::create([])

0 commit comments

Comments
 (0)