1 // http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
3 var tap = require("tap")
4 , globalBefore = Object.keys(global)
6 , files = [ "a", "b", "c", "d", "abc"
7 , "abd", "abe", "bb", "bcd"
8 , "ca", "cb", "dd", "de"
9 , "bdir/", "bdir/cfile"]
10 , next = files.concat([ "a-b", "aXb"
13 tap.test("basic tests", function (t) {
14 var start = Date.now()
16 // [ pattern, [matches], MM opts, files, TAP opts]
17 ; [ "http://www.bashcookbook.com/bashinfo" +
18 "/source/bash-1.14.7/tests/glob-test"
19 , ["a*", ["a", "abc", "abd", "abe"]]
21 // allow null glob expansion
22 , ["X*", [], { null: true }]
24 // isaacs: Slightly different than bash/sh/ksh
25 // \\* is not un-escaped to literal "*" in a failed match,
26 // but it does make it get treated as a literal star
31 , ["c*", ["c", "ca", "cb"]]
35 , ["\\.\\./*/", ["\\.\\./*/"]]
36 , ["s/\\..*//", ["s/\\..*//"]]
38 , "legendary larry crashes bashes"
39 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
40 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"]]
41 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
42 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"]]
45 , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
46 , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
47 "bdir/", "ca", "cb", "dd", "de"]]
48 , ["a*[^c]", ["abd", "abe"]]
49 , function () { files.push("a-b", "aXb") }
50 , ["a[X-]b", ["a-b", "aXb"]]
51 , function () { files.push(".x", ".y") }
52 , ["[^a-c]*", ["d", "dd", "de"]]
53 , function () { files.push("a*b/", "a*b/ooo") }
54 , ["a\\*b/*", ["a*b/ooo"]]
55 , ["a\\*?/*", ["a*b/ooo"]]
56 , ["*\\\\!*", [], {null: true}, ["echo !7"]]
57 , ["*\\!*", ["echo !7"], null, ["echo !7"]]
58 , ["*.\\*", ["r.*"], null, ["r.*"]]
60 , ["a[\\b]c", ["abc"]]
62 , ["a\\*c", [], {null: true}, ["abc"]]
63 , ["", [""], { null: true }, [""]]
65 , "http://www.opensource.apple.com/source/bash/bash-23/" +
66 "bash/tests/glob-test"
67 , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
68 , ["*/man*/bash.*", ["man/man1/bash.1"]]
69 , ["man/man1/bash.1", ["man/man1/bash.1"]]
70 , ["a***c", ["abc"], null, ["abc"]]
71 , ["a*****?c", ["abc"], null, ["abc"]]
72 , ["?*****??", ["abc"], null, ["abc"]]
73 , ["*****??", ["abc"], null, ["abc"]]
74 , ["?*****?c", ["abc"], null, ["abc"]]
75 , ["?***?****c", ["abc"], null, ["abc"]]
76 , ["?***?****?", ["abc"], null, ["abc"]]
77 , ["?***?****", ["abc"], null, ["abc"]]
78 , ["*******c", ["abc"], null, ["abc"]]
79 , ["*******?", ["abc"], null, ["abc"]]
80 , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
81 , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
82 , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
83 , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
84 , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
85 , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
86 , ["[-abc]", ["-"], null, ["-"]]
87 , ["[abc-]", ["-"], null, ["-"]]
88 , ["\\", ["\\"], null, ["\\"]]
89 , ["[\\\\]", ["\\"], null, ["\\"]]
90 , ["[[]", ["["], null, ["["]]
91 , ["[", ["["], null, ["["]]
92 , ["[*", ["[abc"], null, ["[abc"]]
93 , "a right bracket shall lose its special meaning and\n" +
94 "represent itself in a bracket expression if it occurs\n" +
95 "first in the list. -- POSIX.2 2.8.3.2"
96 , ["[]]", ["]"], null, ["]"]]
97 , ["[]-]", ["]"], null, ["]"]]
98 , ["[a-\z]", ["p"], null, ["p"]]
99 , ["[/\\\\]*", ["/tmp"], null, ["/tmp"]]
100 , ["??**********?****?", [], { null: true }, ["abc"]]
101 , ["??**********?****c", [], { null: true }, ["abc"]]
102 , ["?************c****?****", [], { null: true }, ["abc"]]
103 , ["*c*?**", [], { null: true }, ["abc"]]
104 , ["a*****c*?**", [], { null: true }, ["abc"]]
105 , ["a********???*******", [], { null: true }, ["abc"]]
106 , ["[]", [], { null: true }, ["a"]]
107 , ["[abc", [], { null: true }, ["["]]
110 , ["XYZ", ["xYz"], { nocase: true, null: true }
111 , ["xYz", "ABC", "IjK"]]
112 , ["ab*", ["ABC"], { nocase: true, null: true }
113 , ["xYz", "ABC", "IjK"]]
114 , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
115 , ["xYz", "ABC", "IjK"]]
117 // [ pattern, [matches], MM opts, files, TAP opts]
119 , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
120 , ["{/?,*}", ["/a", "bb"], {null: true}
121 , ["/a", "/b/b", "/a/b/c", "bb"]]
123 , "dots should not match unless requested"
124 , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
126 // this also tests that changing the options needs
127 // to change the cache key, even if the pattern is
129 , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
130 , [ ".a/.d", "a/.d", "a/b"]]
132 ].forEach(function (c) {
133 if (typeof c === "function") return c()
134 if (typeof c === "string") return t.comment(c)
137 , expect = c[1].sort(alpha)
138 , options = c[2] || {}
140 , tapOpts = c[4] || {}
142 // options.debug = true
143 var r = mm.makeRe(pattern, options)
144 tapOpts.re = String(r) || JSON.stringify(r)
145 tapOpts.files = JSON.stringify(f)
146 tapOpts.pattern = pattern
148 var actual = mm.match(f, pattern, options)
150 t.equivalent( actual, expect
151 , JSON.stringify(pattern) + " " + JSON.stringify(expect)
155 t.comment("time=" + (Date.now() - start) + "ms")
159 tap.test("global leak test", function (t) {
160 var globalAfter = Object.keys(global)
161 t.equivalent(globalAfter, globalBefore, "no new globals, please")
165 function alpha (a, b) {
166 return a > b ? 1 : -1