Skip to content

Commit

Permalink
add EntrypointsLookup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lhapaipai committed Oct 30, 2023
1 parent 14b7d6a commit 321507a
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 47 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/.local
/.idea
/vendor
/.php-cs-fixer.cache
/.php-cs-fixer.cache
/.phpunit.result.cache
1 change: 0 additions & 1 deletion .phpunit.result.cache

This file was deleted.

40 changes: 20 additions & 20 deletions src/Asset/EntrypointRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ public function renderScripts(
$tags[] = $tagRenderer->createDynamicFallbackScript();
$tags[] = $tagRenderer->createSafariNoModuleScript();

foreach ($entrypointsLookup->getJSFiles('polyfills-legacy') as $fileWithHash) {
foreach ($entrypointsLookup->getJSFiles('polyfills-legacy') as $filePath) {
// normally only one js file
$tags[] = $tagRenderer->createScriptTag(
[
'nomodule' => true,
'crossorigin' => true,
'src' => $this->completeURL($fileWithHash['path'], $useAbsoluteUrl),
'src' => $this->completeURL($filePath, $useAbsoluteUrl),
'id' => 'vite-legacy-polyfill',
]
);
Expand All @@ -136,13 +136,13 @@ public function renderScripts(
}

/* normal js scripts */
foreach ($entrypointsLookup->getJSFiles($entryName) as $fileWithHash) {
foreach ($entrypointsLookup->getJSFiles($entryName) as $filePath) {
$tags[] = $tagRenderer->createScriptTag(
array_merge(
[
'type' => 'module',
'src' => $this->completeURL($fileWithHash['path'], $useAbsoluteUrl),
'integrity' => $fileWithHash['hash'],
'src' => $this->completeURL($filePath, $useAbsoluteUrl),
'integrity' => $entrypointsLookup->getFileHash($filePath),
],
$options['attr'] ?? []
)
Expand All @@ -157,11 +157,11 @@ public function renderScripts(
$tags[] = $tagRenderer->createScriptTag(
[
'nomodule' => true,
'data-src' => $this->completeURL($file['path'], $useAbsoluteUrl),
'data-src' => $this->completeURL($file, $useAbsoluteUrl),
'id' => $id,
'crossorigin' => true,
'class' => 'vite-legacy-entry',
'integrity' => $file['hash'],
'integrity' => $entrypointsLookup->getFileHash($file),
],
InlineContent::getSystemJSInlineCode($id)
);
Expand All @@ -188,33 +188,33 @@ public function renderLinks(

$tags = [];

foreach ($entrypointsLookup->getCSSFiles($entryName) as $fileWithHash) {
foreach ($entrypointsLookup->getCSSFiles($entryName) as $filePath) {
$tags[] = $tagRenderer->createLinkStylesheetTag(
$this->completeURL($fileWithHash['path'], $useAbsoluteUrl),
array_merge(['integrity' => $fileWithHash['hash']], $options['attr'] ?? [])
$this->completeURL($filePath, $useAbsoluteUrl),
array_merge(['integrity' => $entrypointsLookup->getFileHash($filePath)], $options['attr'] ?? [])
);
}

if ($isBuild) {
foreach ($entrypointsLookup->getJavascriptDependencies($entryName) as $fileWithHash) {
if (false === \in_array($fileWithHash['path'], $this->returnedPreloadedScripts, true)) {
foreach ($entrypointsLookup->getJavascriptDependencies($entryName) as $filePath) {
if (false === \in_array($filePath, $this->returnedPreloadedScripts, true)) {
$tags[] = $tagRenderer->createModulePreloadLinkTag(
$this->completeURL($fileWithHash['path'], $useAbsoluteUrl),
['integrity' => $fileWithHash['hash']]
$this->completeURL($filePath, $useAbsoluteUrl),
['integrity' => $entrypointsLookup->getFileHash($filePath)]
);
$this->returnedPreloadedScripts[] = $fileWithHash['path'];
$this->returnedPreloadedScripts[] = $filePath;
}
}
}

if ($isBuild && isset($options['preloadDynamicImports']) && true === $options['preloadDynamicImports']) {
foreach ($entrypointsLookup->getJavascriptDynamicDependencies($entryName) as $fileWithHash) {
if (false === \in_array($fileWithHash['path'], $this->returnedPreloadedScripts, true)) {
foreach ($entrypointsLookup->getJavascriptDynamicDependencies($entryName) as $filePath) {
if (false === \in_array($filePath, $this->returnedPreloadedScripts, true)) {
$tags[] = $tagRenderer->createModulePreloadLinkTag(
$this->completeURL($fileWithHash['path'], $useAbsoluteUrl),
['integrity' => $fileWithHash['hash']]
$this->completeURL($filePath, $useAbsoluteUrl),
['integrity' => $entrypointsLookup->getFileHash($filePath)]
);
$this->returnedPreloadedScripts[] = $fileWithHash['path'];
$this->returnedPreloadedScripts[] = $filePath;
}
}
}
Expand Down
21 changes: 17 additions & 4 deletions src/Asset/EntrypointsLookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Pentatrion\ViteBundle\Asset;

use Pentatrion\ViteBundle\Exception\EntrypointNotFoundException;

class EntrypointsLookup
{
private bool $throwOnMissingEntry;
Expand Down Expand Up @@ -35,8 +37,8 @@ private function getFileContent(): array
throw new \Exception('entrypoints.json not found at '.$this->fileInfos['entrypointsPath']);
}
$content = json_decode(file_get_contents($this->fileInfos['entrypointsPath']), true);
if (!isset($content['isBuild'], $content['entryPoints'], $content['viteServer'])) {
throw new \Exception($this->fileInfos['entrypointsPath'].' : isBuild, entryPoints or viteServer not exists');
if (!isset($content['entryPoints'], $content['viteServer'])) {
throw new \Exception($this->fileInfos['entrypointsPath'].' : entryPoints or viteServer not exists');
}

$this->fileInfos['content'] = $content;
Expand All @@ -45,6 +47,17 @@ private function getFileContent(): array
return $this->fileInfos['content'];
}

public function getFileHash(string $filePath): ?string
{
$infos = $this->getFileContent();

if (is_null($infos['metadatas']) || !array_key_exists($filePath, $infos['metadatas'])) {
return null;
}

return $infos['metadatas'][$filePath]['hash'];
}

public function isLegacyPluginEnabled(): bool
{
$infos = $this->getFileContent();
Expand All @@ -54,7 +67,7 @@ public function isLegacyPluginEnabled(): bool

public function isBuild(): bool
{
return $this->getFileContent()['isBuild'];
return false === $this->getFileContent()['viteServer'];
}

public function getViteServer()
Expand Down Expand Up @@ -119,7 +132,7 @@ private function throwIfEntrypointIsMissing(string $entryName): void
if (!array_key_exists($entryName, $this->getFileContent()['entryPoints'])) {
$keys = array_keys($this->getFileContent()['entryPoints']);
$entryPointKeys = join(', ', array_map(function ($key) { return "'$key'"; }, $keys));
throw new \Exception("Entry '$entryName' not present in the entrypoints file. Defined entrypoints are $entryPointKeys");
throw new EntrypointNotFoundException(sprintf("Entry '%s' not present in the entrypoints file. Defined entrypoints are %s", $entryName, $entryPointKeys));
}
}
}
7 changes: 7 additions & 0 deletions src/Exception/EntrypointNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Pentatrion\ViteBundle\Exception;

class EntrypointNotFoundException extends \InvalidArgumentException
{
}
206 changes: 206 additions & 0 deletions tests/Asset/EntrypointsLookupTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<?php

namespace Pentatrion\ViteBundle\Tests\Asset;

use Pentatrion\ViteBundle\Asset\EntrypointsLookup;
use Pentatrion\ViteBundle\Exception\EntrypointNotFoundException;
use PHPUnit\Framework\TestCase;

class EntrypointsLookupTest extends TestCase
{
private function getEntrypointsLookup($prefix)
{
return new EntrypointsLookup(
__DIR__.'/../fixtures/entrypoints',
['base' => '/'.$prefix.'/'],
true
);
}

public function testExtra()
{
$entrypointsLookupFileNotExists = $this->getEntrypointsLookup('not-found');
$entrypointsLookupBasicBuild = $this->getEntrypointsLookup('basic-build');

$this->assertEquals(
false,
$entrypointsLookupFileNotExists->hasFile()
);

$this->assertEquals(
true,
$entrypointsLookupBasicBuild->hasFile()
);
}

public function testExceptionOnMissingEntry()
{
$entrypointsLookupBasicBuild = $this->getEntrypointsLookup('basic-build');
$this->expectException(EntrypointNotFoundException::class);

$entrypointsLookupBasicBuild->getJSFiles('unknown-entrypoint');
}

public function testViteServer()
{
$entrypointsLookupBasicDev = $this->getEntrypointsLookup('basic-dev');
$entrypointsLookupBasicBuild = $this->getEntrypointsLookup('basic-build');

$this->assertEquals(
['origin' => 'http://127.0.0.1:5173', 'base' => '/build/'],
$entrypointsLookupBasicDev->getViteServer()
);

$this->assertEquals(
false,
$entrypointsLookupBasicBuild->getViteServer()
);

$this->assertEquals(
false,
$entrypointsLookupBasicDev->isBuild()
);

$this->assertEquals(
true,
$entrypointsLookupBasicBuild->isBuild()
);
}

public function devfilesProvider()
{
return [
['app', [
'assets' => [],
'css' => [],
'dynamic' => [],
'js' => ['http://127.0.0.1:5173/build/assets/app.js'],
'preload' => [],
]],
['theme', [
'assets' => [],
'css' => ['http://127.0.0.1:5173/build/assets/theme.scss'],
'dynamic' => [],
'js' => [],
'preload' => [],
]],
];
}

/**
* @dataProvider devfilesProvider
*/
public function testGetDevFiles($entryName, $files)
{
$entrypointsLookupBasicDev = $this->getEntrypointsLookup('basic-dev');

$this->assertEquals($files['css'], $entrypointsLookupBasicDev->getCSSFiles($entryName));
$this->assertEquals($files['dynamic'], $entrypointsLookupBasicDev->getJavascriptDynamicDependencies($entryName));
$this->assertEquals($files['js'], $entrypointsLookupBasicDev->getJSFiles($entryName));
$this->assertEquals($files['preload'], $entrypointsLookupBasicDev->getJavascriptDependencies($entryName));
}

public function buildfilesProvider()
{
return [
['app', [
'assets' => [],
'css' => [],
'dynamic' => [],
'js' => ['/build/assets/pageImports-53eb9fd1.js'],
'preload' => [],
]],
['theme', [
'assets' => [],
'css' => ['/build/assets/theme-62617963.css'],
'dynamic' => [],
'js' => [],
'preload' => [],
]],
['with-dep', [
'assets' => [],
'css' => ['/build/assets/main-76fa9059.css'],
'dynamic' => [],
'js' => ['/build/assets/main-e664f4b5.js'],
'preload' => ['/build/assets/vue-2d05229a.js', '/build/assets/react-2d05228c.js'],
]],
['with-async', [
'assets' => [],
'css' => ['/build/assets/main-76fa9059.css'],
'dynamic' => ['/build/assets/async-script-12324565.js'],
'js' => ['/build/assets/main-e664f4b5.js'],
'preload' => ['/build/assets/vue-2d05229a.js', '/build/assets/react-2d05228c.js'],
]],
];
}

/**
* @dataProvider buildfilesProvider
*/
public function testGetBuildFiles($entryName, $files)
{
$entrypointsLookupBasicBuild = $this->getEntrypointsLookup('basic-build');

$this->assertEquals($files['css'], $entrypointsLookupBasicBuild->getCSSFiles($entryName));
$this->assertEquals($files['dynamic'], $entrypointsLookupBasicBuild->getJavascriptDynamicDependencies($entryName));
$this->assertEquals($files['js'], $entrypointsLookupBasicBuild->getJSFiles($entryName));
$this->assertEquals($files['preload'], $entrypointsLookupBasicBuild->getJavascriptDependencies($entryName));
}

public function buildLegacyProvider()
{
return [
['app', [
'assets' => [],
'css' => [],
'dynamic' => [],
'js' => ['/build/assets/app-23802617.js'],
'preload' => [],
'legacy_js' => '/build/assets/app-legacy-59951366.js',
]],
['theme', [
'assets' => [],
'css' => ['/build/assets/theme-5cd46aed.css'],
'dynamic' => [],
'js' => [],
'preload' => [],
'legacy_js' => '/build/assets/theme-legacy-de9eb869.js',
]],
];
}

/**
* @dataProvider buildLegacyProvider
*/
public function testGetBuildLegacyFiles($entryName, $files)
{
$entrypointsLookupLegacyBuild = $this->getEntrypointsLookup('legacy-build');

$this->assertEquals($files['css'], $entrypointsLookupLegacyBuild->getCSSFiles($entryName));
$this->assertEquals($files['dynamic'], $entrypointsLookupLegacyBuild->getJavascriptDynamicDependencies($entryName));
$this->assertEquals($files['js'], $entrypointsLookupLegacyBuild->getJSFiles($entryName));
$this->assertEquals($files['preload'], $entrypointsLookupLegacyBuild->getJavascriptDependencies($entryName));
$this->assertEquals($files['legacy_js'], $entrypointsLookupLegacyBuild->getLegacyJSFile($entryName));
}

public function testHashOfFiles()
{
$entrypointsLookupBasicBuild = $this->getEntrypointsLookup('basic-build');
$this->assertEquals(
null,
$entrypointsLookupBasicBuild->getFileHash('/build/assets/pageImports-53eb9fd1.js')
);

$entrypointsLookupMetadataBuild = $this->getEntrypointsLookup('metadata-build');
$this->assertEquals(
'sha256-qABtt8+MbhDq8dts7DSJOnBqCO1QbV2S6zg24ylLkKY=',
$entrypointsLookupMetadataBuild->getFileHash('http://cdn.with-cdn.symfony-vite-dev.localhost/assets/pageVue-bda8ac3b.js')
);

$entrypointsLookupMetadataBuild = $this->getEntrypointsLookup('metadata-build');
$this->assertEquals(
null,
$entrypointsLookupMetadataBuild->getFileHash('/build-file-without-metadata.js')
);
}
}
2 changes: 1 addition & 1 deletion tests/Asset/TagRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public function linkPreloadProvider()
'/dependency.js',
[],
'<link rel="modulepreload" href="/dependency.js">',
'global link/script attribute are not added',
'global link/script attributes are not added',
],
];
}
Expand Down
Loading

0 comments on commit 321507a

Please sign in to comment.