diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d77b7520..b6e48a43 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,4 +46,4 @@ jobs: run: composer run-script lint - name: Execute the Composer test script - run: composer run-script lint + run: composer run-script test diff --git a/composer.json b/composer.json index a7e4810a..7e04fc80 100644 --- a/composer.json +++ b/composer.json @@ -58,12 +58,14 @@ "vlucas/phpdotenv": "^5.2" }, "require-dev": { + "brain/monkey": "^2.6", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "filp/whoops": "^2.9", - "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.4", + "pestphp/pest": "^1.0", "phpcompatibility/php-compatibility": "^9.3", - "phpunit/phpunit": "^8.5.8|^9.3.3", "roave/security-advisories": "dev-master", + "spatie/temporary-directory": "^1.3", "squizlabs/php_codesniffer": "^3.5" }, "suggest": { @@ -77,7 +79,7 @@ "scripts": { "lint": "phpcs", "lint:fix": "phpcbf", - "test": "phpunit", - "coverage": "phpunit --coverage-html coverage" + "test": "pest", + "coverage": "pest --coverage --coverage-html=coverage" } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 62960cd3..52fc223f 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -12,8 +12,8 @@ src/Illuminate/* - - + + acorn.php src diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5a52bfae..e3be750b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,7 @@ - - ./tests/Feature - ./tests/Unit + ./tests - - - ./ - - ./ - ./config - ./vendor - ./tests - - - + + + ./src + + + ./src/Illuminate/* + + diff --git a/scripts/download-latest-laravel.sh b/scripts/download-latest-laravel.sh new file mode 100755 index 00000000..4eef6797 --- /dev/null +++ b/scripts/download-latest-laravel.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -e + +# pro tip: maybe don't run this script. i mostly just hacked my way through this. this should definitely not be automated in any way. + +# thx u https://explainshell.com/ + +# YOINK! https://stackoverflow.com/a/4774063 +SCRIPTS_DIR="$(cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)" + +TEMP_DIR="${SCRIPTS_DIR}/.temp" + +LARAVEL_VERSION=$(curl --silent "https://api.github.com/repos/laravel/framework/tags" | jq -r '.[].name' | sort | tail -1) + +ARCHIVE_FILE="${LARAVEL_VERSION}.tar.gz" + +rm -rf "${TEMP_DIR}" +mkdir -p "${TEMP_DIR}" + +wget -q "https://github.com/laravel/framework/archive/${ARCHIVE_FILE}" -O "${TEMP_DIR}/${ARCHIVE_FILE}" + +ROOT_FOLDER=$(tar ztf "${TEMP_DIR}/${ARCHIVE_FILE}" | sort | head -1) + +pushd "${TEMP_DIR}" + +# only extracts the Foundation folder +tar xzf "${TEMP_DIR}/${ARCHIVE_FILE}" "${ROOT_FOLDER}src/Illuminate/Foundation" --strip-components=4 --one-top-level=Foundation + +popd + +# only syncs files that already exist in the destination +rsync -a --existing "${TEMP_DIR}/Foundation/" "${SCRIPTS_DIR}/../src/Illuminate/Foundation/" + +rm -rf "${TEMP_DIR}" diff --git a/src/Illuminate/Foundation/AliasLoader.php b/src/Illuminate/Foundation/AliasLoader.php old mode 100644 new mode 100755 diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php old mode 100644 new mode 100755 index ec1deae4..648cfc6b --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -33,7 +33,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '8.22.1'; + const VERSION = '8.26.1'; /** * The base path for the Laravel installation. @@ -112,6 +112,13 @@ class Application extends Container implements ApplicationContract, CachesConfig */ protected $databasePath; + /** + * The custom language file path defined by the developer. + * + * @var string + */ + protected $langPath; + /** * The custom storage path defined by the developer. * @@ -407,7 +414,30 @@ public function useDatabasePath($path) */ public function langPath() { - return $this->resourcePath().DIRECTORY_SEPARATOR.'lang'; + if ($this->langPath) { + return $this->langPath; + } + + if (is_dir($path = $this->resourcePath().DIRECTORY_SEPARATOR.'lang')) { + return $path; + } + + return $this->basePath().DIRECTORY_SEPARATOR.'lang'; + } + + /** + * Set the language file directory. + * + * @param string $path + * @return $this + */ + public function useLangPath($path) + { + $this->langPath = $path; + + $this->instance('path.lang', $path); + + return $this; } /** @@ -530,7 +560,7 @@ public function environment(...$environments) } /** - * Determine if application is in local environment. + * Determine if the application is in the local environment. * * @return bool */ @@ -540,7 +570,7 @@ public function isLocal() } /** - * Determine if application is in production environment. + * Determine if the application is in the production environment. * * @return bool */ @@ -1230,7 +1260,7 @@ public function setFallbackLocale($fallbackLocale) } /** - * Determine if application locale is the given locale. + * Determine if the application locale is the given locale. * * @param string $locale * @return bool diff --git a/src/Illuminate/Foundation/Exceptions/Handler.php b/src/Illuminate/Foundation/Exceptions/Handler.php index 761175d2..61a775a9 100644 --- a/src/Illuminate/Foundation/Exceptions/Handler.php +++ b/src/Illuminate/Foundation/Exceptions/Handler.php @@ -11,6 +11,8 @@ use Illuminate\Contracts\Debug\ExceptionHandler as ExceptionHandlerContract; use Illuminate\Contracts\Support\Responsable; use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Database\MultipleRecordsFoundException; +use Illuminate\Database\RecordsNotFoundException; use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; @@ -19,7 +21,6 @@ use Illuminate\Session\TokenMismatchException; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\View; use Illuminate\Support\Reflector; use Illuminate\Support\Traits\ReflectsClosures; use Illuminate\Support\ViewErrorBag; @@ -28,6 +29,13 @@ use Psr\Log\LoggerInterface; use Symfony\Component\Console\Application as ConsoleApplication; use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer; +use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; +use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirectResponse; +use Symfony\Component\HttpFoundation\Response as SymfonyResponse; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\HttpException; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Throwable; use Whoops\Handler\HandlerInterface; use Whoops\Run as Whoops; @@ -82,6 +90,8 @@ class Handler implements ExceptionHandlerContract HttpException::class, HttpResponseException::class, ModelNotFoundException::class, + MultipleRecordsFoundException::class, + RecordsNotFoundException::class, SuspiciousOperationException::class, TokenMismatchException::class, ValidationException::class, @@ -362,6 +372,8 @@ protected function prepareException(Throwable $e) $e = new HttpException(419, $e->getMessage(), $e); } elseif ($e instanceof SuspiciousOperationException) { $e = new NotFoundHttpException('Bad hostname provided.', $e); + } elseif ($e instanceof RecordsNotFoundException) { + $e = new NotFoundHttpException('Not found.', $e); } return $e; diff --git a/src/Illuminate/Foundation/Exceptions/ReportableHandler.php b/src/Illuminate/Foundation/Exceptions/ReportableHandler.php old mode 100755 new mode 100644 diff --git a/src/Illuminate/Foundation/ProviderRepository.php b/src/Illuminate/Foundation/ProviderRepository.php old mode 100644 new mode 100755 diff --git a/src/Roots/Acorn/Application.php b/src/Roots/Acorn/Application.php index 78f9d20e..037402e7 100644 --- a/src/Roots/Acorn/Application.php +++ b/src/Roots/Acorn/Application.php @@ -190,31 +190,6 @@ public function useConfigPath($path) return $this; } - /** - * Get the path to the language files. - * - * @return string - */ - public function langPath() - { - return $this->langPath ?: $this->resourcePath('lang'); - } - - /** - * Set the path to the language files. - * - * @param string $path - * @return $this - */ - public function useLangPath($path) - { - $this->langPath = $path; - - $this->instance('path.lang', $path); - - return $this; - } - /** * Get the path to the public / web directory. * @@ -286,7 +261,7 @@ protected function registerBaseServiceProviders() */ public function isDownForMaintenance() { - return is_file($this->storagePath() . '/framework/down') || is_file(ABSPATH . '/.maintenance'); + return is_file($this->storagePath() . '/framework/down') || (defined('ABSPATH') && is_file(constant('ABSPATH') . '/.maintenance')); } /** diff --git a/src/Roots/Acorn/Filesystem/Filesystem.php b/src/Roots/Acorn/Filesystem/Filesystem.php index 5bb7d014..c00a42e2 100644 --- a/src/Roots/Acorn/Filesystem/Filesystem.php +++ b/src/Roots/Acorn/Filesystem/Filesystem.php @@ -83,7 +83,7 @@ public function getRelativePath($basePath, $targetPath) $path = str_repeat('../', count($sourceDirs)) . implode('/', $targetDirs); return $path === '' || $path[0] === '/' - || ($colonPos = strpos($path, ':')) !== false && (($slashPos = strpos($path, '/') >= $colonPos) + || ($colonPos = strpos($path, ':')) !== false && ($colonPos < ($slashPos = strpos($path, '/')) || $slashPos === false) ? "./$path" : $path; } diff --git a/tests/Application/AliasLoaderTest.php b/tests/Application/AliasLoaderTest.php new file mode 100644 index 00000000..cf60f884 --- /dev/null +++ b/tests/Application/AliasLoaderTest.php @@ -0,0 +1,19 @@ +toBeFalse(); + expect(function_exists('asset'))->toBeFalse(); + expect(function_exists('config'))->toBeFalse(); + expect(function_exists('view'))->toBeFalse(); + + $loader->register(); + + expect(function_exists('app'))->toBeTrue(); + expect(function_exists('asset'))->toBeTrue(); + expect(function_exists('config'))->toBeTrue(); + expect(function_exists('view'))->toBeTrue(); +}); diff --git a/tests/Application/ApplicationTest.php b/tests/Application/ApplicationTest.php new file mode 100644 index 00000000..202d169f --- /dev/null +++ b/tests/Application/ApplicationTest.php @@ -0,0 +1,142 @@ +toBeInstanceOf(LazyLoader::class); +}); + +it('instantiates with custom paths', function () { + $app = new Application(null, [ + 'app' => $this->fixture('use_paths/app'), + 'config' => $this->fixture('use_paths/config'), + ]); + + expect($app['path'])->toBe($this->fixture('use_paths/app')); + expect($app['path.config'])->toBe($this->fixture('use_paths/config')); +}); + +it('rejects invalid custom path types', function () { + $app = new Application(); + + $app->usePaths([ + 'app' => $this->fixture('use_paths/app'), + 'not_a_valid_path_type' => $this->fixture('use_paths/resources/lang'), + ]); +})->throws(Exception::class); + +it('rejects invalid custom paths', function () { + $app = new Application(); + + $app->usePaths([ + 'app' => $this->fixture('use_paths/app'), + 'lang' => __DIR__ . '/this/does/not/exist', + ]); +})->throws(Exception::class); + +it('accepts an array of custom paths', function () { + $app = new Application(temp('base_path')); + + expect($app['path'])->not->toBe($this->fixture('use_paths/app')); + expect($app['path.lang'])->not->toBe($this->fixture('use_paths/resources/lang')); + expect($app['path.config'])->not->toBe($this->fixture('use_paths/config')); + expect($app['path.public'])->not->toBe($this->fixture('use_paths/public')); + expect($app['path.storage'])->not->toBe($this->fixture('use_paths/storage')); + expect($app['path.database'])->not->toBe($this->fixture('use_paths/database')); + expect($app['path.resources'])->not->toBe($this->fixture('use_paths/resources')); + expect($app['path.bootstrap'])->not->toBe($this->fixture('use_paths/bootstrap')); + + $app->usePaths([ + 'app' => $this->fixture('use_paths/app'), + 'lang' => $this->fixture('use_paths/resources/lang'), + 'config' => $this->fixture('use_paths/config'), + 'public' => $this->fixture('use_paths/public'), + 'storage' => $this->fixture('use_paths/storage'), + 'database' => $this->fixture('use_paths/database'), + 'resources' => $this->fixture('use_paths/resources'), + 'bootstrap' => $this->fixture('use_paths/bootstrap'), + ]); + + expect($app['path'])->toBe($this->fixture('use_paths/app')); + expect($app['path.lang'])->toBe($this->fixture('use_paths/resources/lang')); + expect($app['path.config'])->toBe($this->fixture('use_paths/config')); + expect($app['path.public'])->toBe($this->fixture('use_paths/public')); + expect($app['path.storage'])->toBe($this->fixture('use_paths/storage')); + expect($app['path.database'])->toBe($this->fixture('use_paths/database')); + expect($app['path.resources'])->toBe($this->fixture('use_paths/resources')); + expect($app['path.bootstrap'])->toBe($this->fixture('use_paths/bootstrap')); +}); + +it('allows specific paths to be changed', function () { + $app = new Application(temp('not_a_path')); + + expect($app['path.bootstrap'])->not->toBe($this->fixture('use_paths/bootstrap')); + $app->useBootstrapPath($this->fixture('use_paths/bootstrap')); + expect($app['path.bootstrap'])->toBe($this->fixture('use_paths/bootstrap')); + + expect($app['path.config'])->not->toBe($this->fixture('use_paths/config')); + $app->useConfigPath($this->fixture('use_paths/config')); + expect($app['path.config'])->toBe($this->fixture('use_paths/config')); + + expect($app['path.public'])->not->toBe($this->fixture('use_paths/public')); + $app->usePublicPath($this->fixture('use_paths/public')); + expect($app['path.public'])->toBe($this->fixture('use_paths/public')); + + expect($app['path.resources'])->not->toBe($this->fixture('use_paths/resource')); + $app->useResourcePath($this->fixture('use_paths/resource')); + expect($app['path.resources'])->toBe($this->fixture('use_paths/resource')); +}); + +it('goes down for maintenance when acorn maintenance file exists', function () { + $app = new Application(); + + expect($app->isDownForMaintenance())->toBeFalse(); + + $app->useStoragePath($this->fixture('is_down_for_maintenance/storage')); + + expect($app->isDownForMaintenance())->toBeTrue(); +}); + +it('goes down for maintenance when wordpress maintenance file exists', function () { + $app = new Application(); + + expect($app->isDownForMaintenance())->toBeFalse(); + + touch(temp(('wp/.maintenance'))); + + expect($app->isDownForMaintenance())->toBeTrue(); +}); + +it('throws an exception if app namespace cannot be determined', function () { + (new Application($this->fixture('get_namespace/a_bedrock_site/a_random_library')))->getNamespace(); +})->throws(RuntimeException::class); + +it('determines namespace based on app composer.json', function () { + $app = new Application($this->fixture('get_namespace/a_sage_theme')); + + expect($app->getNamespace())->toBe('Sage\\'); +}); + +it('determines namespace based on app ancestor composer.json', function () { + $app = new Application($this->fixture('get_namespace/a_bedrock_site/a_sage_theme')); + + expect($app->getNamespace())->toBe('Bedrock\\Sage\\'); +}); + +it('allows the app namespace to changed arbitrarily', function () { + $app = new Application($this->fixture('get_namespace/a_sage_theme')); + + expect($app->getNamespace())->not->toBe('App\\'); + + $app->useNamespace('App'); + + expect($app->getNamespace())->toBe('App\\'); +}); diff --git a/tests/Application/__fixtures__/get_namespace/a_bedrock_site/a_random_library/composer.json b/tests/Application/__fixtures__/get_namespace/a_bedrock_site/a_random_library/composer.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/Application/__fixtures__/get_namespace/a_bedrock_site/a_random_library/composer.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/Application/__fixtures__/get_namespace/a_bedrock_site/a_sage_theme/app/.gitignore b/tests/Application/__fixtures__/get_namespace/a_bedrock_site/a_sage_theme/app/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/get_namespace/a_bedrock_site/a_sage_theme/app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/get_namespace/a_bedrock_site/composer.json b/tests/Application/__fixtures__/get_namespace/a_bedrock_site/composer.json new file mode 100644 index 00000000..7400d224 --- /dev/null +++ b/tests/Application/__fixtures__/get_namespace/a_bedrock_site/composer.json @@ -0,0 +1,7 @@ +{ + "autoload": { + "psr-4": { + "Bedrock\\Sage\\": "a_sage_theme/app/" + } + } +} \ No newline at end of file diff --git a/tests/Application/__fixtures__/get_namespace/a_sage_theme/app/.gitignore b/tests/Application/__fixtures__/get_namespace/a_sage_theme/app/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/get_namespace/a_sage_theme/app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/get_namespace/a_sage_theme/composer.json b/tests/Application/__fixtures__/get_namespace/a_sage_theme/composer.json new file mode 100644 index 00000000..44970e72 --- /dev/null +++ b/tests/Application/__fixtures__/get_namespace/a_sage_theme/composer.json @@ -0,0 +1,7 @@ +{ + "autoload": { + "psr-4": { + "Sage\\": "app/" + } + } +} \ No newline at end of file diff --git a/tests/Application/__fixtures__/is_down_for_maintenance/storage/framework/down b/tests/Application/__fixtures__/is_down_for_maintenance/storage/framework/down new file mode 100644 index 00000000..8337712e --- /dev/null +++ b/tests/Application/__fixtures__/is_down_for_maintenance/storage/framework/down @@ -0,0 +1 @@ +// diff --git a/tests/Application/__fixtures__/is_down_for_maintenance/wp/.maintenance b/tests/Application/__fixtures__/is_down_for_maintenance/wp/.maintenance new file mode 100644 index 00000000..8337712e --- /dev/null +++ b/tests/Application/__fixtures__/is_down_for_maintenance/wp/.maintenance @@ -0,0 +1 @@ +// diff --git a/tests/Application/__fixtures__/use_paths/app/.gitignore b/tests/Application/__fixtures__/use_paths/app/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/app/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/bootstrap/cache/.gitignore b/tests/Application/__fixtures__/use_paths/bootstrap/cache/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/config/.gitignore b/tests/Application/__fixtures__/use_paths/config/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/config/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/database/.gitignore b/tests/Application/__fixtures__/use_paths/database/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/database/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/public/.gitignore b/tests/Application/__fixtures__/use_paths/public/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/public/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/resources/lang/.gitignore b/tests/Application/__fixtures__/use_paths/resources/lang/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/resources/lang/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Application/__fixtures__/use_paths/storage/.gitignore b/tests/Application/__fixtures__/use_paths/storage/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/tests/Application/__fixtures__/use_paths/storage/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Assets/AssetTest.php b/tests/Assets/AssetTest.php new file mode 100644 index 00000000..687be72e --- /dev/null +++ b/tests/Assets/AssetTest.php @@ -0,0 +1,3 @@ +normalizePath('/a//b///c/d//e')) + ->toEqual('/a/b/c/d/e'); +}); + +it('should normalize paths separated by backslashes', function () { + expect((new Filesystem())->normalizePath('/a\\\\b\\\\c/d//e')) + ->toEqual('/a/b/c/d/e'); +}); + +it('should normalize paths to arbitrary separator', function () { + expect((new Filesystem())->normalizePath('/a\\\\b\\\\c/d//e', '|')) + ->toEqual('|a|b|c|d|e'); +}); + +it('should find the closest path within the filesystem', function () { + expect((new Filesystem())->closest($this->fixture('closest/a/b'), 'kjo.txt')) + ->toEqual($this->fixture('closest/kjo.txt')); + + expect((new Filesystem())->closest($this->fixture('closest/a/b'), 'bdubs.txt')) + ->toEqual($this->fixture('closest/a/b/bdubs.txt')); + + expect((new Filesystem())->closest($this->fixture('closest/a/b'), 'apray.txt')) + ->toBeNull(); +}); + +it('should determine the relative path between two absolute paths', function () { + expect((new Filesystem())->getRelativePath('/dir_a/dir_b/', '/dir_a/dir_b/dir_c/file_d')) + ->toEqual('dir_c/file_d'); + + expect((new Filesystem())->getRelativePath('/dir_a/dir_b/dir_c/dir_d/', '/dir_a/dir_b/')) + ->toEqual('../../'); + + expect((new Filesystem())->getRelativePath('/dir_a/dir_b/', '/dir_a/file_kjo')) + ->toEqual('../file_kjo'); + + expect((new Filesystem())->getRelativePath('/dir_a/dir_b/', '/dir_a/dir_b/')) + ->toEqual(''); +}); diff --git a/tests/Unit/__fixtures__/view.php b/tests/Filesystem/__fixtures__/closest/a/b/bdubs.txt similarity index 100% rename from tests/Unit/__fixtures__/view.php rename to tests/Filesystem/__fixtures__/closest/a/b/bdubs.txt diff --git a/tests/Filesystem/__fixtures__/closest/kjo.txt b/tests/Filesystem/__fixtures__/closest/kjo.txt new file mode 100644 index 00000000..ab0c0141 --- /dev/null +++ b/tests/Filesystem/__fixtures__/closest/kjo.txt @@ -0,0 +1 @@ +// \ No newline at end of file diff --git a/tests/Sage/SageTest.php b/tests/Sage/SageTest.php new file mode 100644 index 00000000..13b65ece --- /dev/null +++ b/tests/Sage/SageTest.php @@ -0,0 +1,3 @@ +booted($booted); - $app->booting($booting); - - /** initial boot sets counts to 1 */ - $app->boot(); - $this->assertEquals(1, $bootedCount); - $this->assertEquals(1, $bootingCount); - - /** subsequent boot attempt skips firing callbacks */ - $app->boot(); - $this->assertEquals(1, $bootedCount); - $this->assertEquals(1, $bootingCount); - } -} diff --git a/tests/Unit/AssetDirectiveTest.php b/tests/Unit/AssetDirectiveTest.php deleted file mode 100644 index 17f56209..00000000 --- a/tests/Unit/AssetDirectiveTest.php +++ /dev/null @@ -1,17 +0,0 @@ -assertEquals("", $directive("'scripts/app.js'")); - $this->assertEquals('', $directive('$file')); - } -} diff --git a/tests/Unit/Assets/AssetTest.php b/tests/Unit/Assets/AssetTest.php deleted file mode 100644 index 3cd46f28..00000000 --- a/tests/Unit/Assets/AssetTest.php +++ /dev/null @@ -1,40 +0,0 @@ -contents()); - } - - public function testGetReturnsFalseIfNotExists(): void - { - $asset = new Asset('foo', 'bar'); - - self::assertFalse($asset->get()); - } - - public function testIncludedFileContentIsReturned(): void - { - $temp = stream_get_meta_data(tmpfile())['uri']; - file_put_contents($temp, " 'bar'];\n"); - $asset = new Asset($temp, 'bar'); - - self::assertSame(['foo' => 'bar'], $asset->get()); - } - - public function testCastsToUri(): void - { - $asset = new Asset('foo', 'bar'); - - self::assertSame('bar', (string)$asset); - } - -} diff --git a/tests/Unit/Assets/AssetsManagerTest.php b/tests/Unit/Assets/AssetsManagerTest.php deleted file mode 100644 index e5ca1e5b..00000000 --- a/tests/Unit/Assets/AssetsManagerTest.php +++ /dev/null @@ -1,84 +0,0 @@ -manager->register('foo', $expected); - - self::assertSame($expected, $this->manager->manifest('foo')); - } - - public function testCustomCreatorIsCalledWhenStrategyIsRegistered(): void - { - $expected = new RelativePathManifest('', ''); - $this->manager->extend('foo', function () use ($expected): Manifest { - return $expected; - }); - - self::assertSame($expected, $this->manager->manifest('bar', ['strategy' => 'foo'])); - } - - public function testConfig(): void - { - $expected = new RelativePathManifest('', ''); - $manager = new AssetsManager( - new ContainerStub(['config' => ['assets.manifests.foo' => ['strategy' => 'bar']]]) - ); - $manager->extend('bar', function () use ($expected): Manifest { - return $expected; - }); - - self::assertSame($expected, $manager->manifest('foo', null)); - } - - public function testGetDefaultManifest(): void - { - $manager = new AssetsManager(new ContainerStub(['config' => ['assets.default' => 'foo']])); - - self::assertSame('foo', $manager->getDefaultManifest()); - } - - public function testMissingStrategyThrowsException(): void - { - $this->expectException(InvalidArgumentException::class); - - $this->manager->manifest('foo', ['strategy' => 'bar']); - } - - public function testManifestGetsCalled(): void - { - $spy = new ManifestSpy(); - $manager = new AssetsManager(new ContainerStub(['config' => ['assets.default' => 'default']])); - $manager->register('default', $spy); - - $manager->foobar(); - - $calls = $spy->getCallLog(); - self::assertArrayHasKey('foobar', $calls); - self::assertSame(1, $calls['foobar']); - } - - protected function setUp(): void - { - parent::setUp(); - $app = new Application(); - $this->manager = new AssetsManager($app); - } -} diff --git a/tests/Unit/Assets/AssetsServiceProviderTest.php b/tests/Unit/Assets/AssetsServiceProviderTest.php deleted file mode 100644 index 15699d29..00000000 --- a/tests/Unit/Assets/AssetsServiceProviderTest.php +++ /dev/null @@ -1,61 +0,0 @@ - '/* javascript */', - '/app/themes/sage/dist/styles/app.css' => '/* css */', - ]; - - public function testRegister(): void - { - $app = new Application(); - $app->bind( - 'config', - function (): array { - return [ - 'assets.default' => 'test', - 'assets.manifests.test' => ['manifest' => '', 'path' => 'test', 'uri' => 'test'], - ]; - } - ); - $app->bind( - 'files', - function (): Filesystem { - return new Filesystem(); - } - ); - $service = new AssetsServiceProvider($app); - - $service->register(); - - self::assertInstanceOf(AssetsManager::class, $app->get('assets')); - self::assertInstanceOf(Manifest::class, $app->get('assets.manifest')); - } - - public function setUp(): void - { - $this->fsSetUp(); - $jsonManifest = json_encode( - [ - 'scripts/app.js' => 'scripts/app-123456.js', - 'styles/app.css' => 'styles/app.css?id=123456', - ] - ); - $this->write('/app/themes/sage/dist/assets.json', $jsonManifest); - } -} diff --git a/tests/Unit/Assets/RelativePathManifestTest.php b/tests/Unit/Assets/RelativePathManifestTest.php deleted file mode 100644 index 366278bb..00000000 --- a/tests/Unit/Assets/RelativePathManifestTest.php +++ /dev/null @@ -1,105 +0,0 @@ -manifest->offsetGet('foo'); - - self::assertSame('/foo', $asset->path()); - self::assertSame('/foo', $asset->uri()); - } - - public function testOffsetSet(): void - { - $this->manifest->offsetSet('foo', 'bar'); - $asset = $this->manifest->offsetGet('foo'); - - self::assertSame('/bar', $asset->path()); - self::assertSame('/bar', $asset->uri()); - } - - public function testOffsetUnset(): void - { - $this->manifest->offsetSet('foo', 'bar'); - $this->manifest->offsetUnset('foo'); - $asset = $this->manifest->offsetGet('foo'); - - self::assertSame('/foo', $asset->path()); - self::assertSame('/foo', $asset->uri()); - } - - public function testOffsetExistsTrue(): void - { - $this->manifest->offsetSet('foo', 'bar'); - - self::assertTrue($this->manifest->offsetExists('foo')); - } - - public function testOffsetExistsFalse(): void - { - self::assertFalse($this->manifest->offsetExists('foo')); - } - - public function testCountIsZeroWhenNothingAdded(): void - { - self::assertSame(0, $this->manifest->count()); - } - - public function testCountIsAsExpected(): void - { - $this->manifest->offsetSet('foo', 'bar'); - - self::assertSame(1, $this->manifest->count()); - } - - public function testGetIterator(): void - { - $this->manifest->offsetSet('foo', 'bar'); - - $iterator = $this->manifest->getIterator(); - self::assertTrue($iterator->offsetExists('foo')); - self::assertSame('bar', $iterator->offsetGet('foo')); - } - - public function testToArray(): void - { - $this->manifest->offsetSet('foo', 'bar'); - - $array = $this->manifest->toArray(); - self::assertArrayHasKey('foo', $array); - self::assertSame('bar', $array['foo']); - } - - public function testToJson(): void - { - $this->manifest->offsetSet('foo', 'bar'); - - $json = $this->manifest->toJson(); - $decoded = json_decode($json, true); - self::assertArrayHasKey('foo', $decoded); - self::assertSame('bar', $decoded['foo']); - } - - public function testJsonSerializeReturnsSameDataAsToJson(): void - { - self::assertSame(json_encode($this->manifest, true), $this->manifest->toJson()); - } - - protected function setUp(): void - { - parent::setUp(); - $this->manifest = new RelativePathManifest($this->path, $this->uri); - } - -} diff --git a/tests/Unit/AssetsTest.php b/tests/Unit/AssetsTest.php deleted file mode 100644 index 59b816eb..00000000 --- a/tests/Unit/AssetsTest.php +++ /dev/null @@ -1,107 +0,0 @@ - '/* javascript */', - '/app/themes/sage/dist/styles/app.css' => '/* css */', - ]; - - public function setUp() : void - { - $this->fsSetUp(); - $jsonManifest = json_encode([ - 'scripts/app.js' => 'scripts/app-123456.js', - 'styles/app.css' => 'styles/app.css?id=123456', - ]); - $this->write('/app/themes/sage/dist/assets.json', $jsonManifest); - } - - /** @test */ - public function an_asset_should_strip_query_string_from_its_path() - { - $asset = $this->asset('scripts/app.js?id=123456'); - - $this->assertEquals(get_theme_file_path('/scripts/app.js'), $asset->path()); - } - - /** @test */ - public function an_asset_should_return_its_contents() - { - $path = 'dist/scripts/app.js'; - $contents = '/** my app */'; - file_put_contents(get_theme_file_path($path), $contents); - - $this->assertEquals($contents, $this->asset($path)->contents()); - } - - /** @test */ - public function an_asset_should_determine_whether_it_exists() - { - $asset = $this->asset('dist/scripts/app-123456.js'); - $asset2 = $this->asset('dist/scripts/notafile.js'); - - $this->assertTrue($asset->exists()); - $this->assertFalse($asset2->exists()); - } - - /** @test */ - public function an_asset_should_return_its_path_and_uri() - { - $asset = $this->asset('scripts/app.js', 'scripts/app.js?id=123456'); - - $this->assertEquals(get_theme_file_path('scripts/app.js'), $asset->path()); - $this->assertEquals(get_theme_file_uri('scripts/app.js?id=123456'), $asset->uri()); - } - - /** @test */ - public function a_relative_path_manifest_should_prepend_a_base_path_and_uri() - { - $path = get_theme_file_path('dist'); - $uri = get_theme_file_uri('dist'); - $manifest = new \Roots\Acorn\Assets\RelativePathManifest($path, $uri, [ - 'scripts/app.js' => 'scripts/app-123456.js' - ]); - - $this->assertEquals($manifest->uri(), $uri); - $this->assertEquals($manifest->path(), $path); - $this->assertEquals($manifest->get('scripts/app.js')->uri(), "{$uri}/scripts/app-123456.js"); - $this->assertEquals($manifest->get('scripts/app.js')->path(), "{$path}/scripts/app-123456.js"); - } - - /** @test */ - public function asset_manager_should_resolve_manifest() - { - $app = new \Roots\Acorn\Application(); - $app->singleton('files', \Roots\Acorn\Filesystem\Filesystem::class); - - $assets = new \Roots\Acorn\Assets\AssetsManager($app); - - $manifest = $assets->manifest('my-manifest', [ - 'strategy' => 'relative', - 'manifest' => get_theme_file_path('dist/assets.json'), - 'path' => get_theme_file_path('dist'), - 'uri' => get_theme_file_uri('dist'), - ]); - - $this->assertInstanceOf(\Roots\Acorn\Assets\RelativePathManifest::class, $manifest); - } - - /** - * @param string $path - * @return \Roots\Acorn\Assets\Asset - */ - protected function asset($path, $uri = null) - { - return new \Roots\Acorn\Assets\Asset(get_theme_file_path($path), get_theme_file_uri($uri ?? $path)); - } -} diff --git a/tests/Unit/BootloaderTest.php b/tests/Unit/BootloaderTest.php deleted file mode 100644 index 8808129a..00000000 --- a/tests/Unit/BootloaderTest.php +++ /dev/null @@ -1,74 +0,0 @@ -getBootloader(); - - $this->assertFalse($bootloader->ready()); - - $this->boot(); - - $this->assertTrue($bootloader->ready()); - } - - /** @test */ - public function it_should_defer_callbacks_until_ready() - { - $bootloader = $this->getBootloader(); - - $expected = 'foo'; - - $bootloader->call(function () use (&$expected) { - $expected = 'foobar'; - }); - - $this->assertEquals('foo', $expected); - - $this->boot(); - - $this->assertEquals('foobar', $expected); - } - - /** @test */ - public function it_should_immediately_call_callback_if_ready() - { - $bootloader = $this->getBootloader(); - - $expected = 'foo'; - - $this->boot(); - - $bootloader->call(function () use (&$expected) { - $expected = 'foobar'; - }); - - $this->assertEquals('foobar', $expected); - } - - protected function getBootloader($hook = 'boot') - { - return new \Roots\Acorn\Bootloader($hook, Application::class); - } - - protected function boot($hook = 'boot') - { - \do_action($hook); - } -} - -class Application extends \Roots\Acorn\Application -{ - public function bootstrapWith(array $bootstrappers) - { - } -} diff --git a/tests/Unit/Clover/MetaTest.php b/tests/Unit/Clover/MetaTest.php deleted file mode 100644 index 64ff006c..00000000 --- a/tests/Unit/Clover/MetaTest.php +++ /dev/null @@ -1,34 +0,0 @@ -expectError(); - $this->expectErrorMessage('Meta is immutable and cannot be modified after instantiation.'); - - $meta->set('foo'); - } - - public function testOverloadingGetReturnsMetaInstanceForAssocArrayValue(): void - { - $meta = new Meta(['foo' => ['bar' => 'Lorem Ipsum']]); - - self::assertInstanceOf(Meta::class, $meta->foo); - self::assertSame('Lorem Ipsum', $meta->foo->bar); - } - - public function testOverloadingGetReturnsValue(): void - { - $meta = new Meta(['foo' => ['bar']]); - - self::assertSame(['bar'], $meta->foo); - } -} diff --git a/tests/Unit/Clover/ServiceProviderTest.php b/tests/Unit/Clover/ServiceProviderTest.php deleted file mode 100644 index 5672d845..00000000 --- a/tests/Unit/Clover/ServiceProviderTest.php +++ /dev/null @@ -1,104 +0,0 @@ -service->boot(); - - self::assertTrue($this->plugin->runWasCalled()); - self::assertTrue($this->plugin->lifecycleWasCalled()); - } - - public function testRegisterLoadsPluginConfigFileAndAddsViewPathsToFactory(): void - { - $this->service->register(); - - self::assertContains('dummy-plugin', $this->getViewFactoryFromApp()->getRegisteredNamespaces()); - $paths = $this->getViewFactoryFromApp()->getPathsForNamespace('dummy-plugin'); - self::assertStringContainsString('tests/Unit/__fixtures__/plugin/config/../resources/views', $paths[0]); - } - - public function testRegisterProvidersFromPluginConfig(): void - { - $this->service->register(); - - self::assertTrue($this->getServiceProviderSpy()->isRegisterCalled()); - } - - public function testRegisterBailsEarlyIfNoConfigFound(): void - { - $meta = new Meta( - [ - 'key' => 'my-plugin', - 'plugin' => __DIR__ . '/../fixtures/not-existing/my-plugin.php', - ] - ); - $this->plugin = new PluginStub($meta); - $this->app->bind('my-plugin', function () { - return $this->plugin; - }); - - (new CloverServiceProviderStub($this->app, $meta))->register(); - - $viewFactory = $this->getViewFactoryFromApp(); - self::assertNotContains('my-plugin', $viewFactory->getRegisteredNamespaces()); - } - - protected function setUp(): void - { - parent::setUp(); - $this->app = new Application(); - $meta = new Meta( - [ - 'key' => 'dummy-plugin', - 'plugin' => __DIR__ . '/../__fixtures__/plugin/dummy-plugin.php', - ] - ); - $this->plugin = new PluginStub($meta); - $this->app->bind('dummy-plugin', function () { - return $this->plugin; - }); - $this->viewFactory = new ViewFactoryStub(); - $this->app->bind('view', function (): Factory { - return $this->viewFactory; - }); - $this->service = new CloverServiceProviderStub($this->app, $meta); - } - - private function getViewFactoryFromApp(): Factory - { - $viewFactory = $this->app->get('view'); - assert($viewFactory instanceof ViewFactoryStub); - return $viewFactory; - } - - private function getServiceProviderSpy(): ServiceProviderSpy - { - $viewFactory = $this->app->get(ServiceProviderSpy::class); - assert($viewFactory instanceof ServiceProviderSpy); - return $viewFactory; - } -} diff --git a/tests/Unit/Exceptions/HandlerTest.php b/tests/Unit/Exceptions/HandlerTest.php deleted file mode 100644 index 873612a4..00000000 --- a/tests/Unit/Exceptions/HandlerTest.php +++ /dev/null @@ -1,52 +0,0 @@ -container = new Application(); - $this->env = 'development'; - $this->container->bind('env', function () { - return $this->env; - }); - $this->handler = new Handler($this->container); - } - - public function testRenderSymfonyErrorPageWithoutErrorMessageForProduction(): void - { - $this->env = 'production'; - - $content = $this->handler->render(Request::create('/'), new RuntimeException('Foo Bar')); - - self::assertStringContainsString('500 Internal Server Error', $content); - self::assertStringNotContainsString('Foo bar', $content); - } - - public function testRenderForConsoleRendersErrorMessage(): void - { - $output = new OutputStub(); - - $this->handler->renderForConsole($output, new RuntimeException('Foo bar')); - - self::assertStringContainsString('Foo bar', implode(' ', $output->getWrittenMessages())); - } -} diff --git a/tests/Unit/Exceptions/PrettyPageHandlerTest.php b/tests/Unit/Exceptions/PrettyPageHandlerTest.php deleted file mode 100644 index 07746b85..00000000 --- a/tests/Unit/Exceptions/PrettyPageHandlerTest.php +++ /dev/null @@ -1,27 +0,0 @@ -handler = new PrettyPageHandler(); - } - - public function testPrettyPageHandlerHasExpectedDataTables(): void - { - $tables = $this->handler->getDataTables(); - - self::assertArrayHasKey('WordPress Data', $tables); - self::assertArrayHasKey('WP_Query Data', $tables); - self::assertArrayHasKey('WP_Post Data', $tables); - } -} diff --git a/tests/Unit/FileViewFinderTest.php b/tests/Unit/FileViewFinderTest.php deleted file mode 100644 index 0f14d992..00000000 --- a/tests/Unit/FileViewFinderTest.php +++ /dev/null @@ -1,55 +0,0 @@ - '{{-- foo --}}', - '/views/foo-bar.blade.php' => '{{-- foobar --}}', - '/sage/resources/views/page.blade.php' => '{{-- page --}}', - '/sage/resources/views/page-about.blade.php' => '{{-- about page --}}', - ]; - - /** @test */ - public function it_should_find_other_files_based_on_delimeter_breakpoints_in_specified_name() - { - $this->markTestSkipped("Feature has been removed, but might be added back"); - $finder = $this->getFinder(); - - $this->assertEquals("{$this->filesystem}/views/foo.blade.php", $finder->find('foo')); - $this->assertEquals("{$this->filesystem}/views/foo-bar.blade.php", $finder->find('foo-bar')); - $this->assertEquals("{$this->filesystem}/views/foo-bar.blade.php", $finder->find('foo-bar-biz-baz')); - } - - /** @test */ - public function it_should_find_possible_view_files_based_on_possible_file_name() - { - /** @var \Roots\Acorn\View\FileViewFinder $finder */ - $finder = $this->getFinder(); - - $views = $finder->getPossibleViewFilesFromPath("{$this->filesystem}/sage/resources/views/page.php"); - - $expected = [ - "page.blade.php", - "page.php", - "page.css", - 'page.html', - ]; - - $this->assertEquals($expected, $views); - } - - protected function getFinder() - { - return new \Roots\Acorn\View\FileViewFinder( - new \Illuminate\Filesystem\Filesystem(), - ["{$this->filesystem}/views", "{$this->filesystem}/sage/resources/views"] - ); - } -} diff --git a/tests/Unit/Filesystem/FilesystemServiceProviderTest.php b/tests/Unit/Filesystem/FilesystemServiceProviderTest.php deleted file mode 100644 index 70f3eb9b..00000000 --- a/tests/Unit/Filesystem/FilesystemServiceProviderTest.php +++ /dev/null @@ -1,22 +0,0 @@ -register(); - - $fs = $app->get('files'); - self::assertInstanceOf(Filesystem::class, $fs); - } -} diff --git a/tests/Unit/FilesystemTest.php b/tests/Unit/FilesystemTest.php deleted file mode 100644 index caccf718..00000000 --- a/tests/Unit/FilesystemTest.php +++ /dev/null @@ -1,43 +0,0 @@ -assertEquals('/some/path/to/a/file', $filesystem->normalizePath($path)); - } - - /** @test */ - public function it_should_determine_a_relative_path() - { - $filesystem = new \Roots\Acorn\Filesystem\Filesystem(); - - $relative = $filesystem->getRelativePath( - '/app/themes/sage/', - '/app/plugins/my-plugin/' - ); - - $this->assertEquals('../../plugins/my-plugin/', $relative); - } - - /** @test */ - public function it_should_return_empty_string_when_base_and_target_path_are_equal() - { - $filesystem = new \Roots\Acorn\Filesystem\Filesystem(); - - $relative = $filesystem->getRelativePath( - '/app/themes/sage/', - '/app/themes/sage/' - ); - - $this->assertEquals('', $relative); - } -} diff --git a/tests/Unit/SageTest.php b/tests/Unit/SageTest.php deleted file mode 100644 index d4b9bd25..00000000 --- a/tests/Unit/SageTest.php +++ /dev/null @@ -1,100 +0,0 @@ -fileViewFinder->setPaths([__DIR__ . '/__fixtures__/theme']); - - $result = $this->sage->filterThemeTemplates([], ['sage'], 123, 'page'); - - self::assertSame(['page-template.php' => 'Page Template'], $result); - } - - /** @test */ - public function it_should_compile_list_of_theme_post_type_templates() - { - $this->fileViewFinder->setPaths([__DIR__ . '/__fixtures__/theme']); - - $result = $this->sage->filterThemeTemplates([], ['sage'], 123, 'post'); - - self::assertSame(['post-type-template.php' => 'Post Type Template'], $result); - } - - /** @test */ - public function it_should_include_given_templates_in_compiled_list() - { - $this->fileViewFinder->setPaths([__DIR__ . '/__fixtures__/theme']); - - $result = $this->sage->filterThemeTemplates(['foo' => 'bar'], ['sage'], 123, 'page'); - - self::assertSame(['foo' => 'bar', 'page-template.php' => 'Page Template'], $result); - } - - /** @test */ - public function it_should_share_the_loop_post_with_view() - { - $post = new \WP_Post(); - - $this->sage->filterThePost($post); - - self::assertSame(['post' => $post], $this->viewFactory->getShared()); - } - - /** @test */ - public function it_should_load_data_based_on_body_class() - { - $GLOBALS['body-class'] = ['foo', 'bar']; - $this->fileViewFinder->setPaths([__DIR__ . '/__fixtures__/theme']); - $log = []; - $cb = function ($data, $view, $file) use (&$log): array { - $log[] = [ - 'data' => $data, - 'view' => $view, - 'file' => $file, - ]; - return $data; - }; - add_filter('sage/template/foo/data', $cb); - add_filter('sage/template/bar/data', $cb); - - $this->sage->filterTemplateInclude(__DIR__ . '/__fixtures__/view.php'); - - self::assertSame([], $log[0]['data']); - self::assertSame(ltrim(__DIR__, '/') . '/__fixtures__/view', $log[0]['view']); - self::assertSame(__DIR__ . '/__fixtures__/view.php', $log[0]['file']); - self::assertSame([], $log[1]['data']); - } - - protected function setUp(): void - { - parent::setUp(); - $filesystem = new Filesystem(); - $this->fileViewFinder = new FileViewFinder($filesystem, []); - $this->viewFactory = new ViewFactoryStub(); - $this->sage = new Sage( - $filesystem, - new ViewFinder($this->fileViewFinder, $filesystem), - $this->fileViewFinder, - $this->viewFactory, - new Application() - ); - } -} diff --git a/tests/Unit/SageViewFinderTest.php b/tests/Unit/SageViewFinderTest.php deleted file mode 100644 index 49dd9618..00000000 --- a/tests/Unit/SageViewFinderTest.php +++ /dev/null @@ -1,83 +0,0 @@ - '{{-- page --}}', - '/app/themes/sage-child/resources/views/page.blade.php' => '{{-- child-page --}}', - '/app/themes/sage/resources/views/another-page.blade.php' => '{{-- page --}}', - '/app/themes/sage-child/resources/views/another-page.blade.php' => '{{-- child-page --}}', - ]; - /** @var \Roots\Acorn\View\FileViewFinder */ - private $viewFinder; - /** @var \Roots\Acorn\Filesystem\Filesystem */ - private $fs; - - /** @test */ - public function it_should_compile_list_of_views_for_template_hierarchy() - { - $finder = $this->getFinder(); - - $this->assertEquals( - [ - "resources/views/page.blade.php", - "resources/views/page.php", - "resources/views/page.css", - "resources/views/page.html", - "../sage/resources/views/page.blade.php", - "../sage/resources/views/page.php", - "../sage/resources/views/page.css", - "../sage/resources/views/page.html", - ], - array_values($finder->locate('page.php')) - ); - } - - /** @test */ - public function it_should_support_multiple_files() - { - $finder = $this->getFinder(); - - $templates = array_values($finder->locate(['page.php', 'another-page.php'])); - - self::assertContains("resources/views/page.blade.php", $templates); - self::assertContains("resources/views/another-page.blade.php", $templates); - } - - /** @test */ - public function it_should_return_instance_of_view_finder() - { - $this->assertEquals($this->viewFinder, $this->getFinder()->getFinder()); - } - - /** @test */ - public function it_should_return_instance_of_filesystem() - { - $this->assertEquals($this->fs, $this->getFinder()->getFilesystem()); - } - - protected function getFinder() - { - return new \Roots\Acorn\Sage\ViewFinder($this->viewFinder, $this->fs, "{$this->filesystem}/sage-child"); - } - - protected function setUp(): void - { - parent::setUp(); - $this->fs = new \Roots\Acorn\Filesystem\Filesystem(); - $this->viewFinder = new \Roots\Acorn\View\FileViewFinder( - new \Roots\Acorn\Filesystem\Filesystem(), - [ - "{$this->filesystem}/sage-child/resources/views", - "{$this->filesystem}/sage/resources/views" - ] - ); - } -} diff --git a/tests/Unit/TestDouble/CloverServiceProviderStub.php b/tests/Unit/TestDouble/CloverServiceProviderStub.php deleted file mode 100644 index f77a4882..00000000 --- a/tests/Unit/TestDouble/CloverServiceProviderStub.php +++ /dev/null @@ -1,15 +0,0 @@ -meta = $meta; - } -} diff --git a/tests/Unit/TestDouble/ContainerStub.php b/tests/Unit/TestDouble/ContainerStub.php deleted file mode 100644 index 13effb76..00000000 --- a/tests/Unit/TestDouble/ContainerStub.php +++ /dev/null @@ -1,46 +0,0 @@ - */ - private $map; - - public function __construct(?array $map = null) - { - $this->map = $map ?? []; - } - - /** - * @param string $id - * @return mixed - */ - public function get($id) - { - return $this->map[$id] ?? null; - } - - /** - * @param string $id - * @return bool - */ - public function has($id): bool - { - return array_key_exists($id, $this->map); - } - - /** - * @param string $id - * @param mixed $value - * @return void - */ - public function set($id, $value): void - { - $this->map[$id] = $value; - } -} diff --git a/tests/Unit/TestDouble/ManifestSpy.php b/tests/Unit/TestDouble/ManifestSpy.php deleted file mode 100644 index 367f0106..00000000 --- a/tests/Unit/TestDouble/ManifestSpy.php +++ /dev/null @@ -1,47 +0,0 @@ - */ - private $map; - /** @var array */ - private $callLog; - - public function __construct(?array $map = null) - { - $this->map = $map ?? []; - } - - public function get($key): Asset - { - $asset = $this->map[$key] ?? null; - if ($asset === null) { - throw new RuntimeException(sprintf('Manifest for key "%s" not found', $key)); - } - return $asset; - } - - public function set(string $key, Asset $value): void - { - $this->map[$key] = $value; - } - - public function __call($name, $arguments): void - { - $this->callLog[$name] = ($this->callLog[$name] ?? 0) + 1; - } - - /** - * @return array - */ - public function getCallLog(): array - { - return $this->callLog; - } -} diff --git a/tests/Unit/TestDouble/OutputStub.php b/tests/Unit/TestDouble/OutputStub.php deleted file mode 100644 index dc2abd42..00000000 --- a/tests/Unit/TestDouble/OutputStub.php +++ /dev/null @@ -1,21 +0,0 @@ -written[] = $message; - } - - public function getWrittenMessages(): array - { - return $this->written; - } -} diff --git a/tests/Unit/TestDouble/PluginStub.php b/tests/Unit/TestDouble/PluginStub.php deleted file mode 100644 index bc4facaa..00000000 --- a/tests/Unit/TestDouble/PluginStub.php +++ /dev/null @@ -1,42 +0,0 @@ -meta = $meta; - } - - public function run() - { - $this->runWasCalled = true; - } - - public function runWasCalled(): bool - { - return $this->runWasCalled; - } - - public function lifecycle(Meta $meta): void - { - $this->lifecycleWasCalled = true; - } - - public function lifecycleWasCalled(): bool - { - return $this->lifecycleWasCalled; - } -} diff --git a/tests/Unit/TestDouble/ServiceProviderSpy.php b/tests/Unit/TestDouble/ServiceProviderSpy.php deleted file mode 100644 index 195529c7..00000000 --- a/tests/Unit/TestDouble/ServiceProviderSpy.php +++ /dev/null @@ -1,23 +0,0 @@ -app->bind(self::class, function (): self { - return $this; - }); - $this->registerCalled = true; - } - - public function isRegisterCalled(): bool - { - return $this->registerCalled; - } -} diff --git a/tests/Unit/TestDouble/ViewFactoryStub.php b/tests/Unit/TestDouble/ViewFactoryStub.php deleted file mode 100644 index 6f700d60..00000000 --- a/tests/Unit/TestDouble/ViewFactoryStub.php +++ /dev/null @@ -1,95 +0,0 @@ -> - */ - private $map = []; - /** - * @var array - */ - private $shared = []; - - public function exists($view): bool - { - return false; - } - - public function file($path, $data = [], $mergeData = []): View - { - return new ViewStub(); - } - - public function make($view, $data = [], $mergeData = []): View - { - return new ViewStub(); - } - - public function share($key, $value = null) - { - $keys = is_array($key) ? $key : [$key => $value]; - - foreach ($keys as $key => $value) { - $this->shared[$key] = $value; - } - - return $value; - } - - public function composer($views, $callback): array - { - return []; - } - - public function creator($views, $callback): array - { - return []; - } - - public function addNamespace($namespace, $hints): self - { - $existingHints = $this->map[$namespace] ?? []; - $this->map[$namespace] = array_merge($hints, $existingHints); - return $this; - } - - public function replaceNamespace($namespace, $hints): self - { - $this->map[$namespace] = $hints; - return $this; - } - - /** - * @return string[] - */ - public function getRegisteredNamespaces(): array - { - return array_keys($this->map); - } - - /** - * @return string[] - */ - public function getPathsForNamespace(string $namespace): array - { - return array_values($this->map[$namespace] ?? []); - } - - /** - * @return array - */ - public function getShared(): array - { - return $this->shared; - } -} diff --git a/tests/Unit/TestDouble/ViewStub.php b/tests/Unit/TestDouble/ViewStub.php deleted file mode 100644 index d203c9ab..00000000 --- a/tests/Unit/TestDouble/ViewStub.php +++ /dev/null @@ -1,42 +0,0 @@ - */ - private $map = []; - /** @var string */ - private $content; - /** @var string */ - private $name; - - public function __construct(string $name = '', string $content = '') - { - $this->name = $name; - $this->content = $content; - } - - public function render() - { - return $this->content; - } - - public function name() - { - return $this->name; - } - - public function with($key, $value = null) - { - $this->map[$key] = $value; - return $this; - } - - public function getData(): array - { - return $this->map; - } -} diff --git a/tests/Unit/__fixtures__/plugin/config/dummy-plugin.php b/tests/Unit/__fixtures__/plugin/config/dummy-plugin.php deleted file mode 100644 index 56e002d1..00000000 --- a/tests/Unit/__fixtures__/plugin/config/dummy-plugin.php +++ /dev/null @@ -1,8 +0,0 @@ - [ - \Roots\Acorn\Tests\Unit\TestDouble\ServiceProviderSpy::class - ], - 'views' => [__DIR__ . '/../resources/views'], -]; diff --git a/tests/Unit/__fixtures__/plugin/resources/views/test.php b/tests/Unit/__fixtures__/plugin/resources/views/test.php deleted file mode 100644 index f3e333e8..00000000 --- a/tests/Unit/__fixtures__/plugin/resources/views/test.php +++ /dev/null @@ -1 +0,0 @@ -

Hello World

diff --git a/tests/Unit/__fixtures__/theme/page-template.php b/tests/Unit/__fixtures__/theme/page-template.php deleted file mode 100644 index bdd240ec..00000000 --- a/tests/Unit/__fixtures__/theme/page-template.php +++ /dev/null @@ -1,10 +0,0 @@ - -

Hello World Page

diff --git a/tests/Unit/__fixtures__/theme/post-type-template.php b/tests/Unit/__fixtures__/theme/post-type-template.php deleted file mode 100644 index f9f1671c..00000000 --- a/tests/Unit/__fixtures__/theme/post-type-template.php +++ /dev/null @@ -1,7 +0,0 @@ - -

Hello World Post Type

diff --git a/tests/View/ViewTest.php b/tests/View/ViewTest.php new file mode 100644 index 00000000..3cb61046 --- /dev/null +++ b/tests/View/ViewTest.php @@ -0,0 +1,3 @@ +filesystem = new class ($this->fixtures()) { - /** @var \org\bovigo\vfs\vfsStreamDirectory */ - protected $stream; - - public function __construct($fixtures = []) - { - $this->stream = vfsStream::setup('__fixtures__', null, $fixtures); - } - - public function __call($name, $arguments) - { - return $this->stream->{$name}(...$arguments); - } - - public function __get($name) - { - return $this->stream->{$name}; - } - - public function __toString() - { - return $this->stream->url(); - } - }; - } - - protected function write($file, $contents) - { - $file = str_replace('\\', '/', $file); - $file = ltrim($file, '/'); - - $file = "{$this->filesystem}/{$file}"; - - file_put_contents($file, $contents); - - return $file; - } - - protected function writeDump($file, $data) - { - $contents = var_export($data, true); - return $this->write($file, $contents); - } - - protected function fixtures() - { - $filesystem = []; - - foreach ($this->fixtures ?? [] as $file => $content) { - $limbs = array_reverse(array_filter(explode('/', $file))); - $filesystem = array_merge_recursive(array_reduce($limbs, function ($leaf, $limb) { - return [$limb => $leaf]; - }, $content), $filesystem); - } - - return $filesystem; - } -} diff --git a/tests/Unit/__fixtures__/plugin/dummy-plugin.php b/tests/api.php similarity index 85% rename from tests/Unit/__fixtures__/plugin/dummy-plugin.php rename to tests/api.php index a4abe2da..b3d9bbc7 100644 --- a/tests/Unit/__fixtures__/plugin/dummy-plugin.php +++ b/tests/api.php @@ -1,2 +1 @@ create(); + + define('ABSPATH', $temp->path('wp')); + + register_shutdown_function(function () use ($temp) { + $temp->delete(); + }); + } + + if ($path) { + return $temp->path($path); + } + + return $temp; +} + +function mock(string $class): MockInterface +{ + return Mockery::mock($class); +} diff --git a/tests/mock-api.php b/tests/mock-api.php deleted file mode 100644 index c7a2eaf4..00000000 --- a/tests/mock-api.php +++ /dev/null @@ -1,223 +0,0 @@ - WP_CONTENT_DIR . '/uploads/test', - 'url' => content_url() . '/uploads/test', - 'subdir' => '/test', - 'basedir' => WP_CONTENT_DIR . '/uploads', - 'baseurl' => content_url() . '/uploads' - ]; - } -} - -if (! function_exists('add_filter')) { - function add_filter($key, callable $callback) - { - $GLOBALS['mock-hooks'][$key] = $callback; - - return null; - } -} - -if (! function_exists('apply_filters')) { - function apply_filters($key, $value = null) - { - if (array_key_exists($key, $GLOBALS['mock-hooks'])) { - $callback = $GLOBALS['mock-hooks'][$key]; - unset($GLOBALS['mock-hooks'][$key]); - $args = func_get_args(); - unset($args[0]); - $value = call_user_func($callback, ...$args); - } - - return $value; - } -} - -if (! function_exists('doing_filter')) { - function doing_filter($key) - { - return ! array_key_exists($key, $GLOBALS['mock-hooks']); - } -} - -if (! function_exists('add_action')) { - function add_action($key, $callback) - { - return add_filter($key, $callback); - } -} - -if (! function_exists('do_action')) { - function do_action($key, $value = null) - { - return apply_filters($key, $value); - } -} - -if (! function_exists('did_action')) { - function did_action($key) - { - return doing_filter($key); - } -} - -if (! function_exists('doing_action')) { - function doing_action($key) - { - return doing_filter($key); - } -} - -if (! function_exists('__')) { - function __(): string - { - return mock_translation(...func_get_args()); - } -} - -if (! function_exists('_x')) { - function _x(): string - { - return mock_translation(...func_get_args()); - } -} - -if (! function_exists('_e')) { - function _e(): void - { - echo mock_translation(...func_get_args()); - } -} - -if (! function_exists('_cleanup_header_comment')) { - /** - * Strip close comment and close php tags from file headers used by WP. - * @link https://github.com/WordPress/WordPress/blob/5.2.1/wp-includes/functions.php#L5480-L5492 - * - * @param string $str Header comment to clean up. - * @return string - */ - function _cleanup_header_comment($str) - { - return trim(preg_replace('/\s*(?:\*\/|\?>).*/', '', $str)); - } -} - -if (! function_exists('sanitize_key')) { - /** - * Sanitizes a string key. - * @link https://github.com/WordPress/WordPress/blob/5.2.1/wp-includes/formatting.php#L2114-L2138 - * - * @param string $key String key - * @return string Sanitized key - */ - function sanitize_key($key) - { - $key = strtolower($key); - $key = preg_replace('/[^a-z0-9_\-]/', '', $key); - return $key; - } -} - -if (! function_exists('get_body_class')) { - function get_body_class() - { - return $GLOBALS['body-class']; - } -} - -if (! function_exists('get_template_directory')) { - function get_template_directory() - { - return TEMPLATEPATH; - } -} - -if (! function_exists('get_current_user_id')) { - function get_current_user_id() - { - return 1; - } -} - -if (! class_exists('WP_Post')) { - final class WP_Post - { - - } -} - -function mock_translation() -{ - return 'translated.' . func_get_arg(0); -}