Passed
Push — master ( a80842...bbbee0 )
by Caen
03:37 queued 13s
created

PublicationFieldValueTest   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 400
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 150
dl 0
loc 400
rs 6.96
c 0
b 0
f 0
wmc 53

How to fix   Complexity   

Complex Class

Complex classes like PublicationFieldValueTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PublicationFieldValueTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Publications\Testing\Feature;
6
7
use DateTime;
8
use Exception;
9
use Hyde\Testing\TestCase;
10
use InvalidArgumentException;
11
use Symfony\Component\Yaml\Yaml;
12
use Hyde\Publications\Models\PublicationFieldValue;
13
use Hyde\Publications\Concerns\PublicationFieldTypes;
14
15
/**
16
 * @covers \Hyde\Publications\Models\PublicationFieldValue
17
 */
18
class PublicationFieldValueTest extends TestCase
19
{
20
    // Base tests
21
22
    public function testConstruct()
23
    {
24
        $this->assertInstanceOf(PublicationFieldValue::class,
25
            new PublicationFieldValue(PublicationFieldTypes::String, 'foo')
26
        );
27
    }
28
29
    public function testGetType()
30
    {
31
        $this->assertSame(PublicationFieldTypes::String,
32
            (new PublicationFieldValue(PublicationFieldTypes::String, 'foo'))->getType()
33
        );
34
    }
35
36
    public function testGetValue()
37
    {
38
        $this->assertSame('foo', (new PublicationFieldValue(PublicationFieldTypes::String, 'foo'))->getValue());
39
    }
40
41
    public function testType()
42
    {
43
        $field = new PublicationFieldValue(PublicationFieldTypes::String, 'foo');
44
        $this->assertSame(PublicationFieldTypes::String, $field->type);
45
        $this->assertSame($field->type, $field->getType());
46
    }
47
48
    // StringField tests
49
50
    public function testStringFieldConstruct()
51
    {
52
        $field = $this->makeFieldType('string', 'foo');
53
54
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
55
        $this->assertSame(PublicationFieldTypes::String, $field->type);
56
    }
57
58
    public function testStringFieldGetValue()
59
    {
60
        $this->assertSame('foo', $this->makeFieldType('string', 'foo')->getValue());
61
    }
62
63
    public function testStringFieldToYaml()
64
    {
65
        $this->assertSame('foo', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('string'), 'foo')));
66
    }
67
68
    public function testStringFieldParsingOptions()
69
    {
70
        $this->assertSame('foo', $this->makeFieldType('string', 'foo')->getValue());
71
        $this->assertSame('true', $this->makeFieldType('string', 'true')->getValue());
72
        $this->assertSame('false', $this->makeFieldType('string', 'false')->getValue());
73
        $this->assertSame('null', $this->makeFieldType('string', 'null')->getValue());
74
        $this->assertSame('0', $this->makeFieldType('string', '0')->getValue());
75
        $this->assertSame('1', $this->makeFieldType('string', '1')->getValue());
76
        $this->assertSame('10.5', $this->makeFieldType('string', '10.5')->getValue());
77
        $this->assertSame('-10', $this->makeFieldType('string', '-10')->getValue());
78
    }
79
80
    // DatetimeField tests
81
82
    public function testDatetimeFieldConstruct()
83
    {
84
        $field = $this->makeFieldType('datetime', '2023-01-01');
85
86
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
87
        $this->assertSame(PublicationFieldTypes::Datetime, $field->type);
88
    }
89
90
    public function testDatetimeFieldGetValue()
91
    {
92
        $this->assertEquals(new DateTime('2023-01-01'), $this->makeFieldType('datetime', '2023-01-01')->getValue());
93
    }
94
95
    public function testDatetimeFieldWithInvalidInput()
96
    {
97
        $this->expectException(Exception::class);
98
        $this->expectExceptionMessage('Failed to parse time string (foo)');
99
        new PublicationFieldValue(PublicationFieldTypes::from('datetime'), 'foo');
100
    }
101
102
    public function testDatetimeFieldWithDynamicInput()
103
    {
104
        $field = $this->makeFieldType('datetime', 'now')->getValue();
105
106
        $this->assertInstanceOf(DateTime::class, $field);
107
    }
108
109
    public function testDatetimeFieldToYaml()
110
    {
111
        $this->assertSame('2023-01-01T00:00:00+00:00', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('datetime'), '2023-01-01')));
112
    }
113
114
    // BooleanField tests
115
116
    public function testBooleanFieldConstruct()
117
    {
118
        $field = $this->makeFieldType('boolean', 'true');
119
120
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
121
        $this->assertSame(PublicationFieldTypes::Boolean, $field->type);
122
    }
123
124
    public function testBooleanFieldGetValue()
125
    {
126
        $this->assertSame(true, $this->makeFieldType('boolean', 'true')->getValue());
127
    }
128
129
    public function testBooleanFieldToYaml()
130
    {
131
        $this->assertSame('true', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('boolean'), 'true')));
132
    }
133
134
    public function testBooleanFieldWithInvalidInput()
135
    {
136
        $this->expectException(InvalidArgumentException::class);
137
        $this->expectExceptionMessage('BooleanField: Unable to parse invalid boolean value \'foo\'');
138
        new PublicationFieldValue(PublicationFieldTypes::from('boolean'), 'foo');
139
    }
140
141
    public function testBooleanFieldParsingOptions()
142
    {
143
        $this->assertSame(true, $this->makeFieldType('boolean', 'true')->getValue());
144
        $this->assertSame(true, $this->makeFieldType('boolean', '1')->getValue());
145
        $this->assertSame(false, $this->makeFieldType('boolean', 'false')->getValue());
146
        $this->assertSame(false, $this->makeFieldType('boolean', '0')->getValue());
147
    }
148
149
    // IntegerField tests
150
151
    public function testIntegerFieldConstruct()
152
    {
153
        $field = $this->makeFieldType('integer', '10');
154
155
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
156
        $this->assertSame(PublicationFieldTypes::Integer, $field->type);
157
    }
158
159
    public function testIntegerFieldGetValue()
160
    {
161
        $this->assertSame(10, $this->makeFieldType('integer', '10')->getValue());
162
    }
163
164
    public function testIntegerFieldToYaml()
165
    {
166
        $this->assertSame('10', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('integer'), '10')));
167
    }
168
169
    public function testIntegerFieldWithInvalidInput()
170
    {
171
        $this->expectException(InvalidArgumentException::class);
172
        $this->expectExceptionMessage('IntegerField: Unable to parse invalid integer value \'foo\'');
173
        new PublicationFieldValue(PublicationFieldTypes::from('integer'), 'foo');
174
    }
175
176
    public function testIntegerFieldParsingOptions()
177
    {
178
        $this->assertSame(0, $this->makeFieldType('integer', '0')->getValue());
179
        $this->assertSame(1, $this->makeFieldType('integer', '1')->getValue());
180
        $this->assertSame(10, $this->makeFieldType('integer', '10')->getValue());
181
        $this->assertSame(10, $this->makeFieldType('integer', '10.0')->getValue());
182
        $this->assertSame(10, $this->makeFieldType('integer', '10.5')->getValue());
183
        $this->assertSame(10, $this->makeFieldType('integer', '10.9')->getValue());
184
        $this->assertSame(100, $this->makeFieldType('integer', '1E2')->getValue());
185
        $this->assertSame(-10, $this->makeFieldType('integer', '-10')->getValue());
186
    }
187
188
    // FloatField tests
189
190
    public function testFloatFieldConstruct()
191
    {
192
        $field = $this->makeFieldType('float', '10');
193
194
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
195
        $this->assertSame(PublicationFieldTypes::Float, $field->type);
196
    }
197
198
    public function testFloatFieldGetValue()
199
    {
200
        $this->assertSame(10.0, $this->makeFieldType('float', '10')->getValue());
201
    }
202
203
    public function testFloatFieldToYaml()
204
    {
205
        $this->assertSame('10.0', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('float'), '10')));
206
    }
207
208
    public function testFloatFieldWithInvalidInput()
209
    {
210
        $this->expectException(InvalidArgumentException::class);
211
        $this->expectExceptionMessage('FloatField: Unable to parse invalid float value \'foo\'');
212
        new PublicationFieldValue(PublicationFieldTypes::from('float'), 'foo');
213
    }
214
215
    public function testFloatFieldParsingOptions()
216
    {
217
        $this->assertSame(0.0, $this->makeFieldType('float', '0')->getValue());
218
        $this->assertSame(1.0, $this->makeFieldType('float', '1')->getValue());
219
        $this->assertSame(10.0, $this->makeFieldType('float', '10')->getValue());
220
        $this->assertSame(10.0, $this->makeFieldType('float', '10.0')->getValue());
221
        $this->assertSame(10.5, $this->makeFieldType('float', '10.5')->getValue());
222
        $this->assertSame(10.9, $this->makeFieldType('float', '10.9')->getValue());
223
        $this->assertSame(100.0, $this->makeFieldType('float', '1E2')->getValue());
224
        $this->assertSame(-10.0, $this->makeFieldType('float', '-10')->getValue());
225
    }
226
227
    // ArrayField tests
228
229
    public function testArrayFieldConstruct()
230
    {
231
        $field = $this->makeFieldType('array', 'foo');
232
233
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
234
        $this->assertSame(PublicationFieldTypes::Array, $field->type);
235
    }
236
237
    public function testArrayFieldGetValue()
238
    {
239
        $this->assertSame(['foo'], $this->makeFieldType('array', 'foo')->getValue());
240
    }
241
242
    public function testArrayFieldToYaml()
243
    {
244
        $this->assertSame("- foo\n", $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('array'), 'foo')));
245
    }
246
247
    public function testArrayFieldWithArrayInput()
248
    {
249
        $this->assertSame(['foo'], $this->makeFieldType('array', ['foo'])->getValue());
250
    }
251
252
    public function testArrayFieldParsingOptions()
253
    {
254
        $this->assertSame(['foo'], $this->makeFieldType('array', 'foo')->getValue());
255
        $this->assertSame(['true'], $this->makeFieldType('array', 'true')->getValue());
256
        $this->assertSame(['false'], $this->makeFieldType('array', 'false')->getValue());
257
        $this->assertSame(['null'], $this->makeFieldType('array', 'null')->getValue());
258
        $this->assertSame(['0'], $this->makeFieldType('array', '0')->getValue());
259
        $this->assertSame(['1'], $this->makeFieldType('array', '1')->getValue());
260
        $this->assertSame(['10.5'], $this->makeFieldType('array', '10.5')->getValue());
261
        $this->assertSame(['-10'], $this->makeFieldType('array', '-10')->getValue());
262
    }
263
264
    // TextField tests
265
266
    public function testTextFieldConstruct()
267
    {
268
        $field = $this->makeFieldType('text', 'foo');
269
270
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
271
        $this->assertSame(PublicationFieldTypes::Text, $field->type);
272
    }
273
274
    public function testTextFieldGetValue()
275
    {
276
        $this->assertSame('foo', $this->makeFieldType('text', 'foo')->getValue());
277
    }
278
279
    public function testTextFieldToYaml()
280
    {
281
        $this->assertSame('foo', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('text'), 'foo')));
282
        // Note that this does not use the same flags as the creator action, because that's out of scope for this test.
283
    }
284
285
    public function testTextFieldParsingOptions()
286
    {
287
        $this->assertSame('foo', $this->makeFieldType('text', 'foo')->getValue());
288
        $this->assertSame('true', $this->makeFieldType('text', 'true')->getValue());
289
        $this->assertSame('false', $this->makeFieldType('text', 'false')->getValue());
290
        $this->assertSame('null', $this->makeFieldType('text', 'null')->getValue());
291
        $this->assertSame('0', $this->makeFieldType('text', '0')->getValue());
292
        $this->assertSame('1', $this->makeFieldType('text', '1')->getValue());
293
        $this->assertSame('10.5', $this->makeFieldType('text', '10.5')->getValue());
294
        $this->assertSame('-10', $this->makeFieldType('text', '-10')->getValue());
295
        $this->assertSame("foo\nbar\n", $this->makeFieldType('text', "foo\nbar")->getValue());
296
        $this->assertSame("foo\nbar\n", $this->makeFieldType('text', "foo\nbar\n")->getValue());
297
        $this->assertSame("foo\nbar\nbaz\n", $this->makeFieldType('text', "foo\nbar\nbaz")->getValue());
298
        $this->assertSame("foo\nbar\nbaz\n", $this->makeFieldType('text', "foo\nbar\nbaz\n")->getValue());
299
        $this->assertSame("foo\r\nbar\r\nbaz\n", $this->makeFieldType('text', "foo\r\nbar\r\nbaz\r\n")->getValue());
300
    }
301
302
    // UrlField tests
303
304
    public function testUrlFieldConstruct()
305
    {
306
        $field = $this->makeFieldType('url', 'https://example.com');
307
308
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
309
        $this->assertSame(PublicationFieldTypes::from('url'), $field->type);
310
    }
311
312
    public function testUrlFieldGetValue()
313
    {
314
        $this->assertSame('https://example.com', $this->makeFieldType('url', 'https://example.com')->getValue());
315
    }
316
317
    public function testUrlFieldToYaml()
318
    {
319
        $this->assertSame('\'https://example.com\'', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('url'), 'https://example.com')));
320
    }
321
322
    public function testUrlFieldWithInvalidInput()
323
    {
324
        $this->expectException(InvalidArgumentException::class);
325
        $this->expectExceptionMessage('UrlField: Unable to parse invalid url value \'foo\'');
326
        new PublicationFieldValue(PublicationFieldTypes::from('url'), 'foo');
327
    }
328
329
    // MediaField tests
330
331
    public function testMediaFieldConstruct()
332
    {
333
        $field = $this->makeFieldType('media', 'foo');
334
335
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
336
        $this->assertSame(PublicationFieldTypes::Media, $field->type);
337
    }
338
339
    public function testMediaFieldGetValue()
340
    {
341
        $this->assertSame('foo', $this->makeFieldType('media', 'foo')->getValue());
342
    }
343
344
    public function testMediaFieldToYaml()
345
    {
346
        $this->assertSame('foo', $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('media'), 'foo')));
347
    }
348
349
    // TagField tests
350
351
    public function testTagFieldConstruct()
352
    {
353
        $field = $this->makeFieldType('tag', 'foo');
354
355
        $this->assertInstanceOf(PublicationFieldValue::class, $field);
356
        $this->assertSame(PublicationFieldTypes::Tag, $field->type);
357
    }
358
359
    public function testTagFieldGetValue()
360
    {
361
        $this->assertSame(['foo'], $this->makeFieldType('tag', 'foo')->getValue());
362
    }
363
364
    public function testTagFieldToYaml()
365
    {
366
        $this->assertSame("- foo\n", $this->getYaml(new PublicationFieldValue(PublicationFieldTypes::from('tag'), 'foo')));
367
    }
368
369
    public function testTagFieldWithArrayInput()
370
    {
371
        $this->assertSame(['foo'], $this->makeFieldType('tag', ['foo'])->getValue());
372
    }
373
374
    public function testTagFieldParsingOptions()
375
    {
376
        $this->assertSame(['foo'], $this->makeFieldType('tag', 'foo')->getValue());
377
        $this->assertSame(['true'], $this->makeFieldType('tag', 'true')->getValue());
378
        $this->assertSame(['false'], $this->makeFieldType('tag', 'false')->getValue());
379
        $this->assertSame(['null'], $this->makeFieldType('tag', 'null')->getValue());
380
        $this->assertSame(['0'], $this->makeFieldType('tag', '0')->getValue());
381
        $this->assertSame(['1'], $this->makeFieldType('tag', '1')->getValue());
382
        $this->assertSame(['10.5'], $this->makeFieldType('tag', '10.5')->getValue());
383
        $this->assertSame(['-10'], $this->makeFieldType('tag', '-10')->getValue());
384
    }
385
386
    // Additional tests
387
388
    public function testDefaultValidationRules()
389
    {
390
        $expected = [
391
            'string' => ['string'],
392
            'datetime' => ['date'],
393
            'boolean' => ['boolean'],
394
            'integer' => ['integer'],
395
            'float' => ['numeric'],
396
            'media' => ['string'],
397
            'array' => ['array'],
398
            'text' => ['string'],
399
            'url' => ['url'],
400
            'tag' => [],
401
        ];
402
403
        foreach ($expected as $type => $rules) {
404
            $this->assertSame($rules, PublicationFieldTypes::from($type)->rules());
405
        }
406
    }
407
408
    // Testing helper methods
409
410
    protected function getYaml(PublicationFieldValue $field): string
411
    {
412
        return Yaml::dump($field->getValue());
413
    }
414
415
    protected function makeFieldType(string $type, string|array $value): PublicationFieldValue
416
    {
417
        return new PublicationFieldValue(PublicationFieldTypes::from($type), $value);
418
    }
419
}
420