Rename the top-level lib/ directory to core/ so the project root immediately communicates which code is core platform and which lives in modules/. PHP namespaces (MintyPHP\*) are unchanged — only the Composer PSR-4 path mapping moves from lib/ to core/. Module-internal lib/ directories (modules/*/lib/) are untouched. Updated across the full stack: - composer.json PSR-4 mapping - bootstrap entry points (web/index.php, bin/*, tests/bootstrap.php) - tooling configs (phpstan.neon, phpunit.xml, php-cs-fixer) - 26 architecture contract tests - enforcement-policy, guard-catalog, quality-gates - all documentation (CLAUDE.md, README, 25 docs/, .agents/skills/) - bin/qa-extended.sh search paths - .claude/settings.local.json permission paths Workflow: .agents/runs/CORE-LIB-RENAME-001/ (Analyst → Planner → Executor → Code Review (4 findings fixed) → Security Review → Acceptance Test → Finalizer) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
137 lines
4.6 KiB
PHP
137 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace MintyPHP\Tests\Unit\Support;
|
|
|
|
use MintyPHP\Support\Search\SearchQueryNormalizer;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class SearchQueryNormalizerTest extends TestCase
|
|
{
|
|
// ── normalizeLikeQuery ──
|
|
|
|
public function testNormalizeLikeQueryReturnsEmptyForBlankInput(): void
|
|
{
|
|
self::assertSame('', SearchQueryNormalizer::normalizeLikeQuery(''));
|
|
self::assertSame('', SearchQueryNormalizer::normalizeLikeQuery(' '));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryWrapsWithWildcards(): void
|
|
{
|
|
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('hello'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryDoesNotDoubleWrapLeadingWildcard(): void
|
|
{
|
|
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('*hello'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryDoesNotDoubleWrapTrailingWildcard(): void
|
|
{
|
|
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('hello*'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryDoesNotDoubleWrapBothWildcards(): void
|
|
{
|
|
self::assertSame('%hello%', SearchQueryNormalizer::normalizeLikeQuery('*hello*'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryEscapesBackslash(): void
|
|
{
|
|
self::assertSame('%foo\\\\bar%', SearchQueryNormalizer::normalizeLikeQuery('foo\\bar'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryEscapesUnderscore(): void
|
|
{
|
|
self::assertSame('%foo\\_bar%', SearchQueryNormalizer::normalizeLikeQuery('foo_bar'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryConvertsAsterisksToPercent(): void
|
|
{
|
|
self::assertSame('%foo%bar%', SearchQueryNormalizer::normalizeLikeQuery('foo*bar'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryCombinesEscapingAndWildcards(): void
|
|
{
|
|
// Input: "a_b*c\d" → underscores escaped, * becomes %, backslash escaped, wrapped
|
|
self::assertSame('%a\\_b%c\\\\d%', SearchQueryNormalizer::normalizeLikeQuery('a_b*c\\d'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryTrimsWhitespace(): void
|
|
{
|
|
self::assertSame('%search%', SearchQueryNormalizer::normalizeLikeQuery(' search '));
|
|
}
|
|
|
|
public function testNormalizeLikeQuerySingleCharacter(): void
|
|
{
|
|
self::assertSame('%x%', SearchQueryNormalizer::normalizeLikeQuery('x'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryOnlyWildcard(): void
|
|
{
|
|
self::assertSame('%', SearchQueryNormalizer::normalizeLikeQuery('*'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryMultipleConsecutiveWildcards(): void
|
|
{
|
|
self::assertSame('%a%%%b%', SearchQueryNormalizer::normalizeLikeQuery('a***b'));
|
|
}
|
|
|
|
public function testNormalizeLikeQueryUnicodeInput(): void
|
|
{
|
|
self::assertSame('%Ünterström%', SearchQueryNormalizer::normalizeLikeQuery('Ünterström'));
|
|
}
|
|
|
|
// ── normalizeScoreQuery ──
|
|
|
|
public function testNormalizeScoreQueryReturnsEmptyForBlankInput(): void
|
|
{
|
|
self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery(''));
|
|
self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery(' '));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryStripsAsterisks(): void
|
|
{
|
|
self::assertSame('hello', SearchQueryNormalizer::normalizeScoreQuery('*hello*'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryStripsPercent(): void
|
|
{
|
|
self::assertSame('hello', SearchQueryNormalizer::normalizeScoreQuery('%hello%'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryStripsUnderscore(): void
|
|
{
|
|
self::assertSame('foobar', SearchQueryNormalizer::normalizeScoreQuery('foo_bar'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryStripsAllWildcardTypes(): void
|
|
{
|
|
self::assertSame('abc', SearchQueryNormalizer::normalizeScoreQuery('*a%b_c*'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryPreservesNormalText(): void
|
|
{
|
|
self::assertSame('search term', SearchQueryNormalizer::normalizeScoreQuery('search term'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryTrimsWhitespace(): void
|
|
{
|
|
self::assertSame('query', SearchQueryNormalizer::normalizeScoreQuery(' query '));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryOnlyWildcards(): void
|
|
{
|
|
self::assertSame('', SearchQueryNormalizer::normalizeScoreQuery('*%_'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryPreservesBackslash(): void
|
|
{
|
|
self::assertSame('a\\b', SearchQueryNormalizer::normalizeScoreQuery('a\\b'));
|
|
}
|
|
|
|
public function testNormalizeScoreQueryUnicodeInput(): void
|
|
{
|
|
self::assertSame('Müller', SearchQueryNormalizer::normalizeScoreQuery('Müller'));
|
|
}
|
|
}
|