Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Here's an example configuration:

```json
{
"preset": "laravel",
"presets": ["laravel"],
"ignore": {
"words": [
"config",
Expand All @@ -105,7 +105,9 @@ You can also specify the path to the configuration file using the `--config` opt

In order to make it easier to get started with Peck, we've included a few presets that you can use to ignore common words in your project. The following presets are available:

- `laravel`
- `laravel` - Ignores common Laravel words such as `inertia`, `jetstream`, etc.
- `iso3166` - Ignores all ISO 3166 country codes in alpha-2 and alpha-3 format (e.g., `US`, `USA`, `GB`, `GBR`, etc.)
- `iso4217` - Ignores all ISO 4217 currency codes (e.g., `USD`, `EUR`, `GBP`, etc.)

## Command Options

Expand Down
5 changes: 4 additions & 1 deletion peck.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"preset": "base",
"presets": [
"iso3166",
"iso4217"
],
"ignore": {
"words": [
"php"
Expand Down
20 changes: 13 additions & 7 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Closure;
use Peck\Support\PresetProvider;
use Peck\Support\ProjectPath;
use RuntimeException;

final class Config
{
Expand All @@ -30,11 +31,12 @@ final class Config
*
* @param array<int, string> $whitelistedWords
* @param array<int, string> $whitelistedPaths
* @param array<int, string> $presets
*/
public function __construct(
public array $whitelistedWords = [],
public array $whitelistedPaths = [],
public ?string $preset = null,
public array $presets = [],
) {
$this->whitelistedWords = array_map(strtolower(...), $whitelistedWords);
}
Expand Down Expand Up @@ -86,7 +88,7 @@ public static function instance(): self

/**
* @var array{
* preset?: string,
* presets?: string[],
* ignore?: array{
* words?: array<int, string>,
* paths?: array<int, string>
Expand All @@ -95,10 +97,14 @@ public static function instance(): self
*/
$jsonAsArray = json_decode($contents, true) ?: [];

if (! is_array($jsonAsArray['presets'] ?? [])) {
throw new RuntimeException('The presets must be an array with all the presets you want to use.');
}

return self::$instance = new self(
$jsonAsArray['ignore']['words'] ?? [],
$jsonAsArray['ignore']['paths'] ?? [],
$jsonAsArray['preset'] ?? null,
$jsonAsArray['presets'] ?? [],
);
}

Expand All @@ -116,10 +122,10 @@ public static function init(): bool
return (bool) file_put_contents($filePath, json_encode([
...match (true) {
class_exists('\Illuminate\Support\Str') => [
'preset' => 'laravel',
'presets' => ['laravel'],
],
default => [
'preset' => 'base',
'presets' => ['base'],
],
},
'ignore' => [
Expand Down Expand Up @@ -150,7 +156,7 @@ public function isWordIgnored(string $word): bool
{
return in_array(strtolower($word), [
...$this->whitelistedWords,
...array_map(strtolower(...), PresetProvider::whitelistedWords($this->preset)),
...array_map(strtolower(...), PresetProvider::whitelistedWords($this->presets)),
]);
}

Expand All @@ -162,7 +168,7 @@ private function persist(): void
$filePath = ProjectPath::get().'/'.self::JSON_CONFIGURATION_NAME;

file_put_contents($filePath, json_encode([
...$this->preset !== null ? ['preset' => $this->preset] : [],
'presets' => $this->presets,
'ignore' => [
'words' => $this->whitelistedWords,
'paths' => $this->whitelistedPaths,
Expand Down
31 changes: 21 additions & 10 deletions src/Support/PresetProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,40 @@
/**
* Returns the whitelisted words for the given preset.
*
* @param array<int, string>|null $presets
* @return array<int, string>
*/
public static function whitelistedWords(?string $preset): array
public static function whitelistedWords(?array $presets = []): array
{
if ($preset === null || ! self::stubExists($preset)) {
return [];
}

return [
/** @var array<int, string> */
$words = [
...self::getWordsFromStub('base'),
...self::getWordsFromStub('iso4217'),
...self::getWordsFromStub('iso3166'),
...self::getWordsFromStub($preset),
];

array_map(
static function (string $preset) use (&$words): void {
$words = [
...$words,
...self::getWordsFromStub($preset),
];
},
$presets ?? [],
);

return $words;
}

/**
* Gets the words from the given stub.
*
* @return array<int, string>
*/
private static function getWordsFromStub(string $preset): array
public static function getWordsFromStub(string $preset): array
{
if (! self::stubExists($preset)) {
return [];
}

$path = sprintf('%s/%s.stub', self::PRESET_STUBS_DIRECTORY, $preset);

return array_values(array_filter(array_map('trim', explode("\n", (string) file_get_contents($path)))));
Expand Down
2 changes: 1 addition & 1 deletion tests/.pest/snapshots/Console/OutputTest/it_may_fail.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.............⨯⨯⨯.⨯....⨯⨯.⨯⨯⨯⨯⨯⨯....⨯⨯
.............⨯⨯⨯.⨯.....⨯⨯.⨯⨯⨯⨯⨯⨯....⨯⨯

Misspelling ./tests/Fixtures/FolderWithTypoos: 'typoos'
./tests/Fixtures/FolderWithTypoos
Expand Down
11 changes: 11 additions & 0 deletions tests/Fixtures/invalid-presets-peck.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"presets": "base",
"ignore": {
"words": [
"php"
],
"paths": [
"tests"
]
}
}
62 changes: 11 additions & 51 deletions tests/Unit/Checkers/FileSystemCheckerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,67 +89,27 @@
'onFailure' => fn (): null => null,
]);

expect($issues)->toHaveCount(8)
->and($issues[0]->file)->toEndWith('tests/Fixtures/EnumsToTest')
expect($issues)->toHaveCount(3)
->and($issues[0]->file)->toEndWith('tests/Fixtures/FolderWithTypoos')
->and($issues[0]->line)->toBe(0)
->and($issues[0]->misspelling->word)->toBe('enums')
->and($issues[0]->misspelling->word)->toBe('typoos')
->and($issues[0]->misspelling->suggestions)->toBe([
'enemas',
'animus',
'emus',
'ems',
])->and($issues[1]->file)->toEndWith('tests/Fixtures/EnumsToTest/BackendEnumWithTypoErrors.php')
->and($issues[1]->line)->toBe(0)
->and($issues[1]->misspelling->word)->toBe('backend')
->and($issues[1]->misspelling->suggestions)->toBe([
'backed',
'bookend',
'blackened',
'beckoned',
])->and($issues[2]->file)->toEndWith('tests/Fixtures/EnumsToTest/BackendEnumWithTypoErrors.php')
->and($issues[2]->line)->toBe(0)
->and($issues[2]->misspelling->word)->toBe('enum')
->and($issues[2]->misspelling->suggestions)->toBe([
'enema',
'enemy',
'emu',
'anime',
])->and($issues[3]->file)->toEndWith('tests/Fixtures/EnumsToTest/FolderThatShouldBeIgnored/EnumWithTypoErrors.php')
->and($issues[3]->line)->toBe(0)
->and($issues[3]->misspelling->word)->toBe('enum')
->and($issues[3]->misspelling->suggestions)->toBe([
'enema',
'enemy',
'emu',
'anime',
])->and($issues[4]->file)->toEndWith('tests/Fixtures/EnumsToTest/UnitEnumWithTypoErrors.php')
->and($issues[4]->line)->toBe(0)
->and($issues[4]->misspelling->word)->toBe('enum')
->and($issues[4]->misspelling->suggestions)->toBe([
'enema',
'enemy',
'emu',
'anime',
])->and($issues[5]->file)->toEndWith('tests/Fixtures/FolderWithTypoos')
->and($issues[5]->line)->toBe(0)
->and($issues[5]->misspelling->word)->toBe('typoos')
->and($issues[5]->misspelling->suggestions)->toBe([
'typos',
'types',
'tops',
'poos',
])->and($issues[6]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FileWithTppyo.php')
->and($issues[6]->line)->toBe(0)
->and($issues[6]->misspelling->word)->toBe('tppyo')
->and($issues[6]->misspelling->suggestions)->toBe([
])->and($issues[1]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FileWithTppyo.php')
->and($issues[1]->line)->toBe(0)
->and($issues[1]->misspelling->word)->toBe('tppyo')
->and($issues[1]->misspelling->suggestions)->toBe([
'typo',
'Tokyo',
'typos',
'topi',
])->and($issues[7]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FolderThatShouldBeIgnored/FileThatShoudBeIgnoredBecauseItsInsideWhitelistedFolder.php')
->and($issues[7]->line)->toBe(0)
->and($issues[7]->misspelling->word)->toBe('shoud')
->and($issues[7]->misspelling->suggestions)->toBe([
])->and($issues[2]->file)->toEndWith('tests/Fixtures/FolderWithTypoos/FolderThatShouldBeIgnored/FileThatShoudBeIgnoredBecauseItsInsideWhitelistedFolder.php')
->and($issues[2]->line)->toBe(0)
->and($issues[2]->misspelling->word)->toBe('shoud')
->and($issues[2]->misspelling->suggestions)->toBe([
'should',
'shroud',
'shod',
Expand Down
8 changes: 8 additions & 0 deletions tests/Unit/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,11 @@
'tests',
]);
});

it('throws a runtime exception if the presets value is not an array', function (): void {
Config::resolveConfigFilePathUsing(
fn (): string => 'tests/Fixtures/invalid-presets-peck.json',
);

Config::instance();
})->throws(RuntimeException::class, 'The presets must be an array with all the presets you want to use.');
19 changes: 10 additions & 9 deletions tests/Unit/Support/PresetProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@

use Peck\Support\PresetProvider;

it('returns an empty array when the preset is null', function (): void {
expect(PresetProvider::whitelistedWords(null))->toBe([]);
it('returns only words from base preset when presets are not given', function (): void {
expect(PresetProvider::whitelistedWords())->toBe(PresetProvider::getWordsFromStub('base'));
});

it('returns an empty array when the preset is invalid', function (): void {
expect(PresetProvider::whitelistedWords('invalid'))->toBe([]);
it('returns only words from base preset when all given presets are invalids', function (): void {
expect(PresetProvider::whitelistedWords(['invalid-one', 'invalid-two']))->toBe(PresetProvider::getWordsFromStub('base'));
});

it('returns the whitelisted words for the given preset', function (): void {
expect(PresetProvider::whitelistedWords('laravel'))->toContain(
'http',
'laravel',
'fillable',
it('returns the whitelisted words for the given and base presets', function (): void {
expect(PresetProvider::whitelistedWords(['laravel', 'iso3166', 'iso4217']))->toContain(
'apa',
'USD',
'USA',
'https'
);
});