mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
more tests
This commit is contained in:
@@ -258,4 +258,209 @@ class BuildTriggerTest extends TestCase
|
||||
$this->assertTrue($validator->isValid('staging')); // passes — no inclusions required
|
||||
$this->assertTrue($validator->isValid('feature/foo'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Standalone wildcards
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testStarAloneMatchesSingleSegmentOnly(): void
|
||||
{
|
||||
// * → ^[^/]*$ — matches any single segment; the [^/]* guard prevents crossing /
|
||||
$validator = new BuildTrigger(['*']);
|
||||
$this->assertTrue($validator->isValid('main'));
|
||||
$this->assertTrue($validator->isValid('develop'));
|
||||
$this->assertFalse($validator->isValid('feature/foo')); // * cannot cross /
|
||||
$this->assertFalse($validator->isValid('a/b/c'));
|
||||
}
|
||||
|
||||
public function testDoubleStarAloneMatchesEverything(): void
|
||||
{
|
||||
// ** alone → ^.*$ — matches any string including paths with separators
|
||||
$validator = new BuildTrigger(['**']);
|
||||
$this->assertTrue($validator->isValid('main'));
|
||||
$this->assertTrue($validator->isValid('feature/foo'));
|
||||
$this->assertTrue($validator->isValid('src/a/b/c/d/file.php'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Extension patterns — * scope vs. ** scope
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testStarDotExtMatchesRootLevelOnly(): void
|
||||
{
|
||||
// *.php → ^[^/]*\.php$ — root-level only; * cannot cross /
|
||||
$validator = new BuildTrigger(['*.php']);
|
||||
$this->assertTrue($validator->isValid('Foo.php'));
|
||||
$this->assertTrue($validator->isValid('index.php'));
|
||||
$this->assertFalse($validator->isValid('src/Foo.php')); // * does not cross /
|
||||
$this->assertFalse($validator->isValid('a/b/Foo.php'));
|
||||
$this->assertFalse($validator->isValid('Foo.js'));
|
||||
}
|
||||
|
||||
public function testDoubleStarSlashExtMatchesAnyDepth(): void
|
||||
{
|
||||
// **/*.php → ^(?:.+/)?[^/]*\.php$ — (?:.+/)? is optional so root also matches
|
||||
$validator = new BuildTrigger(['**/*.php']);
|
||||
$this->assertTrue($validator->isValid('Foo.php')); // root — zero leading dirs
|
||||
$this->assertTrue($validator->isValid('src/Foo.php'));
|
||||
$this->assertTrue($validator->isValid('src/components/Foo.php'));
|
||||
$this->assertTrue($validator->isValid('a/b/c/d/Foo.php')); // four levels deep
|
||||
$this->assertFalse($validator->isValid('Foo.js'));
|
||||
$this->assertFalse($validator->isValid('src/Foo.js'));
|
||||
}
|
||||
|
||||
public function testDirPrefixDoubleStarExtPattern(): void
|
||||
{
|
||||
// src/**/*.php → ^src/(?:.+/)?[^/]*\.php$ — scoped to src/ at any depth
|
||||
$validator = new BuildTrigger(['src/**/*.php']);
|
||||
$this->assertTrue($validator->isValid('src/Foo.php'));
|
||||
$this->assertTrue($validator->isValid('src/components/Foo.php'));
|
||||
$this->assertTrue($validator->isValid('src/a/b/c/Foo.php'));
|
||||
$this->assertFalse($validator->isValid('Foo.php')); // outside src/
|
||||
$this->assertFalse($validator->isValid('lib/Foo.php'));
|
||||
$this->assertFalse($validator->isValid('src/Foo.js'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Dots as literal characters
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testDotsInPatternAreLiteral(): void
|
||||
{
|
||||
// preg_quote escapes . to \. — dots are never regex wildcards
|
||||
$validator = new BuildTrigger(['release-1.0.0']);
|
||||
$this->assertTrue($validator->isValid('release-1.0.0'));
|
||||
$this->assertFalse($validator->isValid('release-1X0Y0')); // X/Y must not satisfy a literal dot
|
||||
$this->assertFalse($validator->isValid('release-1.0.0-hotfix')); // extra suffix rejected by $ anchor
|
||||
}
|
||||
|
||||
public function testVersionWildcardBranchPattern(): void
|
||||
{
|
||||
// v*.*.* → ^v[^/]*\.[^/]*\.[^/]*$ — dots literal; [^/]* is greedy and can consume dots,
|
||||
// so v1.2.3.4 also matches (first [^/]* eats "1.2") — documents current behavior
|
||||
$validator = new BuildTrigger(['v*.*.*']);
|
||||
$this->assertTrue($validator->isValid('v1.2.3'));
|
||||
$this->assertTrue($validator->isValid('v10.20.30'));
|
||||
$this->assertTrue($validator->isValid('v1.2.3.4')); // greedy match — first [^/]* eats "1.2"
|
||||
$this->assertFalse($validator->isValid('v1.2')); // only two dot-segments; third \.[^/]* fails
|
||||
$this->assertFalse($validator->isValid('1.2.3')); // missing leading v
|
||||
$this->assertFalse($validator->isValid('v1/2/3')); // [^/]* cannot cross /
|
||||
}
|
||||
|
||||
public function testDottedFilenamePattern(): void
|
||||
{
|
||||
// *.test.js → ^[^/]*\.test\.js$ — both dots literal; * stays in root segment
|
||||
$validator = new BuildTrigger(['*.test.js']);
|
||||
$this->assertTrue($validator->isValid('Button.test.js'));
|
||||
$this->assertTrue($validator->isValid('App.test.js'));
|
||||
$this->assertFalse($validator->isValid('ButtonXtestYjs')); // dots must be literal
|
||||
$this->assertFalse($validator->isValid('src/Button.test.js')); // * does not cross /
|
||||
$this->assertFalse($validator->isValid('Button.test.ts'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Prefix wildcard
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testPrefixWildcardBranchPattern(): void
|
||||
{
|
||||
// main* → ^main[^/]*$ — suffix wildcard; [^/]* cannot cross /
|
||||
$validator = new BuildTrigger(['main*']);
|
||||
$this->assertTrue($validator->isValid('main')); // zero trailing chars
|
||||
$this->assertTrue($validator->isValid('main-extra'));
|
||||
$this->assertTrue($validator->isValid('mainline'));
|
||||
$this->assertFalse($validator->isValid('main/branch')); // [^/]* cannot cross /
|
||||
$this->assertFalse($validator->isValid('develop'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Deep nesting
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testDoubleWildcardInMiddleDeepNesting(): void
|
||||
{
|
||||
// a/**/b → ^a/(?:.+/)?b$ — .+ inside (?:.+/)? matches any chars including /,
|
||||
// so it handles arbitrarily many intermediate directories
|
||||
$validator = new BuildTrigger(['a/**/b']);
|
||||
$this->assertTrue($validator->isValid('a/x/y/z/b')); // three intermediate dirs
|
||||
$this->assertTrue($validator->isValid('a/p/q/r/s/b')); // four intermediate dirs
|
||||
$this->assertTrue($validator->isValid('a/1/2/3/4/5/b')); // five intermediate dirs
|
||||
$this->assertFalse($validator->isValid('a/x/y/z/b/extra')); // trailing segment rejected
|
||||
$this->assertFalse($validator->isValid('prefix/a/x/b')); // leading segment rejected
|
||||
}
|
||||
|
||||
public function testDoubleWildcardAtStartDeepNesting(): void
|
||||
{
|
||||
// **/README.md → ^(?:.+/)?README\.md$ — matches at any depth; $ anchor prevents suffixes
|
||||
$validator = new BuildTrigger(['**/README.md']);
|
||||
$this->assertTrue($validator->isValid('README.md')); // zero leading dirs
|
||||
$this->assertTrue($validator->isValid('docs/README.md'));
|
||||
$this->assertTrue($validator->isValid('a/b/c/d/README.md')); // four levels deep
|
||||
$this->assertTrue($validator->isValid('x/y/z/w/v/README.md')); // five levels deep
|
||||
$this->assertFalse($validator->isValid('a/b/c/README.md.bak')); // $ anchor — no suffix
|
||||
$this->assertFalse($validator->isValid('a/b/c/README.md/extra')); // trailing segment rejected
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Real-world path patterns
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testGeneratedFilesAnywhereExclusion(): void
|
||||
{
|
||||
// !**/generated/** → ^(?:.+/)?generated/.*$ — excludes generated/ at any depth
|
||||
$validator = new BuildTrigger(['!**/generated/**']);
|
||||
$this->assertFalse($validator->isValid('generated/Foo.php')); // root generated/
|
||||
$this->assertFalse($validator->isValid('src/generated/Foo.php'));
|
||||
$this->assertFalse($validator->isValid('src/api/generated/Bar.php')); // deep generated/
|
||||
$this->assertFalse($validator->isValid('generated/sub/deep/File.php')); // deep inside root generated/
|
||||
$this->assertTrue($validator->isValid('src/components/Button.php')); // not under generated/
|
||||
$this->assertTrue($validator->isValid('main'));
|
||||
}
|
||||
|
||||
public function testMultipleExtensionInclusions(): void
|
||||
{
|
||||
// OR semantics: any PHP or JS file triggers; other extensions do not
|
||||
$validator = new BuildTrigger(['**/*.php', '**/*.js']);
|
||||
$this->assertTrue($validator->isValid('index.php'));
|
||||
$this->assertTrue($validator->isValid('src/App.php'));
|
||||
$this->assertTrue($validator->isValid('index.js'));
|
||||
$this->assertTrue($validator->isValid('src/components/App.js'));
|
||||
$this->assertFalse($validator->isValid('styles.css'));
|
||||
$this->assertFalse($validator->isValid('src/styles.css'));
|
||||
$this->assertFalse($validator->isValid('README.md'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Named-prefix single-level branch
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testReleaseBranchPattern(): void
|
||||
{
|
||||
// release/* → ^release/[^/]*$ — one level only; * stops at the next /
|
||||
$validator = new BuildTrigger(['release/*']);
|
||||
$this->assertTrue($validator->isValid('release/1.0'));
|
||||
$this->assertTrue($validator->isValid('release/hotfix'));
|
||||
$this->assertTrue($validator->isValid('release/2024-01-15'));
|
||||
$this->assertFalse($validator->isValid('release/1.0/patch')); // * stops at /
|
||||
$this->assertFalse($validator->isValid('release')); // missing the /* segment
|
||||
$this->assertFalse($validator->isValid('main'));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Case sensitivity
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public function testPatternMatchingIsCaseSensitive(): void
|
||||
{
|
||||
// preg_match is used without the i flag — matching is always case-sensitive
|
||||
$branchValidator = new BuildTrigger(['main']);
|
||||
$this->assertTrue($branchValidator->isValid('main'));
|
||||
$this->assertFalse($branchValidator->isValid('Main'));
|
||||
$this->assertFalse($branchValidator->isValid('MAIN'));
|
||||
|
||||
$wildcardValidator = new BuildTrigger(['feature/*']);
|
||||
$this->assertTrue($wildcardValidator->isValid('feature/foo'));
|
||||
$this->assertFalse($wildcardValidator->isValid('Feature/foo'));
|
||||
$this->assertFalse($wildcardValidator->isValid('FEATURE/foo'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user