diff --git a/src/Console/Commands/CheckCommand.php b/src/Console/Commands/CheckCommand.php
index 6461b0d..e11efba 100644
--- a/src/Console/Commands/CheckCommand.php
+++ b/src/Console/Commands/CheckCommand.php
@@ -198,6 +198,8 @@ private function renderLineIssue(Issue $issue): void
$issue,
);
+ $suggestionsHelperText = ($suggestions > '') ? 'Did you mean:' : 'No suggestions found.';
+
render(<<
@@ -208,7 +210,7 @@ private function renderLineIssue(Issue $issue): void
- Did you mean:
+ {$suggestionsHelperText}
{$suggestions}
@@ -272,6 +274,8 @@ private function renderLineLessIssue(Issue $issue): void
$issue,
);
+ $suggestionsHelperText = ($suggestions > '') ? 'Did you mean:' : 'No suggestions found.';
+
render(<<
@@ -282,7 +286,7 @@ private function renderLineLessIssue(Issue $issue): void
- Did you mean:
+ {$suggestionsHelperText}
{$suggestions}
diff --git a/src/Services/Spellcheckers/Aspell.php b/src/Services/Spellcheckers/Aspell.php
index f517a6d..f436ece 100644
--- a/src/Services/Spellcheckers/Aspell.php
+++ b/src/Services/Spellcheckers/Aspell.php
@@ -64,7 +64,7 @@ public function check(string $text): array
*/
private function getMisspellings(string $text): array
{
- $misspellings = iterator_to_array($this->run($text));
+ $misspellings = $this->run($text);
$this->cache->set($text, $misspellings);
@@ -101,14 +101,45 @@ private function run(string $text): array
$output = $process->getOutput();
- return array_values(array_map(function (string $line): Misspelling {
- [$wordMetadataAsString, $suggestionsAsString] = explode(':', trim($line));
+ $lines = $this->getAspellLinesFromOutput($output);
+
+ return $this->getMisspellingsFromOutputLines($lines);
+ }
+
+ /**
+ * Gets Aspell output lines as an array
+ *
+ * @return array
+ */
+ private function getAspellLinesFromOutput(string $output): array
+ {
+ return array_values(
+ array_filter(
+ explode(PHP_EOL, trim($output)), fn (string $line): bool => ! str_starts_with($line, '@(#)') && $line !== '*'
+ )
+ );
+ }
- $word = explode(' ', $wordMetadataAsString)[1];
- $suggestions = explode(', ', trim($suggestionsAsString));
+ /**
+ * Maps output lines to an array of Misspellings if suggestions exist, null if no suggestions or an empty array if spelling is correct
+ *
+ * @param array $lines
+ * @return array
+ */
+ private function getMisspellingsFromOutputLines(array $lines): array
+ {
+ return array_values(array_map(function (string $line): Misspelling {
+ if (preg_match('/#\\s(\\w*)\\sd*/', $line, $matches)) {
+ $word = $matches[1];
+ $suggestions = [];
+ } else {
+ [$wordMetadataAsString, $suggestionsAsString] = explode(':', trim($line));
+ $word = explode(' ', $wordMetadataAsString)[1];
+ $suggestions = explode(', ', trim($suggestionsAsString));
+ }
return new Misspelling($word, $this->takeSuggestions($suggestions));
- }, array_filter(explode(PHP_EOL, $output), fn (string $line): bool => str_starts_with($line, '&'))));
+ }, $lines));
}
/**
diff --git a/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap b/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap
index c8d0969..3800555 100644
--- a/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap
+++ b/tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap
@@ -1,4 +1,4 @@
- .............⨯⨯⨯.⨯....⨯⨯.⨯⨯⨯⨯⨯⨯....⨯⨯
+ .............⨯⨯⨯.⨯......⨯⨯.⨯⨯⨯⨯⨯⨯....⨯⨯⨯
Misspelling [1m./tests/Fixtures/FolderWithTypoos[0m: '[1mtypoos[0m'
./tests/Fixtures/FolderWithTypoos
@@ -185,7 +185,12 @@
---------------------^
Did you mean: constant, constants, consonant, consent
- FAIL 37 misspelling(s) found in your project.
+ Misspelling [1m./tests/Fixtures/TypoNoSuggestions/ClassWithTypoErrors.php:16:48[0m: '[1mxxxxxxxxxxxxxxxxxxxx[0m'
+ 16▕ [1m public int $propertyWithTypoAndNoSuggestionsXxxxxxxxxxxxxxxxxxxx = 1;[0m
+ ------------------------------------------------^
+ No suggestions found.
+
+ FAIL 38 misspelling(s) found in your project.
Duration: 0.00s
Hint: You may correct the misspellings individually, ignore them one by one, or ignore all of them using the peck --ignore-all option.
diff --git a/tests/Fixtures/TypoNoSuggestions/ClassWithTypoErrors.php b/tests/Fixtures/TypoNoSuggestions/ClassWithTypoErrors.php
new file mode 100644
index 0000000..e350200
--- /dev/null
+++ b/tests/Fixtures/TypoNoSuggestions/ClassWithTypoErrors.php
@@ -0,0 +1,17 @@
+toBeEmpty();
});
+it('detects issue and returns as fail when there are no suggestions', function (): void {
+ $checker = new SourceCodeChecker(
+ Config::instance(),
+ Aspell::default(),
+ );
+
+ $issues = $checker->check([
+ 'directory' => __DIR__.'/../../Fixtures/TypoNoSuggestions',
+ 'onSuccess' => fn (): null => null,
+ 'onFailure' => fn (): null => null,
+ ]);
+
+ expect($issues)->toHaveCount(1)
+ ->and($issues[0]->file)->toEndWith('tests/Fixtures/TypoNoSuggestions/ClassWithTypoErrors.php')
+ ->and($issues[0]->line)->toBe(16)
+ ->and($issues[0]->misspelling->word)->toBe('xxxxxxxxxxxxxxxxxxxx')
+ ->and($issues[0]->misspelling->suggestions)->toBe([]);
+
+});
+
it('detects issues in the given directory of classes', function (): void {
$checker = new SourceCodeChecker(
Config::instance(),
diff --git a/tests/Unit/KernelTest.php b/tests/Unit/KernelTest.php
index f3e10d9..0981a76 100644
--- a/tests/Unit/KernelTest.php
+++ b/tests/Unit/KernelTest.php
@@ -13,5 +13,5 @@
'onFailure' => fn (): null => null,
]);
- expect($issues)->toHaveCount(37);
+ expect($issues)->toHaveCount(38);
});
diff --git a/tests/Unit/Services/AspellTest.php b/tests/Unit/Services/AspellTest.php
index 9560871..598c6c1 100644
--- a/tests/Unit/Services/AspellTest.php
+++ b/tests/Unit/Services/AspellTest.php
@@ -5,6 +5,7 @@
use Peck\Config;
use Peck\Plugins\Cache;
use Peck\Services\Spellcheckers\Aspell;
+use Peck\ValueObjects\Misspelling;
it('does not detect issues', function (): void {
$spellchecker = Aspell::default();
@@ -91,3 +92,16 @@
expect($issues)->not->toBeEmpty();
});
+
+it('reports a bad spelling even when there are no suggestions', function (): void {
+ Cache::default()->flush();
+ $spellchecker = Aspell::default();
+
+ $issues = $spellchecker->check('ppppppppppppppooihihihihih');
+
+ expect($issues)->toBeArray()
+ ->and($issues[0]->word)->toBe('ppppppppppppppooihihihihih')
+ ->and($issues[0]->suggestions)->toBe([])
+ ->and($issues[0])->toBeInstanceOf(Misspelling::class);
+
+});