Passed
Pull Request — master (#15)
by mon
03:05
created

TypeTest::testSetComment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 11
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace FileEye\MimeMap\test;
4
5
use FileEye\MimeMap\Type;
6
use PHPUnit\Framework\TestCase;
7
8
class TypeTest extends TestCase
9
{
10
    /**
11
     * Data provider for testParse.
12
     */
13
    public function parseProvider()
14
    {
15
        return [
16
            'application/ogg;description=Hello there!;asd=fgh' => [
17
                'application/ogg;description=Hello there!;asd=fgh',
18
                [
19
                  'application/ogg',
20
                  'application/ogg; description="Hello there!"; asd="fgh"',
21
                  'application/ogg; description="Hello there!"; asd="fgh"',
22
                ],
23
                ['application', null],
24
                ['ogg', null],
25
                true,
26
                [
27
                  'description' => ['Hello there!', null],
28
                  'asd' => ['fgh', null],
29
                ],
30
            ],
31
            'text/plain' => [
32
                'text/plain',
33
                [
34
                  'text/plain',
35
                  'text/plain',
36
                  'text/plain',
37
                ],
38
                ['text', null],
39
                ['plain', null],
40
                false,
41
                [],
42
            ],
43
            'text/plain;a=b' => [
44
                'text/plain;a=b',
45
                [
46
                  'text/plain',
47
                  'text/plain; a="b"',
48
                  'text/plain; a="b"',
49
                ],
50
                ['text', null],
51
                ['plain', null],
52
                true,
53
                [
54
                  'a' => ['b', null],
55
                ],
56
            ],
57
            'application/ogg' => [
58
                'application/ogg',
59
                [
60
                  'application/ogg',
61
                  'application/ogg',
62
                  'application/ogg',
63
                ],
64
                ['application', null],
65
                ['ogg', null],
66
                false,
67
                [],
68
            ],
69
            '*/*' => [
70
                '*/*',
71
                [
72
                  '*/*',
73
                  '*/*',
74
                  '*/*',
75
                ],
76
                ['*', null],
77
                ['*', null],
78
                false,
79
                [],
80
            ],
81
            'n/n' => [
82
                'n/n',
83
                [
84
                  'n/n',
85
                  'n/n',
86
                  'n/n',
87
                ],
88
                ['n', null],
89
                ['n', null],
90
                false,
91
                [],
92
            ],
93
            '(UTF-8 Plain Text) text / plain ; charset = utf-8' => [
94
                '(UTF-8 Plain Text) text / plain ; charset = utf-8',
95
                [
96
                  'text/plain',
97
                  'text/plain; charset="utf-8"',
98
                  'text (UTF-8 Plain Text)/plain; charset="utf-8"',
99
                ],
100
                ['text', 'UTF-8 Plain Text'],
101
                ['plain', null],
102
                true,
103
                [
104
                  'charset' => ['utf-8', null],
105
                ],
106
            ],
107
            'text (Text) / plain ; charset = utf-8' => [
108
                'text (Text) / plain ; charset = utf-8',
109
                [
110
                  'text/plain',
111
                  'text/plain; charset="utf-8"',
112
                  'text (Text)/plain; charset="utf-8"',
113
                ],
114
                ['text', 'Text'],
115
                ['plain', null],
116
                true,
117
                [
118
                  'charset' => ['utf-8', null],
119
                ],
120
            ],
121
            'text / (Plain) plain ; charset = utf-8' => [
122
                'text / (Plain) plain ; charset = utf-8',
123
                [
124
                  'text/plain',
125
                  'text/plain; charset="utf-8"',
126
                  'text/plain (Plain); charset="utf-8"',
127
                ],
128
                ['text', null],
129
                ['plain', 'Plain'],
130
                true,
131
                [
132
                  'charset' => ['utf-8', null],
133
                ],
134
            ],
135
            'text / plain (Plain Text) ; charset = utf-8' => [
136
                'text / plain (Plain Text) ; charset = utf-8',
137
                [
138
                  'text/plain',
139
                  'text/plain; charset="utf-8"',
140
                  'text/plain (Plain Text); charset="utf-8"',
141
                ],
142
                ['text', null],
143
                ['plain', 'Plain Text'],
144
                true,
145
                [
146
                  'charset' => ['utf-8', null],
147
                ],
148
            ],
149
            'text / plain ; (Charset=utf-8) charset = utf-8' => [
150
                'text / plain ; (Charset=utf-8) charset = utf-8',
151
                [
152
                  'text/plain',
153
                  'text/plain; charset="utf-8"',
154
                  'text/plain; charset="utf-8" (Charset=utf-8)',
155
                ],
156
                ['text', null],
157
                ['plain', null],
158
                true,
159
                [
160
                  'charset' => ['utf-8', 'Charset=utf-8'],
161
                ],
162
            ],
163
            'text / plain ; charset (Charset) = utf-8' => [
164
                'text / plain ; charset (Charset) = utf-8',
165
                [
166
                  'text/plain',
167
                  'text/plain; charset="utf-8"',
168
                  'text/plain; charset="utf-8" (Charset)',
169
                ],
170
                ['text', null],
171
                ['plain', null],
172
                true,
173
                [
174
                  'charset' => ['utf-8', 'Charset'],
175
                ],
176
            ],
177
            'text / plain ; charset = (UTF8) utf-8' => [
178
                'text / plain ; charset = (UTF8) utf-8',
179
                [
180
                  'text/plain',
181
                  'text/plain; charset="utf-8"',
182
                  'text/plain; charset="utf-8" (UTF8)',
183
                ],
184
                ['text', null],
185
                ['plain', null],
186
                true,
187
                [
188
                  'charset' => ['utf-8', 'UTF8'],
189
                ],
190
            ],
191
            'text / plain ; charset = utf-8 (UTF-8 Plain Text)' => [
192
                'text / plain ; charset = utf-8 (UTF-8 Plain Text)',
193
                [
194
                  'text/plain',
195
                  'text/plain; charset="utf-8"',
196
                  'text/plain; charset="utf-8" (UTF-8 Plain Text)',
197
                ],
198
                ['text', null],
199
                ['plain', null],
200
                true,
201
                [
202
                  'charset' => ['utf-8', 'UTF-8 Plain Text'],
203
                ],
204
            ],
205
            'application/x-foobar;description="bbgh(kdur"' => [
206
                'application/x-foobar;description="bbgh(kdur"',
207
                [
208
                  'application/x-foobar',
209
                  'application/x-foobar; description="bbgh(kdur"',
210
                  'application/x-foobar; description="bbgh(kdur"',
211
                ],
212
                ['application', null],
213
                ['x-foobar', null],
214
                true,
215
                [
216
                  'description' => ['bbgh(kdur', null],
217
                ],
218
            ],
219
            'application/x-foobar;description="a \"quoted string\""' => [
220
                'application/x-foobar;description="a \"quoted string\""',
221
                [
222
                  'application/x-foobar',
223
                  'application/x-foobar; description="a \"quoted string\""',
224
                  'application/x-foobar; description="a \"quoted string\""',
225
                ],
226
                ['application', null],
227
                ['x-foobar', null],
228
                true,
229
                [
230
                  'description' => ['a "quoted string"', null],
231
                ],
232
            ],
233
            'text/xml;description=test' => [
234
                'text/xml;description=test',
235
                [
236
                  'text/xml',
237
                  'text/xml; description="test"',
238
                  'text/xml; description="test"',
239
                ],
240
                ['text', null],
241
                ['xml', null],
242
                true,
243
                [
244
                  'description' => ['test', null],
245
                ],
246
            ],
247
            'text/xml;one=test;two=three' => [
248
                'text/xml;one=test;two=three',
249
                [
250
                  'text/xml',
251
                  'text/xml; one="test"; two="three"',
252
                  'text/xml; one="test"; two="three"',
253
                ],
254
                ['text', null],
255
                ['xml', null],
256
                true,
257
                [
258
                  'one' => ['test', null],
259
                  'two' => ['three', null],
260
                ],
261
            ],
262
            'text/xml; this="is"; a="parameter" (with a comment)' => [
263
                'text/xml; this="is"; a="parameter" (with a comment)',
264
                [
265
                  'text/xml',
266
                  'text/xml; this="is"; a="parameter"',
267
                  'text/xml; this="is"; a="parameter" (with a comment)',
268
                ],
269
                ['text', null],
270
                ['xml', null],
271
                true,
272
                [
273
                  'this' => ['is', null],
274
                  'a' => ['parameter', 'with a comment'],
275
                ],
276
            ],
277
            // Various edge cases.
278
            'text/plain; charset="utf-8" (UTF/8)' => [
279
                'text/plain; charset="utf-8" (UTF/8)',
280
                [
281
                  'text/plain',
282
                  'text/plain; charset="utf-8"',
283
                  'text/plain; charset="utf-8" (UTF/8)',
284
                ],
285
                ['text', null],
286
                ['plain', null],
287
                true,
288
                [
289
                  'charset' => ['utf-8', 'UTF/8'],
290
                ],
291
            ],
292
            'appf/xml; a=b; b="parameter" (with; a comment)   ;c=d;  e=f (;) ;   g=h   ' => [
293
                'appf/xml; a=b; b="parameter" (with; a comment)   ;c=d;  e=f (;) ;   g=h   ',
294
                [
295
                  'appf/xml',
296
                  'appf/xml; a="b"; b="parameter"; c="d"; e="f"; g="h"',
297
                  'appf/xml; a="b"; b="parameter" (with; a comment); c="d"; e="f" (;); g="h"',
298
                ],
299
                ['appf', null],
300
                ['xml', null],
301
                true,
302
                [
303
                  'a' => ['b', null],
304
                  'b' => ['parameter', 'with; a comment'],
305
                  'c' => ['d', null],
306
                  'e' => ['f', ';'],
307
                  'g' => ['h', null],
308
                ],
309
            ],
310
            'text/(abc)def(ghi)' => [
311
                'text/(abc)def(ghi)',
312
                [
313
                  'text/def',
314
                  'text/def',
315
                  'text/def (abc ghi)',
316
                ],
317
                ['text', null],
318
                ['def', 'abc ghi'],
319
                false,
320
                [],
321
            ],
322
            'text/(abc)def' => [
323
                'text/(abc)def',
324
                [
325
                  'text/def',
326
                  'text/def',
327
                  'text/def (abc)',
328
                ],
329
                ['text', null],
330
                ['def', 'abc'],
331
                false,
332
                [],
333
            ],
334
            'text/def(ghi)' => [
335
                'text/def(ghi)',
336
                [
337
                  'text/def',
338
                  'text/def',
339
                  'text/def (ghi)',
340
                ],
341
                ['text', null],
342
                ['def', 'ghi'],
343
                false,
344
                [],
345
            ],
346
            'text/plain;a=(\)abc)def(\()' => [
347
                'text/plain;a=(\)abc)def(\()',
348
                [
349
                  'text/plain',
350
                  'text/plain; a="def"',
351
                  'text/plain; a="def" (\)abc \()',
352
                ],
353
                ['text', null],
354
                ['plain', null],
355
                true,
356
                [
357
                  'a' => ['def', '\)abc \('],
358
                ],
359
            ],
360
            'text/plain;a=\\foo(abc)' => [
361
                'text/plain;a=\\foo(abc)',
362
                [
363
                  'text/plain',
364
                  'text/plain; a="foo"',
365
                  'text/plain; a="foo" (abc)',
366
                ],
367
                ['text', null],
368
                ['plain', null],
369
                true,
370
                [
371
                  'a' => ['foo', 'abc'],
372
                ],
373
            ],
374
            'text/plain;a=(a"bc\)def")def' => [
375
                'text/plain;a=(a"bc\)def")def',
376
                [
377
                  'text/plain',
378
                  'text/plain; a="def"',
379
                  'text/plain; a="def" (a"bc\)def")',
380
                ],
381
                ['text', null],
382
                ['plain', null],
383
                true,
384
                [
385
                  'a' => ['def', 'a"bc\)def"'],
386
                ],
387
            ],
388
            'text/plain;a="(abc)def"' => [
389
                'text/plain;a="(abc)def"',
390
                [
391
                  'text/plain',
392
                  'text/plain; a="(abc)def"',
393
                  'text/plain; a="(abc)def"',
394
                ],
395
                ['text', null],
396
                ['plain', null],
397
                true,
398
                [
399
                  'a' => ['(abc)def', null],
400
                ],
401
            ],
402
        ];
403
    }
404
405
    /**
406
     * @dataProvider parseProvider
407
     */
408
    public function testParse($type, array $expectedToString, array $expectedMedia, array $expectedSubType, $expectedHasParameters, array $expectedParameters)
409
    {
410
        $mt = new Type($type);
411
        $this->assertSame($expectedMedia[0], $mt->getMedia());
412
        $this->assertSame($expectedMedia[1], $mt->getMediaComment());
413
        $this->assertSame($expectedSubType[0], $mt->getSubType());
414
        $this->assertSame($expectedSubType[1], $mt->getSubTypeComment());
415
        $this->assertSame($expectedHasParameters, $mt->hasParameters());
416
        $this->assertSame(count($expectedParameters), count($mt->getParameters()));
417
        foreach ($expectedParameters as $name => $param) {
418
            $this->assertTrue(isset($mt->getParameters()[$name]));
419
            $this->assertInstanceOf('FileEye\MimeMap\TypeParameter', $mt->getParameter($name));
420
            $this->assertSame($name, $mt->getParameter($name)->getName());
421
            $this->assertSame($param[0], $mt->getParameter($name)->getValue());
422
            $this->assertSame($param[1], $mt->getParameter($name)->getComment());
423
        }
424
        $this->assertSame($expectedToString[0], $mt->toString(Type::SHORT_TEXT));
425
        $this->assertSame($expectedToString[1], $mt->toString(Type::FULL_TEXT));
426
        $this->assertSame($expectedToString[2], $mt->toString(Type::FULL_TEXT_WITH_COMMENTS));
427
    }
428
429
    /**
430
     * Data provider for testParseMalformed.
431
     */
432
    public function parseMalformedProvider()
433
    {
434
        return [
435
            'null' => [null],
436
            'empty string' => [''],
437
            'n' => ['n'],
438
            'no media' => ['/n'],
439
            'no sub type' => ['n/'],
440
            'no comment closing bracket a' => ['image (open ()/*'],
441
            'no comment closing bracket b' => ['image / * (open (())'],
442
        ];
443
    }
444
445
    /**
446
     * @dataProvider parseMalformedProvider
447
     * @expectedException \FileEye\MimeMap\MalformedTypeException
448
     */
449
    public function testParseMalformed($type)
450
    {
451
        new Type($type);
452
    }
453
454
    public function testParseAgain()
455
    {
456
        $mt = new Type('application/ogg;description=Hello there!;asd=fgh');
457
        $this->assertSame(2, count($mt->getParameters()));
458
459
        $mt = new Type('text/plain;hello=there!');
460
        $this->assertSame(1, count($mt->getParameters()));
461
    }
462
463
    public function testGetDescription()
464
    {
465
        $this->assertNull((new Type('*/*'))->getDescription());
466
        $this->assertNull((new Type('image/*'))->getDescription());
467
        $this->assertNull((new Type('application/java*'))->getDescription());
468
        $this->assertNull((new Type('application/x-t3vm-image'))->getDescription());
469
        $this->assertSame('HTML document', (new Type('text/html'))->getDescription());
470
        $this->assertSame('HTML document, HTML: HyperText Markup Language', (new Type('text/html'))->getDescription(true));
471
472
        $this->assertSame('GPX geographic data', (new Type('application/gpx+xml'))->getDescription());
473
        $this->assertSame('GPX geographic data, GPX: GPS Exchange Format', (new Type('application/gpx+xml'))->getDescription(true));
474
        $this->assertSame('GPX geographic data', (new Type('application/gpx'))->getDescription());
475
        $this->assertSame('GPX geographic data, GPX: GPS Exchange Format', (new Type('application/gpx'))->getDescription(true));
476
        $this->assertSame('GPX geographic data', (new Type('application/x-gpx'))->getDescription());
477
        $this->assertSame('GPX geographic data, GPX: GPS Exchange Format', (new Type('application/x-gpx'))->getDescription(true));
478
    }
479
480
    public function testSetComment()
481
    {
482
        $type = new Type('text/x-test');
483
        $type->setMediaComment('media comment');
484
        $this->assertSame('text (media comment)/x-test', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
485
        $type->setSubTypeComment('subtype comment');
486
        $this->assertSame('text (media comment)/x-test (subtype comment)', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
487
        $type->setMediaComment(null);
488
        $this->assertSame('text/x-test (subtype comment)', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
489
        $type->setSubTypeComment(null);
490
        $this->assertSame('text/x-test', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
491
    }
492
493
    public function testIsExperimental()
494
    {
495
        $this->assertTrue((new Type('text/x-test'))->isExperimental());
496
        $this->assertTrue((new Type('image/X-test'))->isExperimental());
497
        $this->assertFalse((new Type('text/plain'))->isExperimental());
498
    }
499
500
    public function testIsVendor()
501
    {
502
        $this->assertTrue((new Type('application/vnd.openoffice'))->isVendor());
503
        $this->assertFalse((new Type('application/vendor.openoffice'))->isVendor());
504
        $this->assertFalse((new Type('vnd/fsck'))->isVendor());
505
    }
506
507
    public function testIsWildcard()
508
    {
509
        $this->assertTrue((new Type('*/*'))->isWildcard());
510
        $this->assertTrue((new Type('image/*'))->isWildcard());
511
        $this->assertFalse((new Type('text/plain'))->isWildcard());
512
513
        $this->assertTrue((new Type('application/java*'))->isWildcard());
514
        $this->assertTrue((new Type('application/java-*'))->isWildcard());
515
    }
516
517
    public function testIsAlias()
518
    {
519
        $this->assertFalse((new Type('*/*'))->isAlias());
520
        $this->assertFalse((new Type('image/*'))->isAlias());
521
        $this->assertFalse((new Type('text/plain'))->isAlias());
522
        $this->assertFalse((new Type('application/java*'))->isAlias());
523
        $this->assertTrue((new Type('text/x-markdown'))->isAlias());
524
    }
525
526
    public function testWildcardMatch()
527
    {
528
        $this->assertTrue((new Type('image/png'))->wildcardMatch('*/*'));
529
        $this->assertTrue((new Type('image/png'))->wildcardMatch('image/*'));
530
        $this->assertFalse((new Type('text/plain'))->wildcardMatch('image/*'));
531
        $this->assertFalse((new Type('image/png'))->wildcardMatch('image/foo'));
532
533
        $this->assertTrue((new Type('application/javascript'))->wildcardMatch('application/java*'));
534
        $this->assertTrue((new Type('application/java-serialized-object'))->wildcardMatch('application/java-*'));
535
        $this->assertFalse((new Type('application/javascript'))->wildcardMatch('application/java-*'));
536
    }
537
538
    public function testAddParameter()
539
    {
540
        $mt = new Type('image/png; foo=bar');
541
        $mt->addParameter('baz', 'val', 'this is a comment');
542
        $res = $mt->toString(Type::FULL_TEXT_WITH_COMMENTS);
543
        $this->assertContains('foo=', $res);
544
        $this->assertContains('bar', $res);
545
        $this->assertContains('baz=', $res);
546
        $this->assertContains('val', $res);
547
        $this->assertContains('(this is a comment)', $res);
548
        $this->assertSame('image/png; foo="bar"; baz="val" (this is a comment)', $res);
549
    }
550
551
    public function testRemoveParameter()
552
    {
553
        $mt = new Type('image/png; foo=bar;baz=val(this is a comment)');
554
        $mt->removeParameter('foo');
555
        $res = $mt->toString(Type::FULL_TEXT_WITH_COMMENTS);
556
        $this->assertNotContains('foo=', $res);
557
        $this->assertNotContains('bar', $res);
558
        $this->assertContains('baz=', $res);
559
        $this->assertSame('image/png; baz="val" (this is a comment)', $res);
560
    }
561
562
    public function testGetExtensions()
563
    {
564
        $this->assertEquals(['atom'], (new Type('application/atom+xml'))->getExtensions());
565
        $this->assertEquals(['jar', 'ser', 'class', 'js', 'jsm', 'mjs'], (new Type('application/java*'))->getExtensions());
566
        $this->assertEquals(['jar', 'ser', 'class'], (new Type('application/java-*'))->getExtensions());
567
        $this->assertEquals([], (new Type('application/a000'))->getExtensions(false));
568
        $this->assertEquals([], (new Type('application/a000-*'))->getExtensions(false));
569
    }
570
571
    /**
572
     * @expectedException \FileEye\MimeMap\MappingException
573
     */
574
    public function testGetExtensionsFail()
575
    {
576
        $this->assertEquals([], (new Type('application/a000'))->getExtensions());
577
    }
578
579
    public function testGetDefaultExtension()
580
    {
581
        $this->assertEquals('atom', (new Type('application/atom+xml'))->getDefaultExtension());
582
        $this->assertEquals('csv', (new Type('text/csv'))->getDefaultExtension());
583
    }
584
585
    /**
586
     * Data provider for testGetDefaultExtensionFail.
587
     */
588
    public function getDefaultExtensionFailProvider()
589
    {
590
        return [
591
            ['*/*'],
592
            ['n/n'],
593
            ['image/*'],
594
            ['application/java*'],
595
        ];
596
    }
597
598
    /**
599
     * @expectedException \FileEye\MimeMap\MappingException
600
     * @dataProvider getDefaultExtensionFailProvider
601
     */
602
    public function testGetDefaultExtensionFail($type)
603
    {
604
        $this->assertNull((new Type($type))->getDefaultExtension());
605
    }
606
}
607