UNPKG

14.9 kBJavaScriptView Raw
1// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
2//
3// TODO: Some of these tests do very bad things with backslashes, and will
4// most likely fail badly on windows. They should probably be skipped.
5
6var tap = require("tap")
7 , globalBefore = Object.keys(global)
8 , mm = require("../")
9 , files = [ "a", "b", "c", "d", "abc"
10 , "abd", "abe", "bb", "bcd"
11 , "ca", "cb", "dd", "de"
12 , "bdir/", "bdir/cfile"]
13 , next = files.concat([ "a-b", "aXb"
14 , ".x", ".y" ])
15
16
17var patterns =
18 [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
19 , ["a*", ["a", "abc", "abd", "abe"]]
20 , ["X*", ["X*"], {nonull: true}]
21
22 // allow null glob expansion
23 , ["X*", []]
24
25 // isaacs: Slightly different than bash/sh/ksh
26 // \\* is not un-escaped to literal "*" in a failed match,
27 // but it does make it get treated as a literal star
28 , ["\\*", ["\\*"], {nonull: true}]
29 , ["\\**", ["\\**"], {nonull: true}]
30 , ["\\*\\*", ["\\*\\*"], {nonull: true}]
31
32 , ["b*/", ["bdir/"]]
33 , ["c*", ["c", "ca", "cb"]]
34 , ["**", files]
35
36 , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
37 , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
38
39 , "legendary larry crashes bashes"
40 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
41 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
42 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
43 , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
44
45 , "character classes"
46 , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
47 , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
48 "bdir/", "ca", "cb", "dd", "de"]]
49 , ["a*[^c]", ["abd", "abe"]]
50 , function () { files.push("a-b", "aXb") }
51 , ["a[X-]b", ["a-b", "aXb"]]
52 , function () { files.push(".x", ".y") }
53 , ["[^a-c]*", ["d", "dd", "de"]]
54 , function () { files.push("a*b/", "a*b/ooo") }
55 , ["a\\*b/*", ["a*b/ooo"]]
56 , ["a\\*?/*", ["a*b/ooo"]]
57 , ["*\\\\!*", [], {null: true}, ["echo !7"]]
58 , ["*\\!*", ["echo !7"], null, ["echo !7"]]
59 , ["*.\\*", ["r.*"], null, ["r.*"]]
60 , ["a[b]c", ["abc"]]
61 , ["a[\\b]c", ["abc"]]
62 , ["a?c", ["abc"]]
63 , ["a\\*c", [], {null: true}, ["abc"]]
64 , ["", [""], { null: true }, [""]]
65
66 , "http://www.opensource.apple.com/source/bash/bash-23/" +
67 "bash/tests/glob-test"
68 , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
69 , ["*/man*/bash.*", ["man/man1/bash.1"]]
70 , ["man/man1/bash.1", ["man/man1/bash.1"]]
71 , ["a***c", ["abc"], null, ["abc"]]
72 , ["a*****?c", ["abc"], null, ["abc"]]
73 , ["?*****??", ["abc"], null, ["abc"]]
74 , ["*****??", ["abc"], null, ["abc"]]
75 , ["?*****?c", ["abc"], null, ["abc"]]
76 , ["?***?****c", ["abc"], null, ["abc"]]
77 , ["?***?****?", ["abc"], null, ["abc"]]
78 , ["?***?****", ["abc"], null, ["abc"]]
79 , ["*******c", ["abc"], null, ["abc"]]
80 , ["*******?", ["abc"], null, ["abc"]]
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**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
86 , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
87 , ["[-abc]", ["-"], null, ["-"]]
88 , ["[abc-]", ["-"], null, ["-"]]
89 , ["\\", ["\\"], null, ["\\"]]
90 , ["[\\\\]", ["\\"], null, ["\\"]]
91 , ["[[]", ["["], null, ["["]]
92 , ["[", ["["], null, ["["]]
93 , ["[*", ["[abc"], null, ["[abc"]]
94 , "a right bracket shall lose its special meaning and\n" +
95 "represent itself in a bracket expression if it occurs\n" +
96 "first in the list. -- POSIX.2 2.8.3.2"
97 , ["[]]", ["]"], null, ["]"]]
98 , ["[]-]", ["]"], null, ["]"]]
99 , ["[a-\z]", ["p"], null, ["p"]]
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 }, ["["]]
108
109 , "nocase tests"
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"]]
116
117 // [ pattern, [matches], MM opts, files, TAP opts]
118 , "onestar/twostar"
119 , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
120 , ["{/?,*}", ["/a", "bb"], {null: true}
121 , ["/a", "/b/b", "/a/b/c", "bb"]]
122
123 , "dots should not match unless requested"
124 , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
125
126 // .. and . can only match patterns starting with .,
127 // even when options.dot is set.
128 , function () {
129 files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
130 }
131 , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
132 , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
133 , ["a/*/b", ["a/c/b"], {dot:false}]
134 , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
135
136
137 // this also tests that changing the options needs
138 // to change the cache key, even if the pattern is
139 // the same!
140 , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
141 , [ ".a/.d", "a/.d", "a/b"]]
142
143 , "paren sets cannot contain slashes"
144 , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
145
146 // brace sets trump all else.
147 //
148 // invalid glob pattern. fails on bash4 and bsdglob.
149 // however, in this implementation, it's easier just
150 // to do the intuitive thing, and let brace-expansion
151 // actually come before parsing any extglob patterns,
152 // like the documentation seems to say.
153 //
154 // XXX: if anyone complains about this, either fix it
155 // or tell them to grow up and stop complaining.
156 //
157 // bash/bsdglob says this:
158 // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
159 // but we do this instead:
160 , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
161
162 // test partial parsing in the presence of comment/negation chars
163 , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
164 , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
165
166 // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
167 , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
168 , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
169 , {}
170 , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
171
172
173 // crazy nested {,,} and *(||) tests.
174 , function () {
175 files = [ "a", "b", "c", "d"
176 , "ab", "ac", "ad"
177 , "bc", "cb"
178 , "bc,d", "c,db", "c,d"
179 , "d)", "(b|c", "*(b|c"
180 , "b|c", "b|cc", "cb|c"
181 , "x(a|b|c)", "x(a|c)"
182 , "(a|b|c)", "(a|c)"]
183 }
184 , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
185 , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
186 // a
187 // *(b|c)
188 // *(b|d)
189 , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
190 , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
191
192
193 // test various flag settings.
194 , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
195 , { noext: true } ]
196 , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
197 , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
198 , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
199
200
201 // begin channelling Boole and deMorgan...
202 , "negation tests"
203 , function () {
204 files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
205 }
206
207 // anything that is NOT a* matches.
208 , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
209
210 // anything that IS !a* matches.
211 , ["!a*", ["!ab", "!abc"], {nonegate: true}]
212
213 // anything that IS a* matches
214 , ["!!a*", ["a!b"]]
215
216 // anything that is NOT !a* matches
217 , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
218
219 // negation nestled within a pattern
220 , function () {
221 files = [ "foo.js"
222 , "foo.bar"
223 // can't match this one without negative lookbehind.
224 , "foo.js.js"
225 , "blar.js"
226 , "foo."
227 , "boo.js.boo" ]
228 }
229 , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
230
231 // https://github.com/isaacs/minimatch/issues/5
232 , function () {
233 files = [ 'a/b/.x/c'
234 , 'a/b/.x/c/d'
235 , 'a/b/.x/c/d/e'
236 , 'a/b/.x'
237 , 'a/b/.x/'
238 , 'a/.x/b'
239 , '.x'
240 , '.x/'
241 , '.x/a'
242 , '.x/a/b'
243 , 'a/.x/b/.x/c'
244 , '.x/.x' ]
245 }
246 , ["**/.x/**", [ '.x/'
247 , '.x/a'
248 , '.x/a/b'
249 , 'a/.x/b'
250 , 'a/b/.x/'
251 , 'a/b/.x/c'
252 , 'a/b/.x/c/d'
253 , 'a/b/.x/c/d/e' ] ]
254
255 ]
256
257var regexps =
258 [ '/^(?:(?=.)a[^/]*?)$/',
259 '/^(?:(?=.)X[^/]*?)$/',
260 '/^(?:(?=.)X[^/]*?)$/',
261 '/^(?:\\*)$/',
262 '/^(?:(?=.)\\*[^/]*?)$/',
263 '/^(?:\\*\\*)$/',
264 '/^(?:(?=.)b[^/]*?\\/)$/',
265 '/^(?:(?=.)c[^/]*?)$/',
266 '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
267 '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
268 '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
269 '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
270 '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
271 '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
272 '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
273 '/^(?:(?=.)a[^/]*?[^c])$/',
274 '/^(?:(?=.)a[X-]b)$/',
275 '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
276 '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
277 '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
278 '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
279 '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
280 '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
281 '/^(?:(?=.)a[b]c)$/',
282 '/^(?:(?=.)a[b]c)$/',
283 '/^(?:(?=.)a[^/]c)$/',
284 '/^(?:a\\*c)$/',
285 'false',
286 '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
287 '/^(?:man\\/man1\\/bash\\.1)$/',
288 '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
289 '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
290 '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
291 '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
292 '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
293 '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
294 '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
295 '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
296 '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
297 '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
298 '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
299 '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
300 '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
301 '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
302 '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
303 '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
304 '/^(?:(?!\\.)(?=.)[-abc])$/',
305 '/^(?:(?!\\.)(?=.)[abc-])$/',
306 '/^(?:\\\\)$/',
307 '/^(?:(?!\\.)(?=.)[\\\\])$/',
308 '/^(?:(?!\\.)(?=.)[\\[])$/',
309 '/^(?:\\[)$/',
310 '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
311 '/^(?:(?!\\.)(?=.)[\\]])$/',
312 '/^(?:(?!\\.)(?=.)[\\]-])$/',
313 '/^(?:(?!\\.)(?=.)[a-z])$/',
314 '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
315 '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
316 '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
317 '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
318 '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
319 '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
320 '/^(?:\\[\\])$/',
321 '/^(?:\\[abc)$/',
322 '/^(?:(?=.)XYZ)$/i',
323 '/^(?:(?=.)ab[^/]*?)$/i',
324 '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
325 '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
326 '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
327 '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
328 '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
329 '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
330 '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
331 '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
332 '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
333 '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
334 '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
335 '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
336 '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
337 '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
338 '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
339 '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
340 '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
341 '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
342 '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
343 '/^(?:(?=.)a[^/]b)$/',
344 '/^(?:(?=.)#[^/]*?)$/',
345 '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
346 '/^(?:(?=.)\\!a[^/]*?)$/',
347 '/^(?:(?=.)a[^/]*?)$/',
348 '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
349 '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
350 '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
351var re = 0;
352
353tap.test("basic tests", function (t) {
354 var start = Date.now()
355
356 // [ pattern, [matches], MM opts, files, TAP opts]
357 patterns.forEach(function (c) {
358 if (typeof c === "function") return c()
359 if (typeof c === "string") return t.comment(c)
360
361 var pattern = c[0]
362 , expect = c[1].sort(alpha)
363 , options = c[2] || {}
364 , f = c[3] || files
365 , tapOpts = c[4] || {}
366
367 // options.debug = true
368 var m = new mm.Minimatch(pattern, options)
369 var r = m.makeRe()
370 var expectRe = regexps[re++]
371 tapOpts.re = String(r) || JSON.stringify(r)
372 tapOpts.files = JSON.stringify(f)
373 tapOpts.pattern = pattern
374 tapOpts.set = m.set
375 tapOpts.negated = m.negate
376
377 var actual = mm.match(f, pattern, options)
378 actual.sort(alpha)
379
380 t.equivalent( actual, expect
381 , JSON.stringify(pattern) + " " + JSON.stringify(expect)
382 , tapOpts )
383
384 t.equal(tapOpts.re, expectRe, tapOpts)
385 })
386
387 t.comment("time=" + (Date.now() - start) + "ms")
388 t.end()
389})
390
391tap.test("global leak test", function (t) {
392 var globalAfter = Object.keys(global)
393 t.equivalent(globalAfter, globalBefore, "no new globals, please")
394 t.end()
395})
396
397function alpha (a, b) {
398 return a > b ? 1 : -1
399}