Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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('should throw an runtime exception if the presets are not an array', function (): void {
Comment thread
c0nst4ntin marked this conversation as resolved.
Outdated
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'
);
});