Skip to content

Commit 9d81cbc

Browse files
committed
Update some deps, update infection config to match msi to current status, make metadata 100% covered
1 parent 1879972 commit 9d81cbc

9 files changed

Lines changed: 285 additions & 199 deletions

composer.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,15 @@
2626
},
2727
"require-dev": {
2828
"ext-mongodb": "^2.1",
29-
"infection/infection": "^0.31.9",
29+
"infection/infection": "^0.32.6",
3030
"mongodb/mongodb": "^2.1",
3131
"patchlevel/coding-standard": "^1.3.0",
3232
"patchlevel/rango": "1.0.0-alpha.4",
33-
"phpat/phpat": "^0.12.0",
34-
"phpbench/phpbench": "^1.2.15",
35-
"phpstan/phpstan": "^2.1.32",
36-
"phpstan/phpstan-phpunit": "^2.0.8",
37-
"phpunit/phpunit": "^11.5.17",
38-
"symfony/var-dumper": "^6.4.0 || ^7.0.0 || ^8.0.0"
33+
"phpat/phpat": "^0.12.4",
34+
"phpbench/phpbench": "^1.6.1",
35+
"phpstan/phpstan": "^2.1.46",
36+
"phpstan/phpstan-phpunit": "^2.0.16",
37+
"phpunit/phpunit": "^11.5.55"
3938
},
4039
"config": {
4140
"preferred-install": {

composer.lock

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

infection.json.dist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"mutators": {
1717
"@default": true
1818
},
19-
"minMsi": 72,
20-
"minCoveredMsi": 87,
19+
"minMsi": 100,
20+
"minCoveredMsi": 100,
2121
"testFrameworkOptions": "--testsuite=unit"
2222
}

phpstan-baseline.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ parameters:
6666
count: 1
6767
path: src/Repository/MongoDBRepository.php
6868

69+
-
70+
message: '#^Parameter \#1 \$operations of method MongoDB\\Collection\:\:bulkWrite\(\) expects list\<array\{deleteMany\: array\{0\: array\|object, 1\?\: array\}\}\|array\{deleteOne\: array\{0\: array\|object, 1\?\: array\}\}\|array\{insertOne\: array\{array\|object\}\}\|array\{replaceOne\: array\{0\: array\|object, 1\: array\|object, 2\?\: array\}\}\|array\{updateMany\: array\{0\: array\|object, 1\: array\|object, 2\?\: array\}\}\|array\{updateOne\: array\{0\: array\|object, 1\: array\|object, 2\?\: array\}\}\>, non\-empty\-array\<int\|string, array\{updateOne\: array\{array\{_id\: mixed\}, array\{''\$set''\: array\<string, mixed\>\}\}\}\> given\.$#'
71+
identifier: argument.type
72+
count: 1
73+
path: src/Repository/MongoDBRepository.php
74+
6975
-
7076
message: '#^Parameter \#2 \$data of method Patchlevel\\Hydrator\\HydratorWithContext\:\:hydrate\(\) expects array\<string, mixed\>, array\|object given\.$#'
7177
identifier: argument.type

phpunit.xml.dist

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@
1212
<directory>tests/Unit</directory>
1313
</testsuite>
1414
</testsuites>
15+
16+
<coverage>
17+
<report>
18+
<html outputDirectory="./coverage"/>
19+
</report>
20+
</coverage>
21+
1522
<source>
1623
<include>
1724
<directory>src</directory>
1825
</include>
1926
</source>
27+
2028
</phpunit>

src/Repository/MongoDBRepository.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,23 @@ public function update(object ...$objects): void
9292
return;
9393
}
9494

95-
$this->collection->bulkWrite(array_map(function (object $object): array {
96-
if ($object::class !== $this->metadata->className) {
97-
throw new WrongClass($this->metadata->className, $object::class);
98-
}
99-
100-
$data = $this->hydrator->extract(
101-
$object,
102-
[DocumentMetadata::class => $this->metadata],
103-
);
95+
$this->collection->bulkWrite(array_map(
96+
function (object $object): array {
97+
if ($object::class !== $this->metadata->className) {
98+
throw new WrongClass($this->metadata->className, $object::class);
99+
}
104100

105-
return [
106-
'updateOne' => [
107-
['_id' => $data['_id']],
108-
['$set' => $data],
109-
],
110-
];
111-
}, $objects));
101+
$data = $this->hydrator->extract($object, [DocumentMetadata::class => $this->metadata]);
102+
103+
return [
104+
'updateOne' => [
105+
['_id' => $data['_id']],
106+
['$set' => $data],
107+
],
108+
];
109+
},
110+
$objects,
111+
));
112112
}
113113

114114
/**
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Patchlevel\ODM\Tests\Unit\Metadata;
6+
7+
use Patchlevel\ODM\Attribute\Document;
8+
use Patchlevel\ODM\Attribute\Id;
9+
use Patchlevel\ODM\Index;
10+
use Patchlevel\ODM\Metadata\AttributeDocumentMetadataFactory;
11+
use Patchlevel\ODM\Metadata\ClassIsNotAnDocument;
12+
use Patchlevel\ODM\Metadata\DocumentMetadata;
13+
use Patchlevel\ODM\Metadata\FieldMapping;
14+
use Patchlevel\ODM\Metadata\FieldMappingResolver;
15+
use Patchlevel\ODM\Metadata\MultipleIdPropertiesFound;
16+
use Patchlevel\ODM\Metadata\NoIdPropertyFound;
17+
use Patchlevel\ODM\Tests\Unit\Fixtures\Address;
18+
use Patchlevel\ODM\Tests\Unit\Fixtures\Profile;
19+
use PHPUnit\Framework\Attributes\CoversClass;
20+
use PHPUnit\Framework\TestCase;
21+
use ReflectionProperty;
22+
23+
#[CoversClass(AttributeDocumentMetadataFactory::class)]
24+
#[CoversClass(ClassIsNotAnDocument::class)]
25+
#[CoversClass(NoIdPropertyFound::class)]
26+
#[CoversClass(MultipleIdPropertiesFound::class)]
27+
#[CoversClass(FieldMapping::class)]
28+
final class AttributeDocumentMetadataFactoryTest extends TestCase
29+
{
30+
public function testMetadata(): void
31+
{
32+
$expected = new DocumentMetadata(
33+
className: Profile::class,
34+
database: null,
35+
collection: 'rango_documents',
36+
idProperty: 'id',
37+
indexes: [new Index('by_status', ['status' => 'asc'], unique: false)],
38+
fields: ['id' => new FieldMapping('_id', [])],
39+
);
40+
41+
$factory = new AttributeDocumentMetadataFactory();
42+
$metadata = $factory->metadata(Profile::class);
43+
44+
self::assertEquals($expected, $metadata);
45+
}
46+
47+
public function testMetadataOnNonDocumentExpectClassIsNotAnDocument(): void
48+
{
49+
$factory = new AttributeDocumentMetadataFactory();
50+
$this->expectException(ClassIsNotAnDocument::class);
51+
52+
$factory->metadata(Address::class);
53+
}
54+
55+
public function testMetadataInMemoryCache(): void
56+
{
57+
$factory = new AttributeDocumentMetadataFactory();
58+
$metadataFirst = $factory->metadata(Profile::class);
59+
$metadataSecond = $factory->metadata(Profile::class);
60+
61+
self::assertSame($metadataFirst, $metadataSecond);
62+
}
63+
64+
public function testMetadataNonIdDocument(): void
65+
{
66+
$class = new #[Document('rango_documents')]
67+
class () {
68+
};
69+
70+
$factory = new AttributeDocumentMetadataFactory();
71+
$this->expectException(NoIdPropertyFound::class);
72+
73+
$factory->metadata($class::class);
74+
}
75+
76+
public function testMetadataMultipleIdDocument(): void
77+
{
78+
$class = new #[Document('rango_documents')]
79+
class ('1', '2') {
80+
public function __construct(
81+
#[Id]
82+
public string $id,
83+
#[Id]
84+
public string $id2,
85+
) {
86+
}
87+
};
88+
89+
$factory = new AttributeDocumentMetadataFactory();
90+
$this->expectException(MultipleIdPropertiesFound::class);
91+
92+
$factory->metadata($class::class);
93+
}
94+
95+
public function testMetadataWithFieldResolver(): void
96+
{
97+
$expected = new DocumentMetadata(
98+
className: Profile::class,
99+
database: null,
100+
collection: 'rango_documents',
101+
idProperty: 'id',
102+
indexes: [new Index('by_status', ['status' => 'asc'], unique: false)],
103+
fields: [
104+
'id' => new FieldMapping('_id', []),
105+
'status' => new FieldMapping('_newStatus', []),
106+
],
107+
);
108+
109+
$fieldResolver = new class implements FieldMappingResolver
110+
{
111+
public function resolve(ReflectionProperty $reflectionProperty): FieldMapping|null
112+
{
113+
if ($reflectionProperty->getName() === 'status') {
114+
return new FieldMapping('_newStatus', []);
115+
}
116+
117+
return null;
118+
}
119+
};
120+
121+
$factory = new AttributeDocumentMetadataFactory($fieldResolver);
122+
$metadata = $factory->metadata(Profile::class);
123+
124+
self::assertEquals($expected, $metadata);
125+
}
126+
127+
public function testMetadataWithFieldResolverNotUsedForId(): void
128+
{
129+
$expected = new DocumentMetadata(
130+
className: Profile::class,
131+
database: null,
132+
collection: 'rango_documents',
133+
idProperty: 'id',
134+
indexes: [new Index('by_status', ['status' => 'asc'], unique: false)],
135+
fields: ['id' => new FieldMapping('_id', [])],
136+
);
137+
138+
$fieldResolver = new class implements FieldMappingResolver
139+
{
140+
public function resolve(ReflectionProperty $reflectionProperty): FieldMapping|null
141+
{
142+
if ($reflectionProperty->getName() === 'id') {
143+
return new FieldMapping('_otherId', []);
144+
}
145+
146+
return null;
147+
}
148+
};
149+
150+
$factory = new AttributeDocumentMetadataFactory($fieldResolver);
151+
$metadata = $factory->metadata(Profile::class);
152+
153+
self::assertEquals($expected, $metadata);
154+
}
155+
}

tests/Unit/Metadata/DocumentMetadataTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77
use Patchlevel\ODM\Metadata\DocumentMetadata;
88
use Patchlevel\ODM\Metadata\FieldMapping;
9+
use PHPUnit\Framework\Attributes\CoversClass;
910
use PHPUnit\Framework\TestCase;
1011
use stdClass;
1112

13+
#[CoversClass(DocumentMetadata::class)]
1214
final class DocumentMetadataTest extends TestCase
1315
{
1416
public function testPropertyPathToFieldPathWithoutMapping(): void

tests/Unit/Metadata/StackHydratorFieldMappingResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
use Patchlevel\ODM\Metadata\StackHydratorFieldMappingResolver;
1212
use Patchlevel\ODM\Tests\Unit\Fixtures\PersonalData;
1313
use Patchlevel\ODM\Tests\Unit\Fixtures\Profile;
14+
use PHPUnit\Framework\Attributes\CoversClass;
1415
use PHPUnit\Framework\TestCase;
1516
use ReflectionProperty;
1617

18+
#[CoversClass(StackHydratorFieldMappingResolver::class)]
1719
final class StackHydratorFieldMappingResolverTest extends TestCase
1820
{
1921
private StackHydratorFieldMappingResolver $resolver;

0 commit comments

Comments
 (0)