parse-glob-3.0.4/000775 000000 000000 00000000000 12600270472 013531 5ustar00rootroot000000 000000 parse-glob-3.0.4/.editorconfig000664 000000 000000 00000000650 12600270472 016207 0ustar00rootroot000000 000000 # http://editorconfig.org root = true [*] indent_style = space end_of_line = lf charset = utf-8 indent_size = 2 trim_trailing_whitespace = true insert_final_newline = true [*.json] indent_style = space indent_size = 2 [*.yml] indent_style = space indent_size = 2 [*.md] indent_style = space indent_size = 2 trim_trailing_whitespace = false [test/fixtures/*] trim_trailing_whitespace = false insert_final_newline = falseparse-glob-3.0.4/.gitattributes000664 000000 000000 00000000177 12600270472 016431 0ustar00rootroot000000 000000 # Enforce Unix newlines * text eol=lf # binaries *.ai binary *.psd binary *.jpg binary *.gif binary *.png binary *.jpeg binaryparse-glob-3.0.4/.gitignore000664 000000 000000 00000000231 12600270472 015515 0ustar00rootroot000000 000000 *.DS_Store *.DS_store *.sublime-* _gh_pages bower_components node_modules npm-debug.log actual test/actual temp tmp TODO.md vendor support.js example.js parse-glob-3.0.4/.jshintrc000664 000000 000000 00000000431 12600270472 015354 0ustar00rootroot000000 000000 { "asi": false, "boss": true, "curly": true, "eqeqeq": true, "eqnull": true, "esnext": true, "immed": true, "latedef": false, "laxcomma": false, "mocha": true, "newcap": true, "noarg": true, "node": true, "sub": true, "undef": true, "unused": true }parse-glob-3.0.4/.travis.yml000664 000000 000000 00000000130 12600270472 015634 0ustar00rootroot000000 000000 sudo: false language: node_js node_js: - "0.10" - "0.12" - "iojs" git: depth: 10parse-glob-3.0.4/.verb.md000664 000000 000000 00000004724 12600270472 015076 0ustar00rootroot000000 000000 # {%= name %} {%= badge("fury") %} {%= badge("travis") %} > {%= description %} **Changes from v1.0.0 to v{%= version %}** - all path-related properties are now on the `path` object - all boolean properties are now on the `is` object - adds `base` property See the [properties](#properties) section for details. {%= include("install-npm", {save: true}) %} - parses 1,000+ glob patterns in 29ms (2.3 GHz Intel Core i7) - Extensive [unit tests](./test.js) (more than 1,000 lines), covering wildcards, globstars, character classes, brace patterns, extglobs, dotfiles and other complex patterns. See the tests for [hundreds of examples](./test.js). ## Usage ```js var parseGlob = require('{%= name %}'); ``` **Example** ```js parseGlob('a/b/c/**/*.{yml,json}'); ``` **Returns:** ```js { orig: 'a/b/c/**/*.{yml,json}', is: { glob: true, negated: false, extglob: false, braces: true, brackets: false, globstar: true, dotfile: false, dotdir: false }, glob: '**/*.{yml,json}', base: 'a/b/c', path: { dirname: 'a/b/c/**/', basename: '*.{yml,json}', filename: '*', extname: '.{yml,json}', ext: '{yml,json}' } } ``` ## Properties The object returned by parseGlob has the following properties: - `orig`: a copy of the original, unmodified glob pattern - `is`: an object with boolean information about the glob: + `glob`: true if the pattern actually a glob pattern + `negated`: true if it's a negation pattern (`!**/foo.js`) + `extglob`: true if it has extglobs (`@(foo|bar)`) + `braces`: true if it has braces (`{1..2}` or `.{txt,md}`) + `brackets`: true if it has POSIX brackets (`[[:alpha:]]`) + `globstar`: true if the pattern has a globstar (double star, `**`) + `dotfile`: true if the pattern should match dotfiles + `dotdir`: true if the pattern should match dot-directories (like `.git`) - `glob`: the glob pattern part of the string, if any - `base`: the non-glob part of the string, if any - `path`: file path segments + `dirname`: directory + `basename`: file name with extension + `filename`: file name without extension + `extname`: file extension with dot + `ext`: file extension without dot ## Related {%= related(['glob-base', 'glob-parent', 'is-glob', 'glob-path-regex', 'micromatch']) %} ## Contributing {%= include("contributing") %} ## Tests {%= include("tests") %} ## Author {%= include("author") %} ## License {%= copyright({year: 2014}) %} {%= license() %} *** {%= include("footer") %} parse-glob-3.0.4/LICENSE000664 000000 000000 00000002073 12600270472 014540 0ustar00rootroot000000 000000 The MIT License (MIT) Copyright (c) 2015, 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. parse-glob-3.0.4/README.md000664 000000 000000 00000007661 12600270472 015022 0ustar00rootroot000000 000000 # parse-glob [![NPM version](https://badge.fury.io/js/parse-glob.svg)](http://badge.fury.io/js/parse-glob) [![Build Status](https://travis-ci.org/jonschlinkert/parse-glob.svg)](https://travis-ci.org/jonschlinkert/parse-glob) > Parse a glob pattern into an object of tokens. **Changes from v1.0.0 to v3.0.4** * all path-related properties are now on the `path` object * all boolean properties are now on the `is` object * adds `base` property See the [properties](#properties) section for details. Install with [npm](https://www.npmjs.com/) ```sh $ npm i parse-glob --save ``` * parses 1,000+ glob patterns in 29ms (2.3 GHz Intel Core i7) * Extensive [unit tests](./test.js) (more than 1,000 lines), covering wildcards, globstars, character classes, brace patterns, extglobs, dotfiles and other complex patterns. See the tests for [hundreds of examples](./test.js). ## Usage ```js var parseGlob = require('parse-glob'); ``` **Example** ```js parseGlob('a/b/c/**/*.{yml,json}'); ``` **Returns:** ```js { orig: 'a/b/c/**/*.{yml,json}', is: { glob: true, negated: false, extglob: false, braces: true, brackets: false, globstar: true, dotfile: false, dotdir: false }, glob: '**/*.{yml,json}', base: 'a/b/c', path: { dirname: 'a/b/c/**/', basename: '*.{yml,json}', filename: '*', extname: '.{yml,json}', ext: '{yml,json}' } } ``` ## Properties The object returned by parseGlob has the following properties: * `orig`: a copy of the original, unmodified glob pattern * `is`: an object with boolean information about the glob: - `glob`: true if the pattern actually a glob pattern - `negated`: true if it's a negation pattern (`!**/foo.js`) - `extglob`: true if it has extglobs (`@(foo|bar)`) - `braces`: true if it has braces (`{1..2}` or `.{txt,md}`) - `brackets`: true if it has POSIX brackets (`[[:alpha:]]`) - `globstar`: true if the pattern has a globstar (double star, `**`) - `dotfile`: true if the pattern should match dotfiles - `dotdir`: true if the pattern should match dot-directories (like `.git`) * `glob`: the glob pattern part of the string, if any * `base`: the non-glob part of the string, if any * `path`: file path segments - `dirname`: directory - `basename`: file name with extension - `filename`: file name without extension - `extname`: file extension with dot - `ext`: file extension without dot ## Related * [glob-base](https://www.npmjs.com/package/glob-base): Returns an object with the (non-glob) base path and the actual pattern. | [homepage](https://github.com/jonschlinkert/glob-base) * [glob-parent](https://www.npmjs.com/package/glob-parent): Strips glob magic from a string to provide the parent path | [homepage](https://github.com/es128/glob-parent) * [glob-path-regex](https://www.npmjs.com/package/glob-path-regex): Regular expression for matching the parts of glob pattern. | [homepage](https://github.com/regexps/glob-path-regex) * [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern. | [homepage](https://github.com/jonschlinkert/is-glob) * [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://www.npmjs.com/package/micromatch) | [homepage](https://github.com/jonschlinkert/micromatch) ## Contributing Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/parse-glob/issues/new). ## Tests Install dev dependencies: ```sh $ npm i -d && npm test ``` ## Author **Jon Schlinkert** + [github/jonschlinkert](https://github.com/jonschlinkert) + [twitter/jonschlinkert](http://twitter.com/jonschlinkert) ## License Copyright © 2014-2015 Jon Schlinkert Released under the MIT license. *** _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on September 22, 2015._parse-glob-3.0.4/index.js000664 000000 000000 00000007376 12600270472 015213 0ustar00rootroot000000 000000 /*! * parse-glob * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. */ 'use strict'; var isGlob = require('is-glob'); var findBase = require('glob-base'); var extglob = require('is-extglob'); var dotfile = require('is-dotfile'); /** * Expose `cache` */ var cache = module.exports.cache = {}; /** * Parse a glob pattern into tokens. * * When no paths or '**' are in the glob, we use a * different strategy for parsing the filename, since * file names can contain braces and other difficult * patterns. such as: * * - `*.{a,b}` * - `(**|*.js)` */ module.exports = function parseGlob(glob) { if (cache.hasOwnProperty(glob)) { return cache[glob]; } var tok = {}; tok.orig = glob; tok.is = {}; // unescape dots and slashes in braces/brackets glob = escape(glob); var parsed = findBase(glob); tok.is.glob = parsed.isGlob; tok.glob = parsed.glob; tok.base = parsed.base; var segs = /([^\/]*)$/.exec(glob); tok.path = {}; tok.path.dirname = ''; tok.path.basename = segs[1] || ''; tok.path.dirname = glob.split(tok.path.basename).join('') || ''; var basename = (tok.path.basename || '').split('.') || ''; tok.path.filename = basename[0] || ''; tok.path.extname = basename.slice(1).join('.') || ''; tok.path.ext = ''; if (isGlob(tok.path.dirname) && !tok.path.basename) { if (!/\/$/.test(tok.glob)) { tok.path.basename = tok.glob; } tok.path.dirname = tok.base; } if (glob.indexOf('/') === -1 && !tok.is.globstar) { tok.path.dirname = ''; tok.path.basename = tok.orig; } var dot = tok.path.basename.indexOf('.'); if (dot !== -1) { tok.path.filename = tok.path.basename.slice(0, dot); tok.path.extname = tok.path.basename.slice(dot); } if (tok.path.extname.charAt(0) === '.') { var exts = tok.path.extname.split('.'); tok.path.ext = exts[exts.length - 1]; } // unescape dots and slashes in braces/brackets tok.glob = unescape(tok.glob); tok.path.dirname = unescape(tok.path.dirname); tok.path.basename = unescape(tok.path.basename); tok.path.filename = unescape(tok.path.filename); tok.path.extname = unescape(tok.path.extname); // Booleans var is = (glob && tok.is.glob); tok.is.negated = glob && glob.charAt(0) === '!'; tok.is.extglob = glob && extglob(glob); tok.is.braces = has(is, glob, '{'); tok.is.brackets = has(is, glob, '[:'); tok.is.globstar = has(is, glob, '**'); tok.is.dotfile = dotfile(tok.path.basename) || dotfile(tok.path.filename); tok.is.dotdir = dotdir(tok.path.dirname); return (cache[glob] = tok); } /** * Returns true if the glob matches dot-directories. * * @param {Object} `tok` The tokens object * @param {Object} `path` The path object * @return {Object} */ function dotdir(base) { if (base.indexOf('/.') !== -1) { return true; } if (base.charAt(0) === '.' && base.charAt(1) !== '/') { return true; } return false; } /** * Returns true if the pattern has the given `ch`aracter(s) * * @param {Object} `glob` The glob pattern. * @param {Object} `ch` The character to test for * @return {Object} */ function has(is, glob, ch) { return is && glob.indexOf(ch) !== -1; } /** * Escape/unescape utils */ function escape(str) { var re = /\{([^{}]*?)}|\(([^()]*?)\)|\[([^\[\]]*?)\]/g; return str.replace(re, function (outter, braces, parens, brackets) { var inner = braces || parens || brackets; if (!inner) { return outter; } return outter.split(inner).join(esc(inner)); }); } function esc(str) { str = str.split('/').join('__SLASH__'); str = str.split('.').join('__DOT__'); return str; } function unescape(str) { str = str.split('__SLASH__').join('/'); str = str.split('__DOT__').join('.'); return str; } parse-glob-3.0.4/package.json000664 000000 000000 00000002257 12600270472 016025 0ustar00rootroot000000 000000 { "name": "parse-glob", "description": "Parse a glob pattern into an object of tokens.", "version": "3.0.4", "homepage": "https://github.com/jonschlinkert/parse-glob", "author": "Jon Schlinkert (https://github.com/jonschlinkert)", "repository": "jonschlinkert/parse-glob", "bugs": { "url": "https://github.com/jonschlinkert/parse-glob/issues" }, "license": "MIT", "files": [ "index.js" ], "main": "index.js", "engines": { "node": ">=0.10.0" }, "scripts": { "test": "mocha", "prepublish": "browserify -o browser.js -e index.js" }, "dependencies": { "glob-base": "^0.3.0", "is-dotfile": "^1.0.0", "is-extglob": "^1.0.0", "is-glob": "^2.0.0" }, "devDependencies": { "browserify": "^9.0.3", "lodash": "^3.3.1", "mocha": "*" }, "keywords": [ "glob", "match", "bash", "expand", "expansion", "expression", "file", "files", "filter", "find", "glob", "globbing", "globs", "globstar", "match", "matcher", "matches", "matching", "path", "pattern", "patterns", "regex", "regexp", "regular", "shell", "wildcard" ] } parse-glob-3.0.4/test.js000664 000000 000000 00000135365 12600270472 015063 0ustar00rootroot000000 000000 /*! * parse-glob * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. */ 'use strict'; var assert = require('assert'); var parse = require('./'); describe('`is` object:', function () { it('should detect when special characters are in a pattern:', function () { assert.equal(parse('!**{}[:[@()').is.negated, true); assert.equal(parse('!**{}[:[@()').is.glob, true); assert.equal(parse('!**{}[:[@()').is.extglob, true); assert.equal(parse('!**{}[:[@()').is.brackets, true); assert.equal(parse('!**{}[:[@()').is.braces, true); }); it('should detect when the pattern is a glob pattern:', function () { assert.equal(parse('a.min.js').is.glob, false); assert.equal(parse('*.min.js').is.glob, true); assert.equal(parse('foo/{a,b}.min.js').is.glob, true); assert.equal(parse('foo/(a|b).min.js').is.glob, true); assert.equal(parse('foo/[a-b].min.js').is.glob, true); assert.equal(parse('!foo').is.glob, true); }); it('should detect when a pattern is negated:', function () { assert.equal(parse('a.min.js').is.negated, false); assert.equal(parse('!*.min.js').is.negated, true); assert.equal(parse('!foo/{a,b}.min.js').is.negated, true); assert.equal(parse('!foo/(a|b).min.js').is.negated, true); assert.equal(parse('!foo/[a-b].min.js').is.negated, true); assert.equal(parse('foo').is.negated, false); }); it('should detect when a pattern has a globstar:', function () { assert.equal(parse('**').is.globstar, true); assert.equal(parse('**/*.min.js').is.globstar, true); assert.equal(parse('**/*foo.js').is.globstar, true); assert.equal(parse('*/*').is.globstar, false); assert.equal(parse('*/*/**/a.js').is.globstar, true); assert.equal(parse('a.min.js').is.globstar, false); assert.equal(parse('!*.min.js').is.globstar, false); assert.equal(parse('!foo/{a,b}.min.js').is.globstar, false); assert.equal(parse('!foo/(a|b).min.js').is.globstar, false); assert.equal(parse('!foo/[a-b].min.js').is.globstar, false); assert.equal(parse('foo').is.globstar, false); }); it('should detect when a pattern has brace patterns:', function () { assert.equal(parse('a/b/c').is.braces, false); assert.equal(parse('**/*.{js,min.js}').is.braces, true); assert.equal(parse('**/*{bar,foo}.js').is.braces, true); }); }); describe('should get a base path:', function () { it('should extract a base path from a glob pattern:', function () { assert.equal(parse('.*').base, '.'); assert.equal(parse('.*').glob, '.*'); assert.equal(parse('./*').base, '.'); assert.equal(parse('./*').glob, '*'); assert.equal(parse('*').base, '.'); assert.equal(parse('*').glob, '*'); assert.equal(parse('**').base, '.'); assert.equal(parse('**').glob, '**'); assert.equal(parse('**/*.md').base, '.'); assert.equal(parse('**/*.md').glob, '**/*.md'); assert.equal(parse('**/*.min.js').base, '.'); assert.equal(parse('**/*.min.js').glob, '**/*.min.js'); assert.equal(parse('**/*foo.js').base, '.'); assert.equal(parse('**/*foo.js').glob, '**/*foo.js'); assert.equal(parse('**/.*').base, '.'); assert.equal(parse('**/.*').glob, '**/.*'); assert.equal(parse('**/d').base, '.'); assert.equal(parse('**/d').glob, '**/d'); assert.equal(parse('*.*').base, '.'); assert.equal(parse('*.*').glob, '*.*'); assert.equal(parse('*.js').base, '.'); assert.equal(parse('*.js').glob, '*.js'); assert.equal(parse('*.md').base, '.'); assert.equal(parse('*.md').glob, '*.md'); assert.equal(parse('*.min.js').base, '.'); assert.equal(parse('*.min.js').glob, '*.min.js'); assert.equal(parse('*/*').base, '.'); assert.equal(parse('*/*').glob, '*/*'); assert.equal(parse('*/*/*/*').base, '.'); assert.equal(parse('*/*/*/*').glob, '*/*/*/*'); assert.equal(parse('*/*/*/e').base, '.'); assert.equal(parse('*/*/*/e').glob, '*/*/*/e'); assert.equal(parse('*/b/*/e').base, '.'); assert.equal(parse('*/b/*/e').glob, '*/b/*/e'); assert.equal(parse('*b').base, '.'); assert.equal(parse('*b').glob, '*b'); assert.equal(parse('./a/**/j/**/z/*.md').base, './a'); assert.equal(parse('./a/**/j/**/z/*.md').glob, '**/j/**/z/*.md'); assert.equal(parse('./a/**/z/*.md').base, './a'); assert.equal(parse('./a/**/z/*.md').glob, '**/z/*.md'); assert.equal(parse('./{a/b/{c,/foo.js}/e.f.g}').base, '.'); assert.equal(parse('./{a/b/{c,/foo.js}/e.f.g}').glob, '{a/b/{c,/foo.js}/e.f.g}'); assert.equal(parse('./node_modules/*-glob/**/*.js').base, './node_modules'); assert.equal(parse('./node_modules/*-glob/**/*.js').glob, '*-glob/**/*.js'); assert.equal(parse('a/b/{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/.gitignore}').glob, '{c,/.gitignore}'); assert.equal(parse('a/b/.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/.{foo,bar}').glob, '.{foo,bar}'); assert.equal(parse('a/b/*.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/*.{foo,bar}').glob, '*.{foo,bar}'); assert.equal(parse('a/**/b/*.{foo,bar}').base, 'a'); assert.equal(parse('a/**/b/*.{foo,bar}').glob, '**/b/*.{foo,bar}'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').glob, '{c,.gitignore,{a,b}}/{a,b}/abc.foo.js'); assert.equal(parse('a/b/{c,d}/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/').glob, '{c,d}/'); assert.equal(parse('a/b/{c,d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e/f.g').glob, '{c,d}/e/f.g'); assert.equal(parse('.a*').base, '.'); assert.equal(parse('.a*').glob, '.a*'); assert.equal(parse('.b*').base, '.'); assert.equal(parse('.b*').glob, '.b*'); assert.equal(parse('/*').base, '/'); assert.equal(parse('/*').glob, '*'); assert.equal(parse('a/***').base, 'a'); assert.equal(parse('a/***').glob, '***'); assert.equal(parse('a/**/b/*.{foo,bar}').base, 'a'); assert.equal(parse('a/**/b/*.{foo,bar}').glob, '**/b/*.{foo,bar}'); assert.equal(parse('a/**/c/*').base, 'a'); assert.equal(parse('a/**/c/*').glob, '**/c/*'); assert.equal(parse('a/**/c/*.md').base, 'a'); assert.equal(parse('a/**/c/*.md').glob, '**/c/*.md'); assert.equal(parse('a/**/e').base, 'a'); assert.equal(parse('a/**/e').glob, '**/e'); assert.equal(parse('a/**/j/**/z/*.md').base, 'a'); assert.equal(parse('a/**/j/**/z/*.md').glob, '**/j/**/z/*.md'); assert.equal(parse('a/**/z/*.md').base, 'a'); assert.equal(parse('a/**/z/*.md').glob, '**/z/*.md'); assert.equal(parse('a/**c*').base, 'a'); assert.equal(parse('a/**c*').glob, '**c*'); assert.equal(parse('a/**c/*').base, 'a'); assert.equal(parse('a/**c/*').glob, '**c/*'); assert.equal(parse('a/*/*/e').base, 'a'); assert.equal(parse('a/*/*/e').glob, '*/*/e'); assert.equal(parse('a/*/c/*.md').base, 'a'); assert.equal(parse('a/*/c/*.md').glob, '*/c/*.md'); assert.equal(parse('a/b/**/c{d,e}/**/xyz.md').base, 'a/b'); assert.equal(parse('a/b/**/c{d,e}/**/xyz.md').glob, '**/c{d,e}/**/xyz.md'); assert.equal(parse('a/b/**/e').base, 'a/b'); assert.equal(parse('a/b/**/e').glob, '**/e'); assert.equal(parse('a/b/*.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/*.{foo,bar}').glob, '*.{foo,bar}'); assert.equal(parse('a/b/*/e').base, 'a/b'); assert.equal(parse('a/b/*/e').glob, '*/e'); assert.equal(parse('a/b/c/*').base, 'a/b/c'); assert.equal(parse('a/b/c/*').glob, '*'); assert.equal(parse('a/b/c/*.md').base, 'a/b/c'); assert.equal(parse('a/b/c/*.md').glob, '*.md'); assert.equal(parse('a/b/c/.*.md').base, 'a/b/c'); assert.equal(parse('a/b/c/.*.md').glob, '.*.md'); assert.equal(parse('b/*/*/*').base, 'b'); assert.equal(parse('b/*/*/*').glob, '*/*/*'); }); it('file extensions:', function () { assert.equal(parse('.md').base, '.'); assert.equal(parse('.md').glob, '.md'); }); it('negation pattern:', function () { assert.equal(parse('!*.min.js').base, '.'); assert.equal(parse('!*.min.js').glob, '!*.min.js'); assert.equal(parse('!foo').base, '.'); assert.equal(parse('!foo').glob, '!foo'); assert.equal(parse('a/b/c/!foo').base, 'a/b/c'); assert.equal(parse('a/b/c/!foo').glob, '!foo'); assert.equal(parse('!foo/(a|b).min.js').base, '.'); assert.equal(parse('!foo/(a|b).min.js').glob, '!foo/(a|b).min.js'); assert.equal(parse('!foo/[a-b].min.js').base, '.'); assert.equal(parse('!foo/[a-b].min.js').glob, '!foo/[a-b].min.js'); assert.equal(parse('!foo/{a,b}.min.js').base, '.'); assert.equal(parse('!foo/{a,b}.min.js').glob, '!foo/{a,b}.min.js'); }); describe('braces:', function () { it('should know when a base cannot be extracted:', function () { assert.equal(parse('/a/b/{c,/foo.js}/e.f.g/').base, '/a/b'); assert.equal(parse('/a/b/{c,/foo.js}/e.f.g/').glob, '{c,/foo.js}/e.f.g/'); assert.equal(parse('{a/b/c.js,/a/b/{c,/foo.js}/e.f.g/}').base, '.'); assert.equal(parse('{a/b/c.js,/a/b/{c,/foo.js}/e.f.g/}').glob, '{a/b/c.js,/a/b/{c,/foo.js}/e.f.g/}'); assert.equal(parse('/a/b/{c,d}/').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/').glob, '{c,d}/'); assert.equal(parse('/a/b/{c,d}/*.js').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/*.js').glob, '{c,d}/*.js'); assert.equal(parse('/a/b/{c,d}/*.min.js').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/*.min.js').glob, '{c,d}/*.min.js'); assert.equal(parse('/a/b/{c,d}/e.f.g/').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/e.f.g/').glob, '{c,d}/e.f.g/'); assert.equal(parse('{.,*}').base, '.'); assert.equal(parse('{.,*}').glob, '{.,*}'); }); it('should work when the basename has braces:', function () { assert.equal(parse('a/b/.{c,.gitignore}').base, 'a/b'); assert.equal(parse('a/b/.{c,.gitignore}').glob, '.{c,.gitignore}'); assert.equal(parse('a/b/.{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/.{c,/.gitignore}').glob, '.{c,/.gitignore}'); assert.equal(parse('a/b/.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/.{foo,bar}').glob, '.{foo,bar}'); assert.equal(parse('a/b/{c,.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore}').glob, '{c,.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/.gitignore}').glob, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/gitignore}').glob, '{c,/gitignore}'); assert.equal(parse('a/b/{c,d}').base, 'a/b'); assert.equal(parse('a/b/{c,d}').glob, '{c,d}'); }); it('should work when the dirname has braces:', function () { assert.equal(parse('a/b/{c,./d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,./d}/e/f.g').glob, '{c,./d}/e/f.g'); assert.equal(parse('a/b/{c,./d}/e/f.min.g').base, 'a/b'); assert.equal(parse('a/b/{c,./d}/e/f.min.g').glob, '{c,./d}/e/f.min.g'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').glob, '{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').glob, '{c,.gitignore,{a,b}}/{a,b}/*.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').glob, '{c,.gitignore,{a,b}}/{a,b}/abc.foo.js'); assert.equal(parse('a/b/{c,/d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,/d}/e/f.g').glob, '{c,/d}/e/f.g'); assert.equal(parse('a/b/{c,/d}/e/f.min.g').base, 'a/b'); assert.equal(parse('a/b/{c,/d}/e/f.min.g').glob, '{c,/d}/e/f.min.g'); assert.equal(parse('a/b/{c,d}/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/').glob, '{c,d}/'); assert.equal(parse('a/b/{c,d}/*.js').base, 'a/b'); assert.equal(parse('a/b/{c,d}/*.js').glob, '{c,d}/*.js'); assert.equal(parse('a/b/{c,d}/*.min.js').base, 'a/b'); assert.equal(parse('a/b/{c,d}/*.min.js').glob, '{c,d}/*.min.js'); assert.equal(parse('a/b/{c,d}/e.f.g/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e.f.g/').glob, '{c,d}/e.f.g/'); assert.equal(parse('a/b/{c,d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e/f.g').glob, '{c,d}/e/f.g'); assert.equal(parse('a/b/{c,d}/e/f.min.g').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e/f.min.g').glob, '{c,d}/e/f.min.g'); assert.equal(parse('foo/{a,b}.min.js').base, 'foo'); assert.equal(parse('foo/{a,b}.min.js').glob, '{a,b}.min.js'); }); }); it('character classes:', function () { assert.equal(parse('/[.]bashrc').base, '/'); assert.equal(parse('/[.]bashrc').glob, '[.]bashrc'); assert.equal(parse('/[.]bashrc').path.basename, '[.]bashrc'); assert.equal(parse('/[.]bashrc').path.filename, '[.]bashrc'); assert.equal(parse('/[.]bashrc').path.extname, ''); assert.equal(parse('[a-c]b*').base, '.'); assert.equal(parse('[a-c]b*').glob, '[a-c]b*'); assert.equal(parse('[a-j]*[^c]').base, '.'); assert.equal(parse('[a-j]*[^c]').glob, '[a-j]*[^c]'); assert.equal(parse('[a-j]*[^c]b/c').base, '.'); assert.equal(parse('[a-j]*[^c]b/c').glob, '[a-j]*[^c]b/c'); assert.equal(parse('[a-j]*[^c]bc').base, '.'); assert.equal(parse('[a-j]*[^c]bc').glob, '[a-j]*[^c]bc'); assert.equal(parse('[ab][ab]').base, '.'); assert.equal(parse('[ab][ab]').glob, '[ab][ab]'); assert.equal(parse('foo/[a-b].min.js').base, 'foo'); assert.equal(parse('foo/[a-b].min.js').glob, '[a-b].min.js'); }); it('qmarks:', function () { assert.equal(parse('?').base, '.'); assert.equal(parse('?').glob, '?'); assert.equal(parse('?/?').base, '.'); assert.equal(parse('?/?').glob, '?/?'); assert.equal(parse('??').base, '.'); assert.equal(parse('??').glob, '??'); assert.equal(parse('???').base, '.'); assert.equal(parse('???').glob, '???'); assert.equal(parse('?a').base, '.'); assert.equal(parse('?a').glob, '?a'); assert.equal(parse('?b').base, '.'); assert.equal(parse('?b').glob, '?b'); assert.equal(parse('a?b').base, '.'); assert.equal(parse('a?b').glob, 'a?b'); assert.equal(parse('a/?/c.js').base, 'a'); assert.equal(parse('a/?/c.js').glob, '?/c.js'); assert.equal(parse('a/?/c.md').base, 'a'); assert.equal(parse('a/?/c.md').glob, '?/c.md'); assert.equal(parse('a/?/c/?/*/f.js').base, 'a'); assert.equal(parse('a/?/c/?/*/f.js').glob, '?/c/?/*/f.js'); assert.equal(parse('a/?/c/?/*/f.md').base, 'a'); assert.equal(parse('a/?/c/?/*/f.md').glob, '?/c/?/*/f.md'); assert.equal(parse('a/?/c/?/e.js').base, 'a'); assert.equal(parse('a/?/c/?/e.js').glob, '?/c/?/e.js'); assert.equal(parse('a/?/c/?/e.md').base, 'a'); assert.equal(parse('a/?/c/?/e.md').glob, '?/c/?/e.md'); assert.equal(parse('a/?/c/???/e.js').base, 'a'); assert.equal(parse('a/?/c/???/e.js').glob, '?/c/???/e.js'); assert.equal(parse('a/?/c/???/e.md').base, 'a'); assert.equal(parse('a/?/c/???/e.md').glob, '?/c/???/e.md'); assert.equal(parse('a/??/c.js').base, 'a'); assert.equal(parse('a/??/c.js').glob, '??/c.js'); assert.equal(parse('a/??/c.md').base, 'a'); assert.equal(parse('a/??/c.md').glob, '??/c.md'); assert.equal(parse('a/???/c.js').base, 'a'); assert.equal(parse('a/???/c.js').glob, '???/c.js'); assert.equal(parse('a/???/c.md').base, 'a'); assert.equal(parse('a/???/c.md').glob, '???/c.md'); assert.equal(parse('a/????/c.js').base, 'a'); assert.equal(parse('a/????/c.js').glob, '????/c.js'); }); it('non-glob pattern:', function () { assert.equal(parse('').base, '.'); assert.equal(parse('').glob, ''); assert.equal(parse('.').base, '.'); assert.equal(parse('.').glob, '.'); assert.equal(parse('a').base, '.'); assert.equal(parse('a').glob, 'a'); assert.equal(parse('.a').base, '.'); assert.equal(parse('.a').glob, '.a'); assert.equal(parse('/a').base, '/'); assert.equal(parse('/a').glob, 'a'); assert.equal(parse('/a/b/c').base, '/a/b'); assert.equal(parse('/a/b/c').glob, 'c'); assert.equal(parse('/a/b/c/').base, '/a/b/c/'); assert.equal(parse('/a/b/c/').glob, ''); assert.equal(parse('a/b/c/').base, 'a/b/c/'); assert.equal(parse('a/b/c/').glob, ''); assert.equal(parse('a.min.js').base, '.'); assert.equal(parse('a.min.js').glob, 'a.min.js'); assert.equal(parse('a/.x.md').base, 'a'); assert.equal(parse('a/.x.md').glob, '.x.md'); assert.equal(parse('a/b/.gitignore').base, 'a/b'); assert.equal(parse('a/b/.gitignore').glob, '.gitignore'); assert.equal(parse('a/b/c/d.md').base, 'a/b/c'); assert.equal(parse('a/b/c/d.md').glob, 'd.md'); assert.equal(parse('a/b/c/d.e.f/g.min.js').base, 'a/b/c/d.e.f'); assert.equal(parse('a/b/c/d.e.f/g.min.js').glob, 'g.min.js'); assert.equal(parse('a/b/.git').base, 'a/b'); assert.equal(parse('a/b/.git').glob, '.git'); assert.equal(parse('a/b/.git/').base, 'a/b/.git/'); assert.equal(parse('a/b/.git/').glob, ''); assert.equal(parse('a/b/.gitignore').base, 'a/b'); assert.equal(parse('a/b/.gitignore').glob, '.gitignore'); assert.equal(parse('a/b/c').base, 'a/b'); assert.equal(parse('a/b/c').glob, 'c'); assert.equal(parse('a/b/c.d/e.md').base, 'a/b/c.d'); assert.equal(parse('a/b/c.d/e.md').glob, 'e.md'); assert.equal(parse('a/b/c.md').base, 'a/b'); assert.equal(parse('a/b/c.md').glob, 'c.md'); assert.equal(parse('a/b/c.min.js').base, 'a/b'); assert.equal(parse('a/b/c.min.js').glob, 'c.min.js'); assert.equal(parse('a/b/c/').base, 'a/b/c/'); assert.equal(parse('a/b/c/').glob, ''); assert.equal(parse('a/b/c/d.e.f/g.min.js').base, 'a/b/c/d.e.f'); assert.equal(parse('a/b/c/d.e.f/g.min.js').glob, 'g.min.js'); assert.equal(parse('a/b/c/d.md').base, 'a/b/c'); assert.equal(parse('a/b/c/d.md').glob, 'd.md'); assert.equal(parse('a/b/git/').base, 'a/b/git/'); assert.equal(parse('a/b/git/').glob, ''); assert.equal(parse('aa').base, '.'); assert.equal(parse('aa').glob, 'aa'); assert.equal(parse('c.md').base, '.'); assert.equal(parse('c.md').glob, 'c.md'); }); }); describe('path parts:', function () { describe('complex patterns:', function () { it('should get a dirname:', function () { assert.equal(parse('*.min.js').base, '.'); assert.equal(parse('/a/b/c').base, '/a/b'); assert.equal(parse('/a/b/c/').base, '/a/b/c/'); assert.equal(parse('/a/b/{c,d}/').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/*.js').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/*.min.js').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/e.f.g/').base, '/a/b'); assert.equal(parse('/a/b/{c,/foo.js}/e.f.g/').base, '/a/b'); assert.equal(parse('./{a/b/{c,/foo.js}/e.f.g}').base, '.'); assert.equal(parse('[a-c]b*').base, '.'); assert.equal(parse('[a-j]*[^c]').base, '.'); assert.equal(parse('[a-j]*[^c]b/c').base, '.'); assert.equal(parse('[a-j]*[^c]bc').base, '.'); assert.equal(parse('a/b/{c,./d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,/gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,d}').base, 'a/b'); assert.equal(parse('a/b/{c,d}/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/*.js').base, 'a/b'); assert.equal(parse('a/b/{c,d}/*.min.js').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e.f.g/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e/f.g').base, 'a/b'); assert.equal(parse('a').base, '.'); assert.equal(parse('a/**/b/*.{foo,bar}').base, 'a'); assert.equal(parse('a/b/*.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/.gitignore').base, 'a/b'); assert.equal(parse('a/b/.{c,.gitignore}').base, 'a/b'); assert.equal(parse('a/b/.{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/c').base, 'a/b'); assert.equal(parse('a/b/c.d/e.md').base, 'a/b/c.d'); assert.equal(parse('a/b/c.md').base, 'a/b'); assert.equal(parse('a/b/c.min.js').base, 'a/b'); assert.equal(parse('a/b/c/').base, 'a/b/c/'); assert.equal(parse('a/b/c/d.e.f/g.min.js').base, 'a/b/c/d.e.f'); assert.equal(parse('a/b/c/d.md').base, 'a/b/c'); assert.equal(parse('c.md').base, '.'); }); it('should get a basename:', function () { assert.equal(parse('*.min.js').path.basename, '*.min.js'); assert.equal(parse('/a/b/{c,d}/').path.basename, ''); assert.equal(parse('/a/b/{c,d}/*.js').path.basename, '*.js'); assert.equal(parse('/a/b/{c,d}/*.min.js').path.basename, '*.min.js'); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.basename, ''); assert.equal(parse('[a-j]*[^c]').path.basename, '[a-j]*[^c]'); assert.equal(parse('[a-j]*[^c]bc').path.basename, '[a-j]*[^c]bc'); assert.equal(parse('a/**/b/*.{foo,bar}').path.basename, '*.{foo,bar}'); assert.equal(parse('a/b/*.{foo,bar}').path.basename, '*.{foo,bar}'); assert.equal(parse('a/b/.{c,.gitignore}').path.basename, '.{c,.gitignore}'); assert.equal(parse('a/b/.{c,/.gitignore}').path.basename, '.{c,/.gitignore}'); assert.equal(parse('a/b/.{foo,bar}').path.basename, '.{foo,bar}'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.basename, 'f.g'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.basename, 'abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.basename, '*.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.basename, 'abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore}').path.basename, '{c,.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').path.basename, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/d}/e/f.g').path.basename, 'f.g'); assert.equal(parse('a/b/{c,/gitignore}').path.basename, '{c,/gitignore}'); assert.equal(parse('a/b/{c,d}').path.basename, '{c,d}'); assert.equal(parse('a/b/{c,d}/').path.basename, ''); assert.equal(parse('a/b/{c,d}/*.js').path.basename, '*.js'); assert.equal(parse('a/b/{c,d}/*.min.js').path.basename, '*.min.js'); assert.equal(parse('a/b/{c,d}/e.f.g/').path.basename, ''); assert.equal(parse('a/b/{c,d}/e/f.g').path.basename, 'f.g'); }); it('should get a filename:', function () { assert.equal(parse('*.min.js').path.filename, '*'); assert.equal(parse('/a/b/c').path.filename, 'c'); assert.equal(parse('/a/b/c/').path.filename, ''); assert.equal(parse('/a/b/{c,d}/').path.filename, ''); assert.equal(parse('/a/b/{c,d}/*.js').path.filename, '*'); assert.equal(parse('/a/b/{c,d}/*.min.js').path.filename, '*'); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.filename, ''); assert.equal(parse('[a-c]b*').path.filename, '[a-c]b*'); assert.equal(parse('a').path.filename, 'a'); assert.equal(parse('a/**/b/*.{foo,bar}').path.filename, '*'); assert.equal(parse('a/b/*.{foo,bar}').path.filename, '*'); assert.equal(parse('a/b/.gitignore').path.filename, ''); assert.equal(parse('a/b/.{c,.gitignore}').path.filename, ''); assert.equal(parse('a/b/.{c,/.gitignore}').path.filename, ''); assert.equal(parse('a/b/.{foo,bar}').path.filename, ''); assert.equal(parse('a/b/c').path.filename, 'c'); assert.equal(parse('a/b/c.d/e.md').path.filename, 'e'); assert.equal(parse('a/b/c.md').path.filename, 'c'); assert.equal(parse('a/b/c.min.js').path.filename, 'c'); assert.equal(parse('a/b/c/').path.filename, ''); assert.equal(parse('a/b/c/d.e.f/g.min.js').path.filename, 'g'); assert.equal(parse('a/b/c/d.md').path.filename, 'd'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.filename, 'f'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.filename, 'abc'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.filename, '*'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.filename, 'abc'); assert.equal(parse('a/b/{c,.gitignore}').path.filename, '{c,.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').path.filename, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/d}/e/f.g').path.filename, 'f'); assert.equal(parse('a/b/{c,/gitignore}').path.filename, '{c,/gitignore}'); assert.equal(parse('a/b/{c,d}').path.filename, '{c,d}'); assert.equal(parse('a/b/{c,d}/').path.filename, ''); assert.equal(parse('a/b/{c,d}/*.js').path.filename, '*'); assert.equal(parse('a/b/{c,d}/*.min.js').path.filename, '*'); assert.equal(parse('a/b/{c,d}/e.f.g/').path.filename, ''); assert.equal(parse('a/b/{c,d}/e/f.g').path.filename, 'f'); assert.equal(parse('c.md').path.filename, 'c'); }); it('should get an extname:', function () { assert.equal(parse('*.min.js').path.extname, '.min.js'); assert.equal(parse('/a/b/c').path.extname, ''); assert.equal(parse('/a/b/c/').path.extname, ''); assert.equal(parse('/a/b/{c,d}/').path.extname, ''); assert.equal(parse('/a/b/{c,d}/*.js').path.extname, '.js'); assert.equal(parse('/a/b/{c,d}/*.min.js').path.extname, '.min.js'); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.extname, ''); assert.equal(parse('[a-c]b*').path.extname, ''); assert.equal(parse('[a-j]*[^c]bc').path.extname, ''); assert.equal(parse('a').path.extname, ''); assert.equal(parse('a/**/b/*.{foo,bar}').path.extname, '.{foo,bar}'); assert.equal(parse('a/b/*.{foo,bar}').path.extname, '.{foo,bar}'); assert.equal(parse('a/b/.gitignore').path.extname, '.gitignore'); assert.equal(parse('a/b/.{c,.gitignore}').path.extname, '.{c,.gitignore}'); assert.equal(parse('a/b/.{c,/.gitignore}').path.extname, '.{c,/.gitignore}'); assert.equal(parse('a/b/.{foo,bar}').path.extname, '.{foo,bar}'); assert.equal(parse('a/b/c').path.extname, ''); assert.equal(parse('a/b/c.d/e.md').path.extname, '.md'); assert.equal(parse('a/b/c.md').path.extname, '.md'); assert.equal(parse('a/b/c.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/c/').path.extname, ''); assert.equal(parse('a/b/c/d.e.f/g.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/c/d.md').path.extname, '.md'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.extname, '.g'); assert.equal(parse('a/b/{c,./d}/e/f.min.g').path.extname, '.min.g'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.extname, '.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.extname, '.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.extname, '.foo.js'); assert.equal(parse('a/b/{c,.gitignore}').path.extname, ''); assert.equal(parse('a/b/{c,/.gitignore}').path.extname, ''); assert.equal(parse('a/b/{c,/d}/e/f.g').path.extname, '.g'); assert.equal(parse('a/b/{c,/d}/e/f.min.g').path.extname, '.min.g'); assert.equal(parse('a/b/{c,/gitignore}').path.extname, ''); assert.equal(parse('a/b/{c,d}').path.extname, ''); assert.equal(parse('a/b/{c,d}/').path.extname, ''); assert.equal(parse('a/b/{c,d}/*.js').path.extname, '.js'); assert.equal(parse('a/b/{c,d}/*.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/{c,d}/e.f.g/').path.extname, ''); assert.equal(parse('a/b/{c,d}/e/f.g').path.extname, '.g'); assert.equal(parse('a/b/{c,d}/e/f.min.g').path.extname, '.min.g'); assert.equal(parse('c.md').path.extname, '.md'); }); it('should match a path with an extension:', function () { assert.equal(parse('a/b/c.md').glob, 'c.md'); assert.equal(parse('a/b/c.md').base, 'a/b'); assert.equal(parse('a/b/c.md').path.basename, 'c.md'); assert.equal(parse('a/b/c.md').path.filename, 'c'); assert.equal(parse('a/b/c.md').path.extname, '.md'); assert.equal(parse('a/b/c.md').path.ext, 'md'); assert.equal(parse('c.md').glob, 'c.md'); assert.equal(parse('c.md').base, '.'); assert.equal(parse('c.md').path.basename, 'c.md'); assert.equal(parse('c.md').path.filename, 'c'); assert.equal(parse('c.md').path.extname, '.md'); assert.equal(parse('c.md').path.ext, 'md'); }); it('should match a path with multiple extensions:', function () { assert.equal(parse('a/b/c.min.js').glob, 'c.min.js'); assert.equal(parse('a/b/c.min.js').base, 'a/b'); assert.equal(parse('a/b/c.min.js').path.basename, 'c.min.js'); assert.equal(parse('a/b/c.min.js').path.filename, 'c'); assert.equal(parse('a/b/c.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/c.min.js').path.ext, 'js'); }); it('should work with paths that have dots in the dirname:', function () { assert.equal(parse('a/b/c/d.e.f/g.min.js').glob, 'g.min.js'); assert.equal(parse('a/b/c/d.e.f/g.min.js').base, 'a/b/c/d.e.f'); assert.equal(parse('a/b/c/d.e.f/g.min.js').path.basename, 'g.min.js'); assert.equal(parse('a/b/c/d.e.f/g.min.js').path.filename, 'g'); assert.equal(parse('a/b/c/d.e.f/g.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/c/d.e.f/g.min.js').path.ext, 'js'); }); it('should match a path without an extension:', function () { assert.equal(parse('a').glob, 'a'); assert.equal(parse('a').base, '.'); assert.equal(parse('a').path.filename, 'a'); assert.equal(parse('a').path.basename, 'a'); assert.equal(parse('a').path.extname, ''); }); it('should match a file path ending with an extension:', function () { assert.equal(parse('a/b/c/d.md').glob, 'd.md'); assert.equal(parse('a/b/c/d.md').base, 'a/b/c'); assert.equal(parse('a/b/c/d.md').path.basename, 'd.md'); assert.equal(parse('a/b/c/d.md').path.filename, 'd'); assert.equal(parse('a/b/c/d.md').path.extname, '.md'); assert.equal(parse('a/b/c/d.md').path.ext, 'md'); assert.equal(parse('a/b/c.d/e.md').glob, 'e.md'); assert.equal(parse('a/b/c.d/e.md').base, 'a/b/c.d'); assert.equal(parse('a/b/c.d/e.md').path.basename, 'e.md'); assert.equal(parse('a/b/c.d/e.md').path.filename, 'e'); assert.equal(parse('a/b/c.d/e.md').path.extname, '.md'); assert.equal(parse('a/b/c.d/e.md').path.ext, 'md'); }); }); describe('glob characters:', function () { it('should match when the basename starts with a star:', function () { assert.equal(parse('a/b/*.{foo,bar}').glob, '*.{foo,bar}'); assert.equal(parse('a/b/*.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/*.{foo,bar}').path.basename, '*.{foo,bar}'); assert.equal(parse('a/b/*.{foo,bar}').path.filename, '*'); assert.equal(parse('a/b/*.{foo,bar}').path.extname, '.{foo,bar}'); assert.equal(parse('a/b/*.{foo,bar}').path.ext, '{foo,bar}'); }); it('should match with globstars:', function () { assert.equal(parse('a/**/b/*.{foo,bar}').glob, '**/b/*.{foo,bar}'); assert.equal(parse('a/**/b/*.{foo,bar}').base, 'a'); assert.equal(parse('a/**/b/*.{foo,bar}').path.basename, '*.{foo,bar}'); assert.equal(parse('a/**/b/*.{foo,bar}').path.filename, '*'); assert.equal(parse('a/**/b/*.{foo,bar}').path.extname, '.{foo,bar}'); assert.equal(parse('a/**/b/*.{foo,bar}').path.ext, '{foo,bar}'); }); it('should match complex patterns:', function () { assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').glob, '{c,.gitignore,{a,b}}/{a,b}/abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.basename, 'abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.filename, 'abc'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.extname, '.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/abc.foo.js').path.ext, 'js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').glob, '{c,.gitignore,{a,b}}/{a,b}/*.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.basename, '*.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.filename, '*'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.extname, '.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,b}}/{a,b}/*.foo.js').path.ext, 'js'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').glob, '{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.basename, 'abc.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.filename, 'abc'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.extname, '.foo.js'); assert.equal(parse('a/b/{c,.gitignore,{a,./b}}/{a,b}/abc.foo.js').path.ext, 'js'); }); }); describe('should parse a glob:', function () { it('ending with a brace pattern:', function () { assert.equal(parse('a/b/{c,d}').glob, '{c,d}'); assert.equal(parse('a/b/{c,d}').base, 'a/b'); assert.equal(parse('a/b/{c,d}').path.basename, '{c,d}'); assert.equal(parse('a/b/{c,d}').path.filename, '{c,d}'); assert.equal(parse('a/b/{c,d}').path.extname, ''); assert.equal(parse('a/b/{c,d}').path.ext, ''); }); it('with a brace pattern in the dirname:', function () { assert.equal(parse('a/b/{c,d}/*.js').orig, 'a/b/{c,d}/*.js'); assert.equal(parse('a/b/{c,d}/*.js').glob, '{c,d}/*.js'); assert.equal(parse('a/b/{c,d}/*.js').base, 'a/b'); assert.equal(parse('a/b/{c,d}/*.js').path.basename, '*.js'); assert.equal(parse('a/b/{c,d}/*.js').path.filename, '*'); assert.equal(parse('a/b/{c,d}/*.js').path.extname, '.js'); assert.equal(parse('a/b/{c,d}/*.js').path.ext, 'js'); assert.equal(parse('a/b/{c,d}/').orig, 'a/b/{c,d}/'); assert.equal(parse('a/b/{c,d}/').glob, '{c,d}/'); assert.equal(parse('a/b/{c,d}/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/').path.basename, ''); assert.equal(parse('a/b/{c,d}/').path.filename, ''); assert.equal(parse('a/b/{c,d}/').path.extname, ''); assert.equal(parse('a/b/{c,d}/').path.ext, ''); assert.equal(parse('a/b/{c,d}/e.f.g/').orig, 'a/b/{c,d}/e.f.g/'); assert.equal(parse('a/b/{c,d}/e.f.g/').glob, '{c,d}/e.f.g/'); assert.equal(parse('a/b/{c,d}/e.f.g/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e.f.g/').path.basename, ''); assert.equal(parse('a/b/{c,d}/e.f.g/').path.filename, ''); assert.equal(parse('a/b/{c,d}/e.f.g/').path.extname, ''); assert.equal(parse('a/b/{c,d}/e.f.g/').path.ext, ''); assert.equal(parse('/a/b/{c,d}/e.f.g/').orig, '/a/b/{c,d}/e.f.g/'); assert.equal(parse('/a/b/{c,d}/e.f.g/').glob, '{c,d}/e.f.g/'); assert.equal(parse('/a/b/{c,d}/e.f.g/').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.basename, ''); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.filename, ''); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.extname, ''); assert.equal(parse('/a/b/{c,d}/e.f.g/').path.ext, ''); assert.equal(parse('a/b/{c,d}/*.min.js').orig, 'a/b/{c,d}/*.min.js'); assert.equal(parse('a/b/{c,d}/*.min.js').glob, '{c,d}/*.min.js'); assert.equal(parse('a/b/{c,d}/*.min.js').base, 'a/b'); assert.equal(parse('a/b/{c,d}/*.min.js').path.basename, '*.min.js'); assert.equal(parse('a/b/{c,d}/*.min.js').path.filename, '*'); assert.equal(parse('a/b/{c,d}/*.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/{c,d}/*.min.js').path.ext, 'js'); assert.equal(parse('*.min.js').orig, '*.min.js'); assert.equal(parse('*.min.js').glob, '*.min.js'); assert.equal(parse('*.min.js').base, '.'); assert.equal(parse('*.min.js').path.basename, '*.min.js'); assert.equal(parse('*.min.js').path.filename, '*'); assert.equal(parse('*.min.js').path.extname, '.min.js'); assert.equal(parse('*.min.js').path.ext, 'js'); assert.equal(parse('a/b/{c,d}/*.min.js').path.extname, '.min.js'); assert.equal(parse('a/b/{c,d}/*.min.js').path.ext, 'js'); assert.equal(parse('[a-j]*[^c]').glob, '[a-j]*[^c]'); assert.equal(parse('[a-j]*[^c]').base, '.'); assert.equal(parse('[a-j]*[^c]').path.dirname, ''); assert.equal(parse('[a-j]*[^c]').path.basename, '[a-j]*[^c]'); assert.equal(parse('[a-j]*[^c]b/c').glob, '[a-j]*[^c]b/c'); assert.equal(parse('[a-j]*[^c]b/c').base, '.'); assert.equal(parse('[a-j]*[^c]bc').glob, '[a-j]*[^c]bc'); assert.equal(parse('[a-j]*[^c]bc').base, '.'); assert.equal(parse('[a-j]*[^c]bc').path.basename, '[a-j]*[^c]bc'); }); it('ending with a slash:', function () { assert.equal(parse('a/b/{c,d}/').orig, 'a/b/{c,d}/'); assert.equal(parse('a/b/{c,d}/').glob, '{c,d}/'); assert.equal(parse('a/b/{c,d}/').base, 'a/b'); assert.equal(parse('a/b/{c,d}/').path.basename, ''); assert.equal(parse('a/b/{c,d}/').path.filename, ''); assert.equal(parse('a/b/{c,d}/').path.extname, ''); }); it('beginning with a slash:', function () { assert.equal(parse('/a/b/{c,d}/').orig, '/a/b/{c,d}/'); assert.equal(parse('/a/b/{c,d}/').glob, '{c,d}/'); assert.equal(parse('/a/b/{c,d}/').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/').path.basename, ''); assert.equal(parse('/a/b/{c,d}/').path.filename, ''); assert.equal(parse('/a/b/{c,d}/').path.extname, ''); }); it('with a brace pattern in the dirname:', function () { assert.equal(parse('a/b/{c,d}/e/f.g').orig, 'a/b/{c,d}/e/f.g'); assert.equal(parse('a/b/{c,d}/e/f.g').glob, '{c,d}/e/f.g'); assert.equal(parse('a/b/{c,d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,d}/e/f.g').path.basename, 'f.g'); assert.equal(parse('a/b/{c,d}/e/f.g').path.filename, 'f'); assert.equal(parse('a/b/{c,d}/e/f.g').path.extname, '.g'); assert.equal(parse('a/b/{c,d}/e/f.min.g').path.extname, '.min.g'); assert.equal(parse('a/b/{c,d}/e/f.g').path.ext, 'g'); assert.equal(parse('a/b/{c,./d}/e/f.g').orig, 'a/b/{c,./d}/e/f.g'); assert.equal(parse('a/b/{c,./d}/e/f.g').glob, '{c,./d}/e/f.g'); assert.equal(parse('a/b/{c,./d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.basename, 'f.g'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.filename, 'f'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.extname, '.g'); assert.equal(parse('a/b/{c,./d}/e/f.min.g').path.extname, '.min.g'); assert.equal(parse('a/b/{c,./d}/e/f.g').path.ext, 'g'); assert.equal(parse('a/b/{c,/d}/e/f.g').orig, 'a/b/{c,/d}/e/f.g'); assert.equal(parse('a/b/{c,/d}/e/f.g').glob, '{c,/d}/e/f.g'); assert.equal(parse('a/b/{c,/d}/e/f.g').base, 'a/b'); assert.equal(parse('a/b/{c,/d}/e/f.g').path.basename, 'f.g'); assert.equal(parse('a/b/{c,/d}/e/f.g').path.filename, 'f'); assert.equal(parse('a/b/{c,/d}/e/f.g').path.extname, '.g'); assert.equal(parse('a/b/{c,/d}/e/f.min.g').path.extname, '.min.g'); assert.equal(parse('a/b/{c,/d}/e/f.g').path.ext, 'g'); }); }); describe('when the glob pattern has braces:', function () { it('should track the original pattern', function () { assert.equal(parse('/a/b/{c,d}/*.js').orig, '/a/b/{c,d}/*.js'); assert.equal(parse('/a/b/{c,d}/*.js').orig, '/a/b/{c,d}/*.js'); }); it('should extract the dirname', function () { assert.equal(parse('/a/b/{c,d}/*.js').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/*.min.js').base, '/a/b'); assert.equal(parse('/a/b/{c,d}/*.min.js').glob, '{c,d}/*.min.js'); }); it('should extract the basename', function () { assert.equal(parse('/a/b/{c,d}/*.js').path.basename, '*.js'); assert.equal(parse('/a/b/{c,d}/*.min.js').path.basename, '*.min.js'); }); it('should extract the filename', function () { assert.equal(parse('/a/b/{c,d}/*.js').path.filename, '*'); assert.equal(parse('/a/b/{c,d}/*.min.js').path.filename, '*'); }); it('should extract extname', function () { assert.equal(parse('/a/b/{c,d}/*.js').path.extname, '.js'); assert.equal(parse('/a/b/{c,d}/*.min.js').path.extname, '.min.js'); }); it('should extract ext', function () { assert.equal(parse('/a/b/{c,d}/*.js').path.ext, 'js'); assert.equal(parse('/a/b/{c,d}/*.js').path.ext, 'js'); }); }); describe('trailing and leading slashs:', function () { it('should work without a trailing slash:', function () { assert.equal(parse('a/b/c').glob, 'c'); assert.equal(parse('a/b/c').base, 'a/b'); assert.equal(parse('a/b/c').path.filename, 'c'); assert.equal(parse('a/b/c').path.basename, 'c'); assert.equal(parse('a/b/c').path.extname, ''); }); it('should work with a trailing slash:', function () { assert.equal(parse('a/b/c/').glob, ''); assert.equal(parse('a/b/c/').base, 'a/b/c/'); assert.equal(parse('a/b/c/').path.filename, ''); assert.equal(parse('a/b/c/').path.basename, ''); assert.equal(parse('a/b/c/').path.extname, ''); }); it('should work with a leading slash:', function () { assert.equal(parse('/a/b/c').glob, 'c'); assert.equal(parse('/a/b/c').base, '/a/b'); assert.equal(parse('/a/b/c').path.filename, 'c'); assert.equal(parse('/a/b/c').path.basename, 'c'); assert.equal(parse('/a/b/c').path.extname, ''); }); it('should work with both trailing and leading slashes:', function () { assert.equal(parse('/a/b/c/').glob, ''); assert.equal(parse('/a/b/c/').base, '/a/b/c/'); assert.equal(parse('/a/b/c/').path.filename, ''); assert.equal(parse('/a/b/c/').path.basename, ''); assert.equal(parse('/a/b/c/').path.extname, ''); }); }); describe('dotfile and dotdir:', function () { describe('dotfiles:', function () { it('should know when the file is a dotfile:', function () { assert.equal(parse('a/b/.gitignore').is.dotfile, true); assert.equal(parse('a/b/.gitignore').is.dotfile, true); assert.equal(parse('a/b/.git').is.dotfile, true); assert.equal(parse('a/b/.gitignore').is.dotdir, false); assert.equal(parse('a/b/.git').is.dotdir, false); }); it('should work brace patterns:', function () { assert.equal(parse('a/b/.{foo,bar}').orig, 'a/b/.{foo,bar}'); assert.equal(parse('a/b/.{foo,bar}').glob, '.{foo,bar}'); assert.equal(parse('a/b/.{foo,bar}').base, 'a/b'); assert.equal(parse('a/b/.{c,/.gitignore}').orig, 'a/b/.{c,/.gitignore}'); assert.equal(parse('a/b/.{c,/.gitignore}').glob, '.{c,/.gitignore}'); assert.equal(parse('a/b/.{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/.{c,.gitignore}').orig, 'a/b/.{c,.gitignore}'); assert.equal(parse('a/b/.{c,.gitignore}').glob, '.{c,.gitignore}'); assert.equal(parse('a/b/.{c,.gitignore}').base, 'a/b'); }); }); describe('dotdirs:', function () { it('should know when the file is a dot-directory:', function () { assert.equal(parse('a/b/.git/config').is.dotdir, true); assert.equal(parse('a/b/.git/').is.dotdir, true); assert.equal(parse('a/b/git/').is.dotdir, false); assert.equal(parse('a/b/.git/').is.dotfile, false); }); it('should work with braces in the dirname:', function () { // assert.equal(parse('a/b/.{foo,bar}/foo.js').is.dotdir, true); assert.equal(parse('a/b/.{foo,bar}/foo.js').orig, 'a/b/.{foo,bar}/foo.js'); assert.equal(parse('a/b/.{foo,bar}/foo.js').glob, '.{foo,bar}/foo.js'); assert.equal(parse('a/b/.{foo,bar}/foo.js').base, 'a/b'); }); }); }); it('should match character classes:', function () { assert.equal(parse('[a-c]b*').glob, '[a-c]b*'); assert.equal(parse('[a-j]*[^c]').glob, '[a-j]*[^c]'); assert.equal(parse('[a-j]*[^c]').base, '.'); assert.equal(parse('[a-j]*[^c]b/c').glob, '[a-j]*[^c]b/c'); assert.equal(parse('[a-j]*[^c]bc').glob, '[a-j]*[^c]bc'); }); it('should work when a character class has trailing word characters:', function () { assert.equal(parse('[a-c]b*').glob, '[a-c]b*'); assert.equal(parse('[a-c]b*').base, '.'); assert.equal(parse('[a-j]*[^c]bc').base, '.'); }); }); describe('when the glob has brace patterns:', function () { it('should extract the `base` from the glob:', function () { assert.equal(parse('a/b/{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/.gitignore}').glob, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').orig, 'a/b/{c,/.gitignore}'); assert.equal(parse('a/b/{c,/gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/gitignore}').glob, '{c,/gitignore}'); assert.equal(parse('a/b/{c,.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore}').glob, '{c,.gitignore}'); }); it('should work when the brace pattern has dots and slashes:', function () { assert.equal(parse('a/b/{c,/.gitignore}').orig, 'a/b/{c,/.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').glob, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/.gitignore}').path.basename, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').path.filename, '{c,/.gitignore}'); assert.equal(parse('a/b/{c,/.gitignore}').path.extname, ''); assert.equal(parse('a/b/{c,/gitignore}').orig, 'a/b/{c,/gitignore}'); assert.equal(parse('a/b/{c,/gitignore}').glob, '{c,/gitignore}'); assert.equal(parse('a/b/{c,/gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,/gitignore}').path.basename, '{c,/gitignore}'); assert.equal(parse('a/b/{c,/gitignore}').path.filename, '{c,/gitignore}'); assert.equal(parse('a/b/{c,/gitignore}').path.extname, ''); assert.equal(parse('a/b/{c,.gitignore}').orig, 'a/b/{c,.gitignore}'); assert.equal(parse('a/b/{c,.gitignore}').glob, '{c,.gitignore}'); assert.equal(parse('a/b/{c,.gitignore}').base, 'a/b'); assert.equal(parse('a/b/{c,.gitignore}').path.basename, '{c,.gitignore}'); assert.equal(parse('a/b/{c,.gitignore}').path.filename, '{c,.gitignore}'); assert.equal(parse('a/b/{c,.gitignore}').path.extname, ''); parse('a/b/c/**/*.{yml,json}') }); });