Skip to content

Commit

Permalink
feat: predicate methods for matching media type groups (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
neoncitylights authored Dec 11, 2023
1 parent 1a3e18e commit 0314190
Show file tree
Hide file tree
Showing 2 changed files with 336 additions and 0 deletions.
115 changes: 115 additions & 0 deletions src/MediaType.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,121 @@ public function getParameterValue( string $parameterName ): ?string {
return $this->parameters[$parameterName];
}

/**
* @see https://mimesniff.spec.whatwg.org/#image-mime-type
*/
public function isImage(): bool {
return $this->getType() === 'image';
}

/**
* https://mimesniff.spec.whatwg.org/#audio-or-video-mime-type
*/
public function isAudioOrVideo(): bool {
return $this->getType() === 'video'
|| $this->getType() === 'audio'
|| $this->getEssence() === 'application/ogg';
}

/**
* @see https://mimesniff.spec.whatwg.org/#font-mime-type
*/
public function isFont(): bool {
return $this->getType() === 'font'
|| ( $this->getType() === 'application'
&& \in_array( $this->getSubType(), [
'font-cff',
'font-off',
'font-sfnt',
'font-ttf',
'font-woff',
'vnd.ms-fontobject',
'vnd.ms-opentype ',
] ) );
}

/**
* @see https://mimesniff.spec.whatwg.org/#zip-based-mime-type
*/
public function isZipBased(): bool {
return \str_ends_with( $this->getSubType(), '+zip' )
|| $this->getEssence() === 'application/zip';
}

/**
* @see https://mimesniff.spec.whatwg.org/#archive-mime-type
*/
public function isArchive(): bool {
return $this->getType() === 'application'
&& \in_array( $this->getSubType(), [ 'x-rar-compressed', 'zip', 'x-gzip' ] );
}

/**
* @see https://mimesniff.spec.whatwg.org/#xml-mime-type
*/
public function isXml(): bool {
return \str_ends_with( $this->getSubType(), '+xml' )
|| $this->getEssence() === 'text/xml'
|| $this->getEssence() === 'application/xml';
}

/**
* @see https://mimesniff.spec.whatwg.org/#html-mime-type
*
* @return bool
*/
public function isHtml(): bool {
return $this->getEssence() === 'text/html';
}

/**
* @see https://mimesniff.spec.whatwg.org/#scriptable-mime-type
*/
public function isScriptable(): bool {
return $this->isXml()
|| $this->isHtml()
|| $this->getEssence() === 'application/pdf';
}

/**
* @see https://mimesniff.spec.whatwg.org/#javascript-mime-type
*/
public function isJavaScript(): bool {
return (
$this->getType() === 'application'
&& \in_array( $this->getSubType(), [
'ecmascript',
'javascript',
'x-ecmascript',
'x-javascript'
] ) )
|| (
$this->getType() === 'text'
&& \in_array( $this->getSubType(), [
'ecmascript',
'javascript',
'javascript1.0',
'javascript1.1',
'javascript1.2',
'javascript1.3',
'javascript1.4',
'javascript1.5',
'jscript',
'livescript',
'x-ecmascript',
'x-javascript'
] ) );
}

/**
* @see https://mimesniff.spec.whatwg.org/#json-mime-type
*/
public function isJson(): bool {
return \str_ends_with( $this->getSubType(), '+json' )
|| $this->getEssence() === 'application/json'
|| $this->getEssence() === 'text/json';
}

/**
* @see https://mimesniff.spec.whatwg.org/#serializing-a-mime-type
* @return string
Expand Down
221 changes: 221 additions & 0 deletions tests/MediaTypeMatchesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<?php

namespace Neoncitylights\MediaType\Tests;

use Neoncitylights\MediaType\MediaType;
use PHPUnit\Framework\TestCase;

/**
* @coversDefaultClass \Neoncitylights\MediaType\MediaType
*/
class MediaTypeMatchesTest extends TestCase {
/**
* @covers ::isImage
* @dataProvider provideIsImage
*/
public function testIsImage( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isImage()
);
}

/**
* @covers ::isAudioOrVideo
* @dataProvider provideIsAudioOrVideo
*/
public function testIsAudioOrVideo( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isAudioOrVideo()
);
}

/**
* @covers ::isFont
* @dataProvider provideIsFont
*/
public function testIsFont( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isFont()
);
}

/**
* @covers ::isZipBased
* @dataProvider provideIsZipBased
*/
public function testIsZipBased( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isZipBased()
);
}

/**
* @covers ::isArchive
* @dataProvider provideIsArchive
*/
public function testIsArchive( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isArchive()
);
}

/**
* @covers ::isXml
* @dataProvider provideIsXml
*/
public function testIsXml( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isXml()
);
}

/**
* @covers ::isHtml
* @dataProvider provideIsHtml
*/
public function testIsHtml( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isHtml()
);
}

/**
* @covers ::isScriptable
* @dataProvider provideIsXml
* @dataProvider provideIsHtml
* @dataProvider provideIsScriptable
*/
public function testIsScriptable( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isScriptable()
);
}

/**
* @covers ::isJavaScript
* @dataProvider provideIsJavaScript
*/
public function testIsJavaScript( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isJavaScript()
);
}

/**
* @covers ::isJson
* @dataProvider provideIsJson
*/
public function testIsJson( string $type, string $subType, bool $expected ): void {
$mediaType = new MediaType( $type, $subType, [] );
$this->assertEquals(
$expected,
$mediaType->isJson()
);
}

public function provideIsImage(): array {
return [
[ 'image', 'png', true ],
[ 'image', 'jpeg', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsAudioOrVideo(): array {
return [
[ 'audio', 'mpeg', true ],
[ 'video', 'mp4', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsFont(): array {
return [
[ 'font', 'woff', true ],
[ 'font', 'woff2', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsZipBased(): array {
return [
[ 'application', 'zip', true ],
[ 'application', 'automationml-amlx+zip', true ],
[ 'application', 'bacnet-xdd+zip', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsArchive(): array {
return [
[ 'application', 'zip', true ],
[ 'application', 'x-rar-compressed', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsXml(): array {
return [
[ 'application', 'xml', true ],
[ 'application', 'atom+xml', true ],
[ 'application', 'calendar+xml', true ],
[ 'application', 'xslt+xml', true ],
[ 'text', 'xml', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsHtml(): array {
return [
[ 'text', 'html', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsScriptable(): array {
return [
[ 'application', 'pdf', true ],
];
}

public function provideIsJavaScript(): array {
return [
[ 'application', 'ecmascript', true ],
[ 'application', 'javascript', true ],
[ 'application', 'x-javascript', true ],
[ 'application', 'x-ecmascript', true ],
[ 'text', 'javascript', true ],
[ 'text', 'ecmascript', true ],
[ 'text', 'x-javascript', true ],
[ 'text', 'x-ecmascript', true ],
[ 'text', 'plain', false ],
];
}

public function provideIsJson(): array {
return [
[ 'application', 'json', true ],
[ 'model', 'gltf+json', true ],
[ 'text', 'json', true ],
[ 'text', 'plain', false ],
];
}
}

0 comments on commit 0314190

Please sign in to comment.