mirror of
https://github.com/pestphp/pest.git
synced 2026-07-21 17:10:03 +02:00
chore: fixes tia when not running on root
This commit is contained in:
+46
-10
@@ -29,22 +29,54 @@ async function loadRolldown() {
|
||||
return await import(pathToFileURL(path).href)
|
||||
}
|
||||
|
||||
async function readJsonWithComments(path) {
|
||||
const raw = await readFile(path, 'utf8')
|
||||
const stripped = raw
|
||||
.replace(/\/\*[\s\S]*?\*\//g, '')
|
||||
.replace(/(^|[^:])\/\/[^\n]*/g, '$1')
|
||||
return JSON.parse(stripped)
|
||||
export function stripJsonComments(raw) {
|
||||
let out = ''
|
||||
let inString = false
|
||||
let quote = ''
|
||||
let inLine = false
|
||||
let inBlock = false
|
||||
|
||||
for (let i = 0; i < raw.length; i++) {
|
||||
const c = raw[i]
|
||||
const n = raw[i + 1]
|
||||
|
||||
if (inLine) {
|
||||
if (c === '\n') { inLine = false; out += c }
|
||||
continue
|
||||
}
|
||||
if (inBlock) {
|
||||
if (c === '*' && n === '/') { inBlock = false; i++ }
|
||||
continue
|
||||
}
|
||||
if (inString) {
|
||||
out += c
|
||||
if (c === '\\') { out += n ?? ''; i++; continue }
|
||||
if (c === quote) inString = false
|
||||
continue
|
||||
}
|
||||
if (c === '"' || c === "'") { inString = true; quote = c; out += c; continue }
|
||||
if (c === '/' && n === '/') { inLine = true; i++; continue }
|
||||
if (c === '/' && n === '*') { inBlock = true; i++; continue }
|
||||
if (c === '}' || c === ']') out = out.replace(/,\s*$/, '')
|
||||
out += c
|
||||
}
|
||||
|
||||
async function loadAliasFromTsconfig() {
|
||||
return out
|
||||
}
|
||||
|
||||
async function readJsonWithComments(path) {
|
||||
const raw = await readFile(path, 'utf8')
|
||||
return JSON.parse(stripJsonComments(raw))
|
||||
}
|
||||
|
||||
export async function loadAliasFromTsconfig(projectRoot = PROJECT_ROOT) {
|
||||
const alias = {}
|
||||
for (const name of ['tsconfig.json', 'jsconfig.json']) {
|
||||
const p = join(PROJECT_ROOT, name)
|
||||
const p = join(projectRoot, name)
|
||||
if (!existsSync(p)) continue
|
||||
let cfg
|
||||
try { cfg = await readJsonWithComments(p) } catch { continue }
|
||||
const baseUrl = resolve(PROJECT_ROOT, cfg?.compilerOptions?.baseUrl ?? '.')
|
||||
const baseUrl = resolve(projectRoot, cfg?.compilerOptions?.baseUrl ?? '.')
|
||||
const paths = cfg?.compilerOptions?.paths ?? {}
|
||||
for (const [key, targets] of Object.entries(paths)) {
|
||||
if (!key.endsWith('/*')) continue
|
||||
@@ -230,10 +262,14 @@ async function main() {
|
||||
process.stdout.write(JSON.stringify(payload))
|
||||
}
|
||||
|
||||
const invokedDirectly = process.argv[1] !== undefined
|
||||
&& import.meta.url === pathToFileURL(process.argv[1]).href
|
||||
|
||||
if (invokedDirectly) {
|
||||
try {
|
||||
void pathToFileURL
|
||||
await main()
|
||||
} catch (err) {
|
||||
process.stderr.write(String(err?.stack ?? err ?? 'unknown error'))
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.4",
|
||||
"brianium/paratest": "^7.22.4",
|
||||
"brianium/paratest": "^7.23.0",
|
||||
"nunomaduro/collision": "^8.9.4",
|
||||
"nunomaduro/termwind": "^2.4.0",
|
||||
"pestphp/pest-plugin": "^5.0.0",
|
||||
@@ -59,7 +59,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"mrpunyapal/peststan": "^0.2.11",
|
||||
"laravel/pao": "^1.1.1",
|
||||
"laravel/pao": "^1.1.2",
|
||||
"pestphp/pest-dev-tools": "^5.0.0",
|
||||
"pestphp/pest-plugin-browser": "^5.0.0",
|
||||
"pestphp/pest-plugin-type-coverage": "^5.0.0",
|
||||
|
||||
@@ -122,9 +122,9 @@ final readonly class Configuration
|
||||
/**
|
||||
* Gets the evals configuration.
|
||||
*/
|
||||
public function evals(): Evals\Configuration
|
||||
public function evals(): Evals\Configuration // @phpstan-ignore-line
|
||||
{
|
||||
return new Evals\Configuration;
|
||||
return new Evals\Configuration; // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pest\Exceptions;
|
||||
|
||||
use NunoMaduro\Collision\Contracts\RenderlessEditor;
|
||||
use NunoMaduro\Collision\Contracts\RenderlessTrace;
|
||||
use Pest\Contracts\Panicable;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class TiaRequiresRepositoryRoot extends RuntimeException implements ExceptionInterface, Panicable, RenderlessEditor, RenderlessTrace
|
||||
{
|
||||
public function __construct(private readonly string $subdirectoryPrefix)
|
||||
{
|
||||
parent::__construct(sprintf(
|
||||
'Tia mode requires the project root to be the git repository root, but it sits in the subdirectory [%s] of a larger repo.',
|
||||
$this->subdirectoryPrefix,
|
||||
));
|
||||
}
|
||||
|
||||
public function render(OutputInterface $output): void
|
||||
{
|
||||
$output->writeln([
|
||||
'',
|
||||
' <fg=white;options=bold;bg=red> ERROR </> Tia mode requires the git repository root.',
|
||||
'',
|
||||
sprintf(' This project sits in a subdirectory of a larger repo <fg=yellow>%s</>.', $this->subdirectoryPrefix),
|
||||
'',
|
||||
' Give the project its own git repository to use Tia.',
|
||||
'',
|
||||
]);
|
||||
}
|
||||
|
||||
public function exitCode(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ final class HigherOrderExpectation
|
||||
* Dynamically calls methods on the class with the given arguments.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
* @return self<TOriginalValue, mixed>|self<TOriginalValue, TValue>
|
||||
* @return self<TOriginalValue, mixed>
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
{
|
||||
@@ -127,7 +127,7 @@ final class HigherOrderExpectation
|
||||
/**
|
||||
* Accesses properties in the value or in the expectation.
|
||||
*
|
||||
* @return self<TOriginalValue, mixed>|self<TOriginalValue, TValue>
|
||||
* @return self<TOriginalValue, mixed>
|
||||
*/
|
||||
public function __get(string $name): self
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ use Pest\Contracts\Plugins\AddsOutput;
|
||||
use Pest\Contracts\Plugins\HandlesArguments;
|
||||
use Pest\Contracts\Plugins\Terminable;
|
||||
use Pest\Exceptions\NoAffectedTestsFound;
|
||||
use Pest\Exceptions\TiaRequiresRepositoryRoot;
|
||||
use Pest\Panic;
|
||||
use Pest\Plugins\Concerns\HandleArguments;
|
||||
use Pest\Plugins\Tia\BaselineSync;
|
||||
@@ -627,6 +628,13 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable
|
||||
private function handleParent(array $arguments, string $projectRoot, bool $forceRebuild): array
|
||||
{
|
||||
$this->watchPatterns->useDefaults($projectRoot);
|
||||
|
||||
$subdirectoryPrefix = $this->gitSubdirectoryPrefix($projectRoot);
|
||||
|
||||
if ($subdirectoryPrefix !== null) {
|
||||
Panic::with(new TiaRequiresRepositoryRoot($subdirectoryPrefix));
|
||||
}
|
||||
|
||||
$this->branch = new ChangedFiles($projectRoot)->currentBranch() ?? 'main';
|
||||
|
||||
$fingerprint = Fingerprint::compute($projectRoot);
|
||||
@@ -1643,6 +1651,27 @@ final class Tia implements AddsOutput, HandlesArguments, Terminable
|
||||
return implode(', ', array_keys($seen));
|
||||
}
|
||||
|
||||
/**
|
||||
* The path from the git repository root down to $projectRoot (e.g.
|
||||
* `laravel-app`) when the project is nested inside a larger repo, or `null`
|
||||
* when the project root is itself the repo root (or git is unavailable).
|
||||
* TIA requires the two to coincide: git reports and addresses paths
|
||||
* relative to the repo root, while the dependency graph is project-relative.
|
||||
*/
|
||||
private function gitSubdirectoryPrefix(string $projectRoot): ?string
|
||||
{
|
||||
$process = new Process(['git', 'rev-parse', '--show-prefix'], $projectRoot);
|
||||
$process->run();
|
||||
|
||||
if (! $process->isSuccessful()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$prefix = trim($process->getOutput());
|
||||
|
||||
return $prefix === '' ? null : rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $prefix), '/');
|
||||
}
|
||||
|
||||
private function composerLockDelta(string $projectRoot, string $sha): string
|
||||
{
|
||||
$current = @file_get_contents($projectRoot.'/composer.lock');
|
||||
|
||||
@@ -1820,6 +1820,9 @@
|
||||
✓ does not throw when an integer --random-order-seed is passed as a separate argv element
|
||||
✓ still detects --tia when an integer argument is present
|
||||
|
||||
PASS Tests\Unit\Plugins\Tia\ViteDepsHelper
|
||||
✓ loadAliasFromTsconfig() → it resolves an @/* alias from a commented tsconfig with glob includes
|
||||
|
||||
PASS Tests\Unit\Preset
|
||||
✓ preset invalid name
|
||||
✓ preset → myFramework
|
||||
@@ -2006,4 +2009,4 @@
|
||||
✓ pass with dataset with ('my-datas-set-value')
|
||||
✓ within describe → pass with dataset with ('my-datas-set-value')
|
||||
|
||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1389 passed (3097 assertions)
|
||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 40 todos, 35 skipped, 1390 passed (3099 assertions)
|
||||
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
function tiaViteHelperPath(): string
|
||||
{
|
||||
return dirname(__DIR__, 4).'/bin/pest-tia-vite-deps.mjs';
|
||||
}
|
||||
|
||||
function tiaJson(mixed $value): string
|
||||
{
|
||||
return json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
function tiaStripFixtures(): array
|
||||
{
|
||||
return [
|
||||
'plain-object' => ['{"a":1,"b":2}', ['a' => 1, 'b' => 2]],
|
||||
'plain-array' => ['[1,2,3]', [1, 2, 3]],
|
||||
'nested' => ['{"a":{"b":[1,2]}}', ['a' => ['b' => [1, 2]]]],
|
||||
'empty-object' => ['{}', []],
|
||||
'empty-array' => ['[]', []],
|
||||
|
||||
'line-comment-own-line' => ["{\n// comment\n\"a\":1\n}", ['a' => 1]],
|
||||
'line-comment-trailing' => ["{\"a\":1 // trailing\n}", ['a' => 1]],
|
||||
'leading-line-comments' => ["// a\n// b\n{\"a\":1}", ['a' => 1]],
|
||||
'line-comment-eof-no-newline' => ['{"a":1}// end', ['a' => 1]],
|
||||
|
||||
'block-comment-leading' => ['{/* c */"a":1}', ['a' => 1]],
|
||||
'block-comment-inline' => ['{"a":1,/* c */"b":2}', ['a' => 1, 'b' => 2]],
|
||||
'block-comment-multiline' => ["{\n/* line1\nline2 */\n\"a\":1\n}", ['a' => 1]],
|
||||
'block-comment-eof' => ['{"a":1}/* end */', ['a' => 1]],
|
||||
'jsdoc-style-block' => ["{\n/**\n * doc\n */\n\"a\":1\n}", ['a' => 1]],
|
||||
'block-contains-double-slash' => ['{/* // inside */"a":1}', ['a' => 1]],
|
||||
'line-then-block' => ["{// l\n/* b */\"a\":1}", ['a' => 1]],
|
||||
'comment-with-quotes' => ['{/* "b":2 */"a":1}', ['a' => 1]],
|
||||
'comment-with-braces-commas' => ['{"a":1 /* },{ */,"b":2}', ['a' => 1, 'b' => 2]],
|
||||
|
||||
'trailing-comma-object' => ['{"a":1,}', ['a' => 1]],
|
||||
'trailing-comma-array' => ['[1,2,]', [1, 2]],
|
||||
'trailing-comma-nested' => ['{"a":[1,2,],"b":{"c":3,},}', ['a' => [1, 2], 'b' => ['c' => 3]]],
|
||||
'trailing-comma-newline' => ["{\n\"a\":1,\n}", ['a' => 1]],
|
||||
'trailing-comma-then-block' => ['{"a":1, /* x */ }', ['a' => 1]],
|
||||
'trailing-comma-then-line' => ["{\"a\":1, // x\n}", ['a' => 1]],
|
||||
|
||||
'crlf-line-comment' => ["{\r\n\"a\":1 // c\r\n}", ['a' => 1]],
|
||||
'tabs-whitespace' => ["{\n\t\"a\":\t1\n}", ['a' => 1]],
|
||||
|
||||
'url-in-string' => [tiaJson(['u' => 'https://example.com//x']), ['u' => 'https://example.com//x']],
|
||||
'glob-in-string' => [tiaJson(['g' => 'resources/js/**/*.ts']), ['g' => 'resources/js/**/*.ts']],
|
||||
'path-alias-in-string' => [tiaJson(['p' => '@/*']), ['p' => '@/*']],
|
||||
'block-open-in-string' => [tiaJson(['s' => 'a/*b']), ['s' => 'a/*b']],
|
||||
'block-close-in-string' => [tiaJson(['s' => 'b*/c']), ['s' => 'b*/c']],
|
||||
'block-both-in-string' => [tiaJson(['s' => 'x/*y*/z']), ['s' => 'x/*y*/z']],
|
||||
'star-in-string' => [tiaJson(['s' => '5 * 3']), ['s' => '5 * 3']],
|
||||
'single-slashes-in-string' => [tiaJson(['s' => 'a/b/c']), ['s' => 'a/b/c']],
|
||||
|
||||
'escaped-quote-in-string' => [tiaJson(['s' => 'a"b']), ['s' => 'a"b']],
|
||||
'escaped-backslash-in-string' => [tiaJson(['s' => 'a\\']), ['s' => 'a\\']],
|
||||
'backslash-then-slash' => [tiaJson(['s' => 'a\\/b']), ['s' => 'a\\/b']],
|
||||
'newline-escape-in-string' => [tiaJson(['s' => "a\nb"]), ['s' => "a\nb"]],
|
||||
'unicode-in-string' => [tiaJson(['s' => 'café ☕']), ['s' => 'café ☕']],
|
||||
|
||||
'block-secret' => ['{"a":1/*SECRET*/}', ['a' => 1]],
|
||||
];
|
||||
}
|
||||
|
||||
function tiaStripResults(): array
|
||||
{
|
||||
static $cache = null;
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$payload = [];
|
||||
foreach (tiaStripFixtures() as $name => [$raw]) {
|
||||
$payload[] = ['name' => $name, 'raw' => $raw];
|
||||
}
|
||||
|
||||
$inputFile = tempnam(sys_get_temp_dir(), 'tia-strip-');
|
||||
file_put_contents($inputFile, json_encode($payload));
|
||||
|
||||
$helper = str_replace('\\', '/', tiaViteHelperPath());
|
||||
$input = str_replace('\\', '/', $inputFile);
|
||||
|
||||
$script = <<<JS
|
||||
import { stripJsonComments } from '{$helper}'
|
||||
import { readFileSync } from 'node:fs'
|
||||
const cases = JSON.parse(readFileSync('{$input}', 'utf8'))
|
||||
const out = {}
|
||||
for (const c of cases) {
|
||||
const stripped = stripJsonComments(c.raw)
|
||||
const entry = { stripped }
|
||||
try { entry.parsed = JSON.parse(stripped); entry.ok = true }
|
||||
catch (e) { entry.ok = false; entry.error = String(e && e.message ? e.message : e) }
|
||||
out[c.name] = entry
|
||||
}
|
||||
process.stdout.write(JSON.stringify(out))
|
||||
JS;
|
||||
|
||||
$process = new Process(['node', '--input-type=module', '-e', $script]);
|
||||
$process->mustRun();
|
||||
|
||||
@unlink($inputFile);
|
||||
|
||||
return $cache = json_decode($process->getOutput(), true, flags: JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
function tiaAliasFixtures(): array
|
||||
{
|
||||
$config = fn (array $compilerOptions): array => ['tsconfig.json' => tiaJson(['compilerOptions' => $compilerOptions])];
|
||||
|
||||
return [
|
||||
'basic' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@/*' => ['./resources/js/*']]]),
|
||||
['@' => 'resources/js'],
|
||||
],
|
||||
'multiple-aliases' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@/*' => ['./resources/js/*'], '~/*' => ['./src/*']]]),
|
||||
['@' => 'resources/js', '~' => 'src'],
|
||||
],
|
||||
'default-baseUrl' => [
|
||||
$config(['paths' => ['@/*' => ['./resources/js/*']]]),
|
||||
['@' => 'resources/js'],
|
||||
],
|
||||
'baseUrl-subdir' => [
|
||||
$config(['baseUrl' => 'src', 'paths' => ['@/*' => ['lib/*']]]),
|
||||
['@' => 'src/lib'],
|
||||
],
|
||||
'jsconfig-fallback' => [
|
||||
['jsconfig.json' => tiaJson(['compilerOptions' => ['baseUrl' => '.', 'paths' => ['@/*' => ['./resources/js/*']]]])],
|
||||
['@' => 'resources/js'],
|
||||
],
|
||||
'first-target-wins' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@/*' => ['./a/*', './b/*']]]),
|
||||
['@' => 'a'],
|
||||
],
|
||||
'multiple-keys-mixed' => [
|
||||
$config(['baseUrl' => '.', 'paths' => [
|
||||
'@/*' => ['./resources/js/*'],
|
||||
'bad' => ['./x/*'],
|
||||
'~/*' => ['./nope'],
|
||||
]]),
|
||||
['@' => 'resources/js'],
|
||||
],
|
||||
'no-paths' => [
|
||||
$config(['baseUrl' => '.']),
|
||||
[],
|
||||
],
|
||||
'no-compiler-options' => [
|
||||
['tsconfig.json' => '{}'],
|
||||
[],
|
||||
],
|
||||
'key-without-glob' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@' => ['./resources/js/*']]]),
|
||||
[],
|
||||
],
|
||||
'target-without-glob' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@/*' => ['./resources/js']]]),
|
||||
[],
|
||||
],
|
||||
'target-not-array' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@/*' => './resources/js/*']]),
|
||||
[],
|
||||
],
|
||||
'target-empty-array' => [
|
||||
$config(['baseUrl' => '.', 'paths' => ['@/*' => []]]),
|
||||
[],
|
||||
],
|
||||
'commented-tsconfig' => [
|
||||
['tsconfig.json' => <<<'JSON'
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more. */
|
||||
"target": "ESNext", // language target
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./resources/js/*"],
|
||||
},
|
||||
},
|
||||
}
|
||||
JSON],
|
||||
['@' => 'resources/js'],
|
||||
],
|
||||
'trailing-comma-paths' => [
|
||||
['tsconfig.json' => '{"compilerOptions":{"baseUrl":".","paths":{"@/*":["./resources/js/*",],},},}'],
|
||||
['@' => 'resources/js'],
|
||||
],
|
||||
'malformed-json' => [
|
||||
['tsconfig.json' => '{ this is not json'],
|
||||
[],
|
||||
],
|
||||
'missing-config' => [
|
||||
[],
|
||||
[],
|
||||
],
|
||||
'tsconfig-precedence' => [
|
||||
[
|
||||
'tsconfig.json' => tiaJson(['compilerOptions' => ['baseUrl' => '.', 'paths' => ['@/*' => ['./a/*']]]]),
|
||||
'jsconfig.json' => tiaJson(['compilerOptions' => ['baseUrl' => '.', 'paths' => ['@/*' => ['./b/*']]]]),
|
||||
],
|
||||
['@' => 'a'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
function tiaAliasResults(): array
|
||||
{
|
||||
static $cache = null;
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$roots = [];
|
||||
$written = [];
|
||||
$payload = [];
|
||||
|
||||
foreach (tiaAliasFixtures() as $name => [$files]) {
|
||||
$root = sys_get_temp_dir().'/pest-tia-'.bin2hex(random_bytes(6));
|
||||
mkdir($root, 0755, true);
|
||||
foreach ($files as $fname => $content) {
|
||||
file_put_contents($root.'/'.$fname, $content);
|
||||
$written[] = $root.'/'.$fname;
|
||||
}
|
||||
$root = str_replace('\\', '/', $root);
|
||||
$roots[$name] = $root;
|
||||
$payload[] = ['name' => $name, 'root' => $root];
|
||||
}
|
||||
|
||||
$inputFile = tempnam(sys_get_temp_dir(), 'tia-alias-');
|
||||
file_put_contents($inputFile, json_encode($payload));
|
||||
|
||||
$helper = str_replace('\\', '/', tiaViteHelperPath());
|
||||
$input = str_replace('\\', '/', $inputFile);
|
||||
|
||||
$script = <<<JS
|
||||
import { loadAliasFromTsconfig } from '{$helper}'
|
||||
import { readFileSync } from 'node:fs'
|
||||
const cases = JSON.parse(readFileSync('{$input}', 'utf8'))
|
||||
const out = {}
|
||||
for (const c of cases) out[c.name] = await loadAliasFromTsconfig(c.root)
|
||||
process.stdout.write(JSON.stringify(out))
|
||||
JS;
|
||||
|
||||
$process = new Process(['node', '--input-type=module', '-e', $script]);
|
||||
$process->mustRun();
|
||||
|
||||
$aliases = json_decode($process->getOutput(), true, flags: JSON_THROW_ON_ERROR);
|
||||
|
||||
@unlink($inputFile);
|
||||
foreach ($written as $f) {
|
||||
@unlink($f);
|
||||
}
|
||||
foreach ($roots as $r) {
|
||||
@rmdir($r);
|
||||
}
|
||||
|
||||
return $cache = ['roots' => $roots, 'aliases' => $aliases];
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
if ((new ExecutableFinder)->find('node') === null) {
|
||||
$this->markTestSkipped('node is not available.');
|
||||
}
|
||||
});
|
||||
|
||||
it('strips JSONC down to something JSON.parse accepts', function (string $name) {
|
||||
$result = tiaStripResults()[$name];
|
||||
[, $expected] = tiaStripFixtures()[$name];
|
||||
|
||||
expect($result['ok'])->toBeTrue(
|
||||
"[{$name}] did not parse after stripping: ".($result['error'] ?? 'unknown').PHP_EOL.
|
||||
'stripped: '.$result['stripped'],
|
||||
);
|
||||
expect($result['parsed'])->toEqual($expected);
|
||||
})->with(array_keys(tiaStripFixtures()));
|
||||
|
||||
it('never touches comment-looking sequences inside string values', function () {
|
||||
expect(tiaStripResults()['url-in-string']['stripped'])->toContain('https://example.com//x')
|
||||
->and(tiaStripResults()['glob-in-string']['stripped'])->toContain('resources/js/**/*.ts')
|
||||
->and(tiaStripResults()['block-both-in-string']['stripped'])->toContain('x/*y*/z');
|
||||
});
|
||||
|
||||
it('removes the comment body entirely', function () {
|
||||
expect(tiaStripResults()['block-secret']['stripped'])->not->toContain('SECRET');
|
||||
});
|
||||
|
||||
it('builds the expected alias map from a tsconfig', function (string $name) {
|
||||
$results = tiaAliasResults();
|
||||
[, $expectedRelative] = tiaAliasFixtures()[$name];
|
||||
|
||||
$root = $results['roots'][$name];
|
||||
$expected = [];
|
||||
foreach ($expectedRelative as $key => $relative) {
|
||||
$expected[$key] = $root.'/'.$relative;
|
||||
}
|
||||
|
||||
expect($results['aliases'][$name])->toEqual($expected);
|
||||
})->with(array_keys(tiaAliasFixtures()));
|
||||
@@ -24,13 +24,13 @@ test('parallel', function () use ($run) {
|
||||
$file = file_get_contents(__FILE__);
|
||||
$file = preg_replace(
|
||||
'/\$expected = \'.*?\';/',
|
||||
"\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1372 passed (3044 assertions)';",
|
||||
"\$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1373 passed (3046 assertions)';",
|
||||
$file,
|
||||
);
|
||||
file_put_contents(__FILE__, $file);
|
||||
}
|
||||
|
||||
$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1372 passed (3044 assertions)';
|
||||
$expected = '2 deprecated, 4 warnings, 5 incomplete, 3 notices, 40 todos, 27 skipped, 1373 passed (3046 assertions)';
|
||||
|
||||
expect($output)
|
||||
->toContain("Tests: {$expected}")
|
||||
|
||||
Reference in New Issue
Block a user