@@ -29,19 +29,225 @@ class TypeFactoryTest extends TestCase
29
29
public function testGetType (array $ schema , Type $ type ): void
30
30
{
31
31
$ typeFactory = new TypeFactory ();
32
- $ this ->assertSame ($ schema , $ typeFactory ->getType ($ type ));
32
+ $ this ->assertEquals ($ schema , $ typeFactory ->getType ($ type, ' json ' , null , null , new Schema () ));
33
33
}
34
34
35
35
public function typeProvider (): iterable
36
36
{
37
37
yield [['type ' => 'integer ' ], new Type (Type::BUILTIN_TYPE_INT )];
38
+ yield [['nullable ' => true , 'type ' => 'integer ' ], new Type (Type::BUILTIN_TYPE_INT , true )];
38
39
yield [['type ' => 'number ' ], new Type (Type::BUILTIN_TYPE_FLOAT )];
40
+ yield [['nullable ' => true , 'type ' => 'number ' ], new Type (Type::BUILTIN_TYPE_FLOAT , true )];
39
41
yield [['type ' => 'boolean ' ], new Type (Type::BUILTIN_TYPE_BOOL )];
42
+ yield [['nullable ' => true , 'type ' => 'boolean ' ], new Type (Type::BUILTIN_TYPE_BOOL , true )];
43
+ yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_STRING )];
44
+ yield [['nullable ' => true , 'type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_STRING , true )];
40
45
yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_OBJECT )];
46
+ yield [['nullable ' => true , 'type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_OBJECT , true )];
41
47
yield [['type ' => 'string ' , 'format ' => 'date-time ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , \DateTimeImmutable::class)];
48
+ yield [['nullable ' => true , 'type ' => 'string ' , 'format ' => 'date-time ' ], new Type (Type::BUILTIN_TYPE_OBJECT , true , \DateTimeImmutable::class)];
42
49
yield [['type ' => 'string ' , 'format ' => 'duration ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , \DateInterval::class)];
43
- yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , Dummy::class)];
50
+ yield [['type ' => 'string ' , 'format ' => 'iri-reference ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , Dummy::class)];
51
+ yield [['nullable ' => true , 'type ' => 'string ' , 'format ' => 'iri-reference ' ], new Type (Type::BUILTIN_TYPE_OBJECT , true , Dummy::class)];
44
52
yield [['type ' => 'array ' , 'items ' => ['type ' => 'string ' ]], new Type (Type::BUILTIN_TYPE_STRING , false , null , true )];
53
+ yield 'array can be itself nullable ' => [
54
+ ['nullable ' => true , 'type ' => 'array ' , 'items ' => ['type ' => 'string ' ]],
55
+ new Type (Type::BUILTIN_TYPE_STRING , true , null , true ),
56
+ ];
57
+
58
+ yield 'array can contain nullable values ' => [
59
+ [
60
+ 'type ' => 'array ' ,
61
+ 'items ' => [
62
+ 'nullable ' => true ,
63
+ 'type ' => 'string ' ,
64
+ ],
65
+ ],
66
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , true , null , new Type (Type::BUILTIN_TYPE_STRING , true , null , false )),
67
+ ];
68
+
69
+ yield 'map with string keys becomes an object ' => [
70
+ ['type ' => 'object ' , 'additionalProperties ' => ['type ' => 'string ' ]],
71
+ new Type (
72
+ Type::BUILTIN_TYPE_STRING ,
73
+ false ,
74
+ null ,
75
+ true ,
76
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false )
77
+ ),
78
+ ];
79
+
80
+ yield 'nullable map with string keys becomes a nullable object ' => [
81
+ [
82
+ 'nullable ' => true ,
83
+ 'type ' => 'object ' ,
84
+ 'additionalProperties ' => ['type ' => 'string ' ],
85
+ ],
86
+ new Type (
87
+ Type::BUILTIN_TYPE_STRING ,
88
+ true ,
89
+ null ,
90
+ true ,
91
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
92
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false )
93
+ ),
94
+ ];
95
+
96
+ yield 'map value type will be considered ' => [
97
+ ['type ' => 'object ' , 'additionalProperties ' => ['type ' => 'integer ' ]],
98
+ new Type (
99
+ Type::BUILTIN_TYPE_ARRAY ,
100
+ false ,
101
+ null ,
102
+ true ,
103
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
104
+ new Type (Type::BUILTIN_TYPE_INT , false , null , false )
105
+ ),
106
+ ];
107
+
108
+ yield 'map value type nullability will be considered ' => [
109
+ [
110
+ 'type ' => 'object ' ,
111
+ 'additionalProperties ' => [
112
+ 'nullable ' => true ,
113
+ 'type ' => 'integer ' ,
114
+ ],
115
+ ],
116
+ new Type (
117
+ Type::BUILTIN_TYPE_ARRAY ,
118
+ false ,
119
+ null ,
120
+ true ,
121
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
122
+ new Type (Type::BUILTIN_TYPE_INT , true , null , false )
123
+ ),
124
+ ];
125
+
126
+ yield 'nullable map can contain nullable values ' => [
127
+ [
128
+ 'nullable ' => true ,
129
+ 'type ' => 'object ' ,
130
+ 'additionalProperties ' => [
131
+ 'nullable ' => true ,
132
+ 'type ' => 'integer ' ,
133
+ ],
134
+ ],
135
+ new Type (
136
+ Type::BUILTIN_TYPE_ARRAY ,
137
+ true ,
138
+ null ,
139
+ true ,
140
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
141
+ new Type (Type::BUILTIN_TYPE_INT , true , null , false )
142
+ ),
143
+ ];
144
+ }
145
+
146
+ /** @dataProvider openAPIV2typeProvider */
147
+ public function testGetTypeWithOpenAPIV2Syntax (array $ schema , Type $ type ): void
148
+ {
149
+ $ typeFactory = new TypeFactory ();
150
+ $ this ->assertSame ($ schema , $ typeFactory ->getType ($ type , 'json ' , null , null , new Schema (Schema::VERSION_SWAGGER )));
151
+ }
152
+
153
+ public function openAPIV2typeProvider (): iterable
154
+ {
155
+ yield [['type ' => 'integer ' ], new Type (Type::BUILTIN_TYPE_INT )];
156
+ yield [['type ' => 'integer ' ], new Type (Type::BUILTIN_TYPE_INT , true )];
157
+ yield [['type ' => 'number ' ], new Type (Type::BUILTIN_TYPE_FLOAT )];
158
+ yield [['type ' => 'number ' ], new Type (Type::BUILTIN_TYPE_FLOAT , true )];
159
+ yield [['type ' => 'boolean ' ], new Type (Type::BUILTIN_TYPE_BOOL )];
160
+ yield [['type ' => 'boolean ' ], new Type (Type::BUILTIN_TYPE_BOOL , true )];
161
+ yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_STRING )];
162
+ yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_STRING , true )];
163
+ yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_OBJECT )];
164
+ yield [['type ' => 'string ' ], new Type (Type::BUILTIN_TYPE_OBJECT , true )];
165
+ yield [['type ' => 'string ' , 'format ' => 'date-time ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , \DateTimeImmutable::class)];
166
+ yield [['type ' => 'string ' , 'format ' => 'date-time ' ], new Type (Type::BUILTIN_TYPE_OBJECT , true , \DateTimeImmutable::class)];
167
+ yield [['type ' => 'string ' , 'format ' => 'duration ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , \DateInterval::class)];
168
+ yield [['type ' => 'string ' , 'format ' => 'iri-reference ' ], new Type (Type::BUILTIN_TYPE_OBJECT , false , Dummy::class)];
169
+ yield [['type ' => 'string ' , 'format ' => 'iri-reference ' ], new Type (Type::BUILTIN_TYPE_OBJECT , true , Dummy::class)];
170
+ yield [['type ' => 'array ' , 'items ' => ['type ' => 'string ' ]], new Type (Type::BUILTIN_TYPE_STRING , false , null , true )];
171
+ yield 'array can be itself nullable, but ignored in OpenAPI V2 ' => [
172
+ ['type ' => 'array ' , 'items ' => ['type ' => 'string ' ]],
173
+ new Type (Type::BUILTIN_TYPE_STRING , true , null , true ),
174
+ ];
175
+
176
+ yield 'array can contain nullable values, but ignored in OpenAPI V2 ' => [
177
+ [
178
+ 'type ' => 'array ' ,
179
+ 'items ' => ['type ' => 'string ' ],
180
+ ],
181
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , true , null , new Type (Type::BUILTIN_TYPE_STRING , true , null , false )),
182
+ ];
183
+
184
+ yield 'map with string keys becomes an object ' => [
185
+ ['type ' => 'object ' , 'additionalProperties ' => ['type ' => 'string ' ]],
186
+ new Type (
187
+ Type::BUILTIN_TYPE_STRING ,
188
+ false ,
189
+ null ,
190
+ true ,
191
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false )
192
+ ),
193
+ ];
194
+
195
+ yield 'nullable map with string keys becomes a nullable object, but ignored in OpenAPI V2 ' => [
196
+ [
197
+ 'type ' => 'object ' ,
198
+ 'additionalProperties ' => ['type ' => 'string ' ],
199
+ ],
200
+ new Type (
201
+ Type::BUILTIN_TYPE_STRING ,
202
+ true ,
203
+ null ,
204
+ true ,
205
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
206
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false )
207
+ ),
208
+ ];
209
+
210
+ yield 'map value type will be considered ' => [
211
+ ['type ' => 'object ' , 'additionalProperties ' => ['type ' => 'integer ' ]],
212
+ new Type (
213
+ Type::BUILTIN_TYPE_ARRAY ,
214
+ false ,
215
+ null ,
216
+ true ,
217
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
218
+ new Type (Type::BUILTIN_TYPE_INT , false , null , false )
219
+ ),
220
+ ];
221
+
222
+ yield 'map value type nullability will be considered, but ignored in OpenAPI V2 ' => [
223
+ [
224
+ 'type ' => 'object ' ,
225
+ 'additionalProperties ' => ['type ' => 'integer ' ],
226
+ ],
227
+ new Type (
228
+ Type::BUILTIN_TYPE_ARRAY ,
229
+ false ,
230
+ null ,
231
+ true ,
232
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
233
+ new Type (Type::BUILTIN_TYPE_INT , true , null , false )
234
+ ),
235
+ ];
236
+
237
+ yield 'nullable map can contain nullable values, but ignored in OpenAPI V2 ' => [
238
+ [
239
+ 'type ' => 'object ' ,
240
+ 'additionalProperties ' => ['type ' => 'integer ' ],
241
+ ],
242
+ new Type (
243
+ Type::BUILTIN_TYPE_ARRAY ,
244
+ true ,
245
+ null ,
246
+ true ,
247
+ new Type (Type::BUILTIN_TYPE_STRING , false , null , false ),
248
+ new Type (Type::BUILTIN_TYPE_INT , true , null , false )
249
+ ),
250
+ ];
45
251
}
46
252
47
253
public function testGetClassType (): void
@@ -59,4 +265,30 @@ public function testGetClassType(): void
59
265
60
266
$ this ->assertSame (['$ref ' => 'ref ' ], $ typeFactory ->getType (new Type (Type::BUILTIN_TYPE_OBJECT , false , Dummy::class), 'jsonld ' , true , ['foo ' => 'bar ' ], new Schema ()));
61
267
}
268
+
269
+ public function testGetClassTypeWithNullability (): void
270
+ {
271
+ $ schemaFactory = $ this ->createMock (SchemaFactoryInterface::class);
272
+
273
+ $ schemaFactory
274
+ ->method ('buildSchema ' )
275
+ ->willReturnCallback (static function (): Schema {
276
+ $ schema = new Schema ();
277
+
278
+ $ schema ['$ref ' ] = 'the-ref-name ' ;
279
+ $ schema ['description ' ] = 'more stuff here ' ;
280
+
281
+ return $ schema ;
282
+ });
283
+
284
+ $ typeFactory = new TypeFactory ();
285
+ $ typeFactory ->setSchemaFactory ($ schemaFactory );
286
+
287
+ self ::assertSame ([
288
+ 'nullable ' => true ,
289
+ 'anyOf ' => [
290
+ ['$ref ' => 'the-ref-name ' ],
291
+ ],
292
+ ], $ typeFactory ->getType (new Type (Type::BUILTIN_TYPE_OBJECT , true , Dummy::class), 'jsonld ' , true , ['foo ' => 'bar ' ], new Schema ()));
293
+ }
62
294
}
0 commit comments