Skip to content

Commit 28df52f

Browse files
faissalouxJonPurvis
authored andcommitted
Pesty russian detection (#76)
In this PR I made russian detection more Pesty. - We should use `RussianNormalizer`. - Add `.php` extension at the end of file name. - Does not use `pest-plugin-profanity` syntax and does not feel as Pest. - In case of exception it throws the global `\Exception`. - Does not display the profanity the way the package do (See image). ```php RussianNormalizer::assertNoRussianProfanity('Tests\Fixtures\HasExplicitRussianProfanity.php'); ``` ![image](https://github.com/user-attachments/assets/fb51e337-768d-49d3-b0f8-a88287515751) - More Pesty and clean. ```php expect('Tests\Fixtures\HasExplicitRussianProfanity')->toHaveNoProfanity(language: 'ru'); ``` ![image](https://github.com/user-attachments/assets/5e4b785f-f95c-49f9-820e-379691df1de1) PS: I am not sure about the masked profanities on `HasMaskedRussianProfanity` should they be detected or not. They are not detected at the time. If it's the case I think I should remove that file.
1 parent bee5484 commit 28df52f

File tree

4 files changed

+70
-78
lines changed

4 files changed

+70
-78
lines changed

src/Support/Russian.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JonPurvis\Profanify\Support;
6+
7+
final class Russian
8+
{
9+
private static string $pattern = '/[А-Яа-яЁё]+/u';
10+
11+
private bool $detected = false;
12+
13+
/** @var array<string, string> */
14+
private static array $normalized = [];
15+
16+
/** @var array<int|string, string> */
17+
private static array $toNormalize = [
18+
'3' => 'з', '4' => 'ч', '6' => 'б',
19+
'a' => 'а', 'c' => 'с', 'e' => 'е', 'o' => 'о', 'p' => 'р', 'x' => 'х', 'k' => 'к',
20+
'A' => 'д', 'r' => 'г', 'H' => 'н', 'M' => 'м', 'T' => 'т', 'B' => 'в',
21+
];
22+
23+
public function is(string $text): bool
24+
{
25+
if ((bool) preg_match(self::$pattern, $text)) {
26+
$this->detected = true;
27+
}
28+
29+
return $this->detected;
30+
}
31+
32+
public function isDetected(): bool
33+
{
34+
return $this->detected;
35+
}
36+
37+
public static function pattern(): string
38+
{
39+
return self::$pattern;
40+
}
41+
42+
public static function normalize(string $text): string
43+
{
44+
preg_match_all('/\w+/u', $text, $words);
45+
$toNormalizeKeysString = implode('', array_keys(self::$toNormalize));
46+
47+
foreach ($words[0] as $word) {
48+
if (strpbrk($word, $toNormalizeKeysString)) {
49+
$normalized = strtr($word, self::$toNormalize);
50+
self::$normalized[$word] = $normalized;
51+
}
52+
}
53+
54+
return str_replace(array_keys(self::$normalized), array_values(self::$normalized), $text);
55+
}
56+
57+
/**
58+
* @param array<string> $profanities
59+
* @return array<string>
60+
*/
61+
public static function backToOrigin(array $profanities): array
62+
{
63+
return array_map(fn ($profanity): string => array_search($profanity, self::$normalized) ?: $profanity, $profanities);
64+
}
65+
}

src/Support/RussianNormalizer.php

Lines changed: 0 additions & 68 deletions
This file was deleted.

tests/Fixtures/HasExplicitRussianProfanity.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@
77
class HasExplicitRussianProfanity
88
{
99
public string $bad = 'Это полная хуйня!';
10+
11+
public function е6ёт()
12+
{
13+
// Comment...
14+
}
1015
}

tests/Fixtures/HasMaskedRussianProfanity.php

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)