summaryrefslogtreecommitdiff
path: root/std/path/glob_test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'std/path/glob_test.ts')
-rw-r--r--std/path/glob_test.ts582
1 files changed, 454 insertions, 128 deletions
diff --git a/std/path/glob_test.ts b/std/path/glob_test.ts
index dba79c302..bb3f8add0 100644
--- a/std/path/glob_test.ts
+++ b/std/path/glob_test.ts
@@ -1,130 +1,456 @@
import { assert, assertEquals } from "../testing/asserts.ts";
-import { testWalk, touch, walkArray } from "../fs/walk_test.ts";
-import { globToRegExp, isGlob, joinGlobs, normalizeGlob } from "./glob.ts";
-import { SEP, join } from "./mod.ts";
-
-Deno.test({
- name: "glob: glob to regex",
- fn(): void {
- assertEquals(globToRegExp("unicorn.*") instanceof RegExp, true);
- assertEquals(globToRegExp("unicorn.*").test("poney.ts"), false);
- assertEquals(globToRegExp("unicorn.*").test("unicorn.py"), true);
- assertEquals(globToRegExp("*.ts").test("poney.ts"), true);
- assertEquals(globToRegExp("*.ts").test("unicorn.js"), false);
- assertEquals(
- globToRegExp(join("unicorn", "**", "cathedral.ts")).test(
- join("unicorn", "in", "the", "cathedral.ts"),
- ),
- true,
- );
- assertEquals(
- globToRegExp(join("unicorn", "**", "cathedral.ts")).test(
- join("unicorn", "in", "the", "kitchen.ts"),
- ),
- false,
- );
- assertEquals(
- globToRegExp(join("unicorn", "**", "bathroom.*")).test(
- join("unicorn", "sleeping", "in", "bathroom.py"),
- ),
- true,
- );
- assertEquals(
- globToRegExp(join("unicorn", "!(sleeping)", "bathroom.ts"), {
- extended: true,
- }).test(join("unicorn", "flying", "bathroom.ts")),
- true,
- );
- assertEquals(
- globToRegExp(join("unicorn", "(!sleeping)", "bathroom.ts"), {
- extended: true,
- }).test(join("unicorn", "sleeping", "bathroom.ts")),
- false,
- );
- },
-});
-
-testWalk(
- async (d: string): Promise<void> => {
- await Deno.mkdir(d + "/a");
- await Deno.mkdir(d + "/b");
- await touch(d + "/a/x.ts");
- await touch(d + "/b/z.ts");
- await touch(d + "/b/z.js");
- },
- async function globInWalkWildcard(): Promise<void> {
- const arr = await walkArray(".", {
- match: [globToRegExp(join("*", "*.ts"))],
- });
- assertEquals(arr.length, 2);
- assertEquals(arr[0], "a/x.ts");
- assertEquals(arr[1], "b/z.ts");
- },
-);
-
-testWalk(
- async (d: string): Promise<void> => {
- await Deno.mkdir(d + "/a");
- await Deno.mkdir(d + "/a/yo");
- await touch(d + "/a/yo/x.ts");
- },
- async function globInWalkFolderWildcard(): Promise<void> {
- const arr = await walkArray(".", {
- match: [
- globToRegExp(join("a", "**", "*.ts"), {
- flags: "g",
- globstar: true,
- }),
- ],
- });
- assertEquals(arr.length, 1);
- assertEquals(arr[0], "a/yo/x.ts");
- },
-);
-
-testWalk(
- async (d: string): Promise<void> => {
- await Deno.mkdir(d + "/a");
- await Deno.mkdir(d + "/a/unicorn");
- await Deno.mkdir(d + "/a/deno");
- await Deno.mkdir(d + "/a/raptor");
- await touch(d + "/a/raptor/x.ts");
- await touch(d + "/a/deno/x.ts");
- await touch(d + "/a/unicorn/x.ts");
- },
- async function globInWalkFolderExtended(): Promise<void> {
- const arr = await walkArray(".", {
- match: [
- globToRegExp(join("a", "+(raptor|deno)", "*.ts"), {
- flags: "g",
- extended: true,
- }),
- ],
- });
- assertEquals(arr.length, 2);
- assertEquals(arr[0], "a/deno/x.ts");
- assertEquals(arr[1], "a/raptor/x.ts");
- },
-);
-
-testWalk(
- async (d: string): Promise<void> => {
- await touch(d + "/x.ts");
- await touch(d + "/x.js");
- await touch(d + "/b.js");
- },
- async function globInWalkWildcardExtension(): Promise<void> {
- const arr = await walkArray(".", {
- match: [globToRegExp("x.*", { flags: "g", globstar: true })],
- });
- assertEquals(arr.length, 2);
- assertEquals(arr[0], "x.js");
- assertEquals(arr[1], "x.ts");
- },
-);
-
-Deno.test({
- name: "isGlob: pattern to test",
+import {
+ GlobToRegExpOptions,
+ globToRegExp,
+ isGlob,
+ joinGlobs,
+ normalizeGlob,
+} from "./glob.ts";
+import { SEP } from "./mod.ts";
+
+function match(
+ glob: string,
+ path: string,
+ opts: GlobToRegExpOptions = {},
+): boolean {
+ if (opts.os == null) {
+ const matchDarwin = path.match(
+ globToRegExp(glob, { ...opts, os: "darwin" }),
+ );
+ if (matchDarwin) {
+ assertEquals(matchDarwin.length, 1);
+ }
+ const matchLinux = path.match(globToRegExp(glob, { ...opts, os: "linux" }));
+ if (matchLinux) {
+ assertEquals(matchLinux.length, 1);
+ }
+ const matchWindows = path.match(
+ globToRegExp(glob, { ...opts, os: "windows" }),
+ );
+ if (matchWindows) {
+ assertEquals(matchWindows.length, 1);
+ }
+ return !!matchDarwin && !!matchLinux && !!matchWindows;
+ } else {
+ const match = path.match(globToRegExp(glob, opts));
+ if (match) {
+ assertEquals(match.length, 1);
+ }
+ return !!match;
+ }
+}
+
+Deno.test({
+ name: "[path] globToRegExp() Basic RegExp",
+ fn(): void {
+ assertEquals(globToRegExp(""), /^$/);
+ assertEquals(globToRegExp("*.js", { os: "linux" }), /^[^/]*\.js\/*$/);
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() * (wildcard)",
+ fn(): void {
+ assert(match("*", "foo", { extended: false, globstar: false }));
+ assert(match("*", "foo", { extended: false, globstar: false }));
+ assert(match("f*", "foo", { extended: false, globstar: false }));
+ assert(match("f*", "foo", { extended: false, globstar: false }));
+ assert(match("*o", "foo", { extended: false, globstar: false }));
+ assert(match("*o", "foo", { extended: false, globstar: false }));
+ assert(match("u*orn", "unicorn", { extended: false, globstar: false }));
+ assert(match("u*orn", "unicorn", { extended: false, globstar: false }));
+ assert(!match("ico", "unicorn", { extended: false, globstar: false }));
+ assert(match("u*nicorn", "unicorn", { extended: false, globstar: false }));
+ assert(match("u*nicorn", "unicorn", { extended: false, globstar: false }));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() ? (match one character)",
+ fn(): void {
+ assert(match("f?o", "foo", { extended: false, globstar: false }));
+ assert(match("f?o?", "fooo", { extended: false, globstar: false }));
+ assert(!match("f?oo", "foo", { extended: false, globstar: false }));
+ assert(!match("?fo", "fooo", { extended: false, globstar: false }));
+ assert(!match("f?oo", "foo", { extended: false, globstar: false }));
+ assert(!match("foo?", "foo", { extended: false, globstar: false }));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() [seq] (character range)",
+ fn(): void {
+ assert(match("fo[oz]", "foo", { extended: false, globstar: false }));
+ assert(match("fo[oz]", "foz", { extended: false, globstar: false }));
+ assert(!match("fo[oz]", "fog", { extended: false, globstar: false }));
+ assert(match("fo[a-z]", "fob", { extended: false, globstar: false }));
+ assert(!match("fo[a-d]", "fot", { extended: false, globstar: false }));
+ assert(!match("fo[!tz]", "fot", { extended: false, globstar: false }));
+ assert(match("fo[!tz]", "fob", { extended: false, globstar: false }));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() [[:alnum:]] (character class in range)",
+ fn(): void {
+ assert(
+ match(
+ "[[:alnum:]]/bar.txt",
+ "a/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ match(
+ "[[:alnum:]abc]/bar.txt",
+ "1/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ match(
+ "[[:digit:]]/bar.txt",
+ "1/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ match(
+ "[[:digit:]b]/bar.txt",
+ "b/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ match(
+ "[![:digit:]b]/bar.txt",
+ "a/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ !match(
+ "[[:alnum:]]/bar.txt",
+ "!/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ !match(
+ "[[:digit:]]/bar.txt",
+ "a/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ !match(
+ "[[:digit:]b]/bar.txt",
+ "a/bar.txt",
+ { extended: false, globstar: false },
+ ),
+ );
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() {} (brace expansion)",
+ fn(): void {
+ assert(
+ match("foo{bar,baaz}", "foobaaz", { extended: false, globstar: false }),
+ );
+ assert(
+ match("foo{bar,baaz}", "foobar", { extended: false, globstar: false }),
+ );
+ assert(
+ !match("foo{bar,baaz}", "foobuzz", { extended: false, globstar: false }),
+ );
+ assert(
+ match("foo{bar,b*z}", "foobuzz", { extended: false, globstar: false }),
+ );
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() Complex matches",
+ fn(): void {
+ assert(
+ match(
+ "http://?o[oz].b*z.com/{*.js,*.html}",
+ "http://foo.baaz.com/jquery.min.js",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ match(
+ "http://?o[oz].b*z.com/{*.js,*.html}",
+ "http://moz.buzz.com/index.html",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ !match(
+ "http://?o[oz].b*z.com/{*.js,*.html}",
+ "http://moz.buzz.com/index.htm",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ !match(
+ "http://?o[oz].b*z.com/{*.js,*.html}",
+ "http://moz.bar.com/index.html",
+ { extended: false, globstar: false },
+ ),
+ );
+ assert(
+ !match(
+ "http://?o[oz].b*z.com/{*.js,*.html}",
+ "http://flozz.buzz.com/index.html",
+ { extended: false, globstar: false },
+ ),
+ );
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() ** (globstar)",
+ fn(): void {
+ assert(match("/foo/**", "/foo/bar.txt"));
+ assert(match("/foo/**", "/foo/bar/baz.txt"));
+ assert(!match("/foo/**", "/foo/bar/baz.txt", { globstar: false }));
+ assert(match("/foo/**", "/foo/bar", { globstar: false }));
+ assert(match("/foo/**/*.txt", "/foo/bar/baz.txt"));
+ assert(match("/foo/**/*.txt", "/foo/bar/baz/qux.txt"));
+ assert(match("/foo/**/bar.txt", "/foo/bar.txt"));
+ assert(match("/foo/**/**/bar.txt", "/foo/bar.txt"));
+ assert(match("/foo/**/*/baz.txt", "/foo/bar/baz.txt"));
+ assert(match("/foo/**/*.txt", "/foo/bar.txt"));
+ assert(match("/foo/**/**/*.txt", "/foo/bar.txt"));
+ assert(match("/foo/**/*/*.txt", "/foo/bar/baz.txt"));
+ assert(match("**/*.txt", "/foo/bar/baz/qux.txt"));
+ assert(match("**/foo.txt", "foo.txt"));
+ assert(match("**/*.txt", "foo.txt"));
+ assert(!match("/foo/**.txt", "/foo/bar/baz/qux.txt"));
+ assert(
+ !match("/foo/bar**/*.txt", "/foo/bar/baz/qux.txt"),
+ );
+ assert(!match("/foo/bar**", "/foo/bar/baz.txt"));
+ assert(!match("**/.txt", "/foo/bar/baz/qux.txt"));
+ assert(
+ !match(
+ "http://foo.com/*",
+ "http://foo.com/bar/baz/jquery.min.js",
+ ),
+ );
+ assert(
+ !match("http://foo.com/*", "http://foo.com/bar/baz/jquery.min.js"),
+ );
+ assert(
+ match("http://foo.com/**", "http://foo.com/bar/baz/jquery.min.js"),
+ );
+ assert(
+ match(
+ "http://foo.com/**/jquery.min.js",
+ "http://foo.com/bar/baz/jquery.min.js",
+ ),
+ );
+ assert(
+ !match(
+ "http://foo.com/*/jquery.min.js",
+ "http://foo.com/bar/baz/jquery.min.js",
+ ),
+ );
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() ?(pattern-list) (extended: match zero or one)",
+ fn(): void {
+ assert(match("?(foo).txt", "foo.txt"));
+ assert(!match("?(foo).txt", "foo.txt", { extended: false }));
+ assert(match("?(foo).txt", "a(foo).txt", { extended: false }));
+ assert(match("?(foo).txt", ".txt"));
+ assert(match("?(foo|bar)baz.txt", "foobaz.txt"));
+ assert(match("?(ba[zr]|qux)baz.txt", "bazbaz.txt"));
+ assert(match("?(ba[zr]|qux)baz.txt", "barbaz.txt"));
+ assert(match("?(ba[zr]|qux)baz.txt", "quxbaz.txt"));
+ assert(match("?(ba[!zr]|qux)baz.txt", "batbaz.txt"));
+ assert(match("?(ba*|qux)baz.txt", "batbaz.txt"));
+ assert(match("?(ba*|qux)baz.txt", "batttbaz.txt"));
+ assert(match("?(ba*|qux)baz.txt", "quxbaz.txt"));
+ assert(match("?(ba?(z|r)|qux)baz.txt", "bazbaz.txt"));
+ assert(match("?(ba?(z|?(r))|qux)baz.txt", "bazbaz.txt"));
+ assert(!match("?(foo|bar)baz.txt", "foobarbaz.txt"));
+ assert(!match("?(ba[zr]|qux)baz.txt", "bazquxbaz.txt"));
+ assert(!match("?(ba[!zr]|qux)baz.txt", "bazbaz.txt"));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() *(pattern-list) (extended: match zero or more)",
+ fn(): void {
+ assert(match("*(foo).txt", "foo.txt"));
+ assert(!match("*(foo).txt", "foo.txt", { extended: false }));
+ assert(match("*(foo).txt", "bar(foo).txt", { extended: false }));
+ assert(match("*(foo).txt", "foofoo.txt"));
+ assert(match("*(foo).txt", ".txt"));
+ assert(match("*(fooo).txt", ".txt"));
+ assert(!match("*(fooo).txt", "foo.txt"));
+ assert(match("*(foo|bar).txt", "foobar.txt"));
+ assert(match("*(foo|bar).txt", "barbar.txt"));
+ assert(match("*(foo|bar).txt", "barfoobar.txt"));
+ assert(match("*(foo|bar).txt", ".txt"));
+ assert(match("*(foo|ba[rt]).txt", "bat.txt"));
+ assert(match("*(foo|b*[rt]).txt", "blat.txt"));
+ assert(!match("*(foo|b*[rt]).txt", "tlat.txt"));
+ assert(match("*(*).txt", "whatever.txt"));
+ assert(match("*(foo|bar)/**/*.txt", "foo/hello/world/bar.txt"));
+ assert(match("*(foo|bar)/**/*.txt", "foo/world/bar.txt"));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() +(pattern-list) (extended: match 1 or more)",
+ fn(): void {
+ assert(match("+(foo).txt", "foo.txt"));
+ assert(!match("+(foo).txt", "foo.txt", { extended: false }));
+ assert(match("+(foo).txt", "+(foo).txt", { extended: false }));
+ assert(!match("+(foo).txt", ".txt"));
+ assert(match("+(foo|bar).txt", "foobar.txt"));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() @(pattern-list) (extended: match one)",
+ fn(): void {
+ assert(match("@(foo).txt", "foo.txt"));
+ assert(!match("@(foo).txt", "foo.txt", { extended: false }));
+ assert(match("@(foo).txt", "@(foo).txt", { extended: false }));
+ assert(match("@(foo|baz)bar.txt", "foobar.txt"));
+ assert(!match("@(foo|baz)bar.txt", "foobazbar.txt"));
+ assert(!match("@(foo|baz)bar.txt", "foofoobar.txt"));
+ assert(!match("@(foo|baz)bar.txt", "toofoobar.txt"));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() !(pattern-list) (extended: match any except)",
+ fn(): void {
+ assert(match("!(boo).txt", "foo.txt"));
+ assert(!match("!(boo).txt", "foo.txt", { extended: false }));
+ assert(match("!(boo).txt", "!(boo).txt", { extended: false }));
+ assert(match("!(foo|baz)bar.txt", "buzbar.txt"));
+ assert(match("!({foo,bar})baz.txt", "notbaz.txt"));
+ assert(!match("!({foo,bar})baz.txt", "foobaz.txt"));
+ },
+});
+
+Deno.test({
+ name:
+ "[path] globToRegExp() Special extended characters should match themselves",
+ fn(): void {
+ const glob = "\\/$^+.()=!|,.*";
+ assert(match(glob, glob));
+ assert(match(glob, glob, { extended: false }));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() Special extended characters in range",
+ fn(): void {
+ assertEquals(globToRegExp("[?*+@!|]", { os: "linux" }), /^[?*+@!|]\/*$/);
+ assertEquals(globToRegExp("[!?*+@!|]", { os: "linux" }), /^[^?*+@!|]\/*$/);
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() Special RegExp characters in range",
+ fn(): void {
+ // Excluding characters checked in the previous test.
+ assertEquals(globToRegExp("[\\$^.=]", { os: "linux" }), /^[\\$^.=]\/*$/);
+ assertEquals(globToRegExp("[!\\$^.=]", { os: "linux" }), /^[^\\$^.=]\/*$/);
+ assertEquals(globToRegExp("[^^]", { os: "linux" }), /^[\^^]\/*$/);
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() Repeating separators",
+ fn() {
+ assert(match("foo/bar", "foo//bar"));
+ assert(match("foo//bar", "foo/bar"));
+ assert(match("foo//bar", "foo//bar"));
+ assert(match("**/bar", "foo//bar"));
+ assert(match("**//bar", "foo/bar"));
+ assert(match("**//bar", "foo//bar"));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() Trailing separators",
+ fn() {
+ assert(match("foo", "foo/"));
+ assert(match("foo/", "foo"));
+ assert(match("foo/", "foo/"));
+ assert(match("**", "foo/"));
+ assert(match("**/", "foo"));
+ assert(match("**/", "foo/"));
+ },
+});
+
+Deno.test({
+ name: "[path] globToRegExp() Backslashes on Windows",
+ fn() {
+ assert(match("foo/bar", "foo\\bar", { os: "windows" }));
+ assert(match("foo\\bar", "foo/bar", { os: "windows" }));
+ assert(match("foo\\bar", "foo\\bar", { os: "windows" }));
+ assert(match("**/bar", "foo\\bar", { os: "windows" }));
+ assert(match("**\\bar", "foo/bar", { os: "windows" }));
+ assert(match("**\\bar", "foo\\bar", { os: "windows" }));
+ },
+});
+
+Deno.test({
+ name: "[path] GlobToRegExpOptions::extended",
+ fn() {
+ const pattern1 = globToRegExp("?(foo|bar)");
+ assertEquals("foo".match(pattern1)?.[0], "foo");
+ assertEquals("bar".match(pattern1)?.[0], "bar");
+
+ const pattern2 = globToRegExp("?(foo|bar)", { extended: false });
+ assertEquals("foo".match(pattern2)?.[0], undefined);
+ assertEquals("bar".match(pattern2)?.[0], undefined);
+ assertEquals("?(foo|bar)".match(pattern2)?.[0], "?(foo|bar)");
+ },
+});
+
+Deno.test({
+ name: "[path] GlobToRegExpOptions::globstar",
+ fn() {
+ const pattern1 = globToRegExp("**/foo");
+ assertEquals("foo".match(pattern1)?.[0], "foo");
+ assertEquals("path/to/foo".match(pattern1)?.[0], "path/to/foo");
+
+ const pattern2 = globToRegExp("**/foo", { globstar: false });
+ assertEquals("foo".match(pattern2)?.[0], undefined);
+ assertEquals("path/to/foo".match(pattern2)?.[0], undefined);
+ assertEquals("path-to/foo".match(pattern2)?.[0], "path-to/foo");
+ },
+});
+
+Deno.test({
+ name: "[path] GlobToRegExpOptions::os",
+ fn() {
+ const pattern1 = globToRegExp("foo/bar", { os: "linux" });
+ assertEquals("foo/bar".match(pattern1)?.[0], "foo/bar");
+ assertEquals("foo\\bar".match(pattern1)?.[0], undefined);
+
+ const pattern2 = globToRegExp("foo/bar", { os: "windows" });
+ assertEquals("foo/bar".match(pattern2)?.[0], "foo/bar");
+ assertEquals("foo\\bar".match(pattern2)?.[0], "foo\\bar");
+ },
+});
+
+Deno.test({
+ name: "[path] isGlob()",
fn(): void {
// should be true if valid glob pattern
assert(isGlob("!foo.js"));
@@ -238,10 +564,10 @@ Deno.test({
},
});
-Deno.test("normalizeGlobGlobstar", function (): void {
+Deno.test("[path] normalizeGlob() Globstar", function (): void {
assertEquals(normalizeGlob(`**${SEP}..`, { globstar: true }), `**${SEP}..`);
});
-Deno.test("joinGlobsGlobstar", function (): void {
+Deno.test("[path] joinGlobs() Globstar", function (): void {
assertEquals(joinGlobs(["**", ".."], { globstar: true }), `**${SEP}..`);
});