Skip to content

Commit

Permalink
Add tests for errors
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet committed Aug 13, 2021
1 parent ce1f16c commit 9e33f78
Show file tree
Hide file tree
Showing 20 changed files with 204 additions and 32 deletions.
10 changes: 5 additions & 5 deletions src/Runner/Fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Twig\Source;
use TwigCsFixer\Ruleset\Ruleset;
use TwigCsFixer\Token\Token;
use TwigCsFixer\Token\Tokenizer;
use TwigCsFixer\Token\TokenizerInterface;

/**
* Fixer will fix twig files against a set of rules.
Expand All @@ -31,7 +31,7 @@ final class Fixer
private $ruleset;

/**
* @var Tokenizer
* @var TokenizerInterface
*/
private $tokenizer;

Expand Down Expand Up @@ -96,12 +96,12 @@ final class Fixer
private $numFixes = 0;

/**
* @param Ruleset $ruleset
* @param Tokenizer $tokenizer
* @param Ruleset $ruleset
* @param TokenizerInterface $tokenizer
*
* @return void
*/
public function __construct(Ruleset $ruleset, Tokenizer $tokenizer)
public function __construct(Ruleset $ruleset, TokenizerInterface $tokenizer)
{
$this->ruleset = $ruleset;
$this->tokenizer = $tokenizer;
Expand Down
14 changes: 7 additions & 7 deletions src/Runner/Linter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use TwigCsFixer\Report\Report;
use TwigCsFixer\Report\SniffViolation;
use TwigCsFixer\Ruleset\Ruleset;
use TwigCsFixer\Token\Tokenizer;
use TwigCsFixer\Token\TokenizerInterface;

/**
* Linter is the main class and will process twig files against a set of rules.
Expand All @@ -24,17 +24,17 @@ final class Linter
private $env;

/**
* @var Tokenizer
* @var TokenizerInterface
*/
private $tokenizer;

/**
* @param Environment $env
* @param Tokenizer $tokenizer
* @param Environment $env
* @param TokenizerInterface $tokenizer
*
* @return void
*/
public function __construct(Environment $env, Tokenizer $tokenizer)
public function __construct(Environment $env, TokenizerInterface $tokenizer)
{
$this->env = $env;
$this->tokenizer = $tokenizer;
Expand Down Expand Up @@ -120,7 +120,7 @@ private function processTemplate(string $file, Ruleset $ruleset, Report $report)
if (false === $content) {
$sniffViolation = new SniffViolation(
Report::MESSAGE_TYPE_FATAL,
sprintf('Unable to read file "%s"', $file),
'Unable to read file.',
$file
);

Expand All @@ -137,7 +137,7 @@ private function processTemplate(string $file, Ruleset $ruleset, Report $report)
} catch (Error $e) {
$sniffViolation = new SniffViolation(
Report::MESSAGE_TYPE_FATAL,
$e->getRawMessage(),
sprintf('File is invalid: %s', $e->getRawMessage()),
$file,
$e->getTemplateLine()
);
Expand Down
2 changes: 1 addition & 1 deletion src/Token/Tokenizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
* lex_block: string,
* }
*/
final class Tokenizer
final class Tokenizer implements TokenizerInterface
{
private const STATE_DATA = 0;
private const STATE_BLOCK = 1;
Expand Down
21 changes: 21 additions & 0 deletions src/Token/TokenizerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace TwigCsFixer\Token;

use Twig\Error\SyntaxError;
use Twig\Source;

/**
* Interface for Tokenizer.
*/
interface TokenizerInterface
{
/**
* @param Source $source
*
* @return array<int, Token>
*
* @throws SyntaxError
*/
public function tokenize(Source $source): array;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions tests/Command/TwigCsFixerCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function testExecuteWithPaths(): void

$commandTester = new CommandTester($command);
$commandTester->execute([
'paths' => [__DIR__.'/data'],
'paths' => [__DIR__.'/Fixtures'],
]);

self::assertStringContainsString(
Expand All @@ -58,8 +58,8 @@ public function testExecuteWithConfig(): void

$commandTester = new CommandTester($command);
$commandTester->execute([
'paths' => [__DIR__.'/data'],
'--config' => __DIR__.'/data/.twig-cs-fixer.php',
'paths' => [__DIR__.'/Fixtures'],
'--config' => __DIR__.'/Fixtures/.twig-cs-fixer.php',
]);

self::assertStringContainsString(
Expand All @@ -78,8 +78,8 @@ public function testExecuteWithError(): void

$commandTester = new CommandTester($command);
$commandTester->execute([
'paths' => [__DIR__.'/data'],
'--config' => __DIR__.'/data/.config-not-found.php',
'paths' => [__DIR__.'/Fixtures'],
'--config' => __DIR__.'/Fixtures/.config-not-found.php',
]);

self::assertStringStartsWith('Error: ', $commandTester->getDisplay());
Expand Down
14 changes: 7 additions & 7 deletions tests/Config/ConfigResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public function testGetConfig(string $workingDir, ?string $path, string $configN
*/
public function getConfigDataProvider(): iterable
{
yield [__DIR__.'/data/directoryWithoutConfig', null, 'Default'];
yield [__DIR__.'/data/directoryWithConfig', null, 'Custom'];
yield [__DIR__, 'data/directoryWithConfig/.twig-cs-fixer.php', 'Custom'];
yield ['/tmp', __DIR__.'/data/directoryWithConfig/.twig-cs-fixer.php', 'Custom'];
yield [__DIR__.'/Fixtures/directoryWithoutConfig', null, 'Default'];
yield [__DIR__.'/Fixtures/directoryWithConfig', null, 'Custom'];
yield [__DIR__, 'Fixtures/directoryWithConfig/.twig-cs-fixer.php', 'Custom'];
yield ['/tmp', __DIR__.'/Fixtures/directoryWithConfig/.twig-cs-fixer.php', 'Custom'];
}

/**
Expand All @@ -62,8 +62,8 @@ public function testGetConfigException(string $workingDir, ?string $path): void
*/
public function getConfigExceptionDataProvider(): iterable
{
yield [__DIR__.'/data/directoryWithInvalidConfig', null];
yield [__DIR__, 'data/directoryWithInvalidConfig/.twig-cs-fixer.php'];
yield [__DIR__, 'data/path/to/not/found/.twig-cs-fixer.php'];
yield [__DIR__.'/Fixtures/directoryWithInvalidConfig', null];
yield [__DIR__, 'Fixtures/directoryWithInvalidConfig/.twig-cs-fixer.php'];
yield [__DIR__, 'Fixtures/path/to/not/found/.twig-cs-fixer.php'];
}
}
14 changes: 7 additions & 7 deletions tests/File/FinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function testWithNoPath(): void
*/
public function testWithWrongPath(): void
{
$finder = new Finder([__DIR__.'/data/template_not_found.twig']);
$finder = new Finder([__DIR__.'/Fixtures/template_not_found.twig']);

self::expectExceptionMessage('Unknown path');
$finder->findFiles();
Expand All @@ -37,21 +37,21 @@ public function testWithWrongPath(): void
*/
public function testWithPath(): void
{
$finder = new Finder([__DIR__.'/data/template.twig']);
self::assertSame([__DIR__.'/data/template.twig'], $finder->findFiles());
$finder = new Finder([__DIR__.'/Fixtures/template.twig']);
self::assertSame([__DIR__.'/Fixtures/template.twig'], $finder->findFiles());
}

/**
* @return void
*/
public function testWithDirectory(): void
{
$finder = new Finder([__DIR__.'/data']);
$finder = new Finder([__DIR__.'/Fixtures']);

$files = $finder->findFiles();
self::assertCount(3, $files);
self::assertContains(__DIR__.'/data/template.twig', $files);
self::assertContains(__DIR__.'/data/directory/template.twig', $files);
self::assertContains(__DIR__.'/data/directory/subdirectory/template.twig', $files);
self::assertContains(__DIR__.'/Fixtures/template.twig', $files);
self::assertContains(__DIR__.'/Fixtures/directory/template.twig', $files);
self::assertContains(__DIR__.'/Fixtures/directory/subdirectory/template.twig', $files);
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
44 changes: 44 additions & 0 deletions tests/Runner/Fixtures/BuggySniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace TwigCsFixer\Tests\Runner\Fixtures;

use TwigCsFixer\Sniff\AbstractSpacingSniff;
use TwigCsFixer\Token\Token;

/**
* This Sniff is buggy because it can't decide how to solve `,]`.
*/
class BuggySniff extends AbstractSpacingSniff
{
/**
* @param int $tokenPosition
* @param array<int, Token> $tokens
*
* @return int|null
*/
protected function shouldHaveSpaceBefore(int $tokenPosition, array $tokens): ?int
{
$token = $tokens[$tokenPosition];
if ($this->isTokenMatching($token, Token::PUNCTUATION_TYPE, [']'])) {
return 0;
}

return null;
}

/**
* @param int $tokenPosition
* @param array<int, Token> $tokens
*
* @return int|null
*/
protected function shouldHaveSpaceAfter(int $tokenPosition, array $tokens): ?int
{
$token = $tokens[$tokenPosition];
if ($this->isTokenMatching($token, Token::PUNCTUATION_TYPE, [','])) {
return 1;
}

return null;
}
}
1 change: 1 addition & 0 deletions tests/Runner/Fixtures/file.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ [1,] }}
106 changes: 106 additions & 0 deletions tests/Runner/LinterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace TwigCsFixer\Tests\Runner;

use PHPUnit\Framework\TestCase;
use Twig\Environment;
use Twig\Error\SyntaxError;
use TwigCsFixer\Environment\StubbedEnvironment;
use TwigCsFixer\Ruleset\Ruleset;
use TwigCsFixer\Runner\Linter;
use TwigCsFixer\Tests\Runner\Fixtures\BuggySniff;
use TwigCsFixer\Token\Tokenizer;
use TwigCsFixer\Token\TokenizerInterface;

/**
* Test for Linter.
*/
class LinterTest extends TestCase
{
/**
* @return void
*/
public function testUnreadableFilesAreReported(): void
{
$env = new StubbedEnvironment();
$tokenizer = $this->createStub(TokenizerInterface::class);
$ruleset = new Ruleset();

$linter = new Linter($env, $tokenizer);

// Suppress the warning sent by `file_get_content` during the test.
$oldErrorLevel = error_reporting(E_ALL ^ E_WARNING);
$report = $linter->run([__DIR__.'/Fixtures/file_not_readable.twig'], $ruleset);
error_reporting($oldErrorLevel);

$messages = $report->getMessages();
self::assertCount(1, $messages);
self::assertSame('Unable to read file.', $messages[0]->getMessage());
self::assertSame(
sprintf('%s/Fixtures/file_not_readable.twig', __DIR__),
$messages[0]->getFilename()
);
}

/**
* @return void
*/
public function testInvalidFilesAreReported(): void
{
$env = $this->createStub(Environment::class);
$env->method('tokenize')->willThrowException(new SyntaxError('Error.'));
$tokenizer = $this->createStub(TokenizerInterface::class);
$ruleset = new Ruleset();

$linter = new Linter($env, $tokenizer);

$report = $linter->run([__DIR__.'/Fixtures/file.twig'], $ruleset);

$messages = $report->getMessages();
self::assertCount(1, $messages);
self::assertSame('File is invalid: Error.', $messages[0]->getMessage());
self::assertSame(
sprintf('%s/Fixtures/file.twig', __DIR__),
$messages[0]->getFilename()
);
}

/**
* @return void
*/
public function testUntokenizableFilesAreReported(): void
{
$env = new StubbedEnvironment();
$tokenizer = $this->createStub(TokenizerInterface::class);
$tokenizer->method('tokenize')->willThrowException(new SyntaxError('Error.'));
$ruleset = new Ruleset();

$linter = new Linter($env, $tokenizer);

$report = $linter->run([__DIR__.'/Fixtures/file.twig'], $ruleset);

$messages = $report->getMessages();
self::assertCount(1, $messages);
self::assertSame('Unable to tokenize file: Error.', $messages[0]->getMessage());
self::assertSame(
sprintf('%s/Fixtures/file.twig', __DIR__),
$messages[0]->getFilename()
);
}

/**
* @return void
*/
public function testBuggyRulesetCannotBeFixed(): void
{
$env = new StubbedEnvironment();
$tokenizer = new Tokenizer($env);
$ruleset = new Ruleset();
$ruleset->addSniff(new BuggySniff());

$linter = new Linter($env, $tokenizer);

self::expectExceptionMessage(sprintf('Cannot fix the file "%s/Fixtures/file.twig".', __DIR__));
$linter->run([__DIR__.'/Fixtures/file.twig'], $ruleset, true);
}
}

0 comments on commit 9e33f78

Please sign in to comment.