Parse and validate AT Protocol Lexicons with DTO generation for Laravel
1<?php
2
3namespace SocialDept\AtpSchema\Tests\Unit\Generator;
4
5use Orchestra\Testbench\TestCase;
6use SocialDept\AtpSchema\Generator\PropertyGenerator;
7
8class PropertyGeneratorTest extends TestCase
9{
10 protected PropertyGenerator $generator;
11
12 protected function setUp(): void
13 {
14 parent::setUp();
15
16 $this->generator = new PropertyGenerator();
17 }
18
19 public function test_it_generates_required_string_property(): void
20 {
21 $property = $this->generator->generate('name', ['type' => 'string'], ['name']);
22
23 $this->assertStringContainsString('public readonly string $name;', $property);
24 $this->assertStringContainsString('@var string', $property);
25 }
26
27 public function test_it_generates_optional_string_property(): void
28 {
29 $property = $this->generator->generate('nickname', ['type' => 'string'], []);
30
31 $this->assertStringContainsString('public readonly ?string $nickname;', $property);
32 $this->assertStringContainsString('@var string|null', $property);
33 }
34
35 public function test_it_generates_integer_property(): void
36 {
37 $property = $this->generator->generate('age', ['type' => 'integer'], ['age']);
38
39 $this->assertStringContainsString('public readonly int $age;', $property);
40 $this->assertStringContainsString('@var int', $property);
41 }
42
43 public function test_it_generates_boolean_property(): void
44 {
45 $property = $this->generator->generate('active', ['type' => 'boolean'], ['active']);
46
47 $this->assertStringContainsString('public readonly bool $active;', $property);
48 $this->assertStringContainsString('@var bool', $property);
49 }
50
51 public function test_it_generates_array_property(): void
52 {
53 $property = $this->generator->generate('tags', ['type' => 'array'], ['tags']);
54
55 $this->assertStringContainsString('public readonly array $tags;', $property);
56 $this->assertStringContainsString('@var array', $property);
57 }
58
59 public function test_it_includes_description_in_docblock(): void
60 {
61 $property = $this->generator->generate(
62 'name',
63 [
64 'type' => 'string',
65 'description' => 'The user name',
66 ],
67 ['name']
68 );
69
70 $this->assertStringContainsString('* The user name', $property);
71 }
72
73 public function test_it_generates_property_with_default_value(): void
74 {
75 $property = $this->generator->generate(
76 'status',
77 [
78 'type' => 'string',
79 'default' => 'active',
80 ],
81 []
82 );
83
84 $this->assertStringContainsString("= 'active'", $property);
85 }
86
87 public function test_it_generates_multiple_properties(): void
88 {
89 $properties = $this->generator->generateMultiple(
90 [
91 'name' => ['type' => 'string'],
92 'age' => ['type' => 'integer'],
93 ],
94 ['name', 'age']
95 );
96
97 $this->assertCount(2, $properties);
98 $this->assertStringContainsString('$name', $properties[0]);
99 $this->assertStringContainsString('$age', $properties[1]);
100 }
101
102 public function test_it_generates_property_signature(): void
103 {
104 $signature = $this->generator->generateSignature('name', ['type' => 'string'], ['name']);
105
106 $this->assertSame('string $name', $signature);
107 }
108
109 public function test_it_generates_optional_property_signature(): void
110 {
111 $signature = $this->generator->generateSignature('nickname', ['type' => 'string'], []);
112
113 $this->assertSame('?string $nickname', $signature);
114 }
115
116 public function test_it_generates_promoted_property(): void
117 {
118 $promoted = $this->generator->generatePromoted('name', ['type' => 'string'], ['name']);
119
120 $this->assertSame('public readonly string $name', $promoted);
121 }
122
123 public function test_it_generates_optional_promoted_property(): void
124 {
125 $promoted = $this->generator->generatePromoted('nickname', ['type' => 'string'], []);
126
127 $this->assertSame('public readonly ?string $nickname', $promoted);
128 }
129
130 public function test_it_checks_if_property_is_nullable(): void
131 {
132 $this->assertFalse($this->generator->isNullable('name', ['type' => 'string'], ['name']));
133 $this->assertTrue($this->generator->isNullable('nickname', ['type' => 'string'], []));
134 }
135
136 public function test_it_gets_property_type(): void
137 {
138 $type = $this->generator->getType(['type' => 'string']);
139
140 $this->assertSame('string', $type);
141 }
142
143 public function test_it_gets_nullable_property_type(): void
144 {
145 $type = $this->generator->getType(['type' => 'string'], true);
146
147 $this->assertSame('?string', $type);
148 }
149
150 public function test_it_gets_property_doc_type(): void
151 {
152 $docType = $this->generator->getDocType(['type' => 'string']);
153
154 $this->assertSame('string', $docType);
155 }
156
157 public function test_it_gets_nullable_property_doc_type(): void
158 {
159 $docType = $this->generator->getDocType(['type' => 'string'], true);
160
161 $this->assertSame('string|null', $docType);
162 }
163
164 public function test_it_handles_blob_type(): void
165 {
166 $property = $this->generator->generate('image', ['type' => 'blob'], []);
167
168 $this->assertStringContainsString('BlobReference', $property);
169 }
170
171 public function test_it_handles_ref_type(): void
172 {
173 $property = $this->generator->generate(
174 'author',
175 [
176 'type' => 'ref',
177 'ref' => 'app.test.author',
178 ],
179 ['author']
180 );
181
182 $this->assertStringContainsString('public readonly Author $author', $property);
183 }
184
185 public function test_it_generates_promoted_with_default(): void
186 {
187 $promoted = $this->generator->generatePromoted(
188 'status',
189 [
190 'type' => 'string',
191 'default' => 'pending',
192 ],
193 []
194 );
195
196 $this->assertStringContainsString('= \'pending\'', $promoted);
197 }
198
199 public function test_it_handles_number_type(): void
200 {
201 $property = $this->generator->generate('price', ['type' => 'number'], ['price']);
202
203 $this->assertStringContainsString('float $price', $property);
204 }
205
206 public function test_it_handles_mixed_type(): void
207 {
208 $property = $this->generator->generate('data', ['type' => 'unknown'], ['data']);
209
210 $this->assertStringContainsString('mixed $data', $property);
211 }
212}