pax_global_header00006660000000000000000000000064130022323350014503gustar00rootroot0000000000000052 comment=4979130bdb5522e9a8d45472ce73ffb9427a9f27 extglob-1.0.0/000077500000000000000000000000001300223233500131455ustar00rootroot00000000000000extglob-1.0.0/.editorconfig000066400000000000000000000004051300223233500156210ustar00rootroot00000000000000root = true [*] indent_style = space end_of_line = lf charset = utf-8 indent_size = 2 trim_trailing_whitespace = true insert_final_newline = true [{**/{actual,fixtures,expected,templates}/**,*.md}] trim_trailing_whitespace = false insert_final_newline = falseextglob-1.0.0/.eslintrc.json000066400000000000000000000071251300223233500157460ustar00rootroot00000000000000{ "ecmaFeatures": { "modules": true, "experimentalObjectRestSpread": true }, "env": { "browser": false, "es6": true, "node": true, "mocha": true }, "globals": { "document": false, "navigator": false, "window": false }, "rules": { "accessor-pairs": 2, "arrow-spacing": [2, { "before": true, "after": true }], "block-spacing": [2, "always"], "brace-style": [2, "1tbs", { "allowSingleLine": true }], "comma-dangle": [2, "never"], "comma-spacing": [2, { "before": false, "after": true }], "comma-style": [2, "last"], "constructor-super": 2, "curly": [2, "multi-line"], "dot-location": [2, "property"], "eol-last": 2, "eqeqeq": [2, "allow-null"], "generator-star-spacing": [2, { "before": true, "after": true }], "handle-callback-err": [2, "^(err|error)$" ], "indent": [2, 2, { "SwitchCase": 1 }], "key-spacing": [2, { "beforeColon": false, "afterColon": true }], "keyword-spacing": [2, { "before": true, "after": true }], "new-cap": [2, { "newIsCap": true, "capIsNew": false }], "new-parens": 2, "no-array-constructor": 2, "no-caller": 2, "no-class-assign": 2, "no-cond-assign": 2, "no-const-assign": 2, "no-control-regex": 2, "no-debugger": 2, "no-delete-var": 2, "no-dupe-args": 2, "no-dupe-class-members": 2, "no-dupe-keys": 2, "no-duplicate-case": 2, "no-empty-character-class": 2, "no-eval": 2, "no-ex-assign": 2, "no-extend-native": 2, "no-extra-bind": 2, "no-extra-boolean-cast": 2, "no-extra-parens": [2, "functions"], "no-fallthrough": 2, "no-floating-decimal": 2, "no-func-assign": 2, "no-implied-eval": 2, "no-inner-declarations": [2, "functions"], "no-invalid-regexp": 2, "no-irregular-whitespace": 2, "no-iterator": 2, "no-label-var": 2, "no-labels": 2, "no-lone-blocks": 2, "no-mixed-spaces-and-tabs": 2, "no-multi-spaces": 2, "no-multi-str": 2, "no-multiple-empty-lines": [2, { "max": 1 }], "no-native-reassign": 0, "no-negated-in-lhs": 2, "no-new": 2, "no-new-func": 2, "no-new-object": 2, "no-new-require": 2, "no-new-wrappers": 2, "no-obj-calls": 2, "no-octal": 2, "no-octal-escape": 2, "no-proto": 0, "no-redeclare": 2, "no-regex-spaces": 2, "no-return-assign": 2, "no-self-compare": 2, "no-sequences": 2, "no-shadow-restricted-names": 2, "no-spaced-func": 2, "no-sparse-arrays": 2, "no-this-before-super": 2, "no-throw-literal": 2, "no-trailing-spaces": 0, "no-undef": 2, "no-undef-init": 2, "no-unexpected-multiline": 2, "no-unneeded-ternary": [2, { "defaultAssignment": false }], "no-unreachable": 2, "no-unused-vars": [2, { "vars": "all", "args": "none" }], "no-useless-call": 0, "no-with": 2, "one-var": [0, { "initialized": "never" }], "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], "padded-blocks": [0, "never"], "quotes": [2, "single", "avoid-escape"], "radix": 2, "semi": [2, "always"], "semi-spacing": [2, { "before": false, "after": true }], "space-before-blocks": [2, "always"], "space-before-function-paren": [2, "never"], "space-in-parens": [2, "never"], "space-infix-ops": 2, "space-unary-ops": [2, { "words": true, "nonwords": false }], "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], "use-isnan": 2, "valid-typeof": 2, "wrap-iife": [2, "any"], "yoda": [2, "never"] } } extglob-1.0.0/.gitattributes000066400000000000000000000000171300223233500160360ustar00rootroot00000000000000*.* text eol=lfextglob-1.0.0/.gitignore000066400000000000000000000003311300223233500151320ustar00rootroot00000000000000# always ignore files *.DS_Store *.sublime-* # test related, or directories generated by tests test/actual actual coverage # npm node_modules npm-debug.log # misc _gh_pages bower_components vendor temp tmp TODO.md extglob-1.0.0/.travis.yml000066400000000000000000000001541300223233500152560ustar00rootroot00000000000000sudo: false language: node_js os: - linux - osx node_js: - node - '6' - '5' - '0.12' - '0.10' extglob-1.0.0/.verb.md000066400000000000000000000057371300223233500145170ustar00rootroot00000000000000- Convert an extglob string to a regex-compatible string. - More complete (and correct) support than [minimatch](https://github.com/isaacs/minimatch) (minimatch fails a large percentage of the extglob tests) - Handles [negation patterns](#extglob-patterns) - Handles [nested patterns](#extglob-patterns) - Organized code base, easy to maintain and make changes when edge cases arise - As you can see by the [benchmarks](#benchmarks), extglob doesn't pay with speed for it's completeness, accuracy and quality. **Heads up!**: This library only supports extglobs, to handle full glob patterns and other extended globbing features use [micromatch][] instead. ## Usage The main export is a function that takes a string and options, and returns an object with the parsed AST and the compiled `.output`, which is a regex-compatible string that can be used for matching. ```js var extglob = require('{%= name %}'); console.log(extglob('!(xyz)*.js')); ``` ## Extglob cheatsheet Extended globbing patterns can be defined as follows (as described by the [bash man page][bash]): | **pattern** | **regex equivalent** | **description** | | --- | --- | --- | | `?(pattern-list)` | `(...|...)?` | Matches zero or one occurrence of the given pattern(s) | | `*(pattern-list)` | `(...|...)*` | Matches zero or more occurrences of the given pattern(s) | | `+(pattern-list)` | `(...|...)+` | Matches one or more occurrences of the given pattern(s) | | `@(pattern-list)` | `(...|...)` [^1] | Matches one of the given pattern(s) | | `!(pattern-list)` | N/A | Matches anything except one of the given pattern(s) | [^1]: `@` isn't a RegEx character. ## API {%= apidocs("index.js") %} ## Options Available options are based on the options from Bash (and the option names used in bash). ### options.nullglob **Type**: `boolean` **Default**: `undefined` When enabled, the pattern itself will be returned when no matches are found. ### options.nonull Alias for [options.nullglob](#optionsnullglob), included for parity with minimatch. ### options.cache **Type**: `boolean` **Default**: `undefined` Functions are memoized based on the given glob patterns and options. Disable memoization by setting `options.cache` to false. ### options.failglob **Type**: `boolean` **Default**: `undefined` Throw an error is no matches are found. ## Benchmarks Last run on {%= date() %} ```sh {%= docs("benchmark/last.md") %} ``` ## Differences from Bash This library has complete parity with Bash 4.3 with only a couple of minor differences. - In some cases Bash returns true if the given string "contains" the pattern, whereas this library returns true if the string is an exact match for the pattern. You can relax this by setting `options.contains` to true. - This library is more accurate than Bash and thus does not fail some of the tests that Bash 4.3 still lists as failing in their unit tests [bash]: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html [micromatch]: https://github.com/jonschlinkert/micromatch extglob-1.0.0/LICENSE000066400000000000000000000020771300223233500141600ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015-2016, Jon Schlinkert Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extglob-1.0.0/README.md000066400000000000000000000262501300223233500144310ustar00rootroot00000000000000# extglob [![NPM version](https://img.shields.io/npm/v/extglob.svg?style=flat)](https://www.npmjs.com/package/extglob) [![NPM monthly downloads](https://img.shields.io/npm/dm/extglob.svg?style=flat)](https://npmjs.org/package/extglob) [![NPM total downloads](https://img.shields.io/npm/dt/extglob.svg?style=flat)](https://npmjs.org/package/extglob) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/extglob.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/extglob) [![Windows Build Status](https://img.shields.io/appveyor/ci/jonschlinkert/extglob.svg?style=flat&label=AppVeyor)](https://ci.appveyor.com/project/jonschlinkert/extglob) > Extended glob support for JavaScript. Adds (almost) the expressive power of regular expressions to glob patterns. ## Install Install with [npm](https://www.npmjs.com/): ```sh $ npm install --save extglob ``` * Convert an extglob string to a regex-compatible string. * More complete (and correct) support than [minimatch](https://github.com/isaacs/minimatch) (minimatch fails a large percentage of the extglob tests) * Handles [negation patterns](#extglob-patterns) * Handles [nested patterns](#extglob-patterns) * Organized code base, easy to maintain and make changes when edge cases arise * As you can see by the [benchmarks](#benchmarks), extglob doesn't pay with speed for it's completeness, accuracy and quality. **Heads up!**: This library only supports extglobs, to handle full glob patterns and other extended globbing features use [micromatch](https://github.com/jonschlinkert/micromatch) instead. ## Usage The main export is a function that takes a string and options, and returns an object with the parsed AST and the compiled `.output`, which is a regex-compatible string that can be used for matching. ```js var extglob = require('extglob'); console.log(extglob('!(xyz)*.js')); ``` ## Extglob cheatsheet Extended globbing patterns can be defined as follows (as described by the [bash man page](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html)): | **pattern** | **regex equivalent** | **description** | | --- | --- | --- | | `?(pattern-list)` | `(... | ...)?` | Matches zero or one occurrence of the given pattern(s) | | `*(pattern-list)` | `(... | ...)*` | Matches zero or more occurrences of the given pattern(s) | | `+(pattern-list)` | `(... | ...)+` | Matches one or more occurrences of the given pattern(s) | | `@(pattern-list)` | `(... | ...)` [1] | Matches one of the given pattern(s) | | `!(pattern-list)` | N/A | Matches anything except one of the given pattern(s) | ## API ### [extglob](index.js#L37) Convert the given `extglob` pattern into a regex-compatible string. Returns an object with the compiled result and the parsed AST. **Example** ```js var extglob = require('extglob'); console.log(extglob('*.!(*a)')); //=> '(?!\\.)[^/]*?\\.(?!(?!\\.)[^/]*?a\\b).*?' ``` **Params** * `pattern` **{String}** * `options` **{Object}** * `returns` **{String}** ### [.match](index.js#L68) Takes an array of strings and an extglob pattern and returns a new array that contains only the strings that match the pattern. **Example** ```js var extglob = require('extglob'); console.log(extglob.match(['a.a', 'a.b', 'a.c'], '*.!(*a)')); //=> ['a.b', 'a.c'] ``` **Params** * `list` **{Array}**: Array of strings to match * `pattern` **{String}**: Extglob pattern * `options` **{Object}** * `returns` **{Array}**: Returns an array of matches ### [.isMatch](index.js#L123) Returns true if the specified `string` matches the given extglob `pattern`. **Example** ```js var extglob = require('extglob'); console.log(extglob.isMatch('a.a', '*.!(*a)')); //=> false console.log(extglob.isMatch('a.b', '*.!(*a)')); //=> true ``` **Params** * `string` **{String}**: String to match * `pattern` **{String}**: Extglob pattern * `options` **{String}** * `returns` **{Boolean}** ### [.contains](index.js#L162) Returns true if the given `string` contains the given pattern. Similar to `.isMatch` but the pattern can match any part of the string. **Example** ```js var extglob = require('extglob'); console.log(extglob.contains('aa/bb/cc', '*b')); //=> true console.log(extglob.contains('aa/bb/cc', '*d')); //=> false ``` **Params** * `str` **{String}**: The string to match. * `pattern` **{String}**: Glob pattern to use for matching. * `options` **{Object}** * `returns` **{Boolean}**: Returns true if the patter matches any part of `str`. ### [.matcher](index.js#L196) Takes an extglob pattern and returns a matcher function. The returned function takes the string to match as its only argument. **Example** ```js var extglob = require('extglob'); var isMatch = extglob.matcher('*.!(*a)'); console.log(isMatch('a.a')); //=> false console.log(isMatch('a.b')); //=> true ``` **Params** * `pattern` **{String}**: Extglob pattern * `options` **{String}** * `returns` **{Boolean}** ### [.create](index.js#L226) Convert the given `extglob` pattern into a regex-compatible string. Returns an object with the compiled result and the parsed AST. **Example** ```js var extglob = require('extglob'); console.log(extglob.create('*.!(*a)').output); //=> '(?!\\.)[^/]*?\\.(?!(?!\\.)[^/]*?a\\b).*?' ``` **Params** * `str` **{String}** * `options` **{Object}** * `returns` **{String}** ### [.makeRe](index.js#L255) Create a regular expression from the given `pattern` and `options`. **Example** ```js var extglob = require('extglob'); var re = extglob.makeRe('*.!(*a)'); console.log(re); //=> /^[^\/]*?\.(?![^\/]*?a)[^\/]*?$/ ``` **Params** * `pattern` **{String}**: The pattern to convert to regex. * `options` **{Object}** * `returns` **{RegExp}** ## Options Available options are based on the options from Bash (and the option names used in bash). ### options.nullglob **Type**: `boolean` **Default**: `undefined` When enabled, the pattern itself will be returned when no matches are found. ### options.nonull Alias for [options.nullglob](#optionsnullglob), included for parity with minimatch. ### options.cache **Type**: `boolean` **Default**: `undefined` Functions are memoized based on the given glob patterns and options. Disable memoization by setting `options.cache` to false. ### options.failglob **Type**: `boolean` **Default**: `undefined` Throw an error is no matches are found. ## Benchmarks Last run on October 20, 2016 ```sh Benchmarking: (5 of 5) · negation-nested · negation-simple · range-false · range-true · star-simple # benchmark/fixtures/isMatch/negation-nested.js (49 bytes) extglob x 1,988,591 ops/sec ±1.18% (84 runs sampled) minimatch x 73,335 ops/sec ±1.38% (84 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/negation-simple.js (43 bytes) extglob x 2,320,380 ops/sec ±1.71% (86 runs sampled) minimatch x 122,947 ops/sec ±1.28% (86 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/range-false.js (56 bytes) extglob x 1,729,572 ops/sec ±1.22% (84 runs sampled) minimatch x 112,566 ops/sec ±1.26% (85 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/range-true.js (56 bytes) extglob x 1,819,085 ops/sec ±1.28% (83 runs sampled) minimatch x 115,153 ops/sec ±1.50% (85 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/star-simple.js (46 bytes) extglob x 1,970,063 ops/sec ±1.46% (83 runs sampled) minimatch x 138,805 ops/sec ±1.31% (87 runs sampled) fastest is extglob ``` ## Differences from Bash This library has complete parity with Bash 4.3 with only a couple of minor differences. * In some cases Bash returns true if the given string "contains" the pattern, whereas this library returns true if the string is an exact match for the pattern. You can relax this by setting `options.contains` to true. * This library is more accurate than Bash and thus does not fail some of the tests that Bash 4.3 still lists as failing in their unit tests ## About ### Related projects * [braces](https://www.npmjs.com/package/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://github.com/jonschlinkert/braces) | [homepage](https://github.com/jonschlinkert/braces "Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.") * [expand-brackets](https://www.npmjs.com/package/expand-brackets): Expand POSIX bracket expressions (character classes) in glob patterns. | [homepage](https://github.com/jonschlinkert/expand-brackets "Expand POSIX bracket expressions (character classes) in glob patterns.") * [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://github.com/jonschlinkert/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.") * [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or `step` to… [more](https://github.com/jonschlinkert/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range "Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`") * [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.") ### Contributing Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). ### Contributors | **Commits** | **Contributor**
| | --- | --- | --- | --- | --- | | 32 | [jonschlinkert](https://github.com/jonschlinkert) | | 2 | [isiahmeadows](https://github.com/isiahmeadows) | | 1 | [shinnn](https://github.com/shinnn) | ### Building docs _(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ To generate the readme and API documentation with [verb](https://github.com/verbose/verb): ```sh $ npm install -g verb verb-generate-readme && verb ``` ### Running tests Install dev dependencies: ```sh $ npm install -d && npm test ``` ### Author **Jon Schlinkert** * [github/jonschlinkert](https://github.com/jonschlinkert) * [twitter/jonschlinkert](http://twitter.com/jonschlinkert) ### License Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). Released under the [MIT license](https://github.com/jonschlinkert/extglob/blob/master/LICENSE). *** _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on October 20, 2016._
  1. `@` isn't a RegEx character.
extglob-1.0.0/appveyor.yml000066400000000000000000000010651300223233500155370ustar00rootroot00000000000000# Test against this version of Node.js environment: matrix: # node.js - nodejs_version: "6.0" - nodejs_version: "5.0" - nodejs_version: "0.12" - nodejs_version: "0.10" # Install scripts. (runs after repo cloning) install: # Get the latest stable version of Node.js or io.js - ps: Install-Product node $env:nodejs_version # install modules - npm install # Post-install test scripts. test_script: # Output useful info for debugging. - node --version - npm --version # run tests - npm test # Don't actually build. build: off extglob-1.0.0/benchmark/000077500000000000000000000000001300223233500150775ustar00rootroot00000000000000extglob-1.0.0/benchmark/code/000077500000000000000000000000001300223233500160115ustar00rootroot00000000000000extglob-1.0.0/benchmark/code/isMatch/000077500000000000000000000000001300223233500174015ustar00rootroot00000000000000extglob-1.0.0/benchmark/code/isMatch/extglob.js000066400000000000000000000001711300223233500214020ustar00rootroot00000000000000var extglob = require('../../..'); module.exports = function(str, pattern) { return extglob.isMatch(str, pattern); }; extglob-1.0.0/benchmark/code/isMatch/minimatch.js000066400000000000000000000001661300223233500217130ustar00rootroot00000000000000var minimatch = require('minimatch'); module.exports = function(str, pattern) { return minimatch(str, pattern); }; extglob-1.0.0/benchmark/code/match/000077500000000000000000000000001300223233500171055ustar00rootroot00000000000000extglob-1.0.0/benchmark/code/match/extglob.js000066400000000000000000000001711300223233500211060ustar00rootroot00000000000000var extglob = require('../../..'); module.exports = function(file, pattern) { return extglob.match(file, pattern); }; extglob-1.0.0/benchmark/code/match/minimatch.js000066400000000000000000000002001300223233500214040ustar00rootroot00000000000000var minimatch = require('minimatch'); module.exports = function(files, pattern) { return minimatch.match(files, pattern); }; extglob-1.0.0/benchmark/fixtures/000077500000000000000000000000001300223233500167505ustar00rootroot00000000000000extglob-1.0.0/benchmark/fixtures/isMatch/000077500000000000000000000000001300223233500203405ustar00rootroot00000000000000extglob-1.0.0/benchmark/fixtures/isMatch/negation-nested.js000066400000000000000000000000611300223233500237570ustar00rootroot00000000000000module.exports = ['a.b', 'a.!(!(@(*b)))', true]; extglob-1.0.0/benchmark/fixtures/isMatch/negation-simple.js000066400000000000000000000000531300223233500237670ustar00rootroot00000000000000module.exports = ['a.b', 'a.!(*a)', true]; extglob-1.0.0/benchmark/fixtures/isMatch/range-false.js000066400000000000000000000000701300223233500230570ustar00rootroot00000000000000module.exports = ['para381', 'para?([345]|99)1', true]; extglob-1.0.0/benchmark/fixtures/isMatch/range-true.js000066400000000000000000000000701300223233500227440ustar00rootroot00000000000000module.exports = ['para991', 'para?([345]|99)1', true]; extglob-1.0.0/benchmark/fixtures/isMatch/star-simple.js000066400000000000000000000000561300223233500231370ustar00rootroot00000000000000module.exports = ['abef', 'ab*(e|f)*', true]; extglob-1.0.0/benchmark/fixtures/match/000077500000000000000000000000001300223233500200445ustar00rootroot00000000000000extglob-1.0.0/benchmark/fixtures/match/negation-basic.js000066400000000000000000000002071300223233500232640ustar00rootroot00000000000000module.exports = [['a.a', 'a.b', 'a.a.a', 'c.a', 'a.', 'd.a.d', 'a.bb', 'a.ccc'], 'a.!(*a)', ['d.a.d', 'a.', 'a.b', 'a.bb', 'a.ccc']]; extglob-1.0.0/benchmark/fixtures/match/star-basic.js000066400000000000000000000000571300223233500224340ustar00rootroot00000000000000module.exports = [['ab', 'abef'], 'ab*(e|f)']; extglob-1.0.0/benchmark/index.js000066400000000000000000000016611300223233500165500ustar00rootroot00000000000000'use strict'; var path = require('path'); var util = require('util'); var cyan = require('ansi-cyan'); var argv = require('minimist')(process.argv.slice(2)); var isPrimitive = require('is-primitive'); var isObject = require('is-object'); var Suite = require('benchmarked'); function run(type, pattern) { var suite = new Suite({ cwd: __dirname, fixtures: path.join('fixtures', type, '*.js'), code: path.join('code', type, '*.js') }); if (argv.dry) { console.log(type); suite.dryRun(function(code, fixture) { console.log(cyan('%s > %s'), code.key, fixture.key); var args = require(fixture.path); var last = []; if (args.length > 2) { last = args.pop(); } var expected = util.inspect(last, {depth: null}); console.log(util.inspect(code.run.apply(null, args), {depth: null})); console.log(); }); } else { suite.run(); } } run(argv._[0] || 'isMatch'); extglob-1.0.0/benchmark/last.md000066400000000000000000000020521300223233500163630ustar00rootroot00000000000000Benchmarking: (5 of 5) · negation-nested · negation-simple · range-false · range-true · star-simple # benchmark/fixtures/isMatch/negation-nested.js (49 bytes) extglob x 1,988,591 ops/sec ±1.18% (84 runs sampled) minimatch x 73,335 ops/sec ±1.38% (84 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/negation-simple.js (43 bytes) extglob x 2,320,380 ops/sec ±1.71% (86 runs sampled) minimatch x 122,947 ops/sec ±1.28% (86 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/range-false.js (56 bytes) extglob x 1,729,572 ops/sec ±1.22% (84 runs sampled) minimatch x 112,566 ops/sec ±1.26% (85 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/range-true.js (56 bytes) extglob x 1,819,085 ops/sec ±1.28% (83 runs sampled) minimatch x 115,153 ops/sec ±1.50% (85 runs sampled) fastest is extglob # benchmark/fixtures/isMatch/star-simple.js (46 bytes) extglob x 1,970,063 ops/sec ±1.46% (83 runs sampled) minimatch x 138,805 ops/sec ±1.31% (87 runs sampled) fastest is extglob extglob-1.0.0/benchmark/package.json000066400000000000000000000005441300223233500173700ustar00rootroot00000000000000{ "name": "extglob-benchmarks", "version": "0.0.0", "private": true, "main": "index.js", "scripts": { "test": "mocha" }, "devDependencies": { "ansi-cyan": "^0.1.1", "benchmarked": "^0.2.2", "extglob": "^0.3.2", "is-object": "^1.0.1", "is-primitive": "^2.0.0", "minimatch": "^3.0.0", "minimist": "^1.2.0" } } extglob-1.0.0/changelog.md000066400000000000000000000006601300223233500154200ustar00rootroot00000000000000## Changelog ### v1.0.0 **Breaking changes** - The main export now returns the compiled string, instead of the object returned from the compiler **Added features** - Adds a `.create` method to do what the main function did before v1.0.0 **Other changes** - adds `expand-brackets` parsers/compilers to handle nested brackets and extglobs - uses `to-regex` to build regex for `makeRe` method - improves coverage - optimizationsextglob-1.0.0/examples/000077500000000000000000000000001300223233500147635ustar00rootroot00000000000000extglob-1.0.0/examples/extglob.create.js000066400000000000000000000002051300223233500202240ustar00rootroot00000000000000'use strict'; var extglob = require('..'); console.log(extglob.create('*.!(*a)')); console.log(extglob.create('*(*(of*(a)x)z)')); extglob-1.0.0/examples/extglob.js000066400000000000000000000004061300223233500167650ustar00rootroot00000000000000'use strict'; var extglob = require('..'); console.log(extglob('!(xyz)*.js')); //=>'(?:(?!(?:xyz)).*?)(?!\.).*?\.js' console.log(extglob('*.!(*a)')); //=> '(?!\.).*?\.(?:(?!(?:(?!\.).*?a$)).*?)' console.log(extglob('+(*(of*(a)x)z)')); //=> '+((of(a)*x)*z)*' extglob-1.0.0/examples/parser.js000066400000000000000000000003511300223233500166140ustar00rootroot00000000000000'use strict'; var parsers = require('../lib/parsers'); var Extglob = require('../lib/extglob'); var extglob = new Extglob(); extglob.use(parsers); var pattern = '*(*(of*(a)x)z)'; var res = extglob.parse(pattern); console.log(res); extglob-1.0.0/examples/regex.js000066400000000000000000000002251300223233500164320ustar00rootroot00000000000000 var extglob = require('..'); var re = extglob.makeRe('*(a|b|c)'); console.log(re); console.log(re.test('bar')); console.log(re.test('bbbaaaccc')); extglob-1.0.0/examples/source-map.js000066400000000000000000000002541300223233500173750ustar00rootroot00000000000000'use strict'; var extglob = require('..'); var pattern = '*(*(of*(a)x)z)'; console.log(extglob.create(pattern)); console.log(extglob.create(pattern, {sourcemap: true})); extglob-1.0.0/gulpfile.js000066400000000000000000000014731300223233500153170ustar00rootroot00000000000000'use strict'; var gulp = require('gulp'); var mocha = require('gulp-mocha'); var unused = require('gulp-unused'); var istanbul = require('gulp-istanbul'); var eslint = require('gulp-eslint'); gulp.task('coverage', function() { return gulp.src(['index.js', 'lib/*.js']) .pipe(istanbul()) .pipe(istanbul.hookRequire()); }); gulp.task('test', ['coverage'], function() { return gulp.src('test/*.js') .pipe(mocha({reporter: 'spec'})) .pipe(istanbul.writeReports()); }); gulp.task('lint', function() { return gulp.src(['*.js', 'lib/*.js', 'test/{*,support/*}.js']) .pipe(eslint()) .pipe(eslint.format()); }); gulp.task('unused', function() { return gulp.src(['index.js', 'lib/*.js']) .pipe(unused({keys: Object.keys(require('./lib/utils.js'))})); }); gulp.task('default', ['test', 'lint']); extglob-1.0.0/index.js000066400000000000000000000160071300223233500146160ustar00rootroot00000000000000'use strict'; /** * Module dependencies */ var debug = require('debug')('extglob'); var extend = require('extend-shallow'); var unique = require('array-unique'); var toRegex = require('to-regex'); /** * Local dependencies */ var compilers = require('./lib/compilers'); var parsers = require('./lib/parsers'); var Extglob = require('./lib/extglob'); var utils = require('./lib/utils'); var MAX_LENGTH = 1024 * 64; /** * Convert the given `extglob` pattern into a regex-compatible string. Returns * an object with the compiled result and the parsed AST. * * ```js * var extglob = require('extglob'); * console.log(extglob('*.!(*a)')); * //=> '(?!\\.)[^/]*?\\.(?!(?!\\.)[^/]*?a\\b).*?' * ``` * @param {String} `pattern` * @param {Object} `options` * @return {String} * @api public */ function extglob(pattern, options) { debug('initializing from <%s>', __filename); var res = extglob.create(pattern, options); return res.output; } /** * Cache */ extglob.cache = utils.cache; extglob.clearCache = function() { extglob.cache.__data__ = {}; }; /** * Takes an array of strings and an extglob pattern and returns a new * array that contains only the strings that match the pattern. * * ```js * var extglob = require('extglob'); * console.log(extglob.match(['a.a', 'a.b', 'a.c'], '*.!(*a)')); * //=> ['a.b', 'a.c'] * ``` * @param {Array} `list` Array of strings to match * @param {String} `pattern` Extglob pattern * @param {Object} `options` * @return {Array} Returns an array of matches * @api public */ extglob.match = function(list, pattern, options) { if (typeof pattern !== 'string') { throw new TypeError('expected pattern to be a string'); } list = utils.arrayify(list); var isMatch = extglob.matcher(pattern, options); var len = list.length; var idx = -1; var matches = []; while (++idx < len) { var ele = list[idx]; if (isMatch(ele)) { matches.push(ele); } } // if no options were passed, uniquify results and return if (typeof options === 'undefined') { return unique(matches); } if (matches.length === 0) { if (options.failglob === true) { throw new Error('no matches found for "' + pattern + '"'); } if (options.nonull === true || options.nullglob === true) { return [pattern.split('\\').join('')]; } } return options.nodupes !== false ? unique(matches) : matches; }; /** * Returns true if the specified `string` matches the given * extglob `pattern`. * * ```js * var extglob = require('extglob'); * * console.log(extglob.isMatch('a.a', '*.!(*a)')); * //=> false * console.log(extglob.isMatch('a.b', '*.!(*a)')); * //=> true * ``` * @param {String} `string` String to match * @param {String} `pattern` Extglob pattern * @param {String} `options` * @return {Boolean} * @api public */ extglob.isMatch = function(str, pattern, options) { if (typeof pattern !== 'string') { throw new TypeError('expected pattern to be a string'); } if (typeof str !== 'string') { throw new TypeError('expected a string'); } if (pattern === str) { return true; } if (pattern === '' || pattern === ' ' || pattern === '.') { return pattern === str; } var isMatch = utils.memoize('isMatch', pattern, options, extglob.matcher); return isMatch(str); }; /** * Returns true if the given `string` contains the given pattern. Similar to `.isMatch` but * the pattern can match any part of the string. * * ```js * var extglob = require('extglob'); * console.log(extglob.contains('aa/bb/cc', '*b')); * //=> true * console.log(extglob.contains('aa/bb/cc', '*d')); * //=> false * ``` * @param {String} `str` The string to match. * @param {String} `pattern` Glob pattern to use for matching. * @param {Object} `options` * @return {Boolean} Returns true if the patter matches any part of `str`. * @api public */ extglob.contains = function(str, pattern, options) { if (typeof str !== 'string') { throw new TypeError('expected a string'); } if (pattern === '' || pattern === ' ' || pattern === '.') { return pattern === str; } var opts = extend({}, options, {contains: true}); opts.strictClose = false; opts.strictOpen = false; return extglob.isMatch(str, pattern, opts); }; /** * Takes an extglob pattern and returns a matcher function. The returned * function takes the string to match as its only argument. * * ```js * var extglob = require('extglob'); * var isMatch = extglob.matcher('*.!(*a)'); * * console.log(isMatch('a.a')); * //=> false * console.log(isMatch('a.b')); * //=> true * ``` * @param {String} `pattern` Extglob pattern * @param {String} `options` * @return {Boolean} * @api public */ extglob.matcher = function(pattern, options) { if (typeof pattern !== 'string') { throw new TypeError('expected pattern to be a string'); } function matcher() { var re = extglob.makeRe(pattern, options); return function(str) { return re.test(str); }; } return utils.memoize('matcher', pattern, options, matcher); }; /** * Convert the given `extglob` pattern into a regex-compatible string. Returns * an object with the compiled result and the parsed AST. * * ```js * var extglob = require('extglob'); * console.log(extglob.create('*.!(*a)').output); * //=> '(?!\\.)[^/]*?\\.(?!(?!\\.)[^/]*?a\\b).*?' * ``` * @param {String} `str` * @param {Object} `options` * @return {String} * @api public */ extglob.create = function(pattern, options) { if (typeof pattern !== 'string') { throw new TypeError('expected pattern to be a string'); } function create() { var ext = new Extglob(options); var ast = ext.parse(pattern, options); return ext.compile(ast, options); } return utils.memoize('create', pattern, options, create); }; /** * Create a regular expression from the given `pattern` and `options`. * * ```js * var extglob = require('extglob'); * var re = extglob.makeRe('*.!(*a)'); * console.log(re); * //=> /^[^\/]*?\.(?![^\/]*?a)[^\/]*?$/ * ``` * @param {String} `pattern` The pattern to convert to regex. * @param {Object} `options` * @return {RegExp} * @api public */ extglob.makeRe = function(pattern, options) { if (pattern instanceof RegExp) { return pattern; } if (typeof pattern !== 'string') { throw new TypeError('expected pattern to be a string'); } if (pattern.length > MAX_LENGTH) { throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); } function makeRe() { var opts = extend({strictErrors: false}, options); if (opts.strictErrors === true) opts.strict = true; var res = extglob.create(pattern, opts); return toRegex(res.output, opts); } var regex = utils.memoize('makeRe', pattern, options, makeRe); if (regex.source.length > MAX_LENGTH) { throw new SyntaxError('potentially malicious regex detected'); } return regex; }; /** * Expose `Extglob` constructor, parsers and compilers */ extglob.Extglob = Extglob; extglob.compilers = compilers; extglob.parsers = parsers; /** * Expose `extglob` * @type {Function} */ module.exports = extglob; extglob-1.0.0/lib/000077500000000000000000000000001300223233500137135ustar00rootroot00000000000000extglob-1.0.0/lib/compilers.js000066400000000000000000000064011300223233500162470ustar00rootroot00000000000000'use strict'; var brackets = require('expand-brackets'); /** * Extglob compilers */ module.exports = function(extglob) { var star = extglob.options.star || '.*?'; /** * Use `expand-brackets` compilers */ extglob.use(brackets.compilers); extglob.compiler /** * Escaped: "\\*" */ .set('escape', function(node) { return this.emit(node.val, node); }) /** * Dot: "." */ .set('dot', function(node) { return this.emit('\\' + node.val, node); }) /** * Question mark: "?" */ .set('qmark', function(node) { var val = '[^\\\\/.]'; var prev = this.prev(); if (node.parsed.slice(-1) === '(') { var ch = node.rest.charAt(0); if (ch !== '!' && ch !== '=' && ch !== ':') { return this.emit(val, node); } return this.emit(node.val, node); } if (prev.type === 'text' && prev.val) { return this.emit(val, node); } if (node.val.length > 1) { val += '{' + node.val.length + '}'; } return this.emit(val, node); }) /** * Plus: "+" */ .set('plus', function(node) { var prev = node.parsed.slice(-1); if (prev === ']' || prev === ')') { return this.emit(node.val, node); } var ch = this.output.slice(-1); if (!this.output || (/[?*+]/.test(ch) && node.parent.type !== 'bracket')) { return this.emit('\\+', node); } if (/\w/.test(ch) && !node.inside) { return this.emit('+\\+?', node); } return this.emit('+', node); }) /** * Star: "*" */ .set('star', function(node) { var prev = this.prev(); var prefix = prev.type !== 'text' && prev.type !== 'escape' ? '(?!\\.)' : ''; return this.emit(prefix + star, node); }) /** * Parens */ .set('paren', function(node) { node.prev = this.prev(); return this.mapVisit(node.nodes); }) .set('paren.open', function(node) { switch (node.parent.prefix) { case '!': case '^': return this.emit('(?:(?!(?:', node); case '@': case '+': case '*': case '?': return this.emit('(', node); default: { return this.emit(node.val, node); } } }) .set('paren.close', function(node) { if (!node.parent.prev) { return this.emit('\\' + node.val, node); } switch (node.prefix) { case '!': case '^': var rest = node.rest; var val = !this.options.bash ? '))' + star + ')' : ').)*$)'; var boundary = !rest || /^[).]/.test(rest); if (!node.suffix && !this.options.bash && boundary) { val = '$' + val; } return this.emit(val, node); case '+': return this.emit(')+', node); case '*': return this.emit(')*', node); case '?': return this.emit(')?', node); case '@': default: { return this.emit(')', node); } } }) /** * Text */ .set('text', function(node) { var val = node.val.replace(/[\[\]]/g, '\\$&'); return this.emit(val, node); }); }; extglob-1.0.0/lib/extglob.js000066400000000000000000000034371300223233500157240ustar00rootroot00000000000000'use strict'; /** * Module dependencies */ var Snapdragon = require('snapdragon'); var define = require('define-property'); var extend = require('extend-shallow'); var debug = require('debug')('extglob'); /** * Local dependencies */ var compilers = require('./compilers'); var parsers = require('./parsers'); /** * Customize Snapdragon parser and renderer */ function Extglob(options) { debug('initializing from <%s>', __filename); this.options = extend({source: 'extglob'}, options); this.snapdragon = this.options.snapdragon || new Snapdragon(this.options); this.snapdragon.patterns = this.snapdragon.patterns || {}; this.compiler = this.snapdragon.compiler; this.parser = this.snapdragon.parser; compilers(this.snapdragon); parsers(this.snapdragon); /** * Override Snapdragon `.parse` method */ define(this.snapdragon, 'parse', function(str, options) { var parsed = Snapdragon.prototype.parse.apply(this, arguments); parsed.input = str; // escape unmatched brace/bracket/parens var last = this.parser.stack.pop(); if (last && this.options.strict !== true) { var node = last.nodes[0]; node.val = '\\' + node.val; var sibling = node.parent.nodes[1]; if (sibling.type === 'star') { sibling.loose = true; } } // add non-enumerable parser reference define(parsed, 'parser', this.parser); return parsed; }); /** * Decorate `.parse` method */ define(this, 'parse', function(ast, options) { return this.snapdragon.parse.apply(this.snapdragon, arguments); }); /** * Decorate `.compile` method */ define(this, 'compile', function(ast, options) { return this.snapdragon.compile.apply(this.snapdragon, arguments); }); } /** * Expose `Extglob` */ module.exports = Extglob; extglob-1.0.0/lib/parsers.js000066400000000000000000000061441300223233500157350ustar00rootroot00000000000000'use strict'; var brackets = require('expand-brackets'); var define = require('define-property'); var utils = require('./utils'); /** * Characters to use in text regex (we want to "not" match * characters that are matched by other parsers) */ var TEXT_REGEX = '([!@*?+]?\\(|\\)|[*?.+\\\\]|\\[:?(?=.*\\])|:?\\])+'; var not = utils.createRegex(TEXT_REGEX); /** * Extglob parsers */ function parsers(extglob) { extglob.state = extglob.state || {}; /** * Use `expand-brackets` parsers */ extglob.use(brackets.parsers); extglob.parser.sets.paren = extglob.parser.sets.paren || []; extglob.parser /** * Extglob open: "*(" */ .capture('paren.open', function() { var parsed = this.parsed; var pos = this.position(); var m = this.match(/^([!@*?+])?\(/); if (!m) return; var prev = this.prev(); var prefix = m[1]; var val = m[0]; var open = pos({ type: 'paren.open', parsed: parsed, val: val }); var node = pos({ type: 'paren', prefix: prefix, nodes: [open] }); // if nested negation extglobs, just cancel them out to simplify if (prefix === '!' && prev.type === 'paren' && prev.prefix === '!') { prev.prefix = '@'; node.prefix = '@'; } define(node, 'rest', this.input); define(node, 'parsed', parsed); define(node, 'parent', prev); define(open, 'parent', node); this.push('paren', node); prev.nodes.push(node); }) /** * Extglob close: ")" */ .capture('paren.close', function() { var parsed = this.parsed; var pos = this.position(); var m = this.match(/^\)/); if (!m) return; var parent = this.pop('paren'); var node = pos({ type: 'paren.close', rest: this.input, parsed: parsed, val: m[0] }); if (!this.isType(parent, 'paren')) { if (this.options.strict) { throw new Error('missing opening paren: "("'); } node.escaped = true; return node; } node.prefix = parent.prefix; parent.nodes.push(node); define(node, 'parent', parent); }) /** * Escape: "\\." */ .capture('escape', function() { var pos = this.position(); var m = this.match(/^\\(.)/); if (!m) return; return pos({ type: 'escape', val: m[0], ch: m[1] }); }) /** * Question marks: "?" */ .capture('qmark', function() { var parsed = this.parsed; var pos = this.position(); var m = this.match(/^\?+(?!\()/); if (!m) return; extglob.state.metachar = true; return pos({ type: 'qmark', rest: this.input, parsed: parsed, val: m[0] }); }) /** * Character parsers */ .capture('star', /^\*(?!\()/) .capture('plus', /^\+(?!\()/) .capture('dot', /^\./) .capture('text', not); }; /** * Expose text regex string */ module.exports.TEXT_REGEX = TEXT_REGEX; /** * Extglob parsers */ module.exports = parsers; extglob-1.0.0/lib/utils.js000066400000000000000000000023471300223233500154170ustar00rootroot00000000000000'use strict'; var regex = require('regex-not'); var Cache = require('fragment-cache'); var utils = module.exports; var cache = utils.cache = new Cache(); /** * Cast `val` to an array * @return {Array} */ utils.arrayify = function(val) { if (!Array.isArray(val)) { return [val]; } return val; }; /** * Memoize a generated regex or function */ utils.memoize = function(type, pattern, options, fn) { var key = utils.createKey(type + pattern, options); if (cache.has(type, key)) { return cache.get(type, key); } var val = fn(pattern, options); if (options && options.cache === false) { return val; } cache.set(type, key, val); return val; }; /** * Create the key to use for memoization. The key is generated * by iterating over the options and concatenating key-value pairs * to the pattern string. */ utils.createKey = function(pattern, options) { var key = pattern; if (typeof options === 'undefined') { return key; } for (var prop in options) { key += ';' + prop + '=' + String(options[prop]); } return key; }; /** * Create the regex to use for matching text */ utils.createRegex = function(str) { var opts = {contains: true, strictClose: false}; return regex(str, opts); }; extglob-1.0.0/package.json000066400000000000000000000043021300223233500154320ustar00rootroot00000000000000{ "name": "extglob", "description": "Extended glob support for JavaScript. Adds (almost) the expressive power of regular expressions to glob patterns.", "version": "1.0.0", "homepage": "https://github.com/jonschlinkert/extglob", "author": "Jon Schlinkert (https://github.com/jonschlinkert)", "contributors": [ "Isiah Meadows (https://www.isiahmeadows.com)", "Jon Schlinkert (http://twitter.com/jonschlinkert)", "Shinnosuke Watanabe (https://shinnn.github.io)" ], "repository": "jonschlinkert/extglob", "bugs": { "url": "https://github.com/jonschlinkert/extglob/issues" }, "license": "MIT", "files": [ "index.js", "lib" ], "main": "index.js", "engines": { "node": ">=0.10.0" }, "scripts": { "test": "mocha" }, "dependencies": { "array-unique": "^0.3.2", "debug": "^2.2.0", "define-property": "^0.2.5", "expand-brackets": "^2.0.1", "extend-shallow": "^2.0.1", "fragment-cache": "^0.2.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^2.1.0" }, "devDependencies": { "bash-match": "^0.1.1", "for-own": "^0.1.4", "gulp": "^3.9.1", "gulp-eslint": "^3.0.1", "gulp-format-md": "^0.1.11", "gulp-istanbul": "^1.1.1", "gulp-mocha": "^3.0.1", "gulp-unused": "^0.2.0", "helper-changelog": "^0.3.0", "is-windows": "^0.2.0", "micromatch": "^2.3.11", "minimatch": "^3.0.3", "mocha": "^3.1.2", "multimatch": "^2.1.0", "yargs-parser": "^4.0.2" }, "keywords": [ "bash", "extended", "extglob", "glob", "globbing", "ksh", "match", "pattern", "patterns", "regex", "test", "wildcard" ], "verb": { "toc": false, "layout": "default", "tasks": [ "readme" ], "related": { "list": [ "braces", "expand-brackets", "expand-range", "fill-range", "micromatch" ] }, "helpers": [ "helper-changelog" ], "plugins": [ "gulp-format-md" ], "lint": { "reflinks": true }, "reflinks": [ "verb", "verb-generate-readme" ] } } extglob-1.0.0/test/000077500000000000000000000000001300223233500141245ustar00rootroot00000000000000extglob-1.0.0/test/bash.extglob.js000066400000000000000000000164161300223233500170520ustar00rootroot00000000000000'use strict'; require('mocha'); var match = require('./support/match'); var assert = require('assert'); // ported from http://www.bashcookbook.com/bashinfo/source/bash-4.3/tests/extglob.tests describe('bash tests derived from the pd-ksh test suite:', function() { var startLine = 11; var tests = [ [ '/dev/udp/129.22.8.102/45', '/dev/@(tcp|udp)/*/*', true ], '', 'valid numbers', [ '0', '0|[1-9]*([0-9])', true ], // Bash 4.3 disagrees [ '12', '0|[1-9]*([0-9])', true ], // Bash 4.3 disagrees [ '12abc', '0|[1-9]*([0-9])', false ], [ '1', '0|[1-9]*([0-9])', true ], // Bash 4.3 disagrees '', 'octal numbers', [ '07', '+([0-7])', true ], [ '0377', '+([0-7])', true ], [ '09', '+([0-7])', false ], '', 'stuff from korn\'s book', [ 'paragraph', 'para@(chute|graph)', true ], [ 'paramour', 'para@(chute|graph)', false ], [ 'para991', 'para?([345]|99)1', true ], [ 'para381', 'para?([345]|99)1', false ], [ 'paragraph', 'para*([0-9])', false ], [ 'para', 'para*([0-9])', true ], [ 'para13829383746592', 'para*([0-9])', true ], [ 'paragraph', 'para*([0-9])', false ], [ 'para', 'para+([0-9])', false ], [ 'para987346523', 'para+([0-9])', true ], [ 'paragraph', 'para!(*.[0-9])', true ], [ 'para.38', 'para!(*.[0-9])', true ], [ 'para.graph', 'para!(*.[0-9])', true ], [ 'para39', 'para!(*.[0-9])', true ], '', 'tests derived from those rosenblatt\'s korn shell book', [ '', '*(0|1|3|5|7|9)', true ], [ '""', '*(0|1|3|5|7|9)', false ], [ '137577991', '*(0|1|3|5|7|9)', true ], [ '2468', '*(0|1|3|5|7|9)', false ], [ 'file.c', '*.c?(c)', true ], [ 'file.C', '*.c?(c)', false ], [ 'file.cc', '*.c?(c)', true ], [ 'file.ccc', '*.c?(c)', false ], [ 'parse.y', '!(*.c|*.h|Makefile.in|config*|README)', true ], [ 'shell.c', '!(*.c|*.h|Makefile.in|config*|README)', false ], [ 'Makefile', '!(*.c|*.h|Makefile.in|config*|README)', true ], [ '"VMS.FILE;1"', '*\\;[1-9]*([0-9])', false ], [ '"VMS.FILE;0"', '*\\;[1-9]*([0-9])', false ], [ '"VMS.FILE;"', '*\\;[1-9]*([0-9])', false ], [ '"VMS.FILE;139"', '*\\;[1-9]*([0-9])', false ], [ '"VMS.FILE;139"', '*;[1-9]*([0-9])', false ], [ '"VMS.FILE;139"', '*;[1-9]*([0-9])*', true ], [ '"VMS.FILE;139"', '*;[1-9]**([0-9])*', true ], [ '"VMS.FILE;1N"', '*;[1-9]*([0-9])', false ], '', ['abcx', '!([*)*', true], ['abcx', '!(\\[*)*', true], ['abcz', '!([*)*', true], ['abcz', '!(\\[*)*', true], ['bbc', '!([*)*', true], ['bbc', '!(\\[*)*', true], ['abcx', '+(a|b[)*', true], ['abcx', '+(a|b\\[)*', true], ['abcz', '+(a|b[)*', true], ['abcz', '+(a|b\\[)*', true], ['bbc', '+(a|b[)*', false], ['abcx', '[a*(]*z', false], ['abcx', '[a*\\(]*z', false], ['abcz', '[a*(]*z', true], ['abcz', '[a*\\(]*z', true], ['bbc', '[a*(]*z', false], ['bbc', '[a*\\(]*z', false], '', ['abc', '+()c', false], ['abc', '+()x', false], ['abc', '+(*)c', true], ['abc', '+(*)x', false], ['abc', 'no-file+(a|b)stuff', false], ['abc', 'no-file+(a*(c)|b)stuff', false], '', ['abc', 'a+(b|c)d', false], ['abd', 'a+(b|c)d', true], ['acd', 'a+(b|c)d', true], '', ['abc', 'a!(@(b|B))d', false], ['abd', 'a!(@(b|B))d', false], ['acd', 'a!(@(b|B))d', true], '', ['abc', 'a[b*(foo|bar)]d', false], ['abd', 'a[b*(foo|bar)]d', true], ['acd', 'a[b*(foo|bar)]d', false], '', 'simple kleene star tests', ['foo', '*(a|b[)', false], ['foo', '*(a|b[)|f*', true], 'this doesn\'t work right yet (from bash notes, it does work in extglob)', ['*(a|b[)', '*(a|b[)', true], '', 'More tests derived from a bug report concerning extended glob patterns following a *', ['ab', 'ab*(e|f)', true], ['abcdef', 'ab*(e|f)', false], ['abcfef', 'ab*(e|f)', false], ['abcfefg', 'ab*(e|f)', false], ['abef', 'ab*(e|f)', true], '', ['ab', 'b?*(e|f)', false], ['abcdef', 'b?*(e|f)', false], ['abcfef', 'b?*(e|f)', false], ['abcfefg', 'b?*(e|f)', false], ['abef', 'b?*(e|f)', false], '', ['ab', 'ab*d+(e|f)', false], ['abcdef', 'ab*d+(e|f)', true], ['abcfef', 'ab*d+(e|f)', false], ['abcfefg', 'ab*d+(e|f)', false], ['abef', 'ab*d+(e|f)', false], '', ['ab', 'ab**(e|f)', true], ['abcdef', 'ab**(e|f)', true], ['abcfef', 'ab**(e|f)', true], ['abcfefg', 'ab**(e|f)', true], ['abef', 'ab**(e|f)', true], '', ['ab', 'ab*+(e|f)', false], ['abcdef', 'ab*+(e|f)', true], ['abcfef', 'ab*+(e|f)', true], ['abcfefg', 'ab*+(e|f)', false], ['abef', 'ab*+(e|f)', true], '', ['ab', 'ab**(e|f)', true], ['abcdef', 'ab**(e|f)', true], ['abcfef', 'ab**(e|f)', true], ['abcfefg', 'ab**(e|f)', true], ['abef', 'ab**(e|f)', true], '', ['ab', 'ab**(e|f)g', false], ['abcdef', 'ab**(e|f)g', false], ['abcfef', 'ab**(e|f)g', false], ['abcfefg', 'ab**(e|f)g', true], ['abef', 'ab**(e|f)g', false], '', ['ab', 'ab*+(e|f)', false], ['abcdef', 'ab*+(e|f)', true], ['abcfef', 'ab*+(e|f)', true], ['abcfefg', 'ab*+(e|f)', false], ['abef', 'ab*+(e|f)', true], '', ['ab', 'ab***ef', false], ['abcdef', 'ab***ef', true], ['abcfef', 'ab***ef', true], ['abcfefg', 'ab***ef', false], ['abef', 'ab***ef', true], '', ['ab', 'ab**', true], ['abcdef', 'ab**', true], ['abcfef', 'ab**', true], ['abcfefg', 'ab**', true], ['abef', 'ab**', true], '', 'bug in all versions up to and including bash-2.05b', ['123abc', '*?(a)bc', true], '', 'character classes', [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a[^[:alnum:]]b', ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a[-.,:; _]b', ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a@([^[:alnum:]])b', ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a@([-.,:; _])b', ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a@([.])b', ['a.b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a@([^.])b', ['a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a@([^x])b', ['a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a+([^[:alnum:]])b', ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], [['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b'], 'a@(.|[^[:alnum:]])b', ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']], '', ['a , b', '*([[:space:]]),*([[:space:]])', false], ['a , b', 'a*([[:space:]]),*([[:space:]])b', true] ]; tests.forEach(function(test, i) { if (!Array.isArray(test) || !test) return; var fixture = test[0]; var pattern = test[1]; // if (pattern !== 'a[-.,:\;\ _]b') return; var expected = test[2]; var msg = ') should ' + (expected ? '' : 'not ') + 'match ' + pattern; it((startLine + i) + msg, function() { if (Array.isArray(fixture)) { match(fixture, pattern, expected, msg); } else { assert.equal(match.isMatch(fixture, pattern), expected, msg); } }); }); }); extglob-1.0.0/test/bash.extglob1.js000066400000000000000000000021711300223233500171240ustar00rootroot00000000000000'use strict'; require('mocha'); var match = require('./support/match'); var assert = require('assert'); // ported from http://www.bashcookbook.com/bashinfo/source/bash-4.3/tests/extglob1.sub describe('bash extglob1 tests', function() { var startLine = 11; var tests = [ ['a.c', '+([[:alpha:].])', true], ['a.c', '+([[:alpha:].])+([[:alpha:].])', true], ['a.c', '*([[:alpha:].])', true], ['a.c', '*([[:alpha:].])*([[:alpha:].])', true], ['a.c', '?([[:alpha:].])?([[:alpha:].])?([[:alpha:].])', true], ['a.c', '@([[:alpha:].])@([[:alpha:].])@([[:alpha:].])', true], ['.', '!([[:alpha:].])', false], ['.', '?([[:alpha:].])', true], ['.', '@([[:alpha:].])', true], ['.', '*([[:alpha:].])', true], ['.', '+([[:alpha:].])', true] ]; tests.forEach(function(test, i) { if (!Array.isArray(test)) return; var fixture = test[0]; var pattern = test[1]; var expected = test[2]; var msg = 'should ' + (expected ? '' : 'not ') + 'match ' + pattern; it((startLine + i) + ' ' + msg, function() { assert.equal(match.isMatch(fixture, pattern), expected, msg); }); }); }); extglob-1.0.0/test/bash.extglob1a.js000066400000000000000000000021021300223233500172570ustar00rootroot00000000000000'use strict'; require('mocha'); var match = require('./support/match'); var assert = require('assert'); // ported from http://www.bashcookbook.com/bashinfo/source/bash-4.3/tests/extglob1a.sub describe('bash extglob1a tests', function() { var startLine = 11; var tests = [ ['a', 'a*!(x)', true], ['ab', 'a*!(x)', true], ['ba', 'a*!(x)', false], ['ax', 'a*!(x)', true], ['a', 'a!(x)', true], ['ab', 'a!(x)', true], ['ba', 'a!(x)', false], ['ax', 'a!(x)', false], ['a', 'a*?(x)', true], ['ab', 'a*?(x)', true], ['ba', 'a*?(x)', false], ['ax', 'a*?(x)', true], ['a', 'a?(x)', true], ['ab', 'a?(x)', false], ['ba', 'a?(x)', false], ['ax', 'a?(x)', true] ]; tests.forEach(function(test, i) { if (!Array.isArray(test)) return; var fixture = test[0]; var pattern = test[1]; var expected = test[2]; var msg = 'should ' + (expected ? '' : 'not ') + 'match ' + pattern; it((startLine + i) + ' ' + msg, function() { assert.equal(match.isMatch(fixture, pattern), expected, msg); }); }); }); extglob-1.0.0/test/bash.extglob2.js000066400000000000000000000072371300223233500171350ustar00rootroot00000000000000'use strict'; require('mocha'); var assert = require('assert'); var match = require('./support/match'); // tests ported from http://www.bashcookbook.com/bashinfo/source/bash-4.3/tests/extglob2.tests describe('bash extglob2 tests', function() { var startLine = 11; var tests = [ [ 'fofo', '*(f*(o))', true ], [ 'ffo', '*(f*(o))', true ], [ 'foooofo', '*(f*(o))', true ], [ 'foooofof', '*(f*(o))', true ], [ 'fooofoofofooo', '*(f*(o))', true ], [ 'foooofof', '*(f+(o))', false ], [ 'xfoooofof', '*(f*(o))', false ], [ 'foooofofx', '*(f*(o))', false ], [ 'ofxoofxo', '*(*(of*(o)x)o)', true ], [ 'ofooofoofofooo', '*(f*(o))', false ], [ 'foooxfooxfoxfooox', '*(f*(o)x)', true ], [ 'foooxfooxofoxfooox', '*(f*(o)x)', false ], [ 'foooxfooxfxfooox', '*(f*(o)x)', true ], [ 'ofxoofxo', '*(*(of*(o)x)o)', true ], [ 'ofoooxoofxo', '*(*(of*(o)x)o)', true ], [ 'ofoooxoofxoofoooxoofxo', '*(*(of*(o)x)o)', true ], [ 'ofoooxoofxoofoooxoofxoo', '*(*(of*(o)x)o)', true ], [ 'ofoooxoofxoofoooxoofxofo', '*(*(of*(o)x)o)', false ], [ 'ofoooxoofxoofoooxoofxooofxofxo', '*(*(of*(o)x)o)', true ], [ 'aac', '*(@(a))a@(c)', true ], [ 'ac', '*(@(a))a@(c)', true ], [ 'c', '*(@(a))a@(c)', false ], [ 'aaac', '*(@(a))a@(c)', true ], [ 'baaac', '*(@(a))a@(c)', false ], [ 'abcd', '?@(a|b)*@(c)d', true ], [ 'abcd', '@(ab|a*@(b))*(c)d', true ], [ 'acd', '@(ab|a*(b))*(c)d', true ], [ 'abbcd', '@(ab|a*(b))*(c)d', true ], [ 'effgz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', true ], [ 'efgz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', true ], [ 'egz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', true ], [ 'egzefffgzbcdij', '*(b+(c)d|e*(f)g?|?(h)i@(j|k))', true ], [ 'egz', '@(b+(c)d|e+(f)g?|?(h)i@(j|k))', false ], [ 'ofoofo', '*(of+(o))', true ], [ 'oxfoxoxfox', '*(oxf+(ox))', true ], [ 'oxfoxfox', '*(oxf+(ox))', false ], [ 'ofoofo', '*(of+(o)|f)', true ], 'the following is supposed to match only as fo+ofo+ofo', [ 'foofoofo', '@(foo|f|fo)*(f|of+(o))', true ], [ 'oofooofo', '*(of|oof+(o))', true ], [ 'fffooofoooooffoofffooofff', '*(*(f)*(o))', true ], 'the following tests backtracking in alternation matches', [ 'fofoofoofofoo', '*(fo|foo)', true ], 'exclusion', [ 'foo', '!(x)', true ], [ 'foo', '!(x)*', true ], [ 'foo', '!(foo)', false ], [ 'foo', '!(foo)*', false ], // Bash 4.3 disagrees! [ 'foobar', '!(foo)', true ], [ 'foobar', '!(foo)*', false ], // Bash 4.3 disagrees! [ 'moo.cow', '!(*.*).!(*.*)', false ], // Bash 4.3 disagrees! [ 'mad.moo.cow', '!(*.*).!(*.*)', false ], [ 'mucca.pazza', 'mu!(*(c))?.pa!(*(z))?', false ], [ 'fff', '!(f)', true ], [ 'fff', '*(!(f))', true ], [ 'fff', '+(!(f))', true ], [ 'ooo', '!(f)', true ], [ 'ooo', '*(!(f))', true ], [ 'ooo', '+(!(f))', true ], [ 'foo', '!(f)', true ], [ 'foo', '*(!(f))', true ], [ 'foo', '+(!(f))', true ], [ 'f', '!(f)', false ], [ 'f', '*(!(f))', false ], [ 'f', '+(!(f))', false ], [ 'foot', '@(!(z*)|*x)', true ], [ 'zoot', '@(!(z*)|*x)', false ], [ 'foox', '@(!(z*)|*x)', true ], [ 'zoox', '@(!(z*)|*x)', true ], [ 'foo', '*(!(foo))', false ], // Bash 4.3 disagrees! [ 'foob', '!(foo)b*', false ], [ 'foobb', '!(foo)b*', false ] // Bash 4.3 disagrees! ]; tests.forEach(function(test, n) { if (!Array.isArray(test)) return; var fixture = test[0]; var pattern = test[1]; var expected = test[2]; var msg = 'should ' + (expected ? '' : 'not ') + 'match ' + pattern; it((startLine + n) + ' ' + msg, function() { assert.equal(match.isMatch(fixture, pattern), expected, msg); }); }); }); extglob-1.0.0/test/bash.extglob3.js000066400000000000000000000033361300223233500171320ustar00rootroot00000000000000'use strict'; require('mocha'); var match = require('./support/match'); var assert = require('assert'); // ported from http://www.bashcookbook.com/bashinfo/source/bash-4.3/tests/extglob3.tests describe('bash extglob3 tests', function() { var startLine = 11; var tests = [ [ 'ab/../', '@(ab|+([^/]))/..?(/)', true ], [ 'ab/../', '+([^/])/..?(/)', true ], [ 'ab/../', '@(ab|?b)/..?(/)', true ], [ 'ab/../', '+([^/])/../', true ], [ 'ab/../', '+([!/])/..?(/)', true ], [ 'ab/../', '@(ab|+([!/]))/..?(/)', true ], [ 'ab/../', '+([!/])/../', true ], [ 'ab/../', '+([!/])/..?(/)', true ], [ 'ab/../', '+([!/])/..@(/)', true ], [ 'ab/../', '+(ab)/..?(/)', true ], [ 'ab/../', '[!/][!/]/../', true ], [ 'ab/../', '@(ab|?b)/..?(/)', true ], [ 'ab/../', '[^/][^/]/../', true ], [ 'ab/../', '?b/..?(/)', true ], [ 'ab/../', '+(?b)/..?(/)', true ], [ 'ab/../', '+(?b|?b)/..?(/)', true ], [ 'ab/../', '@(?b|?b)/..?(/)', true ], [ 'ab/../', '@(a?|?b)/..?(/)', true ], [ 'ab/../', '?(ab)/..?(/)', true ], [ 'ab/../', '?(ab|??)/..?(/)', true ], [ 'ab/../', '@(??)/..?(/)', true ], [ 'ab/../', '@(??|a*)/..?(/)', true ], [ 'ab/../', '@(a*)/..?(/)', true ], [ 'ab/../', '+(??)/..?(/)', true ], [ 'ab/../', '+(??|a*)/..?(/)', true ], [ 'ab/../', '+(a*)/..?(/)', true ], [ 'x', '@(x)', true ] ]; tests.forEach(function(test, i) { if (!Array.isArray(test)) return; var fixture = test[0]; var pattern = test[1]; var expected = test[2]; var msg = 'should ' + (expected ? '' : 'not ') + 'match ' + pattern; it((startLine + i) + ' ' + msg, function() { assert.equal(match.isMatch(fixture, pattern), expected, msg); }); }); }); extglob-1.0.0/test/bash.js000066400000000000000000000233751300223233500154110ustar00rootroot00000000000000'use strict'; require('mocha'); var match = require('./support/match'); var assert = require('assert'); describe('running extglob against minimatch tests', function() { var tests = [ ['*(a|b[)', '*(a|b\\[)', false], ['123abc', 'ab*d+(e|f)', false], ['123abc', 'ab?*(e|f)', false], ['a', '!(a)', false], ['a', '(b)', false], ['a', '??', false], ['a', 'a??b', false], ['a', 'b?(a|b)', false], ['a.', '*.+(b|d)', false], ['a.a', '!(*.[a-b]*)', false], ['a.a', '!(*.a|*.b|*.c)', false], ['a.a', '!(*[a-b].[a-b]*)', false], ['a.a', '!*.(a|b)', false], ['a.a', '!*.(a|b)*', false], ['a.a', '*.!(a)', false], ['a.a', '*.+(b|d)', false], ['a.a.a', '!(*.[a-b]*)', false], ['a.a.a', '!(*[a-b].[a-b]*)', false], ['a.a.a', '!*.(a|b)', false], ['a.a.a', '!*.(a|b)*', false], ['a.a.a', '*.+(b|d)', false], ['a.abcd', '!(*.a|*.b|*.c)', false], ['a.abcd', '!(*.a|*.b|*.c)*', false], ['a.abcd', '*.!(a|b|c)', false], ['a.abcd', '*.!(a|b|c)*', false], ['a.b', '!(*.*)', false], ['a.b', '!(*.[a-b]*)', false], ['a.b', '!(*[a-b].[a-b]*)', false], ['a.b', '!*.(a|b)', false], ['a.b', '!*.(a|b)*', false], ['a.bb', '!(*.[a-b]*)', false], ['a.bb', '!(*[a-b].[a-b]*)', false], ['a.bb', '!*.(a|b)', false], ['a.bb', '!*.(a|b)*', false], ['a.ccc', '!*.(a|b)', false], ['a.ccc', '!*.(a|b)*', false], ['a.ccc', '*.+(b|d)', false], ['a.js', '!(*.js)', false], ['a.js', '*.!(js)', false], ['a.js.js', '!(*.js)', false], ['aa', '?', false], ['aa', '@(a)b', false], ['aa', 'a??b', false], ['aab', '?', false], ['aab', '??', false], ['aab', '@(c)b', false], ['ab', 'a!(@(b|B))', false], ['aB', 'a!(@(b|B))', false], ['ab', 'a(*b', false], ['ab', 'ab**(e|f)g', false], ['ab', 'ab*+(e|f)', false], ['ab', 'ab*d+(e|f)', false], ['ab', 'ab?*(e|f)', false], ['abcdef', '(a+|b)+', false], ['abcdef', 'ab**(e|f)g', false], ['abcdef', 'ab?*(e|f)', false], ['abcfef', '(a+|b)+', false], ['abcfef', 'ab**(e|f)g', false], ['abcfef', 'ab*d+(e|f)', false], ['abcfefg', '(a+|b)+', false], ['abcfefg', 'ab*d+(e|f)', false], ['abcfefg', 'ab?*(e|f)', false], ['abd', '(a+|b)+', false], ['abd', 'a!(@(b|B))d', false], ['abd', 'ab*d+(e|f)', false], ['abef', '(a+|b)+', false], ['abef', '*(a+|b)', false], ['abef', 'ab**(e|f)g', false], ['abef', 'ab*d+(e|f)', false], ['acd', '(a+|b)+', false], ['acd', 'ab*d+(e|f)', false], ['acd', 'ab?*(e|f)', false], ['ax', 'a?(b*)', false], ['b/a', '!(b/a)', false], ['baaac', '*(@(a))a@(c)', false], ['bb', 'a?(a|b)', false], ['c', '*(@(a))a@(c)', false], ['c.a', '!(*.[a-b]*)', false], ['c.a', '!*.(a|b)', false], ['c.a', '!*.(a|b)*', false], ['c.a', '*.!(a)', false], ['c.a', '*.+(b|d)', false], ['c.js', '!(*.js)', false], ['c.js', '*.!(js)', false], ['cow', '.!(*.*)', false], ['d.a.d', '!*.(a|b)', false], ['d.a.d', '!*.(a|b)*', false], ['egz', '@(b+(c)d|e+(f)g?|?(h)i@(j|k))', false], ['f', '!(f)', false], ['f', '*(!(f))', false], ['f', '+(!(f))', false], ['f.a', '!(*.a|*.b|*.c)', false], ['f.a', '*.!(a|b|c)', false], ['foo', '!(foo)', false], ['foo', '!(foo)*', false], // bash 4.3 disagrees ['foo', '!(foo)+', false], ['foo', '!(foo)b*', false], ['foo', '*(!(foo))', false], ['foo.js.js', '*.!(js)*', false], ['foo.js.js', '*.!(js)*.!(js)', false], ['foo.js.js', '*.!(js)+', false], ['foob', '!(foo)b*', false], ['foobar', '!(foo)*', false], // bash 4.3 disagrees ['foobar', '!(foo)b*', false], ['foobb', '!(foo)b*', false], ['foooofof', '*(f+(o))', false], ['foooofofx', '*(f*(o))', false], ['foooxfooxofoxfooox', '*(f*(o)x)', false], ['mad.moo.cow', '!(*.*).!(*.*)', false], ['mad.moo.cow', '.!(*.*)', false], ['Makefile.in', '!(*.c|*.h|Makefile.in|config*|README)', false], ['moo', '.!(*.*)', false], ['moo.cow', '!(*.*).!(*.*)', false], // bash 4.3 disagrees ['moo.cow', '.!(*.*)', false], ['mucca.pazza', 'mu!(*(c))?.pa!(*(z))?', false], ['ofooofoofofooo', '*(f*(o))', false], ['ofoooxoofxoofoooxoofxofo', '*(*(of*(o)x)o)', false], ['oxfoxfox', '*(oxf+(ox))', false], ['shell.c', '!(*.c|*.h|Makefile.in|config*|README)', false], ['xfoooofof', '*(f*(o))', false], ['zoot', '@(!(z*)|*x)', false], ['zz', '(a+|b)*', false], ['a', '(a)', true], ['a', '*(a)', true], ['a', '+(a)', true], ['a', '?', true], ['a', '?(a|b)', true], ['a', 'a?(a|b)', true], ['a', 'a?(x)', true], ['a((((b', 'a(*b', true], ['a((b', 'a(*b', true], ['a(b', 'a(*b', true], ['a.', '!(*.a|*.b|*.c)', true], ['a.', '*!(.a|.b|.c)', true], ['a.', '*.!(a)', true], ['a.', '*.!(a|b|c)', true], ['a.a', '(a|d).(a|b)*', true], ['a.a', '*!(.a|.b|.c)', true], ['a.a.a', '*.!(a)', true], ['a.abcd', '*!(*.a|*.b|*.c)*', true], ['a.abcd', '*!(.a|.b|.c)', true], ['a.b', '(a|d).(a|b)*', true], ['a.b', '*!(.a|.b|.c)', true], ['a.b', '*.!(a)', true], ['a.b', '*.+(b|d)', true], ['a.bb', '(a|d).(a|b)*', true], ['a.bb', '*.+(b|d)', true], ['a.c', '*!(.a|.b|.c)', true], ['a.c.d', '!(*.a|*.b|*.c)', true], ['a.c.d', '*!(.a|.b|.c)', true], ['a.c.d', '*.!(a|b|c)', true], ['a.ccc', '!(*.[a-b]*)', true], ['a.ccc', '!(*[a-b].[a-b]*)', true], ['a.js', '*!(.js)', true], ['a.js.js', '*!(.js)', true], ['a.js.js', '*.!(js)', true], ['a.md', '!(*.js)', true], ['a.md', '*!(.js)', true], ['a.md', '*.!(js)', true], ['aa', '!(a)', true], ['aaac', '*(@(a))a@(c)', true], ['aab', 'a??b', true], ['aac', '*(@(a))a@(c)', true], ['ab', '!(*.*)', true], ['ab', '(a+|b)+', true], ['ab', 'ab**(e|f)', true], ['ab]', 'a!(@(b|B))', true], ['abab', 'ab**(e|f)', true], ['abb', '!(*.*)', true], ['abbcd', '@(ab|a*(b))*(c)d', true], ['aBc', 'a!(@(b|B))', true], ['abcd', '?@(a|b)*@(c)d', true], ['abcd', '@(ab|a*@(b))*(c)d', true], ['abcdef', '(a+|b)*', true], ['abcdef', 'ab**(e|f)', true], ['abcdef', 'ab*+(e|f)', true], ['abcdef', 'ab*d+(e|f)', true], ['abcfef', '(a+|b)*', true], ['abcfef', 'ab**(e|f)', true], ['abcfef', 'ab*+(e|f)', true], ['abcfef', 'ab?*(e|f)', true], ['abcfefg', '(a+|b)*', true], ['abcfefg', 'ab**(e|f)', true], ['abd', '(a+|b)*', true], ['abd', 'a!(@(b|B))', true], ['abd', 'ab**(e|f)', true], ['abd', 'ab?*(e|f)', true], ['abef', '(a+|b)*', true], ['abef', 'ab**(e|f)', true], ['abef', 'ab*+(e|f)', true], ['abef', 'ab?*(e|f)', true], ['ac', '*(@(a))a@(c)', true], ['ac', 'a!(@(b|B))', true], ['acd', '(a+|b)*', true], ['acd', '@(ab|a*(b))*(c)d', true], ['acd', 'a!(@(b|B))', true], ['acd', 'a!(@(b|B))d', true], ['ax', '?(a*|b)', true], ['b', '(a+|b)*', true], ['b/b', '!(b/a)', true], ['b/c', '!(b/a)', true], ['ba', 'b?(a|b)', true], ['bar', '!(foo)*', true], ['bar', '!(foo)b*', true], ['baz', '!(foo)*', true], ['baz', '!(foo)b*', true], ['c.a', '!(*[a-b].[a-b]*)', true], ['c.c', '*!(.a|.b|.c)', true], ['c.ccc', '!(*.[a-b]*)', true], ['c.ccc', '!(*[a-b].[a-b]*)', true], ['c.js', '*!(.js)', true], ['d.a.d', '!(*.[a-b]*)', true], ['d.a.d', '!(*[a-b].[a-b]*)', true], ['d.a.d', '*.!(a)', true], ['d.a.d', '*.+(b|d)', true], ['d.d', '!(*.a|*.b|*.c)', true], ['d.d', '*!(.a|.b|.c)', true], ['d.d', '*.!(a|b|c)', true], ['d.js.d', '!(*.js)', true], ['d.js.d', '*!(.js)', true], ['d.js.d', '*.!(js)', true], ['e.e', '!(*.a|*.b|*.c)', true], ['e.e', '*!(.a|.b|.c)', true], ['e.e', '*.!(a|b|c)', true], ['effgz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', true], ['efgz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', true], ['egz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', true], ['egzefffgzbcdij', '*(b+(c)d|e*(f)g?|?(h)i@(j|k))', true], ['f.a', '*!(.a|.b|.c)', true], ['f.f', '!(*.a|*.b|*.c)', true], ['f.f', '*!(.a|.b|.c)', true], ['f.f', '*.!(a|b|c)', true], ['fff', '!(f)', true], ['fff', '*(!(f))', true], ['fff', '+(!(f))', true], ['fffooofoooooffoofffooofff', '*(*(f)*(o))', true], ['ffo', '*(f*(o))', true], ['fofo', '*(f*(o))', true], ['fofoofoofofoo', '*(fo|foo)', true], ['foo', '!(f)', true], ['foo', '!(x)', true], ['foo', '!(x)*', true], ['foo', '*(!(f))', true], ['foo', '+(!(f))', true], ['foo.js.js', '*.!(js)', true], ['foobar', '!(foo)', true], ['foofoofo', '@(foo|f|fo)*(f|of+(o))', true], ['fooofoofofooo', '*(f*(o))', true], ['foooofo', '*(f*(o))', true], ['foooofof', '*(f*(o))', true], ['foooxfooxfoxfooox', '*(f*(o)x)', true], ['foooxfooxfxfooox', '*(f*(o)x)', true], ['foot', '@(!(z*)|*x)', true], ['foox', '@(!(z*)|*x)', true], ['Makefile', '!(*.c|*.h|Makefile.in|config*|README)', true], ['ofoofo', '*(of+(o))', true], ['ofoofo', '*(of+(o)|f)', true], ['ofoooxoofxo', '*(*(of*(o)x)o)', true], ['ofoooxoofxoofoooxoofxo', '*(*(of*(o)x)o)', true], ['ofoooxoofxoofoooxoofxoo', '*(*(of*(o)x)o)', true], ['ofoooxoofxoofoooxoofxooofxofxo', '*(*(of*(o)x)o)', true], ['ofxoofxo', '*(*(of*(o)x)o)', true], ['oofooofo', '*(of|oof+(o))', true], ['ooo', '!(f)', true], ['ooo', '*(!(f))', true], ['ooo', '+(!(f))', true], ['oxfoxoxfox', '*(oxf+(ox))', true], ['parse.y', '!(*.c|*.h|Makefile.in|config*|README)', true], ['zoox', '@(!(z*)|*x)', true] ]; tests.forEach(function(test) { var fixture = test[0]; var pattern = test[1]; var expected = test[2]; var msg = 'should ' + (expected ? '' : 'not ') + 'match ' + pattern; it(msg, function() { assert.equal(match.isMatch(fixture, pattern), expected, msg); }); }); }); extglob-1.0.0/test/errors.js000066400000000000000000000034521300223233500160020ustar00rootroot00000000000000'use strict'; var assert = require('assert'); var extglob = require('..'); describe('errors', function() { it('should throw an error when extglob() receives an invalid pattern', function(cb) { try { assert(extglob()); cb(new Error('expected an error')); } catch (err) { assert.equal(err.message, 'expected pattern to be a string'); } cb(); }); it('should throw an error when extglob.isMatch() receives an invalid pattern', function(cb) { try { assert(extglob.isMatch()); cb(new Error('expected an error')); } catch (err) { assert.equal(err.message, 'expected pattern to be a string'); } cb(); }); it('should throw an error when extglob.makeRe() receives an invalid pattern', function(cb) { try { assert(extglob.makeRe()); cb(new Error('expected an error')); } catch (err) { assert.equal(err.message, 'expected pattern to be a string'); } cb(); }); it('should throw an error when extglob.create() receives an invalid pattern', function(cb) { try { assert(extglob.create()); cb(new Error('expected an error')); } catch (err) { assert.equal(err.message, 'expected pattern to be a string'); } cb(); }); it('should throw an error when extglob.isMatch() receives an invalid string', function(cb) { try { assert(extglob.isMatch(null, '*')); cb(new Error('expected an error')); } catch (err) { assert.equal(err.message, 'expected a string'); } cb(); }); it('should throw an error when extglob.match() receives an invalid pattern', function(cb) { try { assert(extglob.match()); cb(new Error('expected an error')); } catch (err) { assert.equal(err.message, 'expected pattern to be a string'); } cb(); }); }); extglob-1.0.0/test/fixtures/000077500000000000000000000000001300223233500157755ustar00rootroot00000000000000extglob-1.0.0/test/fixtures/posix.txt000066400000000000000000000072461300223233500177110ustar00rootroot00000000000000# A test suite for the POSIX.2 (BRE) pattern matching code LC_ALL=C LANG=C # First, test POSIX.2 character classes case e in [[:xdigit:]]) echo ok 1;; esac case a in [[:alpha:]123]) echo ok 2;; esac case 1 in [[:alpha:]123]) echo ok 3;; esac case 9 in [![:alpha:]]) echo ok 4;; esac # invalid character class expressions are just characters to be matched case a in [:al:]) echo ok 5;; esac case a in [[:al:]) echo ok 6;; esac case '!' in [abc[:punct:][0-9]) echo ok 7;; esac # let's try to match the start of a valid sh identifier case 'PATH' in [_[:alpha:]]*) echo ok 8;; esac # let's try to match the first two characters of a valid sh identifier case PATH in [_[:alpha:]][_[:alnum:]]*) echo ok 9;; esac # is ^C a cntrl character? case $'\003' in [[:cntrl:]]) echo ok 10;; esac # how about A? case A in [[:cntrl:]]) echo oops -- cntrl ;; *) echo ok 11;; esac case 9 in [[:digit:]]) echo ok 12;; esac case X in [[:digit:]]) echo oops -- digit;; *) echo ok 13;; esac case $'\033' in [[:graph:]]) echo oops -- graph;; *) echo ok 14;; esac case $'\040' in [[:graph:]]) echo oops -- graph 2;; *) echo ok 15;; esac case ' ' in [[:graph:]]) echo oops -- graph 3;; *) echo ok 16;; esac case 'aB' in [[:lower:]][[:upper:]]) echo ok 17;; esac case $'\040' in [[:print:]]) echo ok 18;; *) echo oops -- print;; esac case PS3 in [_[:alpha:]][_[:alnum:]][_[:alnum:]]*) echo ok 19;; esac case a in [[:alpha:][:digit:]]) echo ok 20;; *) echo oops - skip brackpat ;; esac case a in [[:alpha:]\]) echo oops -- dangling backslash in brackpat ;; *) echo ok 21 ;; esac # what's a newline? is it a blank? a space? case $'\n' in [[:blank:]]) echo ok -- blank ;; [[:space:]]) echo ok -- space ;; *) echo oops newline ;; esac # OK, what's a tab? is it a blank? a space? case $'\t' in [[:blank:]]) echo ok -- blank ;; [[:space:]]) echo ok -- space ;; *) echo oops newline ;; esac # let's check out characters in the ASCII range case $'\377' in [[:ascii:]]) echo oops -- ascii\?;; esac case 9 in [1[:alpha:]123]) echo oops 1;; esac # however, an unterminated brace expression containing a valid char class # that matches had better fail case a in [[:alpha:]) echo oops 2;; esac case $'\b' in [[:graph:]]) echo oops 3;; esac case $'\b' in [[:print:]]) echo oops 4;; esac case $' ' in [[:punct:]]) echo oops 5;; esac # Next, test POSIX.2 collating symbols case 'a' in [[.a.]]) echo ok 1;; esac case '-' in [[.hyphen.]-9]) echo ok 2;; esac case 'p' in [[.a.]-[.z.]]) echo ok 3;; esac case '-' in [[.-.]]) echo ok 4;; esac case ' ' in [[.space.]]) echo ok 5;; esac case ' ' in [[.grave-accent.]]) echo oops - grave;; *) echo ok 6;; esac case '4' in [[.-.]-9]) echo ok 7;; esac # an invalid collating symbol cannot be the first part of a range case 'c' in [[.yyz.]-[.z.]]) echo oops - yyz;; *) echo ok 8;; esac case 'c' in [[.yyz.][.a.]-z]) echo ok 9;; esac # but when not part of a range is not an error case 'c' in [[.yyz.][.a.]-[.z.]]) echo ok 10 ;; esac case 'p' in [[.a.]-[.Z.]]) echo oops -- bad range ;; *) echo ok 11;; esac case p in [[.a.]-[.zz.]p]) echo ok 12;; *) echo oops -- bad range 2;; esac case p in [[.aa.]-[.z.]p]) echo ok 13;; *) echo oops -- bad range 3;; esac case c in [[.yyz.]cde]) echo ok 14;; esac case abc in [[.cb.]a-Za]*) echo ok 15;; esac case $'\t' in [[.space.][.tab.][.newline.]]) echo ok 16;; esac # and finally, test POSIX.2 equivalence classes case "abc" in [[:alpha:]][[=b=]][[:ascii:]]) echo ok 1;; esac case "abc" in [[:alpha:]][[=B=]][[:ascii:]]) echo oops -- =B=;; *) echo ok 2 ;; esac case a in [[=b=]) echo oops;; # an incomplete equiv class is just a string *) echo ok 3;; esac extglob-1.0.0/test/negations.js000066400000000000000000000055441300223233500164610ustar00rootroot00000000000000'use strict'; /** * minimatch "tricky negations test" */ module.exports = { 'bar.min.js': { '*.!(js|css)': true, '!*.+(js|css)': false, '*.+(js|css)': true }, 'a-integration-test.js': { '*.!(j)': true, '*.!(js)': false, '!(*-integration-test.js)': false, '*-!(integration-)test.js': true, '*-!(integration)-test.js': false, '*!(-integration)-test.js': true, '*!(-integration-)test.js': true, '*!(integration)-test.js': true, '*!(integration-test).js': true, '*-!(integration-test).js': true, '*-!(integration-test.js)': true, '*-!(integra)tion-test.js': false, '*-integr!(ation)-test.js': false, '*-integr!(ation-t)est.js': false, '*-i!(ntegration-)test.js': false, '*i!(ntegration-)test.js': true, '*te!(gration-te)st.js': true, '*-!(integration)?test.js': false, '*?!(integration)?test.js': true }, 'foo-integration-test.js': { 'foo-integration-test.js': true, '!(*-integration-test.js)': false }, 'foo.jszzz.js': { '*.!(js).js': true }, 'asd.jss': { '*.!(js)': true }, 'asd.jss.xyz': { '*.!(js).!(xy)': true }, 'asd.jss.xy': { '*.!(js).!(xy)': false }, 'asd.js.xyz': { '*.!(js)*.!(xyz)*': false, '*.!(js)*.!(xyz)': false, '*.!(js).!(xyz)': false, '*.!(js)*.!(xy)*': false, '*.!(js)*.!(xy)': false, '*.!(js).!(xy)*': false, '*.!(js).!(xy)': true }, 'asd.js.xy': { '*.!(js).!(xy)': false }, 'asd.sjs.zxy': { '*.!(js).!(xy)': true }, 'asd..xyz': { '*.!(js).!(xy)': true }, 'asd..xy': { '*.!(js).!(xy)': false, '*.!(js|x).!(xy)': false }, 'foo.js.js': { '*!(js)': true, '*!(.js)': true, '*!(.js.js)': true, '*!(.js.js)*': true, '*(.js.js)': false, '**(.js.js)': true, '*(!(.js.js))': true, '*.!(js)*.!(js)': false, '*.!(js)+': false, '!(*(.js.js))': true, '*.!(js)': true, '*.!(js)*': false, // Bash 4.3 disagrees! '*.!(js)*.js': false // Bash 4.3 disagrees! }, 'a/foo.js.js': { '*/**(.*)': true, '*/**(.*.*)': true, 'a/**(.*.*)': true, '*/**(.js.js)': true, 'a/f*(!(.js.js))': true, 'a/!(*(.*))': true, 'a/!(+(.*))': true, 'a/!(*(.*.*))': true, '*/!(*(.*.*))': true, 'a/!(*(.js.js))': true }, 'testjson.json': { '*(*.json|!(*.js))': true, '+(*.json|!(*.js))': true, '@(*.json|!(*.js))': true, '?(*.json|!(*.js))': true }, 'foojs.js': { '*(*.json|!(*.js))': false, // Bash 4.3 disagrees! '*(*.json|!(*.js))*': true, '+(*.json|!(*.js))': false, // Bash 4.3 disagrees! '@(*.json|!(*.js))': false, '?(*.json|!(*.js))': false }, 'other.bar': { '*(*.json|!(*.js))': true, '*(*.json|!(*.js))*': true, '!(*(*.json|!(*.js)))*': false, '+(*.json|!(*.js))': true, '@(*.json|!(*.js))': true, '?(*.json|!(*.js))': true } }; extglob-1.0.0/test/options.js000066400000000000000000000023661300223233500161640ustar00rootroot00000000000000'use strict'; var assert = require('assert'); var matcher = require('./support/match'); var extglob = require('..'); describe('options', function() { describe('options.nonull', function() { it('should return the pattern when no matches are found', function() { matcher.match(['ax'], 'a?(b*)', []); matcher.match(['ax'], 'a?(b*)', ['a?(b*)'], {nonull: true}); matcher.match(['az'], 'a?(b*)', ['a?(b*)'], {nonull: true}); matcher.match(['ag'], 'a?(b*)', ['a?(b*)'], {nonull: true}); }); }); describe('options.failglob', function() { it('should throw an error when no matches are found', function(cb) { try { extglob.match(['ax'], 'a?(b*)', {failglob: true}); return cb(new Error('expected an error')); } catch (err) { assert(/no matches/.test(err.message)); } cb(); }); }); describe('options.strict', function() { it('should throw an error when an opening brace is missing', function(cb) { assert(!extglob.isMatch('foo', 'a)')); try { assert(!extglob.isMatch('foo', 'a)', {strict: true})); return cb(new Error('expected an error')); } catch (err) { assert(/missing/.test(err.message)); } cb(); }); }); }); extglob-1.0.0/test/reference.js000066400000000000000000000013451300223233500164230ustar00rootroot00000000000000'use strict'; require('mocha'); var assert = require('assert'); var forOwn = require('for-own'); var negations = require('./negations'); var matcher = require('./support/matcher'); describe('running extglob against minimatch tests', function() { forOwn(negations, function(val, fixture) { if (fixture !== 'asd.js.xyz') return; describe('"' + fixture + '"', function() { forOwn(val, function(expected, pattern) { var exp = expected === false ? ' not' : ''; it('should' + exp + ' match "' + pattern + '"', function() { var actual = matcher.isMatch(fixture, pattern); if (actual === null) return; assert.equal(actual, expected, pattern); }); }); }); }); }); extglob-1.0.0/test/support/000077500000000000000000000000001300223233500156405ustar00rootroot00000000000000extglob-1.0.0/test/support/compare.js000066400000000000000000000001701300223233500176220ustar00rootroot00000000000000module.exports = function(a, b) { a = a.toLowerCase(); b = b.toLowerCase(); return a > b ? 1 : a < b ? -1 : 0; }; extglob-1.0.0/test/support/match.js000066400000000000000000000026501300223233500172750ustar00rootroot00000000000000'use strict'; var assert = require('assert'); var matcher = require('./matcher'); var compare = require('./compare'); var utils = require('./utils'); module.exports = function(fixtures, pattern, expected, options, msg) { if (!Array.isArray(expected)) { var tmp = expected; expected = options; options = tmp; } if (typeof options === 'string') { msg = options; options = {}; } msg = msg ? (pattern + ' ' + msg) : pattern; var actual = matcher.match(utils.arrayify(fixtures), pattern, options); expected.sort(compare); actual.sort(compare); assert.deepEqual(actual, expected, msg); }; module.exports.match = function(fixtures, pattern, expected, options, msg) { if (!Array.isArray(expected)) { var tmp = expected; expected = options; options = tmp; } if (typeof options === 'string') { msg = options; options = {}; } msg = msg ? (pattern + ' ' + msg) : pattern; var actual = matcher.match(utils.arrayify(fixtures), pattern, options); expected.sort(compare); actual.sort(compare); assert.deepEqual(actual, expected, msg); }; module.exports.isMatch = function(fixture, pattern, options) { return matcher.isMatch.apply(null, arguments); }; module.exports.contains = function(fixture, pattern, options) { return matcher.contains.apply(null, arguments); }; module.exports.makeRe = function(pattern, options) { return matcher.makeRe.apply(null, arguments); }; extglob-1.0.0/test/support/matcher.js000066400000000000000000000033111300223233500176170ustar00rootroot00000000000000'use strict'; var argv = require('yargs-parser')(process.argv.slice(2)); var mm = require('multimatch'); var minimatch = require('minimatch'); var bash = require('./try-bash'); var utils = require('./utils'); var extglob = require('../..'); // use multimatch for the array/array scenario function mi() { return mm.apply(null, arguments); } // label for debugging mm.multimatch = true; mi.minimatch = true; extglob.extglob = true; bash.bash = true; /** * Decorate methods onto multimatch for parity with nanomatch */ mm.isMatch = function(files, patterns, options) { return mm(utils.arrayify(files), patterns, options).length > 0; }; mm.contains = function(files, patterns, options) { return mm.isMatch(files, patterns, options); }; mm.match = function(files, patterns, options) { return mm(utils.arrayify(files), patterns, options); }; mm.makeRe = function(pattern, options) { return mi.makeRe(pattern, options); }; /** * Decorate methods onto minimatch for parity with nanomatch */ mi.isMatch = function(file, pattern, options) { return minimatch(file, pattern, options); }; mi.contains = function(files, patterns, options) { return mi.isMatch(files, patterns, options); }; mi.match = function(files, pattern, options) { return minimatch.match(utils.arrayify(files), pattern, options); }; mi.makeRe = function(pattern, options) { return minimatch.makeRe(pattern, options); }; /** * Detect matcher based on argv, with nanomatch as default */ var matcher = argv.mm ? mm : (argv.mi ? mi : extglob); if (argv.bash) { matcher = bash; } /** * Expose matcher */ module.exports = matcher; module.exports.bash = bash; module.exports.extglob = extglob; module.exports.mm = mm; module.exports.mi = mi; extglob-1.0.0/test/support/parse.js000066400000000000000000000021221300223233500173050ustar00rootroot00000000000000'use strict'; var fs = require('fs'); var path = require('path'); var mm = require('micromatch'); function parseFiles(pattern, options) { var opts = Object.assign({cwd: path.join(__dirname, '../fixtures')}, options); var cwd = opts.cwd; var files = mm(fs.readdirSync(cwd), pattern); var tests = {}; for (var i = 0; i < files.length; i++) { var file = files[i]; var name = path.basename(file, path.extname(file)); tests[name] = parse(path.join(cwd, file)); } return tests; } function parse(fp) { var str = fs.readFileSync(fp, 'utf8'); var lines = str.split('\n'); var len = lines.length; var idx = -1; var tests = []; while (++idx < len) { var line = lines[idx].trim(); if (!line) continue; if (/^#\s\w/.test(line)) { tests.push(line.replace(/^[#\s]+/, '').toLowerCase()); continue; } if (!/^[tf] /.test(line)) continue; var segs = line.split(/\s+/).filter(Boolean); if (segs.length !== 3) continue; tests.push([segs[1], segs[2], segs[0] === 't']); } return tests.filter(Boolean); } module.exports = parseFiles; extglob-1.0.0/test/support/try-bash.js000066400000000000000000000010571300223233500177320ustar00rootroot00000000000000'use strict'; var bash = require('bash-match'); var isWindows = require('is-windows'); function matcher() { if (isWindows()) return; return bash.apply(null, arguments); } matcher.match = function(fixtures, pattern) { if (isWindows()) return; try { return bash.match(fixtures, pattern); } catch (err) {} return null; }; matcher.isMatch = function(fixtures, pattern) { if (isWindows()) return; try { return bash.isMatch(fixtures, pattern); } catch (err) {} return null; }; /** * Expose `matcher` */ module.exports = matcher; extglob-1.0.0/test/support/utils.js000066400000000000000000000003511300223233500173350ustar00rootroot00000000000000'use strict'; exports.arrayify = function(val) { return val ? (Array.isArray(val) ? val : [val]) : []; }; exports.alphaSort = function(a, b) { a = a.toLowerCase(); b = b.toLowerCase(); return a > b ? 1 : a < b ? -1 : 0; }; extglob-1.0.0/test/test.js000066400000000000000000000632111300223233500154440ustar00rootroot00000000000000'use strict'; var assert = require('assert'); var match = require('./support/match'); var extglob = require('..'); /** * These tests were converted directly from bash 4.3 and 4.4 unit tests. */ describe('extglobs', function() { it('should export a function', function() { assert.equal(typeof extglob, 'function'); }); it.skip('failing unit test from bash', function() { match(['moo.cow'], '!(*.*).!(*.*)', ['moo.cow']); match(['foo.js.js'], '*.!(js)*', ['foo.js.js']); }); it('should throw on imbalanced sets when `options.strictErrors` is true', function() { assert.throws(function() { match.isMatch('a((b', 'a(b', {strictErrors: true}); }, 'row:1 col:2 missing opening parens: "a(b"'); assert.throws(function() { match.isMatch('a((b', 'a(*b', {strictErrors: true}); }, 'row:1 col:2 missing opening parens: "a(*b"'); }); // from minimatch tests it('should match extglobs ending with statechar', function() { assert(!match.isMatch('ax', 'a?(b*)')); assert(match.isMatch('ax', '?(a*|b)')); }); it('should not choke on non-extglobs', function() { match(['c/z/v'], 'c/z/v', ['c/z/v']); }); it('should support star (`*`) extglobs', function() { match(['cz', 'abz', 'az'], 'a*(z)', ['az']); match(['cz', 'abz', 'az'], 'a**(z)', ['az', 'abz']); match(['c/z/v', 'z', 'zf', 'fz'], '*(z)', ['z']); match(['c/z/v', 'c/a/v'], 'c/*(z)/v', ['c/z/v']); match(['a.js.js', 'a.md.js'], '*.*(js).js', ['a.js.js']); }); it('should support negation (`!`) extglobs', function() { match(['c/z/v', 'c/a/v'], 'c/!(z)/v', ['c/a/v']); match(['c/z/v', 'c/a/v'], 'c/!(z)/v', ['c/a/v']); match(['cz', 'abz', 'az'], 'a!(z)', ['abz']); match(['cz', 'abz', 'az'], 'a*!(z)', ['az', 'abz']); match(['c/a/v'], 'c/!(z)/v', ['c/a/v']); match(['a/z', 'a/b'], 'a/!(z)', ['a/b']); var f1 = ['a/a', 'a/b', 'a/c', 'b/a', 'b/b', 'b/c']; match(f1, '*(b/a)', ['b/a']); match(f1, '!(b/a)', [], {star: '[^/]*?'}); match(f1, '!((b/a))', [], {star: '[^/]*?'}); match(f1, '!((?:b/a))', [], {star: '[^/]*?'}); match(f1, '!(b/(a))', [], {star: '[^/]*?'}); match(f1, '!(b/a)', ['a/a', 'a/b', 'a/c', 'b/b', 'b/c']); match(f1, '!((b/a))', ['a/a', 'a/b', 'a/c', 'b/b', 'b/c']); match(f1, '!((?:b/a))', ['a/a', 'a/b', 'a/c', 'b/b', 'b/c']); match(f1, '!(b/(a))', ['a/a', 'a/b', 'a/c', 'b/b', 'b/c']); var f2 = ['a', 'b', 'aa', 'ab', 'bb', 'ac', 'aaa', 'aab', 'abb', 'ccc']; match(f2, '!(a)', ['aa', 'aaa', 'aab', 'ab', 'abb', 'ac', 'b', 'bb', 'ccc']); match(f2, '!(a)*', ['b', 'bb', 'ccc']); match(f2, 'a!(b)*', ['a', 'aa', 'aaa', 'aab', 'ac']); }); it('should support plus (`+`) extglobs', function() { match(['cz', 'abz', 'az'], 'a+(z)', ['az']); match(['c/z/v', 'z', 'zf', 'fz'], '+(z)', ['z']); match(['c/z/v', 'c/a/v'], 'c/+(z)/v', ['c/z/v']); match(['az', 'bz', 'axz'], 'a+(z)', ['az']); }); it('should support qmark (`?`) extglobs', function() { match(['c/z/v', 'z', 'zf', 'fz'], '?(z)', ['z']); match(['cz', 'abz', 'az'], 'a?(z)', ['az']); }); it('should support ampersand (`@`) extglobs', function() { match(['c/z/v', 'c/a/v'], 'c/@(z)/v', ['c/z/v']); match(['cz', 'abz', 'az'], 'a*@(z)', ['az', 'abz']); match(['cz', 'abz', 'az'], 'a@(z)', ['az']); }); it('should support qmark matching', function() { var arr = ['a', 'aa', 'ab', 'aaa', 'abcdefg']; match(arr, '?', ['a']); match(arr, '??', ['aa', 'ab']); match(arr, '???', ['aaa']); }); it('should match exactly one of the given pattern:', function() { var arr = ['aa.aa', 'a.bb', 'a.aa.a', 'cc.a', 'a.a', 'c.a', 'dd.aa.d', 'b.a']; match(arr, '(b|a).(a)', ['a.a', 'b.a']); match(arr, '@(b|a).@(a)', ['a.a', 'b.a']); }); it('stuff from korn\'s book', function() { assert(!match.isMatch('para', 'para+([0-9])')); assert(!match.isMatch('para381', 'para?([345]|99)1')); assert(!match.isMatch('paragraph', 'para*([0-9])')); assert(!match.isMatch('paragraph', 'para*([0-9])')); assert(!match.isMatch('paramour', 'para@(chute|graph)')); assert(match.isMatch('para', 'para*([0-9])')); assert(match.isMatch('para.38', 'para!(*.[00-09])')); assert(match.isMatch('para.graph', 'para!(*.[0-9])')); assert(match.isMatch('para13829383746592', 'para*([0-9])')); assert(match.isMatch('para39', 'para!(*.[0-9])')); assert(match.isMatch('para987346523', 'para+([0-9])')); assert(match.isMatch('para991', 'para?([345]|99)1')); assert(match.isMatch('paragraph', 'para!(*.[0-9])')); assert(match.isMatch('paragraph', 'para@(chute|graph)')); }); it('tests derived from those in rosenblatt\'s korn shell book', function() { match(['', '137577991', '2468'], '*(0|1|3|5|7|9)', ['', '137577991']); match(['file.c', 'file.C', 'file.cc', 'file.ccc'], '*.c?(c)', ['file.c', 'file.cc']); match(['parse.y', 'shell.c', 'Makefile', 'Makefile.in'], '!(*.c|*.h|Makefile.in|config*|README)', ['parse.y', 'Makefile']); match(['VMS.FILE;', 'VMS.FILE;0', 'VMS.FILE;1', 'VMS.FILE;139', 'VMS.FILE;1N'], '*\\;[1-9]*([0-9])', ['VMS.FILE;1', 'VMS.FILE;139']); }); it('tests derived from the pd-ksh test suite', function() { match(['abcx', 'abcz', 'bbc'], '!([[*])*', ['abcx', 'abcz', 'bbc']); match(['abcx', 'abcz', 'bbc'], '+(a|b\\[)*', ['abcx', 'abcz']); match(['abd', 'acd'], 'a+(b|c)d', ['abd', 'acd']); match(['abd', 'acd', 'ac', 'ab'], 'a!(@(b|B))', ['acd', 'abd', 'ac']); match(['abd', 'acd'], 'a!(@(b|B))d', ['acd']); match(['abd', 'acd'], 'a[b*(foo|bar)]d', ['abd']); match(['abcx', 'abcz', 'bbc', 'aaz', 'aaaz'], '[a*(]*z', ['aaz', 'aaaz', 'abcz']); }); it('simple kleene star tests', function() { assert(!match.isMatch('foo', '*(a|b\\[)')); assert(match.isMatch('foo', '*(a|b\\[)|f*')); }); it('this doesn\'t work in bash either (per bash extglob.tests notes)', function() { assert(!match.isMatch('*(a|b[)', '*(a|b\\[)')); assert(match.isMatch('*(a|b[)', '\\*\\(a\\|b\\[\\)')); }); it('should support multiple extglobs:', function() { var arr = ['a.a', 'a.b', 'a.c', 'a.c.d', 'c.c', 'a.', 'd.d', 'e.e', 'f.f', 'a.abcd']; match(arr, '*.(a|b|@(ab|a*@(b))*(c)d)', ['a.a', 'a.b', 'a.abcd']); match(arr, '!(*.a|*.b|*.c)', ['a.', 'a.c.d', 'd.d', 'e.e', 'f.f']); match(arr, '!(*.[^a-c])', ['a.a', 'a.b', 'a.c', 'c.c', 'a.', 'a.abcd']); match(arr, '!(*.[a-c])', ['a.', 'a.c.d', 'a.abcd', 'd.d', 'e.e', 'f.f']); match(arr, '!(*.[a-c]*)', ['a.', 'a.c.d', 'd.d', 'e.e', 'f.f']); match(arr, '!(*.[a-c])*', ['a.', 'd.d', 'e.e', 'f.f']); match(arr, '*!(.a|.b|.c)', arr); match(arr, '*!(.a|.b|.c)*', arr); match(arr, '*.!(a|b|c)', ['a.c.d', 'a.', 'd.d', 'e.e', 'f.f']); match(arr, '*.!(a|b|c)*', ['a.c.d', 'a.', 'd.d', 'e.e', 'f.f']); }); it('should correctly match empty parens', function() { match(['def', 'ef'], '()ef', ['ef']); }); it('should match escaped parens', function() { var arr = ['a(b', 'a\\(b', 'a((b', 'a((((b', 'ab']; match(arr, 'a(b', ['a(b']); match(arr, 'a\\(b', ['a(b']); match(arr, 'a(*b', ['a(b', 'a((b', 'a((((b']); }); it('should match escaped backslashes', function() { match(['a(b', 'a\\(b', 'a((b', 'a((((b', 'ab'], 'a\\\\(b', ['a\\(b']); match(['a\\b', 'a/b', 'ab'], 'a\\\\b', ['a\\b']); }); // these are not extglobs, and do not need to pass, but they are included // to test integration with expand-brackets it('should match common regex patterns', function() { var fixtures = ['a c', 'a1c', 'a123c', 'a.c', 'a.xy.zc', 'a.zc', 'abbbbc', 'abbbc', 'abbc', 'abc', 'abq', 'axy zc', 'axy', 'axy.zc', 'axyzc']; match(['a\\b', 'a/b', 'ab'], 'a/b', ['a/b']); match(fixtures, 'ab?bc', ['abbbc']); match(fixtures, 'ab*c', ['abbbbc', 'abbbc', 'abbc', 'abc']); match(fixtures, 'ab+bc', ['abbbbc', 'abbbc', 'abbc']); match(fixtures, '^abc$', ['abc']); match(fixtures, 'a.c', ['a.c']); match(fixtures, 'a.*c', ['a.c', 'a.xy.zc', 'a.zc']); match(fixtures, 'a*c', ['a c', 'a.c', 'a1c', 'a123c', 'abbbbc', 'abbbc', 'abbc', 'abc', 'axyzc', 'axy zc', 'axy.zc', 'a.xy.zc', 'a.zc']); match(fixtures, 'a\\w+c', ['a1c', 'a123c', 'abbbbc', 'abbbc', 'abbc', 'abc', 'axyzc'], 'Should match word characters'); match(fixtures, 'a\\W+c', ['a.c', 'a c'], 'Should match non-word characters'); match(fixtures, 'a\\d+c', ['a1c', 'a123c'], 'Should match numbers'); match(['foo@#$%123ASD #$$%^&', 'foo!@#$asdfl;', '123'], '\\d+', ['123']); match(['a123c', 'abbbc'], 'a\\D+c', ['abbbc'], 'Should match non-numbers'); match(['foo', ' foo '], '(f|o)+\\b', ['foo'], 'Should match word boundaries'); }); }); describe('bash unit tests', function() { var fixtures = ['ffffffo', 'fffooofoooooffoofffooofff', 'ffo', 'fofo', 'fofoofoofofoo', 'foo', 'foob', 'foobb', 'foofoofo', 'fooofoofofooo', 'foooofo', 'foooofof', 'foooofofx', 'foooxfooxfoxfooox', 'foooxfooxfxfooox', 'foooxfooxofoxfooox', 'foot', 'foox', 'ofoofo', 'ofooofoofofooo', 'ofoooxoofxo', 'ofoooxoofxoofoooxoofxo', 'ofoooxoofxoofoooxoofxofo', 'ofoooxoofxoofoooxoofxoo', 'ofoooxoofxoofoooxoofxooofxofxo', 'ofxoofxo', 'oofooofo', 'ooo', 'oxfoxfox', 'oxfoxoxfox', 'xfoooofof']; it('should match extended globs from the bash spec:', function() { var f2 = ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foo/bar', 'foobar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']; match(f2, '!(foo)', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo/bar', 'foobar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(!(foo))', ['foo']); match(f2, '!(!(!(foo)))', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo/bar', 'foobar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(!(!(!(foo))))', ['foo']); match(f2, '!(!(foo))*', ['foo', 'foo/bar', 'foobar', 'foot', 'foox']); match(f2, '!(f!(o))', ['fo']); match(f2, '!(f(o))', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(f)', ['bar', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(f)', ['bar', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(foo)', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(foo)*', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '!(x)', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'xx']); match(f2, '!(x)*', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox']); match(f2, '*(!(f))', ['bar', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '*((foo))', ['foo']); match(f2, '+(!(f))', ['bar', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, '@(!(z*)|*x)', ['bar', 'f', 'fa', 'fb', 'ff', 'fff', 'fo', 'foo', 'foobar', 'foo/bar', 'foot', 'foox', 'o', 'of', 'ooo', 'ox', 'x', 'xx']); match(f2, 'foo/!(foo)', ['foo/bar']); match(fixtures, '(foo)bb', ['foobb']); match(fixtures, '*(*(f)*(o))', [ 'ffffffo', 'fffooofoooooffoofffooofff', 'ffo', 'fofo', 'fofoofoofofoo', 'foo', 'foofoofo', 'fooofoofofooo', 'foooofo', 'foooofof', 'ofoofo', 'ofooofoofofooo', 'oofooofo', 'ooo']); match(fixtures, '*(*(of*(o)x)o)', [ 'ofoooxoofxo', 'ofoooxoofxoofoooxoofxo', 'ofoooxoofxoofoooxoofxoo', 'ofoooxoofxoofoooxoofxooofxofxo', 'ofxoofxo', 'ooo']); match(fixtures, '*(f*(o))', ['ffffffo', 'fffooofoooooffoofffooofff', 'ffo', 'fofo', 'fofoofoofofoo', 'foo', 'foofoofo', 'fooofoofofooo', 'foooofo', 'foooofof']); match(fixtures, '*(f*(o)x)', ['foooxfooxfoxfooox', 'foooxfooxfxfooox', 'foox']); match(fixtures, '*(f+(o))', ['fofo', 'fofoofoofofoo', 'foo', 'foofoofo', 'fooofoofofooo', 'foooofo']); match(fixtures, '*(of+(o))', ['ofoofo']); match(fixtures, '*(of+(o)|f)', ['fofo', 'fofoofoofofoo', 'ofoofo', 'ofooofoofofooo']); match(fixtures, '*(of|oof+(o))', ['ofoofo', 'oofooofo']); match(fixtures, '*(oxf+(ox))', ['oxfoxoxfox']); match(fixtures, '@(!(z*)|*x)', ['ffffffo', 'fffooofoooooffoofffooofff', 'ffo', 'fofo', 'fofoofoofofoo', 'foo', 'foob', 'foobb', 'foofoofo', 'fooofoofofooo', 'foooofo', 'foooofof', 'foooofofx', 'foooxfooxfoxfooox', 'foooxfooxfxfooox', 'foooxfooxofoxfooox', 'foot', 'foox', 'ofoofo', 'ofooofoofofooo', 'ofoooxoofxo', 'ofoooxoofxoofoooxoofxo', 'ofoooxoofxoofoooxoofxofo', 'ofoooxoofxoofoooxoofxoo', 'ofoooxoofxoofoooxoofxooofxofxo', 'ofxoofxo', 'oofooofo', 'ooo', 'oxfoxfox', 'oxfoxoxfox', 'xfoooofof']); match(fixtures, '@(foo|f|fo)*(f|of+(o))', ['fofo', 'fofoofoofofoo', 'foo', 'foofoofo', 'fooofoofofooo']); var arr = ['aaac', 'aac', 'ac', 'abbcd', 'abcd', 'acd', 'baaac', 'c', 'foo']; match(arr, '*(@(a))a@(c)', ['aaac', 'aac', 'ac']); match(arr, '@(ab|a*(b))*(c)d', ['abbcd', 'abcd', 'acd']); match(arr, '?@(a|b)*@(c)d', ['abbcd', 'abcd']); match(arr, '@(ab|a*@(b))*(c)d', ['abbcd', 'abcd']); match(['aac'], '*(@(a))b@(c)', []); }); it('should backtrack in alternation matches', function() { match(fixtures, '*(fo|foo)', ['fofo', 'fofoofoofofoo', 'foo', 'foofoofo']); }); it('should support exclusions', function() { match(['foob', 'foobb', 'foo', 'bar', 'baz', 'foobar'], '!(foo)b*', ['bar', 'baz']); match(['foo', 'bar', 'baz', 'foobar'], '*(!(foo))', ['bar', 'baz', 'foobar']); // Bash 4.3 says this should match `foo` and `foobar` too match(['foo', 'bar', 'baz', 'foobar'], '!(foo)*', ['bar', 'baz']); match(['moo.cow', 'moo', 'cow'], '!(*.*)', ['moo', 'cow']); match(['mad.moo.cow'], '!(*.*).!(*.*)', []); match(['moo.cow', 'moo', 'cow'], '!(*.*).', []); match(['moo.cow', 'moo', 'cow'], '.!(*.*)', []); match(['mucca.pazza'], 'mu!(*(c))?.pa!(*(z))?', []); match(['effgz'], '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', ['effgz']); match(['efgz'], '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', ['efgz']); match(['egz'], '@(b+(c)d|e*(f)g?|?(h)i@(j|k))', ['egz']); match(['egz'], '@(b+(c)d|e+(f)g?|?(h)i@(j|k))', []); match(['egzefffgzbcdij'], '*(b+(c)d|e*(f)g?|?(h)i@(j|k))', ['egzefffgzbcdij']); }); it('valid numbers', function() { assert(match.isMatch('/dev/udp/129.22.8.102/45', '/dev/@(tcp|udp)/*/*')); match(['0', '12', '1', '12abc', '555'], '[1-6]([0-9])', ['12']); match(['0', '12', '1', '12abc', '555'], '[1-6]*([0-9])', ['1', '12', '555']); match(['0', '12', '1', '12abc', '555'], '[1-5]*([6-9])', ['1']); match(['0', '12', '1', '12abc', '555'], '0|[1-6]*([0-9])', ['0', '1', '12', '555']); match(['07', '0377', '09'], '+([0-7])', ['0377', '07']); }); it('stuff from korn\'s book', function() { assert(!match.isMatch('para', 'para+([0-9])')); assert(!match.isMatch('para381', 'para?([345]|99)1')); assert(!match.isMatch('paragraph', 'para*([0-9])')); assert(!match.isMatch('paragraph', 'para*([0-9])')); assert(!match.isMatch('paramour', 'para@(chute|graph)')); assert(match.isMatch('para', 'para*([0-9])')); assert(match.isMatch('para.38', 'para!(*.[0-9])')); assert(match.isMatch('para.graph', 'para!(*.[0-9])')); assert(match.isMatch('para13829383746592', 'para*([0-9])')); assert(match.isMatch('para39', 'para!(*.[0-9])')); assert(match.isMatch('para987346523', 'para+([0-9])')); assert(match.isMatch('para991', 'para?([345]|99)1')); assert(match.isMatch('paragraph', 'para!(*.[0-9])')); assert(match.isMatch('paragraph', 'para@(chute|graph)')); }); it('tests derived from those in rosenblatt\'s korn shell book', function() { assert(match.isMatch('', '*(0|1|3|5|7|9)')); assert(match.isMatch('137577991', '*(0|1|3|5|7|9)')); assert(!match.isMatch('2468', '*(0|1|3|5|7|9)')); assert(!match.isMatch('file.C', '*.c?(c)')); assert(!match.isMatch('file.ccc', '*.c?(c)')); assert(match.isMatch('file.c', '*.c?(c)')); assert(match.isMatch('file.cc', '*.c?(c)')); assert(match.isMatch('parse.y', '!(*.c|*.h|Makefile.in|config*|README)')); assert(match.isMatch('Makefile', '!(*.c|*.h|Makefile.in|config*|README)')); assert(!match.isMatch('shell.c', '!(*.c|*.h|Makefile.in|config*|README)')); assert(!match.isMatch('VMS.FILE;', '*\\;[1-9]*([0-9])')); assert(!match.isMatch('VMS.FILE;0', '*\\;[1-9]*([0-9])')); assert(!match.isMatch('VMS.FILE;1N', '*\\;[1-9]*([0-9])')); assert(match.isMatch('VMS.FILE;1', '*\\;[1-9]*([0-9])')); assert(match.isMatch('VMS.FILE;139', '*\\;[1-9]*([0-9])')); }); it('tests derived from the pd-ksh test suite', function() { match(['abcx', 'abcz', 'bbc'], '!([*)*', ['abcx', 'abcz', 'bbc']); match(['abcx', 'abcz', 'bbc'], '+(a|b[)*', ['abcx', 'abcz']); match(['abcx', 'abcz', 'bbc'], '[a*(]*)z', []); match(['abc'], '+()c', []); match(['abc'], '+()x', []); match(['abc'], '+(*)c', ['abc']); match(['abc'], '+(*)x', []); match(['abc'], 'no-file+(a|b)stuff', []); match(['abc'], 'no-file+(a*(c)|b)stuff', []); match(['abd', 'acd'], 'a+(b|c)d', ['abd', 'acd']); match(['abc'], 'a+(b|c)d', []); match(['acd'], 'a!(@(b|B))d', ['acd']); match(['abc', 'abd'], 'a!(@(b|B))d', []); match(['abd'], 'a[b*(foo|bar)]d', ['abd']); match(['abc', 'acd'], 'a[b*(foo|bar)]d', []); }); it('simple kleene star tests', function() { assert(!match.isMatch('foo', '*(a|b[)')); assert(!match.isMatch('(', '*(a|b[)')); assert(!match.isMatch(')', '*(a|b[)')); assert(!match.isMatch('|', '*(a|b[)')); assert(match.isMatch('a', '*(a|b)')); assert(match.isMatch('b', '*(a|b)')); assert(match.isMatch('b[', '*(a|b\\[)')); assert(match.isMatch('ab[', '+(a|b\\[)')); assert(!match.isMatch('ab[cde', '+(a|b\\[)')); assert(match.isMatch('ab[cde', '+(a|b\\[)*')); }); it('check extended globbing in pattern removal', function() { match(['a', 'abc'], '+(a|abc)', ['a', 'abc']); match(['abcd', 'abcde', 'abcedf'], '+(a|abc)', []); match(['f'], '+(def|f)', ['f']); match(['def'], '+(f|def)', ['def']); match(['cdef', 'bcdef', 'abcedf'], '+(f|def)', []); match(['abcd'], '*(a|b)cd', ['abcd']); match(['a', 'ab', 'abc'], '*(a|b)cd', []); match(['a', 'ab', 'abc', 'abcde', 'abcdef'], '"*(a|b)cd"', []); }); it('More tests derived from a bug report (in bash) concerning extended glob patterns following a *', function() { var fixtures = ['123abc', 'ab', 'abab', 'abcdef', 'accdef', 'abcfefg', 'abef', 'abcfef', 'abd', 'acd']; match(['/dev/udp/129.22.8.102/45'], '/dev\\/@(tcp|udp)\\/*\\/*', ['/dev/udp/129.22.8.102/45']); match(fixtures, '(a+|b)*', ['ab', 'abab', 'accdef', 'abcdef', 'abcfefg', 'abef', 'abcfef', 'abd', 'acd']); match(fixtures, '(a+|b)+', ['ab', 'abab']); match(fixtures, 'a(b*(foo|bar))d', ['abd']); match(fixtures, 'ab*(e|f)', ['ab', 'abef']); match(fixtures, 'ab**(e|f)', ['ab', 'abab', 'abcdef', 'abcfef', 'abd', 'abef', 'abcfefg']); match(fixtures, 'ab**(e|f)g', ['abcfefg']); match(fixtures, 'ab***ef', ['abcdef', 'abcfef', 'abef']); match(fixtures, 'ab*+(e|f)', ['abcdef', 'abcfef', 'abef']); match(fixtures, 'ab*d*(e|f)', ['abcdef', 'abd']); match(fixtures, 'ab*d+(e|f)', ['abcdef']); match(fixtures, 'ab?*(e|f)', ['abcfef', 'abd', 'abef']); }); it('bug in all versions up to and including bash-2.05b', function() { assert(match.isMatch('123abc', '*?(a)bc')); }); it('should work with character classes', function() { var fixtures = ['a.b', 'a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']; match(fixtures, 'a[^[:alnum:]]b', fixtures); match(fixtures, 'a[-.,:\\;\\ _]b', fixtures); match(fixtures, 'a@([^[:alnum:]])b', fixtures); match(fixtures, 'a@([-.,:; _])b', fixtures); match(fixtures, 'a@([.])b', ['a.b']); match(fixtures, 'a@([^.])b', ['a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']); match(fixtures, 'a@([^x])b', ['a,b', 'a:b', 'a-b', 'a;b', 'a b', 'a_b']); match(fixtures, 'a+([^[:alnum:]])b', fixtures); match(fixtures, 'a@(.|[^[:alnum:]])b', fixtures); }); it('should support POSIX character classes in extglobs', function() { assert(match.isMatch('a.c', '+([[:alpha:].])')); assert(match.isMatch('a.c', '+([[:alpha:].])+([[:alpha:].])')); assert(match.isMatch('a.c', '*([[:alpha:].])')); assert(match.isMatch('a.c', '*([[:alpha:].])*([[:alpha:].])')); assert(match.isMatch('a.c', '?([[:alpha:].])?([[:alpha:].])?([[:alpha:].])')); assert(match.isMatch('a.c', '@([[:alpha:].])@([[:alpha:].])@([[:alpha:].])')); assert(!match.isMatch('.', '!(\\.)')); assert(!match.isMatch('.', '!([[:alpha:].])')); assert(match.isMatch('.', '?([[:alpha:].])')); assert(match.isMatch('.', '@([[:alpha:].])')); }); // ported from http://www.bashcookbook.com/bashinfo/source/bash-4.3/tests/extglob2.tests it('should pass extglob2 tests', function() { assert(!match.isMatch('baaac', '*(@(a))a@(c)')); assert(!match.isMatch('c', '*(@(a))a@(c)')); assert(!match.isMatch('egz', '@(b+(c)d|e+(f)g?|?(h)i@(j|k))')); assert(!match.isMatch('foooofof', '*(f+(o))')); assert(!match.isMatch('foooofofx', '*(f*(o))')); assert(!match.isMatch('foooxfooxofoxfooox', '*(f*(o)x)')); assert(!match.isMatch('ofooofoofofooo', '*(f*(o))')); assert(!match.isMatch('ofoooxoofxoofoooxoofxofo', '*(*(of*(o)x)o)')); assert(!match.isMatch('oxfoxfox', '*(oxf+(ox))')); assert(!match.isMatch('xfoooofof', '*(f*(o))')); assert(match.isMatch('aaac', '*(@(a))a@(c)')); assert(match.isMatch('aac', '*(@(a))a@(c)')); assert(match.isMatch('abbcd', '@(ab|a*(b))*(c)d')); assert(match.isMatch('abcd', '?@(a|b)*@(c)d')); assert(match.isMatch('abcd', '@(ab|a*@(b))*(c)d')); assert(match.isMatch('ac', '*(@(a))a@(c)')); assert(match.isMatch('acd', '@(ab|a*(b))*(c)d')); assert(match.isMatch('effgz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))')); assert(match.isMatch('efgz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))')); assert(match.isMatch('egz', '@(b+(c)d|e*(f)g?|?(h)i@(j|k))')); assert(match.isMatch('egzefffgzbcdij', '*(b+(c)d|e*(f)g?|?(h)i@(j|k))')); assert(match.isMatch('fffooofoooooffoofffooofff', '*(*(f)*(o))')); assert(match.isMatch('ffo', '*(f*(o))')); assert(match.isMatch('fofo', '*(f*(o))')); assert(match.isMatch('foofoofo', '@(foo|f|fo)*(f|of+(o))')); assert(match.isMatch('fooofoofofooo', '*(f*(o))')); assert(match.isMatch('foooofo', '*(f*(o))')); assert(match.isMatch('foooofof', '*(f*(o))')); assert(match.isMatch('foooxfooxfoxfooox', '*(f*(o)x)')); assert(match.isMatch('foooxfooxfxfooox', '*(f*(o)x)')); assert(match.isMatch('ofoofo', '*(of+(o))')); assert(match.isMatch('ofoofo', '*(of+(o)|f)')); assert(match.isMatch('ofoooxoofxo', '*(*(of*(o)x)o)')); assert(match.isMatch('ofoooxoofxoofoooxoofxo', '*(*(of*(o)x)o)')); assert(match.isMatch('ofoooxoofxoofoooxoofxoo', '*(*(of*(o)x)o)')); assert(match.isMatch('ofoooxoofxoofoooxoofxooofxofxo', '*(*(of*(o)x)o)')); assert(match.isMatch('ofxoofxo', '*(*(of*(o)x)o)')); assert(match.isMatch('oofooofo', '*(of|oof+(o))')); assert(match.isMatch('oxfoxoxfox', '*(oxf+(ox))')); }); it('should support backtracking in alternation matches', function() { assert(match.isMatch('fofoofoofofoo', '*(fo|foo)')); }); it('should support exclusions', function() { assert(!match.isMatch('f', '!(f)')); assert(!match.isMatch('f', '*(!(f))')); assert(!match.isMatch('f', '+(!(f))')); assert(!match.isMatch('foo', '!(foo)')); assert(!match.isMatch('foob', '!(foo)b*')); assert(!match.isMatch('mad.moo.cow', '!(*.*).!(*.*)')); assert(!match.isMatch('mucca.pazza', 'mu!(*(c))?.pa!(*(z))?')); assert(!match.isMatch('zoot', '@(!(z*)|*x)')); assert(match.isMatch('fff', '!(f)')); assert(match.isMatch('fff', '*(!(f))')); assert(match.isMatch('fff', '+(!(f))')); assert(match.isMatch('foo', '!(f)')); assert(match.isMatch('foo', '!(x)')); assert(match.isMatch('foo', '!(x)*')); assert(match.isMatch('foo', '*(!(f))')); assert(match.isMatch('foo', '+(!(f))')); assert(match.isMatch('foobar', '!(foo)')); assert(match.isMatch('foot', '@(!(z*)|*x)')); assert(match.isMatch('foox', '@(!(z*)|*x)')); assert(match.isMatch('ooo', '!(f)')); assert(match.isMatch('ooo', '*(!(f))')); assert(match.isMatch('ooo', '+(!(f))')); assert(match.isMatch('zoox', '@(!(z*)|*x)')); }); it('should pass extglob3 tests', function() { assert(match.isMatch('ab/../', '+(??)/..?(/)')); assert(match.isMatch('ab/../', '+(??|a*)/..?(/)')); assert(match.isMatch('ab/../', '+(?b)/..?(/)')); assert(match.isMatch('ab/../', '+(?b|?b)/..?(/)')); assert(match.isMatch('ab/../', '+([!/])/../')); assert(match.isMatch('ab/../', '+([!/])/..?(/)')); assert(match.isMatch('ab/../', '+([!/])/..@(/)')); assert(match.isMatch('ab/../', '+([^/])/../')); assert(match.isMatch('ab/../', '+([^/])/..?(/)')); assert(match.isMatch('ab/../', '+(a*)/..?(/)')); assert(match.isMatch('ab/../', '+(ab)/..?(/)')); assert(match.isMatch('ab/../', '?(ab)/..?(/)')); assert(match.isMatch('ab/../', '?(ab|??)/..?(/)')); assert(match.isMatch('ab/../', '?b/..?(/)')); assert(match.isMatch('ab/../', '@(??)/..?(/)')); assert(match.isMatch('ab/../', '@(??|a*)/..?(/)')); assert(match.isMatch('ab/../', '@(?b|?b)/..?(/)')); assert(match.isMatch('ab/../', '@(a*)/..?(/)')); assert(match.isMatch('ab/../', '@(a?|?b)/..?(/)')); assert(match.isMatch('ab/../', '@(ab|+([!/]))/..?(/)')); assert(match.isMatch('ab/../', '@(ab|+([^/]))/..?(/)')); assert(match.isMatch('ab/../', '@(ab|?b)/..?(/)')); assert(match.isMatch('ab/../', '[!/][!/]/../')); assert(match.isMatch('ab/../', '[^/][^/]/../')); assert(match.isMatch('x', '@(x)')); }); });