diff --git a/readme.md b/readme.md index 6a559060..5fe03a5a 100644 --- a/readme.md +++ b/readme.md @@ -6,8 +6,8 @@ ## Install (Requires PHP 8.1+) ->**Note** ->TLint is intended to work with the tools included in [Duster](https://github.com/tighten/duster). To receive the best coverage we recommend using Duster to install and configure TLint. +> **Note** +> TLint is intended to work with the tools included in [Duster](https://github.com/tighten/duster). To receive the best coverage we recommend using Duster to install and configure TLint. ```bash # Include in project @@ -35,13 +35,13 @@ TLint 9 requires PHP >= 8.1. Now linting the following files and directories: -- `public/` -- `bootstrap/` -- `server.php` -- `app/Http/Middleware/RedirectIfAuthenticated.php` -- `Exceptions/Handler.php` -- `app/Http/Controllers/Auth/` -- `app/Http/Kernel.php` +- `public/` +- `bootstrap/` +- `server.php` +- `app/Http/Middleware/RedirectIfAuthenticated.php` +- `Exceptions/Handler.php` +- `app/Http/Controllers/Auth/` +- `app/Http/Kernel.php` To continue excluding these files and directories add them to your `tlint.json` file under `excluded`. @@ -53,7 +53,7 @@ If you want to roll these out gradually or disable them altogether, you can use ### Upgrading from 6.x to 7.x TLint focuses on linting and formatting issues other tools are not able to catch. -The `7.x` release removes lints and formatters covered by tools in [Duster](https://github.com/tighten/duster). If you need to add these back you can grab them from an earlier version of TLint and follow the [Custom Configuration](#custom-configuration--presets) documentation. +The `7.x` release removes lints and formatters covered by tools in [Duster](https://github.com/tighten/duster). If you need to add these back you can grab them from an earlier version of TLint and follow the [Custom Configuration](#custom-configuration--presets) documentation. ## What Is It? @@ -114,6 +114,7 @@ tlint lint test.php --json ``` Want the output from a file as a [checkstyle XML report](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/v3.22.0/doc/schemas/fix/checkstyle.xsd)? (Primarily used with CI tools like [reviewdog](https://github.com/reviewdog/reviewdog) and [cs2pr](https://github.com/staabm/annotate-pull-request-from-checkstyle)) + ``` tlint lint test.php --checkstyle ``` @@ -220,97 +221,93 @@ This lets you define custom linting/formatting functionality, or modify the exis ## Available Linters -| Linter | Description | -| --- | --- | -| `ApplyMiddlewareInRoutes` | Apply middleware in routes (not controllers). | -| `ArrayParametersOverViewWith` | Prefer `view(..., [...])` over `view(...)->with(...)`. | -| `FullyQualifiedFacades` | Import facades using their full namespace. | -| `MailableMethodsInBuild` | Mailable values (from and subject etc) should be set in build(). | -| `NoDatesPropertyOnModels` | The `$dates` property was deprecated in Laravel 8. Use `$casts` instead. | -| `NoDocBlocksForMigrationUpDown` | Remove doc blocks from the up and down method in migrations. | -| `NoJsonDirective` | Use blade `{{ $model }}` auto escaping for models, and double quotes via json_encode over @json blade directive: `` -> `` OR `` | -| `NoLeadingSlashesOnRoutePaths` | No leading slashes on route paths. | -| `NoRequestAll` | No `request()->all()`. Use `request()->only(...)` to retrieve specific input values. | -| `NoSpaceAfterBladeDirectives` | No space between blade template directive names and the opening paren:`@section (` -> `@section(` | -| `OneLineBetweenClassVisibilityChanges` | Class members of differing visibility must be separated by a blank line | -| `PureRestControllers` | You should not mix restful and non-restful public methods in a controller | -| `QualifiedNamesOnlyForClassName` | Fully Qualified Class Names should only be used for accessing class names | -| `RemoveLeadingSlashNamespaces` | Prefer `Namespace\...` over `\Namespace\...`. | -| `RequestHelperFunctionWherePossible` | Use the request(...) helper function directly to access request values wherever possible | -| `RequestValidation` | Use `request()->validate(...)` helper function or extract a FormRequest instead of using `$this->validate(...)` in controllers | -| `SpaceAfterBladeDirectives` | Put a space between blade control structure names and the opening paren:`@if(` -> `@if (` | -| `SpacesAroundBladeRenderContent` | Spaces around blade rendered content:`{{1 + 1}}` -> `{{ 1 + 1 }}` | -| `UseAnonymousMigrations` | Prefer anonymous class migrations. | -| `UseAuthHelperOverFacade` | Prefer the `auth()` helper function over the `Auth` Facade. | +| Linter | Description | +| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ApplyMiddlewareInRoutes` | Apply middleware in routes (not controllers). | +| `ArrayParametersOverViewWith` | Prefer `view(..., [...])` over `view(...)->with(...)`. | +| `FullyQualifiedFacades` | Import facades using their full namespace. | +| `MailableMethodsInBuild` | Mailable values (from and subject etc) should be set in build(). | +| `NoDatesPropertyOnModels` | The `$dates` property was deprecated in Laravel 8. Use `$casts` instead. | +| `NoDocBlocksForMigrationUpDown` | Remove doc blocks from the up and down method in migrations. | +| `NoJsonDirective` | Use blade `{{ $model }}` auto escaping for models, and double quotes via json_encode over @json blade directive: `` -> `` OR `` | +| `NoLeadingSlashesOnRoutePaths` | No leading slashes on route paths. | +| `NoRequestAll` | No `request()->all()`. Use `request()->only(...)` to retrieve specific input values. | +| `NoSpaceAfterBladeDirectives` | No space between blade template directive names and the opening paren:`@section (` -> `@section(` | +| `OneLineBetweenClassVisibilityChanges` | Class members of differing visibility must be separated by a blank line | +| `PureRestControllers` | You should not mix restful and non-restful public methods in a controller | +| `QualifiedNamesOnlyForClassName` | Fully Qualified Class Names should only be used for accessing class names | +| `RemoveLeadingSlashNamespaces` | Prefer `Namespace\...` over `\Namespace\...`. | +| `RequestHelperFunctionWherePossible` | Use the request(...) helper function directly to access request values wherever possible | +| `RequestValidation` | Use `request()->validate(...)` helper function or extract a FormRequest instead of using `$this->validate(...)` in controllers | +| `SpaceAfterBladeDirectives` | Put a space between blade control structure names and the opening paren:`@if(` -> `@if (` | +| `SpacesAroundBladeRenderContent` | Spaces around blade rendered content:`{{1 + 1}}` -> `{{ 1 + 1 }}` | +| `UseAnonymousMigrations` | Prefer anonymous class migrations. | ### General PHP -- `OneLineBetweenClassVisibilityChanges` -- `QualifiedNamesOnlyForClassName` -- `RemoveLeadingSlashNamespaces` +- `OneLineBetweenClassVisibilityChanges` +- `QualifiedNamesOnlyForClassName` +- `RemoveLeadingSlashNamespaces` ### Laravel -- `ApplyMiddlewareInRoutes` -- `ArrayParametersOverViewWith` -- `FullyQualifiedFacades` -- `MailableMethodsInBuild` -- `NoLeadingSlashesOnRoutePaths` -- `NoDocBlocksForMigrationUpDown` -- `NoJsonDirective` -- `NoSpaceAfterBladeDirectives`, `SpaceAfterBladeDirectives` -- `PureRestControllers` -- `RequestHelperFunctionWherePossible` -- `RequestValidation` -- `SpacesAroundBladeRenderContent` -- `UseAnonymousMigrations` -- `UseAuthHelperOverFacade` +- `ApplyMiddlewareInRoutes` +- `ArrayParametersOverViewWith` +- `FullyQualifiedFacades` +- `MailableMethodsInBuild` +- `NoLeadingSlashesOnRoutePaths` +- `NoDocBlocksForMigrationUpDown` +- `NoJsonDirective` +- `NoSpaceAfterBladeDirectives`, `SpaceAfterBladeDirectives` +- `PureRestControllers` +- `RequestHelperFunctionWherePossible` +- `RequestValidation` +- `SpacesAroundBladeRenderContent` +- `UseAnonymousMigrations` ## Available Formatters **Notes about formatting** -- Formatting is designed to alter the least amount of code possible. -- Import related formatters are not designed to alter grouped imports. - -| Formatter | Description | -| --- | --- | -| `ArrayParametersOverViewWith` | Prefer `view(..., [...])` over `view(...)->with(...)`. | -| `FullyQualifiedFacades` | Import facades using their full namespace. | -| `MailableMethodsInBuild` | Mailable values (from and subject etc) should be set in build(). | -| `NoDatesPropertyOnModels` | Use `$casts` instead of `$dates` on Eloquent models. | -| `NoDocBlocksForMigrationUpDown` | Removes doc blocks from the up and down method in migrations. | -| `NoLeadingSlashesOnRoutePaths` | No leading slashes on route paths. | -| `NoSpaceAfterBladeDirectives` | No space between blade template directive names and the opening paren:`@section (` -> `@section(` | -| `OneLineBetweenClassVisibilityChanges` | Class members of differing visibility must be separated by a blank line | -| `RemoveLeadingSlashNamespaces` | Prefer `Namespace\...` over `\Namespace\...`. | -| `RequestHelperFunctionWherePossible` | Use the request(...) helper function directly to access request values wherever possible | -| `RequestValidation` | Use `request()->validate(...)` helper function or extract a FormRequest instead of using `$this->validate(...)` in controllers | -| `SpaceAfterBladeDirectives` | Put a space between blade control structure names and the opening paren:`@if(` -> `@if (` | -| `SpacesAroundBladeRenderContent` | Spaces around blade rendered content:`{{1 + 1}}` -> `{{ 1 + 1 }}` | -| `UseAnonymousMigrations` | Prefer anonymous class migrations. | -| `UseAuthHelperOverFacade` | Prefer the `auth()` helper function over the `Auth` Facade. | +- Formatting is designed to alter the least amount of code possible. +- Import related formatters are not designed to alter grouped imports. + +| Formatter | Description | +| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `ArrayParametersOverViewWith` | Prefer `view(..., [...])` over `view(...)->with(...)`. | +| `FullyQualifiedFacades` | Import facades using their full namespace. | +| `MailableMethodsInBuild` | Mailable values (from and subject etc) should be set in build(). | +| `NoDatesPropertyOnModels` | Use `$casts` instead of `$dates` on Eloquent models. | +| `NoDocBlocksForMigrationUpDown` | Removes doc blocks from the up and down method in migrations. | +| `NoLeadingSlashesOnRoutePaths` | No leading slashes on route paths. | +| `NoSpaceAfterBladeDirectives` | No space between blade template directive names and the opening paren:`@section (` -> `@section(` | +| `OneLineBetweenClassVisibilityChanges` | Class members of differing visibility must be separated by a blank line | +| `RemoveLeadingSlashNamespaces` | Prefer `Namespace\...` over `\Namespace\...`. | +| `RequestHelperFunctionWherePossible` | Use the request(...) helper function directly to access request values wherever possible | +| `RequestValidation` | Use `request()->validate(...)` helper function or extract a FormRequest instead of using `$this->validate(...)` in controllers | +| `SpaceAfterBladeDirectives` | Put a space between blade control structure names and the opening paren:`@if(` -> `@if (` | +| `SpacesAroundBladeRenderContent` | Spaces around blade rendered content:`{{1 + 1}}` -> `{{ 1 + 1 }}` | +| `UseAnonymousMigrations` | Prefer anonymous class migrations. | ### General PHP -- `OneLineBetweenClassVisibilityChanges` -- `RemoveLeadingSlashNamespaces` +- `OneLineBetweenClassVisibilityChanges` +- `RemoveLeadingSlashNamespaces` ### Laravel -- `ArrayParametersOverViewWith` -- `FullyQualifiedFacades` -- `MailableMethodsInBuild` -- `NoDatesPropertyOnModels` -- `NoDocBlocksForMigrationUpDown` -- `NoLeadingSlashesOnRoutePaths` -- `NoSpaceAfterBladeDirectives` -- `RequestHelperFunctionWherePossible` -- `RequestValidation` -- `SpaceAfterBladeDirectives` -- `SpacesAroundBladeRenderContent` -- `UseAnonymousMigrations` -- `UseAuthHelperOverFacade` +- `ArrayParametersOverViewWith` +- `FullyQualifiedFacades` +- `MailableMethodsInBuild` +- `NoDatesPropertyOnModels` +- `NoDocBlocksForMigrationUpDown` +- `NoLeadingSlashesOnRoutePaths` +- `NoSpaceAfterBladeDirectives` +- `RequestHelperFunctionWherePossible` +- `RequestValidation` +- `SpaceAfterBladeDirectives` +- `SpacesAroundBladeRenderContent` +- `UseAnonymousMigrations` ## Contributing @@ -322,10 +319,10 @@ If you discover any security related issues, please email hello@tighten.co inste ## Credits -- [Logan Henson](https://github.com/loganhenson) -- [Jacob Baker-Kretzmar](https://github.com/bakerkretzmar) -- [Anthony Clark](https://github.com/driftingly) -- [All Contributors](../../contributors) +- [Logan Henson](https://github.com/loganhenson) +- [Jacob Baker-Kretzmar](https://github.com/bakerkretzmar) +- [Anthony Clark](https://github.com/driftingly) +- [All Contributors](../../contributors) ## License diff --git a/src/Commands/BaseCommand.php b/src/Commands/BaseCommand.php index 4a99ef2a..a1a74741 100644 --- a/src/Commands/BaseCommand.php +++ b/src/Commands/BaseCommand.php @@ -17,7 +17,7 @@ abstract class BaseCommand extends Command public $cwd; public $config; - public function __construct(string $cwd = null) + public function __construct(?string $cwd = null) { $this->cwd = $cwd; $configPath = $this->resolveFileOrDirectory('tlint.json'); diff --git a/src/Formatters/NoDatesPropertyOnModels.php b/src/Formatters/NoDatesPropertyOnModels.php index 72b6b9a8..a2603acd 100644 --- a/src/Formatters/NoDatesPropertyOnModels.php +++ b/src/Formatters/NoDatesPropertyOnModels.php @@ -76,7 +76,7 @@ private function nodeFinderForModelProperty(string $attribute): Closure }; } - private function addDatesToCasts(Property $dates, Property $casts = null): Property + private function addDatesToCasts(Property $dates, ?Property $casts = null): Property { // Get the names of all the existing date attributes $dateAttributes = array_map(function ($item) { diff --git a/src/Formatters/UseAuthHelperOverFacade.php b/src/Formatters/UseAuthHelperOverFacade.php deleted file mode 100644 index d3e91798..00000000 --- a/src/Formatters/UseAuthHelperOverFacade.php +++ /dev/null @@ -1,168 +0,0 @@ -bladeCode = $bladeCompiler->compileString($code); - } - - parent::__construct($code, $filename); - } - - public static function appliesToPath(string $path, array $configPaths): bool - { - return Linter::appliesToPath($path, $configPaths); - } - - public function format(Parser $parser, Lexer $lexer): string - { - if ($this->bladeCode) { - return $this->formatBlade($parser, $lexer); - } - - return $this->formatCode($this->code, $parser, $lexer); - } - - private function formatBlade(Parser $parser, Lexer $lexer) - { - // Check if compiled blade code contains any Auth:: calls - if ($this->bladeCode === $this->formatCode($this->bladeCode, $parser, $lexer)) { - return $this->code; - } - - // Find/replace in original blade code - foreach ($this->getCodeLines() as $index => $codeLine) { - $matches = []; - - preg_match_all( - self::AUTH_SEARCH, - $codeLine, - $matches, - PREG_SET_ORDER - ); - - foreach ($matches as $match) { - if (in_array($match[1], self::AUTH_HELPER_METHODS)) { - $codeLine = str_replace($match[0], 'auth()->' . $match[1] . '(', $codeLine); - - $this->code = $this->replaceCodeLine($index + 1, $codeLine); - } - } - } - - return $this->code; - } - - private function formatCode(string $code, Parser $parser, Lexer $lexer) - { - $traverser = new NodeTraverser; - $traverser->addVisitor(new CloningVisitor); - - $oldStmts = $parser->parse($code); - $newStmts = $traverser->traverse($oldStmts); - - $traverser = new NodeTraverser; - $traverser->addVisitor($this->visitor()); - - $newStmts = $traverser->traverse($newStmts); - - return (new Standard)->printFormatPreserving($newStmts, $oldStmts, $lexer->getTokens()); - } - - private function visitor(): NodeVisitorAbstract - { - return new class extends NodeVisitorAbstract - { - private bool $useAuthFacade = false; - - public function beforeTraverse(array $nodes) - { - $this->useAuthFacade = false; - - return null; - } - - public function enterNode(Node $node): Node|int|null - { - if ($node instanceof Node\Stmt\UseUse && $node->name instanceof Node\Name) { - if ($node->name->toString() === 'Illuminate\Support\Facades\Auth') { - $this->useAuthFacade = true; - } - } - - if (! $node instanceof Node\Expr\StaticCall) { - return null; - } - - if (! $node->class instanceof Node\Name) { - return null; - } - - if ($this->useAuthFacade && $node->class->toString() !== 'Auth') { - return null; - } - - if (! $this->useAuthFacade && $node->class->toString() !== 'Illuminate\Support\Facades\Auth') { - return null; - } - - if ($node->name->name === 'routes') { - return null; - } - - return new MethodCall(new FuncCall(new Name('auth')), $node->name, $node->args); - } - }; - } -} diff --git a/src/Illuminate/BladeCompiler.php b/src/Illuminate/BladeCompiler.php deleted file mode 100644 index 8bbf3605..00000000 --- a/src/Illuminate/BladeCompiler.php +++ /dev/null @@ -1,21 +0,0 @@ -files = $files; - $this->cachePath = $cachePath; - } -} diff --git a/src/Linters/UseAuthHelperOverFacade.php b/src/Linters/UseAuthHelperOverFacade.php deleted file mode 100644 index b54bc20f..00000000 --- a/src/Linters/UseAuthHelperOverFacade.php +++ /dev/null @@ -1,46 +0,0 @@ -compileString($code); - } - - parent::__construct($code, $filename); - } - - protected function visitor(): Closure - { - return function (Node $node) { - static $usesAuthFacade = false; - - if ($node instanceof Node\Stmt\UseUse && $node->name instanceof Node\Name) { - if ($node->name->toString() === 'Illuminate\Support\Facades\Auth') { - $usesAuthFacade = true; - } - } - - return $node instanceof Node\Expr\StaticCall - // use Illuminate\Support\Facades\Auth and calling Auth:: - && (($usesAuthFacade && $node->class instanceof Node\Name && $node->class->toString() === 'Auth') - // FQCN usage - || ( - $node->class instanceof Node\Name - && $node->class->toString() === 'Illuminate\Support\Facades\Auth' - )) - && ($node->class instanceof Node\Name && $node->name->name !== 'routes'); - }; - } -} diff --git a/src/Presets/TightenPreset.php b/src/Presets/TightenPreset.php index 21607ed5..37806eb7 100644 --- a/src/Presets/TightenPreset.php +++ b/src/Presets/TightenPreset.php @@ -25,7 +25,6 @@ public function getLinters(): array Linters\RequestValidation::class, Linters\SpaceAfterBladeDirectives::class, Linters\SpacesAroundBladeRenderContent::class, - Linters\UseAuthHelperOverFacade::class, Linters\NoJsonDirective::class, ]; } @@ -46,7 +45,6 @@ public function getFormatters(): array Formatters\RequestValidation::class, Formatters\SpaceAfterBladeDirectives::class, Formatters\SpacesAroundBladeRenderContent::class, - Formatters\UseAuthHelperOverFacade::class, ]; } } diff --git a/tests/Formatting/Formatters/UseAuthHelperOverFacadeTest.php b/tests/Formatting/Formatters/UseAuthHelperOverFacadeTest.php deleted file mode 100644 index fa81fdb6..00000000 --- a/tests/Formatting/Formatters/UseAuthHelperOverFacadeTest.php +++ /dev/null @@ -1,192 +0,0 @@ -Email - -@else - -@endif -file; - - $correctlyFormatted = <<<'file' -@extends('layouts.app') -@if (!auth()->check()) - - -@else - -@endif -file; - - $formatted = (new TFormat)->format( - new UseAuthHelperOverFacade($file, '.blade.php') - ); - - $this->assertEquals($correctlyFormatted, $formatted); - } - - /** @test */ - public function catches_auth_facade_usage_in_code() - { - $file = <<<'file' -name; -echo Auth::user()->projects()->count(); -Auth::login($user); - -RateLimiter::clear($this->throttleKey()); -file; - - $correctlyFormatted = <<<'file' -user()->name; -echo auth()->user()->projects()->count(); -auth()->login($user); - -RateLimiter::clear($this->throttleKey()); -file; - - $formatted = (new TFormat)->format( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals($correctlyFormatted, $formatted); - } - - /** @test */ - public function does_not_trigger_on_non_auth_call() - { - $file = <<<'file' -name; -file; - - $formatted = (new TFormat)->format( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals($file, $formatted); - } - - /** @test */ - public function does_not_trigger_on_non_facade_call() - { - $file = <<<'file' -value; -file; - - $formatted = (new TFormat)->format( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals($file, $formatted); - } - - /** @test */ - public function does_not_trigger_when_calling_routes() - { - $file = <<<'file' -format( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals($file, $formatted); - } - - /** @test */ - public function does_not_throw_when_file_contains_dynamic_class_variables() - { - $file = <<<'file' -count() > 0) { - return $className::all()->random(); - } - - return factory($className)->create(); - } -} -file; - - $formatted = (new TFormat)->format( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals($file, $formatted); - } - - /** @test */ - public function does_not_throw_when_using_static_call_on_dynamic_variable() - { - $file = <<<'file' -format( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals($file, $formatted); - } - - /** @test */ - public function does_not_attempt_to_compile_x_component_tags() - { - $file = <<<'file' - - Hello world! - -file; - - $formatted = (new TFormat)->format( - new UseAuthHelperOverFacade($file, '.blade.php') - ); - - $this->assertEquals($file, $formatted); - } -} diff --git a/tests/Linting/Linters/UseAuthHelperOverFacadeTest.php b/tests/Linting/Linters/UseAuthHelperOverFacadeTest.php deleted file mode 100644 index b7a37330..00000000 --- a/tests/Linting/Linters/UseAuthHelperOverFacadeTest.php +++ /dev/null @@ -1,163 +0,0 @@ -Email - - @else - - @endif -file; - - $lints = (new TLint)->lint( - new UseAuthHelperOverFacade($file, '.blade.php') - ); - - $this->assertNotNull($lints[0]); - } - - /** @test */ - public function catches_auth_facade_usage_in_code() - { - $file = <<name; -file; - - $lints = (new TLint)->lint( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEquals(4, $lints[0]->getNode()->getLine()); - } - - /** @test */ - public function does_not_trigger_on_non_auth_call() - { - $file = <<name; - file; - - $lints = (new TLint)->lint( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEmpty($lints); - } - - /** @test */ - public function does_not_trigger_on_non_facade_call() - { - $file = <<<'file' -value; -file; - - $lints = (new TLint)->lint( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEmpty($lints); - } - - /** @test */ - public function does_not_trigger_when_calling_routes() - { - $file = <<lint( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEmpty($lints); - } - - /** @test */ - public function does_not_throw_when_file_contains_dynamic_class_variables() - { - $file = <<count() > 0) { - return \$className::all()->random(); - } - - return factory(\$className)->create(); - } -} -file; - - $lints = (new TLint)->lint( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEmpty($lints); - } - - /** @test */ - public function does_not_throw_when_using_static_call_on_dynamic_variable() - { - $file = <<lint( - new UseAuthHelperOverFacade($file, '.php') - ); - - $this->assertEmpty($lints); - } - - /** @test */ - public function does_not_attempt_to_compile_x_component_tags() - { - $file = <<<'file' - - Hello world! - -file; - - $this->assertEmpty((new TLint)->lint(new UseAuthHelperOverFacade($file, '.blade.php'))); - } -}