Passed
Pull Request — master (#15)
by mon
01:47
created

TypeTest::testGetDescription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 0
dl 0
loc 15
rs 9.8666
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;one="test";two="three"' => [
263
                'text/xml;one="test";two="three"',
264
                [
265
                  'text/xml',
266
                  'text/xml; one="test"; two="three"',
267
                  'text/xml; one="test"; two="three"',
268
                ],
269
                ['text', null],
270
                ['xml', null],
271
                true,
272
                [
273
                  'one' => ['test', null],
274
                  'two' => ['three', null],
275
                ],
276
            ],
277
            'text/xml; this="is"; a="parameter" (with a comment)' => [
278
                'text/xml; this="is"; a="parameter" (with a comment)',
279
                [
280
                  'text/xml',
281
                  'text/xml; this="is"; a="parameter"',
282
                  'text/xml; this="is"; a="parameter" (with a comment)',
283
                ],
284
                ['text', null],
285
                ['xml', null],
286
                true,
287
                [
288
                  'this' => ['is', null],
289
                  'a' => ['parameter', 'with a comment'],
290
                ],
291
            ],
292
            // Various edge cases.
293
            'text/plain; charset="utf-8" (UTF/8)' => [
294
                'text/plain; charset="utf-8" (UTF/8)',
295
                [
296
                  'text/plain',
297
                  'text/plain; charset="utf-8"',
298
                  'text/plain; charset="utf-8" (UTF/8)',
299
                ],
300
                ['text', null],
301
                ['plain', null],
302
                true,
303
                [
304
                  'charset' => ['utf-8', 'UTF/8'],
305
                ],
306
            ],
307
            'appf/xml; a=b; b="parameter" (with; a comment)   ;c=d;  e=f (;) ;   g=h   ' => [
308
                'appf/xml; a=b; b="parameter" (with; a comment)   ;c=d;  e=f (;) ;   g=h   ',
309
                [
310
                  'appf/xml',
311
                  'appf/xml; a="b"; b="parameter"; c="d"; e="f"; g="h"',
312
                  'appf/xml; a="b"; b="parameter" (with; a comment); c="d"; e="f" (;); g="h"',
313
                ],
314
                ['appf', null],
315
                ['xml', null],
316
                true,
317
                [
318
                  'a' => ['b', null],
319
                  'b' => ['parameter', 'with; a comment'],
320
                  'c' => ['d', null],
321
                  'e' => ['f', ';'],
322
                  'g' => ['h', null],
323
                ],
324
            ],
325
            'text/(abc)def(ghi)' => [
326
                'text/(abc)def(ghi)',
327
                [
328
                  'text/def',
329
                  'text/def',
330
                  'text/def (abc ghi)',
331
                ],
332
                ['text', null],
333
                ['def', 'abc ghi'],
334
                false,
335
                [],
336
            ],
337
            'text/(abc)def' => [
338
                'text/(abc)def',
339
                [
340
                  'text/def',
341
                  'text/def',
342
                  'text/def (abc)',
343
                ],
344
                ['text', null],
345
                ['def', 'abc'],
346
                false,
347
                [],
348
            ],
349
            'text/def(ghi)' => [
350
                'text/def(ghi)',
351
                [
352
                  'text/def',
353
                  'text/def',
354
                  'text/def (ghi)',
355
                ],
356
                ['text', null],
357
                ['def', 'ghi'],
358
                false,
359
                [],
360
            ],
361
            'text/plain;a=(\)abc)def(\()' => [
362
                'text/plain;a=(\)abc)def(\()',
363
                [
364
                  'text/plain',
365
                  'text/plain; a="def"',
366
                  'text/plain; a="def" (\)abc \()',
367
                ],
368
                ['text', null],
369
                ['plain', null],
370
                true,
371
                [
372
                  'a' => ['def', '\)abc \('],
373
                ],
374
            ],
375
            'text/plain;a=\\foo(abc)' => [
376
                'text/plain;a=\\foo(abc)',
377
                [
378
                  'text/plain',
379
                  'text/plain; a="foo"',
380
                  'text/plain; a="foo" (abc)',
381
                ],
382
                ['text', null],
383
                ['plain', null],
384
                true,
385
                [
386
                  'a' => ['foo', 'abc'],
387
                ],
388
            ],
389
            'text/plain;a=(a"bc\)def")def' => [
390
                'text/plain;a=(a"bc\)def")def',
391
                [
392
                  'text/plain',
393
                  'text/plain; a="def"',
394
                  'text/plain; a="def" (a"bc\)def")',
395
                ],
396
                ['text', null],
397
                ['plain', null],
398
                true,
399
                [
400
                  'a' => ['def', 'a"bc\)def"'],
401
                ],
402
            ],
403
            'text/plain;a="(abc)def"' => [
404
                'text/plain;a="(abc)def"',
405
                [
406
                  'text/plain',
407
                  'text/plain; a="(abc)def"',
408
                  'text/plain; a="(abc)def"',
409
                ],
410
                ['text', null],
411
                ['plain', null],
412
                true,
413
                [
414
                  'a' => ['(abc)def', null],
415
                ],
416
            ],
417
        ];
418
    }
419
420
    /**
421
     * @dataProvider parseProvider
422
     */
423
    public function testParse($type, array $expectedToString, array $expectedMedia, array $expectedSubType, $expectedHasParameters, array $expectedParameters)
424
    {
425
        $mt = new Type($type);
426
        $this->assertSame($expectedMedia[0], $mt->getMedia());
427
        $this->assertSame($expectedMedia[1], $mt->getMediaComment());
428
        $this->assertSame($expectedSubType[0], $mt->getSubType());
429
        $this->assertSame($expectedSubType[1], $mt->getSubTypeComment());
430
        $this->assertSame($expectedHasParameters, $mt->hasParameters());
431
        $this->assertSame(count($expectedParameters), count($mt->getParameters()));
432
        foreach ($expectedParameters as $name => $param) {
433
            $this->assertTrue(isset($mt->getParameters()[$name]));
434
            $this->assertInstanceOf('FileEye\MimeMap\TypeParameter', $mt->getParameter($name));
435
            $this->assertSame($name, $mt->getParameter($name)->getName());
436
            $this->assertSame($param[0], $mt->getParameter($name)->getValue());
437
            $this->assertSame($param[1], $mt->getParameter($name)->getComment());
438
        }
439
        $this->assertSame($expectedToString[0], $mt->toString(Type::SHORT_TEXT));
440
        $this->assertSame($expectedToString[1], $mt->toString(Type::FULL_TEXT));
441
        $this->assertSame($expectedToString[2], $mt->toString(Type::FULL_TEXT_WITH_COMMENTS));
442
    }
443
444
    /**
445
     * Data provider for testParseMalformed.
446
     */
447
    public function parseMalformedProvider()
448
    {
449
        return [
450
            'null' => [null],
451
            'empty string' => [''],
452
            'n' => ['n'],
453
            'no media' => ['/n'],
454
            'no sub type' => ['n/'],
455
            'no comment closing bracket a' => ['image (open ()/*'],
456
            'no comment closing bracket b' => ['image / * (open (())'],
457
        ];
458
    }
459
460
    /**
461
     * @dataProvider parseMalformedProvider
462
     * @expectedException \FileEye\MimeMap\MalformedTypeException
463
     */
464
    public function testParseMalformed($type)
465
    {
466
        new Type($type);
467
    }
468
469
    public function testParseAgain()
470
    {
471
        $mt = new Type('application/ogg;description=Hello there!;asd=fgh');
472
        $this->assertSame(2, count($mt->getParameters()));
473
474
        $mt = new Type('text/plain;hello=there!');
475
        $this->assertSame(1, count($mt->getParameters()));
476
    }
477
478
    public function testGetDescription()
479
    {
480
        $this->assertNull((new Type('*/*'))->getDescription());
481
        $this->assertNull((new Type('image/*'))->getDescription());
482
        $this->assertNull((new Type('application/java*'))->getDescription());
483
        $this->assertNull((new Type('application/x-t3vm-image'))->getDescription());
484
        $this->assertSame('HTML document', (new Type('text/html'))->getDescription());
485
        $this->assertSame('HTML document, HTML: HyperText Markup Language', (new Type('text/html'))->getDescription(true));
486
487
        $this->assertSame('GPX geographic data', (new Type('application/gpx+xml'))->getDescription());
488
        $this->assertSame('GPX geographic data, GPX: GPS Exchange Format', (new Type('application/gpx+xml'))->getDescription(true));
489
        $this->assertSame('GPX geographic data', (new Type('application/gpx'))->getDescription());
490
        $this->assertSame('GPX geographic data, GPX: GPS Exchange Format', (new Type('application/gpx'))->getDescription(true));
491
        $this->assertSame('GPX geographic data', (new Type('application/x-gpx'))->getDescription());
492
        $this->assertSame('GPX geographic data, GPX: GPS Exchange Format', (new Type('application/x-gpx'))->getDescription(true));
493
    }
494
495
    public function testSetComment()
496
    {
497
        $type = new Type('text/x-test');
498
        $type->setMediaComment('media comment');
499
        $this->assertSame('text (media comment)/x-test', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
500
        $type->setSubTypeComment('subtype comment');
501
        $this->assertSame('text (media comment)/x-test (subtype comment)', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
502
        $type->setMediaComment(null);
503
        $this->assertSame('text/x-test (subtype comment)', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
504
        $type->setSubTypeComment(null);
505
        $this->assertSame('text/x-test', $type->toString(Type::FULL_TEXT_WITH_COMMENTS));
506
    }
507
508
    public function testIsExperimental()
509
    {
510
        $this->assertTrue((new Type('text/x-test'))->isExperimental());
511
        $this->assertTrue((new Type('image/X-test'))->isExperimental());
512
        $this->assertFalse((new Type('text/plain'))->isExperimental());
513
    }
514
515
    public function testIsVendor()
516
    {
517
        $this->assertTrue((new Type('application/vnd.openoffice'))->isVendor());
518
        $this->assertFalse((new Type('application/vendor.openoffice'))->isVendor());
519
        $this->assertFalse((new Type('vnd/fsck'))->isVendor());
520
    }
521
522
    public function testIsWildcard()
523
    {
524
        $this->assertTrue((new Type('*/*'))->isWildcard());
525
        $this->assertTrue((new Type('image/*'))->isWildcard());
526
        $this->assertFalse((new Type('text/plain'))->isWildcard());
527
528
        $this->assertTrue((new Type('application/java*'))->isWildcard());
529
        $this->assertTrue((new Type('application/java-*'))->isWildcard());
530
    }
531
532
    public function testIsAlias()
533
    {
534
        $this->assertFalse((new Type('*/*'))->isAlias());
535
        $this->assertFalse((new Type('image/*'))->isAlias());
536
        $this->assertFalse((new Type('text/plain'))->isAlias());
537
        $this->assertFalse((new Type('application/java*'))->isAlias());
538
        $this->assertTrue((new Type('text/x-markdown'))->isAlias());
539
    }
540
541
    public function testWildcardMatch()
542
    {
543
        $this->assertTrue((new Type('image/png'))->wildcardMatch('*/*'));
544
        $this->assertTrue((new Type('image/png'))->wildcardMatch('image/*'));
545
        $this->assertFalse((new Type('text/plain'))->wildcardMatch('image/*'));
546
        $this->assertFalse((new Type('image/png'))->wildcardMatch('image/foo'));
547
548
        $this->assertTrue((new Type('application/javascript'))->wildcardMatch('application/java*'));
549
        $this->assertTrue((new Type('application/java-serialized-object'))->wildcardMatch('application/java-*'));
550
        $this->assertFalse((new Type('application/javascript'))->wildcardMatch('application/java-*'));
551
    }
552
553
    public function testAddParameter()
554
    {
555
        $mt = new Type('image/png; foo=bar');
556
        $mt->addParameter('baz', 'val', 'this is a comment');
557
        $res = $mt->toString(Type::FULL_TEXT_WITH_COMMENTS);
558
        $this->assertContains('foo=', $res);
559
        $this->assertContains('bar', $res);
560
        $this->assertContains('baz=', $res);
561
        $this->assertContains('val', $res);
562
        $this->assertContains('(this is a comment)', $res);
563
        $this->assertSame('image/png; foo="bar"; baz="val" (this is a comment)', $res);
564
    }
565
566
    public function testRemoveParameter()
567
    {
568
        $mt = new Type('image/png; foo=bar;baz=val(this is a comment)');
569
        $mt->removeParameter('foo');
570
        $res = $mt->toString(Type::FULL_TEXT_WITH_COMMENTS);
571
        $this->assertNotContains('foo=', $res);
572
        $this->assertNotContains('bar', $res);
573
        $this->assertContains('baz=', $res);
574
        $this->assertSame('image/png; baz="val" (this is a comment)', $res);
575
    }
576
577
    public function testGetAliases()
578
    {
579
        $this->assertSame(['image/x-wmf', 'image/x-win-metafile', 'application/x-wmf', 'application/wmf'], (new Type('image/wmf'))->getAliases());
580
        $this->assertSame([], (new Type('foo/bar'))->getAliases(false));
581
        $this->assertSame([], (new Type('image/x-wmf'))->getAliases(false));
582
    }
583
584
    /**
585
     * @expectedException \FileEye\MimeMap\MappingException
586
     * @expectedExceptionMessage Cannot get aliases for 'image/x-wmf', it is an alias itself
587
     */
588
    public function testGetAliasesOnAliasStrict()
589
    {
590
        $this->assertSame([], (new Type('image/x-wmf'))->getAliases());
591
    }
592
593
    /**
594
     * @expectedException \FileEye\MimeMap\MappingException
595
     * @expectedExceptionMessage No MIME type found for foo/bar in map
596
     */
597
    public function testGetAliasesOnMissingTypeStrict()
598
    {
599
        $this->assertSame([], (new Type('foo/bar'))->getAliases());
600
    }
601
602
    public function testGetExtensions()
603
    {
604
        $this->assertEquals(['atom'], (new Type('application/atom+xml'))->getExtensions());
605
        $this->assertEquals(['jar', 'ser', 'class', 'js', 'jsm', 'mjs'], (new Type('application/java*'))->getExtensions());
606
        $this->assertEquals(['jar', 'ser', 'class'], (new Type('application/java-*'))->getExtensions());
607
        $this->assertEquals([], (new Type('application/a000'))->getExtensions(false));
608
        $this->assertEquals([], (new Type('application/a000-*'))->getExtensions(false));
609
610
        $this->assertSame(['smi', 'smil', 'sml', 'kino'], (new Type('application/smil+xml'))->getExtensions());
611
        $this->assertSame(['smi', 'smil', 'sml', 'kino'], (new Type('application/smil'))->getExtensions());
612
    }
613
614
    /**
615
     * @expectedException \FileEye\MimeMap\MappingException
616
     */
617
    public function testGetExtensionsFail()
618
    {
619
        $this->assertEquals([], (new Type('application/a000'))->getExtensions());
620
    }
621
622
    public function testGetDefaultExtension()
623
    {
624
        $this->assertEquals('atom', (new Type('application/atom+xml'))->getDefaultExtension());
625
        $this->assertEquals('csv', (new Type('text/csv'))->getDefaultExtension());
626
627
        $this->assertSame('smi', (new Type('application/smil+xml'))->getDefaultExtension());
628
        $this->assertSame('smi', (new Type('application/smil'))->getDefaultExtension());
629
    }
630
631
    /**
632
     * Data provider for testGetDefaultExtensionFail.
633
     */
634
    public function getDefaultExtensionFailProvider()
635
    {
636
        return [
637
            ['*/*'],
638
            ['n/n'],
639
            ['image/*'],
640
            ['application/java*'],
641
        ];
642
    }
643
644
    /**
645
     * @expectedException \FileEye\MimeMap\MappingException
646
     * @dataProvider getDefaultExtensionFailProvider
647
     */
648
    public function testGetDefaultExtensionFail($type)
649
    {
650
        $this->assertNull((new Type($type))->getDefaultExtension());
651
    }
652
}
653