Skip to content

Commit 7b4314d

Browse files
committed
minor #439 [Store] Add comprehensive unit tests for TextDocument (OskarStark)
This PR was squashed before being merged into the main branch. Discussion ---------- [Store] Add comprehensive unit tests for `TextDocument` | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | Docs? | no | Issues | -- | License | MIT Commits ------- e0125e0 [Store] Add comprehensive unit tests for `TextDocument`
2 parents 4bb633d + e0125e0 commit 7b4314d

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Store\Tests\Document;
13+
14+
use PHPUnit\Framework\Attributes\CoversClass;
15+
use PHPUnit\Framework\Attributes\DataProvider;
16+
use PHPUnit\Framework\Attributes\TestDox;
17+
use PHPUnit\Framework\Attributes\TestWith;
18+
use PHPUnit\Framework\TestCase;
19+
use Symfony\AI\Store\Document\Metadata;
20+
use Symfony\AI\Store\Document\TextDocument;
21+
use Symfony\AI\Store\Exception\InvalidArgumentException;
22+
use Symfony\Component\Uid\Uuid;
23+
24+
#[CoversClass(TextDocument::class)]
25+
final class TextDocumentTest extends TestCase
26+
{
27+
#[TestDox('Creates document with valid content and metadata')]
28+
public function testConstructorWithValidContent()
29+
{
30+
$id = Uuid::v4();
31+
$content = 'This is valid content';
32+
$metadata = new Metadata(['title' => 'Test Document']);
33+
34+
$document = new TextDocument($id, $content, $metadata);
35+
36+
$this->assertSame($id, $document->id);
37+
$this->assertSame($content, $document->content);
38+
$this->assertSame($metadata, $document->metadata);
39+
}
40+
41+
#[TestDox('Creates document with default empty metadata when not provided')]
42+
public function testConstructorWithDefaultMetadata()
43+
{
44+
$id = Uuid::v4();
45+
$content = 'This is valid content';
46+
47+
$document = new TextDocument($id, $content);
48+
49+
$this->assertSame($id, $document->id);
50+
$this->assertSame($content, $document->content);
51+
$this->assertInstanceOf(Metadata::class, $document->metadata);
52+
$this->assertCount(0, $document->metadata);
53+
}
54+
55+
#[TestWith([''])]
56+
#[TestWith([' '])]
57+
#[TestWith([' '])]
58+
#[TestWith(["\t\t\t"])]
59+
#[TestWith(["\n\n\n"])]
60+
#[TestWith([" \t \n \r "])]
61+
#[TestWith(["\r\r\r"])]
62+
#[TestDox('Throws exception for invalid content: $content')]
63+
public function testConstructorThrowsExceptionForInvalidContent(string $content)
64+
{
65+
$this->expectException(InvalidArgumentException::class);
66+
$this->expectExceptionMessage('The content shall not be an empty string.');
67+
68+
new TextDocument(Uuid::v4(), $content);
69+
}
70+
71+
#[TestWith(['Hello, World!'])]
72+
#[TestWith([' Leading whitespace'])]
73+
#[TestWith(['Trailing whitespace '])]
74+
#[TestWith(["Line 1\nLine 2\nLine 3"])]
75+
#[TestWith([" Text with\t\ttabs and\n\nnewlines "])]
76+
#[TestWith(['a'])]
77+
#[TestWith(['123456789'])]
78+
#[TestWith(['!@#$%^&*()_+-=[]{}|;:,.<>?'])]
79+
#[TestWith(['Hello 世界 🌍'])]
80+
#[TestWith(['{"key": "value", "number": 42}'])]
81+
#[TestWith(['<html><body><p>Hello World</p></body></html>'])]
82+
#[TestWith(['# Heading\n\nThis is **bold** and this is *italic*.'])]
83+
#[TestDox('Accepts valid content')]
84+
public function testConstructorAcceptsValidContent(string $content)
85+
{
86+
$id = Uuid::v4();
87+
88+
$document = new TextDocument($id, $content);
89+
90+
$this->assertSame($id, $document->id);
91+
$this->assertSame($content, $document->content);
92+
}
93+
94+
#[TestDox('Accepts very long text content')]
95+
public function testConstructorAcceptsVeryLongContent()
96+
{
97+
$id = Uuid::v4();
98+
$content = str_repeat('Lorem ipsum dolor sit amet, ', 1000);
99+
100+
$document = new TextDocument($id, $content);
101+
102+
$this->assertSame($id, $document->id);
103+
$this->assertSame($content, $document->content);
104+
}
105+
106+
#[TestDox('Properties are publicly accessible and readonly')]
107+
public function testReadonlyProperties()
108+
{
109+
$id = Uuid::v4();
110+
$content = 'Test content';
111+
$metadata = new Metadata(['key' => 'value']);
112+
113+
$document = new TextDocument($id, $content, $metadata);
114+
115+
// Test that properties are publicly accessible
116+
$this->assertSame($id, $document->id);
117+
$this->assertSame($content, $document->content);
118+
$this->assertSame($metadata, $document->metadata);
119+
}
120+
121+
#[TestDox('Metadata contents can be modified even though the property is readonly')]
122+
public function testMetadataCanBeModified()
123+
{
124+
$id = Uuid::v4();
125+
$content = 'Test content';
126+
$metadata = new Metadata();
127+
128+
$document = new TextDocument($id, $content, $metadata);
129+
130+
// Metadata is readonly but its contents can be modified (ArrayObject behavior)
131+
$metadata['key'] = 'value';
132+
$metadata->setSource('test.txt');
133+
134+
$this->assertSame('value', $document->metadata['key']);
135+
$this->assertSame('test.txt', $document->metadata->getSource());
136+
}
137+
138+
#[DataProvider('uuidVersionProvider')]
139+
#[TestDox('Accepts UUID version $version')]
140+
public function testDifferentUuidVersions(string $version, Uuid $uuid)
141+
{
142+
$content = 'Test content';
143+
144+
$document = new TextDocument($uuid, $content);
145+
146+
$this->assertSame($uuid, $document->id);
147+
$this->assertSame($content, $document->content);
148+
}
149+
150+
/**
151+
* @return \Iterator<string, array{version: string, uuid: Uuid}>
152+
*/
153+
public static function uuidVersionProvider(): \Iterator
154+
{
155+
yield 'UUID v4' => ['version' => '4', 'uuid' => Uuid::v4()];
156+
yield 'UUID v6' => ['version' => '6', 'uuid' => Uuid::v6()];
157+
yield 'UUID v7' => ['version' => '7', 'uuid' => Uuid::v7()];
158+
}
159+
160+
#[TestDox('Handles complex nested metadata with special keys')]
161+
public function testDocumentWithComplexMetadata()
162+
{
163+
$id = Uuid::v4();
164+
$content = 'Document content';
165+
$metadata = new Metadata([
166+
'title' => 'Test Document',
167+
'author' => 'John Doe',
168+
'tags' => ['test', 'document', 'example'],
169+
'created_at' => '2024-01-01',
170+
'version' => 1.0,
171+
'nested' => [
172+
'key1' => 'value1',
173+
'key2' => 'value2',
174+
],
175+
]);
176+
$metadata->setParentId('parent-123');
177+
$metadata->setText('Additional text');
178+
$metadata->setSource('source.pdf');
179+
180+
$document = new TextDocument($id, $content, $metadata);
181+
182+
$expected = [
183+
'title' => 'Test Document',
184+
'author' => 'John Doe',
185+
'tags' => ['test', 'document', 'example'],
186+
'created_at' => '2024-01-01',
187+
'version' => 1.0,
188+
'nested' => [
189+
'key1' => 'value1',
190+
'key2' => 'value2',
191+
],
192+
'_parent_id' => 'parent-123',
193+
'_text' => 'Additional text',
194+
'_source' => 'source.pdf',
195+
];
196+
197+
$this->assertSame($expected, $document->metadata->getArrayCopy());
198+
}
199+
200+
#[TestDox('Multiple documents can share the same content with different IDs and metadata')]
201+
public function testMultipleDocumentsWithSameContent()
202+
{
203+
$content = 'Shared content';
204+
$metadata1 = new Metadata(['source' => 'doc1.txt']);
205+
$metadata2 = new Metadata(['source' => 'doc2.txt']);
206+
207+
$document1 = new TextDocument(Uuid::v4(), $content, $metadata1);
208+
$document2 = new TextDocument(Uuid::v4(), $content, $metadata2);
209+
210+
$this->assertSame($content, $document1->content);
211+
$this->assertSame($content, $document2->content);
212+
$this->assertNotSame($document1->id, $document2->id);
213+
$this->assertNotSame($document1->metadata, $document2->metadata);
214+
}
215+
216+
#[TestDox('Documents can have the same ID but different content')]
217+
public function testDocumentWithSameIdButDifferentContent()
218+
{
219+
$id = Uuid::v4();
220+
221+
$document1 = new TextDocument($id, 'Content 1');
222+
$document2 = new TextDocument($id, 'Content 2');
223+
224+
$this->assertSame($id, $document1->id);
225+
$this->assertSame($id, $document2->id);
226+
$this->assertNotSame($document1->content, $document2->content);
227+
}
228+
229+
#[TestDox('Content with whitespace is stored as-is without trimming')]
230+
public function testTrimBehaviorValidation()
231+
{
232+
// Content with whitespace that is not purely whitespace should be valid
233+
$id = Uuid::v4();
234+
$contentWithWhitespace = ' Valid content with spaces ';
235+
236+
$document = new TextDocument($id, $contentWithWhitespace);
237+
238+
// The content is stored as-is, not trimmed
239+
$this->assertSame($contentWithWhitespace, $document->content);
240+
}
241+
242+
#[TestDox('Exception message is correct for empty content')]
243+
public function testExceptionMessageIsCorrect()
244+
{
245+
$this->expectException(InvalidArgumentException::class);
246+
$this->expectExceptionMessage('The content shall not be an empty string.');
247+
248+
new TextDocument(Uuid::v4(), ' ');
249+
}
250+
}

0 commit comments

Comments
 (0)