From 57e01933b0c7db9d029bdeba8f66cffea440e120 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Mon, 8 Apr 2019 03:57:12 +0300 Subject: [PATCH] Bring back arg passing. --- README.md | 10 +++++----- index.js | 46 ++++++++++++++++++++++++---------------------- test.js | 38 +++++++++++++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index db3a72d..7ada7e0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,10 @@ npm install anymatchx String to be directly matched, string with glob patterns, regular expression test, function that takes the testString as an argument and returns a truthy value if it should be matched, or an array of any number and mix of these types. -* __testString__: (_String) The string to test against the matchers. +* __testString__: (_String|Array_) The string to test against the matchers. If +passed as an array, the first element of the array will be used as the +`testString` for non-function matchers, while the entire array will be applied +as the arguments for function matchers. * __returnIndex__: (_Boolean [optional]_) If true, return the array index of the first matcher that that testString matched, or -1 if no match, instead of a boolean result. @@ -44,9 +47,6 @@ anymatch(matchers, 'bar.js'); // false anymatch(matchers, 'foo.js', true); // 2 anymatch(matchers, 'path/anyjs/foo.js', true); // 1 -// skip matchers -anymatch(matchers, 'path/to/file.js', false, 1); // false - // using globs to match directories and their children anymatch('node_modules', 'node_modules'); // true anymatch('node_modules', 'node_modules/somelib/index.js'); // false @@ -73,7 +73,7 @@ Change Log ---------- [See release notes page on GitHub](https://github.com/micromatch/anymatch/releases) -- **v3.0:**: `testString` can no longer be an Array. Removed `startIndex` and `endIndex` arguments. +- **v3.0:**: Removed `startIndex` and `endIndex` arguments. - **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information). - **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch) for glob pattern matching. Issues with glob pattern matching should be diff --git a/index.js b/index.js index ed5e448..b5bf3f4 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,6 @@ const picomatch = require('picomatch'); const normalizePath = require('normalize-path'); -const {sep} = require('path'); // required for tests. /** * @typedef {(string:String) => boolean} AnymatchFn @@ -14,36 +13,33 @@ const BANG = '!'; const arrify = (item) => Array.isArray(item) ? item : [item]; /** - * * @param {AnymatchPattern} matcher - * @returns {AnymatchFn} + * @returns {Function} */ const createPattern = (matcher) => { + if (typeof matcher === 'function') { + return matcher; + } const isString = typeof matcher === 'string'; - let glob; - if (isString) glob = picomatch(matcher); - return (string) => { - if (typeof matcher === 'function') { - return matcher(string); - } - if (isString) { - return matcher === string || glob(string); - } - if (matcher instanceof RegExp) { - return matcher.test(string); - } - return false; + if (typeof matcher === 'string') { + const glob = picomatch(matcher); + return (string) => matcher === string || glob(string); } + if (matcher instanceof RegExp) { + return (string) => matcher.test(string); + } + return (string) => false; }; /** * @param {Array} patterns * @param {Array} negatedGlobs - * @param {String} path + * @param {String|Array} path * @param {Boolean} returnIndex */ const matchPatterns = (patterns, negatedGlobs, path, returnIndex) => { - const upath = normalizePath(path); + const additionalArgs = Array.isArray(path); + const upath = normalizePath(additionalArgs ? path[0] : path); if (negatedGlobs.length > 0) { for (let index = 0; index < negatedGlobs.length; index++) { const nglob = negatedGlobs[index]; @@ -54,8 +50,14 @@ const matchPatterns = (patterns, negatedGlobs, path, returnIndex) => { } for (let index = 0; index < patterns.length; index++) { const pattern = patterns[index]; - if (pattern(upath)) { - return returnIndex ? index : true; + if (additionalArgs) { + if (pattern(...path)) { + return returnIndex ? index : true; + } + } else { + if (pattern(upath)) { + return returnIndex ? index : true; + } } } @@ -64,7 +66,7 @@ const matchPatterns = (patterns, negatedGlobs, path, returnIndex) => { /** * @param {AnymatchMatcher} matchers - * @param {String} testString + * @param {String|Array} testString * @param {Boolean=} returnIndex * @returns {boolean|Number|Function} */ @@ -86,7 +88,7 @@ const anymatch = (matchers, testString, returnIndex = false) => { return matchPatterns(patterns, negatedGlobs, testString, returnIndex); } } - if (typeof testString !== 'string') { + if (!Array.isArray(testString) && typeof testString !== 'string') { throw new TypeError('anymatch: second argument must be a string: got ' + Object.prototype.toString.call(testString)) } diff --git a/test.js b/test.js index 09814e0..6a9f479 100644 --- a/test.js +++ b/test.js @@ -1,8 +1,8 @@ 'use strict'; -var anymatch = require('./'); -var assert = require('assert'); -var path = require('path'); +let anymatch = require('./'); +let assert = require('assert'); +let path = require('path'); describe('anymatch', () => { var matchers = [ @@ -96,8 +96,36 @@ describe('anymatch', () => { it('should not allow no args', () => { assert.throws(() => anymatch()); }) - it('should not allow string to be passed as first member of an array', () => { - assert.throws(() => anymatch(matchers, ['path/to/bar.js'])); + it('should not allow bad testString', () => { + assert.throws(() => anymatch(matchers, {path: 'path/to/bar.js'})); + }); + it('should allow string to be passed as first member of an array', () => { + assert.doesNotThrow(() => anymatch(matchers, ['path/to/bar.js'])); + }); + + it('should pass extra args to function matchers', () => { + matchers.push((string, arg1, arg2) => arg1 || arg2); + assert(!anymatch(matchers, 'bar.js'), 1); + assert(!anymatch(matchers, ['bar.js', 0]), 2); + assert(anymatch(matchers, ['bar.js', true]), 3); + assert(anymatch(matchers, ['bar.js', 0, true]), 4); + // with returnIndex + assert.equal(anymatch(matchers, ['bar.js', 1], true), 4, 5); + // curried versions + var matchFn1 = anymatch(matchers); + var matchFn2 = anymatch(matchers[4]); + assert(!matchFn1(['bar.js', 0]), 6); + assert(!matchFn2(['bar.js', 0]), 7); + assert(matchFn1(['bar.js', true]), 8); + assert(matchFn2(['bar.js', true]), 9); + assert(matchFn1(['bar.js', 0, true]), 10); + assert(matchFn2(['bar.js', 0, true]), 11); + // curried with returnIndex + assert.equal(matchFn1(['bar.js', 1], true), 4, 12); + assert.equal(matchFn2(['bar.js', 1], true), 0, 13); + assert.equal(matchFn1(['bar.js', 0], true), -1, 14); + assert.equal(matchFn2(['bar.js', 0], true), -1, 15); + matchers.pop(); }); });