Skip to content

Commit

Permalink
add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jonschlinkert committed Apr 3, 2019
1 parent 60eb988 commit 4ed704b
Show file tree
Hide file tree
Showing 18 changed files with 1,207 additions and 257 deletions.
25 changes: 0 additions & 25 deletions appveyor.yml

This file was deleted.

20 changes: 10 additions & 10 deletions bench/index.js
Expand Up @@ -51,21 +51,21 @@ bench.skip = name => {
};

bench('expand - set')
.add(' braces', () => braces.expand('foo/{a,b,c}/bar'))
.add(' braces', () => braces.compile('foo/{a,b,c}/bar'))
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,c}/bar'))
.run();

bench('expand - nested sets')
.add(' braces', () => braces.expand('foo/{a,b,{x,y,z}}/bar'))
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,{x,y,z}}/bar'))
.run();

bench('expand - range')
.add(' braces', () => braces.expand('foo/{a..z}/bar'))
.add(' braces', () => braces.compile('foo/{a..z}/bar'))
.add('minimatch', () => minimatch.braceExpand('foo/{a..z}/bar'))
.run();

bench('compile regex - set')
.add(' braces', () => braces.makeRe(parse('foo/{a,b,c}/bar')))
.add('minimatch', () => minimatch.makeRe('foo/{a,b,c}/bar'))
bench('expand - nested sets')
.add(' braces', () => braces.compile('foo/{a,b,{x,y,z}}/bar'))
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,{x,y,z}}/bar'))
.run();

bench('expand - nested ranges')
.add(' braces', () => braces.compile('foo/{a,b,{1..25}}/bar'))
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,{1..25}}/bar'))
.run();
43 changes: 11 additions & 32 deletions index.js
@@ -1,11 +1,9 @@
'use strict';

const { MAX_LENGTH } = require('./lib/constants');
const stringify = require('./lib/stringify');
const compile = require('./lib/compile');
const expand = require('./lib/expand');
const parse = require('./lib/parse');
const toRegex = require('to-regex');

/**
* Expand the given pattern or create a regex-compatible string.
Expand Down Expand Up @@ -53,19 +51,7 @@ const braces = (input, options = {}) => {
* @api public
*/

braces.parse = (input, options = {}) => {
if (typeof input !== 'string') {
throw new TypeError('Expected a string');
}

let opts = options || {};
let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
if (input.length > max) {
throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
}

return parse(input, options);
};
braces.parse = (input, options = {}) => parse(input, options);

/**
* Creates a braces string from an AST, or an AST node.
Expand Down Expand Up @@ -129,9 +115,16 @@ braces.compile = (input, options = {}) => {

braces.expand = (input, options = {}) => {
if (typeof input === 'string') {
return expand(braces.parse(input, options), options);
input = braces.parse(input, options);
}

let result = expand(input, options);

// filter out duplicates if specified
if (options.nodupes === true) {
result = [...new Set(result)];
}
return expand(input, options);
return result;
};

/**
Expand Down Expand Up @@ -173,21 +166,7 @@ braces.create = (input, options = {}) => {
};

/**
* Create a regular expression from the given string `pattern`.
*
* ```js
* const braces = require('braces');
* console.log(braces.makeRe('foo/id-{200..300}'));
* //=> /^(?:foo/id-(20[0-9]|2[1-9][0-9]|300))$/
* ```
* @param {String} `pattern` The pattern to convert to regex.
* @param {Object} `options`
* @return {RegExp}
* @api public
* Expose "braces"
*/

braces.makeRe = (pattern, options) => {
return toRegex(braces.compile(pattern, options), { strictErrors: false, ...options });
};

module.exports = braces;
5 changes: 1 addition & 4 deletions lib/compile.js
Expand Up @@ -37,6 +37,7 @@ const compile = (ast, options = {}) => {
if (node.nodes && node.ranges > 0) {
let args = utils.reduce(node.nodes);
let range = fill(...args, { ...options, wrap: false, toRegex: true });

if (range.length !== 0) {
return args.length > 1 && range.length > 1 ? `(${range})` : range;
}
Expand All @@ -54,7 +55,3 @@ const compile = (ast, options = {}) => {
};

module.exports = compile;

const parse = require('./parse');
console.log(compile(parse('{a,,,,}'), { escapeInvalid: true }));
console.log('(a|)');
58 changes: 46 additions & 12 deletions lib/expand.js
@@ -1,5 +1,6 @@
'use strict';

const fill = require('fill-range');
const stringify = require('./stringify');
const utils = require('./utils');

Expand Down Expand Up @@ -30,38 +31,71 @@ const append = (queue = '', stash = '', enclose = false) => {
};

const expand = (ast, options = {}) => {
let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;

let walk = (node, parent = {}) => {
node.queue = [];

let p = parent;
let q = parent.queue;

while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
p = p.parent;
q = p.queue;
}

if (node.invalid || node.dollar) {
parent.queue.push(append(parent.queue.pop(), stringify(node, options)));
q.push(append(q.pop(), stringify(node, options)));
return;
}

if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
parent.queue.push(append(parent.queue.pop(), ['{}']));
q.push(append(q.pop(), ['{}']));
return;
}

if (node.nodes && node.ranges > 0) {
let args = utils.reduce(node.nodes);

if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
}

let range = fill(...args, options);
if (range.length === 0) {
range = stringify(node, options);
}

q.push(append(q.pop(), range));
node.nodes = [];
return;
}

let enclose = utils.encloseBrace(node);
let queue = node.queue;
let block = node;

while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
block = block.parent;
queue = block.queue;
}

for (let i = 0; i < node.nodes.length; i++) {
let child = node.nodes[i];

if (child.type === 'comma') {
node.queue.push('');
if (i === 1) {
node.queue.push('');
}
if (child.type === 'comma' && node.type === 'brace') {
if (i === 1) queue.push('');
queue.push('');
continue;
}

if (child.type === 'text') {
node.queue.push(append(node.queue.pop(), child.value));
if (child.type === 'close') {
q.push(append(q.pop(), queue, enclose));
continue;
}

if (child.type === 'close') {
parent.queue.push(append(parent.queue.pop(), node.queue, enclose));
if (child.value && child.type !== 'open') {
queue.push(append(queue.pop(), child.value));
continue;
}

Expand All @@ -70,7 +104,7 @@ const expand = (ast, options = {}) => {
}
}

return node.queue;
return queue;
};

return utils.flatten(walk(ast));
Expand Down

0 comments on commit 4ed704b

Please sign in to comment.