diff -Nru node-to-regex-range-3.0.0/bower.json node-to-regex-range-5.0.1/bower.json --- node-to-regex-range-3.0.0/bower.json 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/bower.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -{ - "name": "to-regex-range", - "description": "Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions.", - "repository": "micromatch/to-regex-range", - "license": "MIT", - "homepage": "https://github.com/micromatch/to-regex-range", - "authors": [ - "Jon Schlinkert (https://github.com/jonschlinkert)" - ], - "main": [ - "index.js" - ], - "dependencies": { - "is-number": "^4.0.0", - "repeat-string": "^1.6.1" - }, - "devDependencies": { - "fill-range": "^4.0.0", - "gulp-format-md": "^0.1.12", - "mocha": "^3.2.0", - "text-table": "^0.2.0", - "time-diff": "^0.3.1" - }, - "keywords": [ - "alpha", - "alphabetical", - "bash", - "brace", - "date", - "expand", - "expansion", - "glob", - "match", - "matches", - "matching", - "number", - "numerical", - "range", - "ranges", - "regex", - "sequence", - "sh", - "to", - "year" - ], - "version": "2.1.1", - "bugs": { - "url": "https://github.com/micromatch/to-regex-range/issues" - }, - "files": [ - "index.js" - ], - "ignore": [ - "actual", - "bower_components", - "fixtures", - "node_modules", - "temp", - "test", - "test.js", - "tmp" - ] -} \ No newline at end of file diff -Nru node-to-regex-range-3.0.0/debian/changelog node-to-regex-range-5.0.1/debian/changelog --- node-to-regex-range-3.0.0/debian/changelog 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/changelog 2019-09-02 04:39:38.000000000 +0000 @@ -1,3 +1,26 @@ +node-to-regex-range (5.0.1-2) unstable; urgency=medium + + * Team upload + * Back to unstable after successful tests + * Switch install to pkg-js-tools + * Bump debhelper compatibility level to 12 + * Declare compliance with policy 4.4.0 + + -- Xavier Guimard Mon, 02 Sep 2019 06:39:38 +0200 + +node-to-regex-range (5.0.1-1) experimental; urgency=medium + + * Team upload + * Bump debhelper compatibility level to 11 + * Declare compliance with policy 4.3.0 + * Add debian/gbp.conf + * New upstream version 5.0.1 + * Update debian/copyright + * Update VCS fields to salsa + * Add upstream/metadata + + -- Xavier Guimard Wed, 05 Jun 2019 21:30:25 +0200 + node-to-regex-range (3.0.0-1) unstable; urgency=medium * Team upload diff -Nru node-to-regex-range-3.0.0/debian/compat node-to-regex-range-5.0.1/debian/compat --- node-to-regex-range-3.0.0/debian/compat 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru node-to-regex-range-3.0.0/debian/control node-to-regex-range-5.0.1/debian/control --- node-to-regex-range-3.0.0/debian/control 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/control 2019-09-02 04:39:38.000000000 +0000 @@ -1,23 +1,25 @@ Source: node-to-regex-range -Section: javascript -Priority: optional Maintainer: Debian Javascript Maintainers Uploaders: Pirate Praveen -Build-Depends: debhelper (>= 10), +Section: javascript +Priority: optional +Testsuite: autopkgtest-pkg-nodejs +Build-Depends: debhelper-compat (= 12), mocha, node-fill-range, - node-is-number (>= 2.1.0~), - node-repeat-string (>= 1.5.4~), - nodejs -Standards-Version: 4.1.1 + node-is-number, + node-repeat-string, + nodejs, + pkg-js-tools (>= 0.9.8~) +Standards-Version: 4.4.0 +Vcs-Browser: https://salsa.debian.org/js-team/node-to-regex-range +Vcs-Git: https://salsa.debian.org/js-team/node-to-regex-range.git Homepage: https://github.com/jonschlinkert/to-regex-range -Vcs-Git: https://anonscm.debian.org/git/pkg-javascript/node-to-regex-range.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-javascript/node-to-regex-range.git Package: node-to-regex-range Architecture: all -Depends: node-is-number (>= 2.1.0~), - node-repeat-string (>= 1.5.4~), +Depends: node-is-number, + node-repeat-string, nodejs, ${misc:Depends} Description: returns a regex-compatible range from two numbers, min and max diff -Nru node-to-regex-range-3.0.0/debian/copyright node-to-regex-range-5.0.1/debian/copyright --- node-to-regex-range-3.0.0/debian/copyright 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/copyright 2019-09-02 04:37:39.000000000 +0000 @@ -4,11 +4,12 @@ Source: https://github.com/jonschlinkert/to-regex-range Files: * -Copyright: 2016 Jon Schlinkert (https://github.com/jonschlinkert) +Copyright: 2015-present, Jon Schlinkert (https://github.com/jonschlinkert) License: Expat Files: debian/* -Copyright: 2016 Pirate Praveen +Copyright: 2016, Pirate Praveen + 2019, Xavier Guimard License: Expat License: Expat diff -Nru node-to-regex-range-3.0.0/debian/gbp.conf node-to-regex-range-5.0.1/debian/gbp.conf --- node-to-regex-range-3.0.0/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/gbp.conf 2019-09-02 04:37:39.000000000 +0000 @@ -0,0 +1,5 @@ +[DEFAULT] +pristine-tar = True + +[import-orig] +filter = [ '.gitignore', '.travis.yml', '.git*' ] diff -Nru node-to-regex-range-3.0.0/debian/install node-to-regex-range-5.0.1/debian/install --- node-to-regex-range-3.0.0/debian/install 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -package.json usr/lib/nodejs/to-regex-range/ -index.js usr/lib/nodejs/to-regex-range/ diff -Nru node-to-regex-range-3.0.0/debian/rules node-to-regex-range-5.0.1/debian/rules --- node-to-regex-range-3.0.0/debian/rules 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/rules 2019-09-02 04:37:39.000000000 +0000 @@ -1,7 +1,4 @@ #!/usr/bin/make -f %: - dh $@ - -override_dh_auto_test: - mocha + dh $@ --with nodejs diff -Nru node-to-regex-range-3.0.0/debian/tests/control node-to-regex-range-5.0.1/debian/tests/control --- node-to-regex-range-3.0.0/debian/tests/control 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -Tests: require -Depends: @ - -Tests: upstreamtestsuite -Depends: @, node-fill-range, node-mocha diff -Nru node-to-regex-range-3.0.0/debian/tests/pkg-js/test node-to-regex-range-5.0.1/debian/tests/pkg-js/test --- node-to-regex-range-3.0.0/debian/tests/pkg-js/test 1970-01-01 00:00:00.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/tests/pkg-js/test 2019-09-02 04:37:39.000000000 +0000 @@ -0,0 +1 @@ +mocha diff -Nru node-to-regex-range-3.0.0/debian/tests/require node-to-regex-range-5.0.1/debian/tests/require --- node-to-regex-range-3.0.0/debian/tests/require 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/tests/require 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#!/bin/sh -set -e -nodejs -e "require('to-regex-range');" diff -Nru node-to-regex-range-3.0.0/debian/tests/upstreamtestsuite node-to-regex-range-5.0.1/debian/tests/upstreamtestsuite --- node-to-regex-range-3.0.0/debian/tests/upstreamtestsuite 2017-11-25 16:31:18.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/tests/upstreamtestsuite 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -#!/bin/sh -set -e -cp test/test.js test.js -sed -i test.js -e "s|require('..')|require('to-regex-range')|g" -mocha test.js diff -Nru node-to-regex-range-3.0.0/debian/upstream/metadata node-to-regex-range-5.0.1/debian/upstream/metadata --- node-to-regex-range-3.0.0/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ node-to-regex-range-5.0.1/debian/upstream/metadata 2019-09-02 04:37:39.000000000 +0000 @@ -0,0 +1,7 @@ +--- +Archive: GitHub +Bug-Database: https://github.com/jonschlinkert/to-regex-range/issues +Contact: https://github.com/jonschlinkert/to-regex-range/issues +Name: to-regex-range +Repository: https://github.com/jonschlinkert/to-regex-range.git +Repository-Browse: https://github.com/jonschlinkert/to-regex-range diff -Nru node-to-regex-range-3.0.0/.eslintrc.json node-to-regex-range-5.0.1/.eslintrc.json --- node-to-regex-range-3.0.0/.eslintrc.json 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/.eslintrc.json 2019-04-07 06:04:46.000000000 +0000 @@ -1,4 +1,8 @@ { + "extends": [ + "eslint:recommended" + ], + "env": { "browser": false, "es6": true, @@ -6,6 +10,15 @@ "mocha": true }, + "parserOptions":{ + "ecmaVersion": 9, + "sourceType": "module", + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true + } + }, + "globals": { "document": false, "navigator": false, diff -Nru node-to-regex-range-3.0.0/examples.js node-to-regex-range-5.0.1/examples.js --- node-to-regex-range-3.0.0/examples.js 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/examples.js 2019-04-07 06:04:46.000000000 +0000 @@ -1,51 +1,53 @@ 'use strict'; -var toRegexRange = require('./'); -var table = require('text-table'); -var Time = require('time-diff'); -var time = new Time(); +const toRegexRange = require('./'); +const table = require('text-table'); +const Time = require('time-diff'); +const time = new Time(); /** * $ node examples.js */ -function toRange(min, max) { - var key = 'to-range' + min + max; +const toRange = (min, max) => { + let key = 'to-range' + min + max; time.start(key); - var str = toRegexRange(min, max); + return [ '', - '`toRegexRange(\'' + min + ', ' + max + '\')`', - '`' + str.split('|').join('\\|') + '`', - '_' + time.end(key) + '_', + `\`toRegexRange(${min}, ${max})\``, + `\`${toRegexRange(min, max, { wrap: false }).split('|').join('\\|')}\``, + `_${time.end(key)}_`, '' ]; -} +}; toRange('1', '3'); -var rows = [ +let rows = [ ['', '**Range**', '**Result**', '**Compile time**', ''], ['', '--- ', '--- ', '---', ''], ]; -var examples = [ - // ['0001', '5555'], - // ['1', '5555'], - // ['1', '555'], - // ['1', '55'], - // ['1', '50'], - - ['5', '5'], - ['5', '6'], - ['29', '51'], - ['31', '877'], - ['111', '555'], +let examples = [ ['-10', '10'], ['-100', '-10'], ['-100', '100'], + ['001', '100'], + ['001', '555'], ['0010', '1000'], + + ['1', '50'], + ['1', '55'], + ['1', '555'], + ['1', '5555'], + ['111', '555'], + ['29', '51'], + ['31', '877'], + + ['5', '5'], + ['5', '6'], ['1', '2'], ['1', '5'], ['1', '10'], @@ -55,11 +57,11 @@ ['1', '100000'], ['1', '1000000'], ['1', '10000000'], -].forEach(function(args) { +].forEach(args => { rows.push(toRange.apply(null, args)); }); -var text = table(rows, {hsep: ' | '}); +let text = table(rows, { hsep: ' | ' }); console.log(text); /** @@ -67,8 +69,7 @@ * by verb and used in the .verb.md readme template */ -module.exports = function() { - return text.split('\n').map(function(line) { - return line.replace(/^ +/, ''); - }).join('\n'); +module.exports = () => { + return text.split('\n').map(line => line.replace(/^ +/, '')).join('\n'); }; + diff -Nru node-to-regex-range-3.0.0/.gitignore node-to-regex-range-5.0.1/.gitignore --- node-to-regex-range-3.0.0/.gitignore 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/.gitignore 2019-04-07 06:04:46.000000000 +0000 @@ -1,6 +1,7 @@ # always ignore files *.DS_Store .idea +.vscode *.sublime-* # test related, or directories generated by tests diff -Nru node-to-regex-range-3.0.0/index.js node-to-regex-range-5.0.1/index.js --- node-to-regex-range-3.0.0/index.js 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/index.js 2019-04-07 06:04:46.000000000 +0000 @@ -1,113 +1,120 @@ /*! * to-regex-range * - * Copyright (c) 2015-2017, Jon Schlinkert. + * Copyright (c) 2015-present, Jon Schlinkert. * Released under the MIT License. */ 'use strict'; -var repeat = require('repeat-string'); -var isNumber = require('is-number'); -var cache = {}; +const isNumber = require('is-number'); -function toRegexRange(min, max, options) { +const toRegexRange = (min, max, options) => { if (isNumber(min) === false) { - throw new RangeError('toRegexRange: first argument is invalid.'); + throw new TypeError('toRegexRange: expected the first argument to be a number'); } - if (typeof max === 'undefined' || min === max) { + if (max === void 0 || min === max) { return String(min); } if (isNumber(max) === false) { - throw new RangeError('toRegexRange: second argument is invalid.'); + throw new TypeError('toRegexRange: expected the second argument to be a number.'); } - options = options || {}; - var relax = String(options.relaxZeros); - var shorthand = String(options.shorthand); - var capture = String(options.capture); - var key = min + ':' + max + '=' + relax + shorthand + capture; - if (cache.hasOwnProperty(key)) { - return cache[key].result; + let opts = { relaxZeros: true, ...options }; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; } - var a = Math.min(min, max); - var b = Math.max(min, max); + let relax = String(opts.relaxZeros); + let shorthand = String(opts.shorthand); + let capture = String(opts.capture); + let wrap = String(opts.wrap); + let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; + + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; + } + + let a = Math.min(min, max); + let b = Math.max(min, max); if (Math.abs(a - b) === 1) { - var result = min + '|' + max; - if (options.capture) { - return '(' + result + ')'; + let result = min + '|' + max; + if (opts.capture) { + return `(${result})`; } - return result; + if (opts.wrap === false) { + return result; + } + return `(?:${result})`; } - var isPadded = padding(min) || padding(max); - var positives = []; - var negatives = []; + let isPadded = hasPadding(min) || hasPadding(max); + let state = { min, max, a, b }; + let positives = []; + let negatives = []; - var tok = {min: min, max: max, a: a, b: b}; if (isPadded) { - tok.isPadded = isPadded; - tok.maxLen = String(tok.max).length; + state.isPadded = isPadded; + state.maxLen = String(state.max).length; } if (a < 0) { - var newMin = b < 0 ? Math.abs(b) : 1; - var newMax = Math.abs(a); - negatives = splitToPatterns(newMin, newMax, tok, options); - a = tok.a = 0; + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; } if (b >= 0) { - positives = splitToPatterns(a, b, tok, options); + positives = splitToPatterns(a, b, state, opts); } - tok.negatives = negatives; - tok.positives = positives; - tok.result = siftPatterns(negatives, positives, options); + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives, opts); - if (options.capture && (positives.length + negatives.length) > 1) { - tok.result = '(' + tok.result + ')'; + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { + state.result = `(?:${state.result})`; } - cache[key] = tok; - return tok.result; -} + toRegexRange.cache[cacheKey] = state; + return state.result; +}; -function siftPatterns(neg, pos, options) { - var onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; - var onlyPositive = filterPatterns(pos, neg, '', false, options) || []; - var intersected = filterPatterns(neg, pos, '-?', true, options) || []; - var subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); +function collatePatterns(neg, pos, options) { + let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + let intersected = filterPatterns(neg, pos, '-?', true, options) || []; + let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); return subpatterns.join('|'); } function splitToRanges(min, max) { - min = Number(min); - max = Number(max); + let nines = 1; + let zeros = 1; - var nines = 1; - var stops = [max]; - var stop = +countNines(min, nines); + let stop = countNines(min, nines); + let stops = new Set([max]); while (min <= stop && stop <= max) { - stops = push(stops, stop); + stops.add(stop); nines += 1; - stop = +countNines(min, nines); + stop = countNines(min, nines); } - var zeros = 1; stop = countZeros(max + 1, zeros) - 1; while (min < stop && stop <= max) { - stops = push(stops, stop); + stops.add(stop); zeros += 1; stop = countZeros(max + 1, zeros) - 1; } + stops = [...stops]; stops.sort(compare); return stops; } @@ -121,69 +128,64 @@ function rangeToPattern(start, stop, options) { if (start === stop) { - return {pattern: String(start), digits: []}; + return { pattern: start, count: [], digits: 0 }; } - var zipped = zip(String(start), String(stop)); - var len = zipped.length, i = -1; - - var pattern = ''; - var digits = 0; + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; - while (++i < len) { - var numbers = zipped[i]; - var startDigit = numbers[0]; - var stopDigit = numbers[1]; + for (let i = 0; i < digits; i++) { + let [startDigit, stopDigit] = zipped[i]; if (startDigit === stopDigit) { pattern += startDigit; } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit); + pattern += toCharacterClass(startDigit, stopDigit, options); } else { - digits += 1; + count++; } } - if (digits) { - pattern += options.shorthand ? '\\d' : '[0-9]'; + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; } - return { pattern: pattern, digits: [digits] }; + return { pattern, count: [count], digits }; } function splitToPatterns(min, max, tok, options) { - var ranges = splitToRanges(min, max); - var len = ranges.length; - var idx = -1; - - var tokens = []; - var start = min; - var prev; - - while (++idx < len) { - var range = ranges[idx]; - var obj = rangeToPattern(start, range, options); - var zeros = ''; + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; + + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.digits.length > 1) { - prev.digits.pop(); + if (prev.count.length > 1) { + prev.count.pop(); } - prev.digits.push(obj.digits[0]); - prev.string = prev.pattern + toQuantifier(prev.digits); - start = range + 1; + + prev.count.push(obj.count[0]); + prev.string = prev.pattern + toQuantifier(prev.count); + start = max + 1; continue; } if (tok.isPadded) { - zeros = padZeros(range, tok); + zeros = padZeros(max, tok, options); } - obj.string = zeros + obj.pattern + toQuantifier(obj.digits); + obj.string = zeros + obj.pattern + toQuantifier(obj.count); tokens.push(obj); - start = range + 1; + start = max + 1; prev = obj; } @@ -191,40 +193,31 @@ } function filterPatterns(arr, comparison, prefix, intersection, options) { - var res = []; + let result = []; - for (var i = 0; i < arr.length; i++) { - var tok = arr[i]; - var ele = tok.string; - - if (options.relaxZeros !== false) { - if (prefix === '-' && ele.charAt(0) === '0') { - if (ele.charAt(1) === '{') { - ele = '0*' + ele.replace(/^0\{\d+\}/, ''); - } else { - ele = '0*' + ele.slice(1); - } - } - } + for (let ele of arr) { + let { string } = ele; - if (!intersection && !contains(comparison, 'string', ele)) { - res.push(prefix + ele); + // only push if _both_ are negative... + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); } - if (intersection && contains(comparison, 'string', ele)) { - res.push(prefix + ele); + // or _both_ are positive + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); } } - return res; + return result; } /** - * Zip strings (`for in` can be used on string characters) + * Zip strings */ function zip(a, b) { - var arr = []; - for (var ch in a) arr.push([a[ch], b[ch]]); + let arr = []; + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); return arr; } @@ -232,22 +225,12 @@ return a > b ? 1 : b > a ? -1 : 0; } -function push(arr, ele) { - if (arr.indexOf(ele) === -1) arr.push(ele); - return arr; -} - function contains(arr, key, val) { - for (var i = 0; i < arr.length; i++) { - if (arr[i][key] === val) { - return true; - } - } - return false; + return arr.some(ele => ele[key] === val); } function countNines(min, len) { - return String(min).slice(0, -len) + repeat('9', len); + return Number(String(min).slice(0, -len) + '9'.repeat(len)); } function countZeros(integer, zeros) { @@ -255,39 +238,50 @@ } function toQuantifier(digits) { - var start = digits[0]; - var stop = digits[1] ? (',' + digits[1]) : ''; - if (!stop && (!start || start === 1)) { - return ''; + let [start = 0, stop = ''] = digits; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; } - return '{' + start + stop + '}'; + return ''; } -function toCharacterClass(a, b) { - return '[' + a + ((b - a === 1) ? '' : '-') + b + ']'; +function toCharacterClass(a, b, options) { + return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; } -function padding(str) { - return /^-?(0+)\d/.exec(str); +function hasPadding(str) { + return /^-?(0+)\d/.test(str); } -function padZeros(val, tok) { - if (tok.isPadded) { - var diff = Math.abs(tok.maxLen - String(val).length); - switch (diff) { - case 0: - return ''; - case 1: - return '0'; - default: { - return '0{' + diff + '}'; - } +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; + } + + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; + + switch (diff) { + case 0: + return ''; + case 1: + return relax ? '0?' : '0'; + case 2: + return relax ? '0{0,2}' : '00'; + default: { + return relax ? `0{0,${diff}}` : `0{${diff}}`; } } - return val; } /** + * Cache + */ + +toRegexRange.cache = {}; +toRegexRange.clearCache = () => (toRegexRange.cache = {}); + +/** * Expose `toRegexRange` */ diff -Nru node-to-regex-range-3.0.0/LICENSE node-to-regex-range-5.0.1/LICENSE --- node-to-regex-range-3.0.0/LICENSE 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/LICENSE 2019-04-07 06:04:46.000000000 +0000 @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2017, Jon Schlinkert. +Copyright (c) 2015-present, 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 diff -Nru node-to-regex-range-3.0.0/.npmrc node-to-regex-range-5.0.1/.npmrc --- node-to-regex-range-3.0.0/.npmrc 1970-01-01 00:00:00.000000000 +0000 +++ node-to-regex-range-5.0.1/.npmrc 2019-04-07 06:04:46.000000000 +0000 @@ -0,0 +1 @@ +package-lock=false diff -Nru node-to-regex-range-3.0.0/package.json node-to-regex-range-5.0.1/package.json --- node-to-regex-range-3.0.0/package.json 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/package.json 2019-04-07 06:04:46.000000000 +0000 @@ -1,7 +1,7 @@ { "name": "to-regex-range", "description": "Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions.", - "version": "3.0.0", + "version": "5.0.1", "homepage": "https://github.com/micromatch/to-regex-range", "author": "Jon Schlinkert (https://github.com/jonschlinkert)", "contributors": [ @@ -18,56 +18,49 @@ ], "main": "index.js", "engines": { - "node": ">=0.10.0" + "node": ">=8.0" }, "scripts": { "test": "mocha" }, "dependencies": { - "is-number": "^4.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" }, "devDependencies": { - "fill-range": "^5.0.0", - "gulp-format-md": "^1.0.0", - "mocha": "^3.5.0", + "fill-range": "^6.0.0", + "gulp-format-md": "^2.0.0", + "mocha": "^6.0.2", "text-table": "^0.2.0", "time-diff": "^0.3.1" }, "keywords": [ - "alpha", - "alphabetical", "bash", - "brace", "date", "expand", "expansion", + "expression", "glob", "match", + "match date", + "match number", + "match numbers", + "match year", "matches", "matching", "number", + "numbers", "numerical", "range", "ranges", "regex", - "sequence", - "sh", - "to", - "year" + "regexp", + "regular", + "regular expression", + "sequence" ], "verb": { - "related": { - "list": [ - "expand-range", - "fill-range", - "micromatch", - "repeat-element", - "repeat-string" - ] - }, - "toc": false, "layout": "default", + "toc": false, "tasks": [ "readme" ], @@ -77,11 +70,19 @@ "lint": { "reflinks": true }, - "helpers": [ - "./examples.js" - ], - "reflinks": [ - "micromatch" - ] + "helpers": { + "examples": { + "displayName": "examples" + } + }, + "related": { + "list": [ + "expand-range", + "fill-range", + "micromatch", + "repeat-element", + "repeat-string" + ] + } } } diff -Nru node-to-regex-range-3.0.0/README.md node-to-regex-range-5.0.1/README.md --- node-to-regex-range-3.0.0/README.md 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/README.md 2019-04-07 06:04:46.000000000 +0000 @@ -1,4 +1,4 @@ -# to-regex-range [![NPM version](https://img.shields.io/npm/v/to-regex-range.svg?style=flat)](https://www.npmjs.com/package/to-regex-range) [![NPM monthly downloads](https://img.shields.io/npm/dm/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![NPM total downloads](https://img.shields.io/npm/dt/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![Linux Build Status](https://img.shields.io/travis/micromatch/to-regex-range.svg?style=flat&label=Travis)](https://travis-ci.org/micromatch/to-regex-range) +# to-regex-range [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/to-regex-range.svg?style=flat)](https://www.npmjs.com/package/to-regex-range) [![NPM monthly downloads](https://img.shields.io/npm/dm/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![NPM total downloads](https://img.shields.io/npm/dt/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![Linux Build Status](https://img.shields.io/travis/micromatch/to-regex-range.svg?style=flat&label=Travis)](https://travis-ci.org/micromatch/to-regex-range) > Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions. @@ -22,8 +22,8 @@ **Example** ```js -var toRegexRange = require('to-regex-range'); -var regex = new RegExp(toRegexRange('15', '95')); +const toRegexRange = require('to-regex-range'); +const regex = new RegExp(toRegexRange('15', '95')); ``` A string is returned so that you can do whatever you need with it before passing it to `new RegExp()` (like adding `^` or `$` boundaries, defining flags, or combining it another string). @@ -59,13 +59,13 @@ ### Heavily tested -As of November 01, 2017, this library runs [2,783,483 test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are indeed correct. +As of April 07, 2019, this library runs [>1m test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are correct. -Tests run in ~870ms on my MacBook Pro, 2.5 GHz Intel Core i7. +Tests run in ~280ms on my MacBook Pro, 2.5 GHz Intel Core i7. -### Highly optimized +### Optimized -Generated regular expressions are highly optimized: +Generated regular expressions are optimized: * duplicate sequences and character classes are reduced using quantifiers * smart enough to use `?` conditionals when number(s) or range(s) can be positive or negative @@ -80,20 +80,20 @@ Add this library to your javascript application with the following line of code ```js -var toRegexRange = require('to-regex-range'); +const toRegexRange = require('to-regex-range'); ``` The main export is a function that takes two integers: the `min` value and `max` value (formatted as strings or numbers). ```js -var source = toRegexRange('15', '95'); +const source = toRegexRange('15', '95'); //=> 1[5-9]|[2-8][0-9]|9[0-5] -var re = new RegExp('^' + source + '$'); -console.log(re.test('14')); //=> false -console.log(re.test('50')); //=> true -console.log(re.test('94')); //=> true -console.log(re.test('96')); //=> false +const regex = new RegExp(`^${source}$`); +console.log(regex.test('14')); //=> false +console.log(regex.test('50')); //=> true +console.log(regex.test('94')); //=> true +console.log(regex.test('96')); //=> false ``` ## Options @@ -110,7 +110,7 @@ console.log(toRegexRange('-10', '10')); //=> -[1-9]|-?10|[0-9] -console.log(toRegexRange('-10', '10', {capture: true})); +console.log(toRegexRange('-10', '10', { capture: true })); //=> (-[1-9]|-?10|[0-9]) ``` @@ -126,7 +126,7 @@ console.log(toRegexRange('0', '999999')); //=> [0-9]|[1-9][0-9]{1,5} -console.log(toRegexRange('0', '999999', {shorthand: true})); +console.log(toRegexRange('0', '999999', { shorthand: true })); //=> \d|[1-9]\d{1,5} ``` @@ -136,58 +136,60 @@ **Default**: `true` -This option only applies to **negative zero-padded ranges**. By default, when a negative zero-padded range is defined, the number of leading zeros is relaxed using `-0*`. +This option relaxes matching for leading zeros when when ranges are zero-padded. ```js -console.log(toRegexRange('-001', '100')); -//=> -0*1|0{2}[0-9]|0[1-9][0-9]|100 - -console.log(toRegexRange('-001', '100', {relaxZeros: false})); -//=> -0{2}1|0{2}[0-9]|0[1-9][0-9]|100 +const source = toRegexRange('-0010', '0010'); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> true +console.log(regex.test('-010')); //=> true +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> true +console.log(regex.test('010')); //=> true +console.log(regex.test('0010')); //=> true ``` -
-Why are zeros relaxed for negative zero-padded ranges by default? - -Consider the following. +When `relaxZeros` is false, matching is strict: ```js -var regex = toRegexRange('-001', '100'); +const source = toRegexRange('-0010', '0010', { relaxZeros: false }); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> false +console.log(regex.test('-010')); //=> false +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> false +console.log(regex.test('010')); //=> false +console.log(regex.test('0010')); //=> true ``` -_Note that `-001` and `100` are both three digits long_. - -In most zero-padding implementations, only a single leading zero is enough to indicate that zero-padding should be applied. Thus, the leading zeros would be "corrected" on the negative range in the example to `-01`, instead of `-001`, to make total length of each string no greater than the length of the largest number in the range (in other words, `-001` is 4 digits, but `100` is only three digits). - -If zeros were not relaxed by default, you might expect the resulting regex of the above pattern to match `-001` - given that it's defined that way in the arguments - _but it wouldn't_. It would, however, match `-01`. This gets even more ambiguous with large ranges, like `-01` to `1000000`. - -Thus, we relax zeros by default to provide a more predictable experience for users. - -
- ## Examples -| **Range** | **Result** | **Compile time** | -| --- | --- | --- | -| `toRegexRange('5, 5')` | `5` | _33μs_ | -| `toRegexRange('5, 6')` | `5\|6` | _53μs_ | -| `toRegexRange('29, 51')` | `29\|[34][0-9]\|5[01]` | _699μs_ | -| `toRegexRange('31, 877')` | `3[1-9]\|[4-9][0-9]\|[1-7][0-9]{2}\|8[0-6][0-9]\|87[0-7]` | _711μs_ | -| `toRegexRange('111, 555')` | `11[1-9]\|1[2-9][0-9]\|[2-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _62μs_ | -| `toRegexRange('-10, 10')` | `-[1-9]\|-?10\|[0-9]` | _74μs_ | -| `toRegexRange('-100, -10')` | `-1[0-9]\|-[2-9][0-9]\|-100` | _49μs_ | -| `toRegexRange('-100, 100')` | `-[1-9]\|-?[1-9][0-9]\|-?100\|[0-9]` | _45μs_ | -| `toRegexRange('001, 100')` | `0{2}[1-9]\|0[1-9][0-9]\|100` | _158μs_ | -| `toRegexRange('0010, 1000')` | `0{2}1[0-9]\|0{2}[2-9][0-9]\|0[1-9][0-9]{2}\|1000` | _61μs_ | -| `toRegexRange('1, 2')` | `1\|2` | _10μs_ | -| `toRegexRange('1, 5')` | `[1-5]` | _24μs_ | -| `toRegexRange('1, 10')` | `[1-9]\|10` | _23μs_ | -| `toRegexRange('1, 100')` | `[1-9]\|[1-9][0-9]\|100` | _30μs_ | -| `toRegexRange('1, 1000')` | `[1-9]\|[1-9][0-9]{1,2}\|1000` | _52μs_ | -| `toRegexRange('1, 10000')` | `[1-9]\|[1-9][0-9]{1,3}\|10000` | _47μs_ | -| `toRegexRange('1, 100000')` | `[1-9]\|[1-9][0-9]{1,4}\|100000` | _44μs_ | -| `toRegexRange('1, 1000000')` | `[1-9]\|[1-9][0-9]{1,5}\|1000000` | _49μs_ | -| `toRegexRange('1, 10000000')` | `[1-9]\|[1-9][0-9]{1,6}\|10000000` | _63μs_ | +| **Range** | **Result** | **Compile time** | +| --- | --- | --- | +| `toRegexRange(-10, 10)` | `-[1-9]\|-?10\|[0-9]` | _132μs_ | +| `toRegexRange(-100, -10)` | `-1[0-9]\|-[2-9][0-9]\|-100` | _50μs_ | +| `toRegexRange(-100, 100)` | `-[1-9]\|-?[1-9][0-9]\|-?100\|[0-9]` | _42μs_ | +| `toRegexRange(001, 100)` | `0{0,2}[1-9]\|0?[1-9][0-9]\|100` | _109μs_ | +| `toRegexRange(001, 555)` | `0{0,2}[1-9]\|0?[1-9][0-9]\|[1-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _51μs_ | +| `toRegexRange(0010, 1000)` | `0{0,2}1[0-9]\|0{0,2}[2-9][0-9]\|0?[1-9][0-9]{2}\|1000` | _31μs_ | +| `toRegexRange(1, 50)` | `[1-9]\|[1-4][0-9]\|50` | _24μs_ | +| `toRegexRange(1, 55)` | `[1-9]\|[1-4][0-9]\|5[0-5]` | _23μs_ | +| `toRegexRange(1, 555)` | `[1-9]\|[1-9][0-9]\|[1-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _30μs_ | +| `toRegexRange(1, 5555)` | `[1-9]\|[1-9][0-9]{1,2}\|[1-4][0-9]{3}\|5[0-4][0-9]{2}\|55[0-4][0-9]\|555[0-5]` | _43μs_ | +| `toRegexRange(111, 555)` | `11[1-9]\|1[2-9][0-9]\|[2-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _38μs_ | +| `toRegexRange(29, 51)` | `29\|[34][0-9]\|5[01]` | _24μs_ | +| `toRegexRange(31, 877)` | `3[1-9]\|[4-9][0-9]\|[1-7][0-9]{2}\|8[0-6][0-9]\|87[0-7]` | _32μs_ | +| `toRegexRange(5, 5)` | `5` | _8μs_ | +| `toRegexRange(5, 6)` | `5\|6` | _11μs_ | +| `toRegexRange(1, 2)` | `1\|2` | _6μs_ | +| `toRegexRange(1, 5)` | `[1-5]` | _15μs_ | +| `toRegexRange(1, 10)` | `[1-9]\|10` | _22μs_ | +| `toRegexRange(1, 100)` | `[1-9]\|[1-9][0-9]\|100` | _25μs_ | +| `toRegexRange(1, 1000)` | `[1-9]\|[1-9][0-9]{1,2}\|1000` | _31μs_ | +| `toRegexRange(1, 10000)` | `[1-9]\|[1-9][0-9]{1,3}\|10000` | _34μs_ | +| `toRegexRange(1, 100000)` | `[1-9]\|[1-9][0-9]{1,4}\|100000` | _36μs_ | +| `toRegexRange(1, 1000000)` | `[1-9]\|[1-9][0-9]{1,5}\|1000000` | _42μs_ | +| `toRegexRange(1, 10000000)` | `[1-9]\|[1-9][0-9]{1,6}\|10000000` | _42μs_ | ## Heads up! @@ -265,7 +267,7 @@ You might also be interested in these projects: -* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used… [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. Used by [micromatch].") +* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used… [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. 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/micromatch/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.") * [repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.") @@ -273,23 +275,31 @@ ### Contributors -| **Commits** | **Contributor** | -| --- | --- | -| 51 | [jonschlinkert](https://github.com/jonschlinkert) | -| 2 | [realityking](https://github.com/realityking) | +| **Commits** | **Contributor** | +| --- | --- | +| 63 | [jonschlinkert](https://github.com/jonschlinkert) | +| 3 | [doowb](https://github.com/doowb) | +| 2 | [realityking](https://github.com/realityking) | ### Author **Jon Schlinkert** -* [github/jonschlinkert](https://github.com/jonschlinkert) -* [twitter/jonschlinkert](https://twitter.com/jonschlinkert) +* [GitHub Profile](https://github.com/jonschlinkert) +* [Twitter Profile](https://twitter.com/jonschlinkert) +* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) + +Please consider supporting me on Patreon, or [start your own Patreon page](https://patreon.com/invite/bxpbvm)! + + + + ### License -Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). +Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). Released under the [MIT License](LICENSE). *** -_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on November 01, 2017._ \ No newline at end of file +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 07, 2019._ \ No newline at end of file diff -Nru node-to-regex-range-3.0.0/test/test.js node-to-regex-range-5.0.1/test/test.js --- node-to-regex-range-3.0.0/test/test.js 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/test/test.js 2019-04-07 06:04:46.000000000 +0000 @@ -1,207 +1,235 @@ 'use strict'; require('mocha'); -var assert = require('assert'); -var fill = require('fill-range'); -var toRange = require('..'); -var count = 0; +const assert = require('assert').strict; +const fill = require('fill-range'); +const toRange = require('..'); +let count = 0; + +const inRange = (min, max, num) => min <= num && max >= num; +const toRegex = str => new RegExp(`^${str}$`); +const toRangeRegex = (min, max, options) => { + return toRegex(toRange(min, max, { wrap: true, ...options })); +}; + +const matcher = (...args) => { + const regex = toRangeRegex(...args); + return num => regex.test(String(num)); +}; -function toRangeRegex(min, max, options) { - return toRegex(toRange(min, max, options)); -} - -function toRegex(str) { - return new RegExp('^(?:' + str + ')$'); -} - -function match(min, max) { - var regex = toRangeRegex(min, max); - return function(num) { - return regex.test(String(num)); - }; -} - -function matchRange(min, max, expected, match, notMatch) { +const matchRange = (min, max, expected, match, notMatch) => { if (max - min >= 1000000) { throw new RangeError('range is too big'); } - var actual = toRange(min, max); - var msg = actual + ' => ' + expected; + let actual = toRange(min, max); + let msg = actual + ' => ' + expected; // test expected string - assert.strictEqual(actual, expected, msg); + assert.equal(actual, expected, msg); - var re = toRegex(actual); - for (var i = 0; i < match.length; i++) { + let re = toRegex(actual); + for (let i = 0; i < match.length; i++) { assert(re.test(match[i]), 'should match ' + msg); count++; } if (!Array.isArray(notMatch)) return; - for (var j = 0; j < notMatch.length; j++) { + for (let j = 0; j < notMatch.length; j++) { assert(!re.test(notMatch[j]), 'should not match ' + msg); count++; } } -function verifyRange(min, max, from, to, zeros) { - var isMatch = match(min, max); - var minNum = Math.min(min, max); - var maxNum = Math.max(min, max); - var num = from - 1; +const verifyRange = (min, max, from, to) => { + let isMatch = matcher(min, max); + let minNum = Math.min(min, max); + let maxNum = Math.max(min, max); + let num = from - 1; while (++num < to) { - var n = Number(num); + let n = Number(num); if (inRange(minNum, maxNum, n)) { - assert(isMatch(num), 'should match "' + num + '"'); + assert(isMatch(num), `should match "${num}"`); } else { - assert(!isMatch(num), 'should not match "' + num + '"'); + assert(!isMatch(num), `should not match "${num}"`); } count++; } -} +}; -function verifyZeros(min, max, from, to) { - var range = fill(from, to); - var len = range.length; - var idx = -1; - - var isMatch = match(min, max); - var minNum = Math.min(min, max); - var maxNum = Math.max(min, max); +const verifyZeros = (min, max, from, to) => { + let range = fill(from, to); + let len = range.length; + let idx = -1; + + let isMatch = matcher(min, max); + let minNum = Math.min(min, max); + let maxNum = Math.max(min, max); while (++idx < len) { - var num = range[idx]; - var n = Number(num); + let num = range[idx]; + let n = Number(num); if (inRange(minNum, maxNum, n)) { - assert(isMatch(num), 'should match "' + num + '"'); + assert(isMatch(num), `should match "${num}"`); } else { - assert(!isMatch(num), 'should not match "' + num + '"'); + assert(!isMatch(num), `should not match "${num}"`); } count++; } -} +}; -function inRange(min, max, num) { - return min <= num && max >= num; -} - -describe('to-regex-range', function() { - after(function() { - var num = (+(+(count).toFixed(2))).toLocaleString(); +describe('to-regex-range', () => { + after(() => { console.log(); - console.log(' ', num, 'values tested'); + console.log(' ', (+(+count.toFixed(2))).toLocaleString(), 'assertions'); }); - describe('range', function() { - it('should throw an error when the first arg is invalid:', function() { - assert.throws(function() { - toRange(); - }, /toRegexRange: first argument is invalid/); + describe('range', () => { + it('should throw an error when the first arg is invalid:', () => { + assert.throws(() => toRange(), /expected/); + }); + + it('should throw an error when the second arg is invalid:', () => { + assert.throws(() => toRange(1, {}), /expected/); + }); + + it('should match the given numbers', () => { + let oneFifty = toRegex(toRange(1, 150)); + assert(oneFifty.test('125')); + assert(!oneFifty.test('0')); + assert(oneFifty.test('1')); + assert(oneFifty.test('126')); + assert(oneFifty.test('150')); + assert(!oneFifty.test('151')); + + let oneTwentyFive = toRegex(toRange(1, 125)); + assert(oneTwentyFive.test('125')); + assert(!oneTwentyFive.test('0')); + assert(oneTwentyFive.test('1')); + assert(!oneTwentyFive.test('126')); + assert(!oneTwentyFive.test('150')); + assert(!oneTwentyFive.test('151')); }); + }); - it('should throw an error when the second arg is invalid:', function() { - assert.throws(function() { - toRange(1, {}); - }, /toRegexRange: second argument is invalid/); + describe('minimum / maximum', () => { + it('should reverse `min/max` when the min is larger than the max:', () => { + assert.equal(toRange(55, 10), '(?:1[0-9]|[2-4][0-9]|5[0-5])'); }); }); - describe('minimum / maximum', function() { - it('should reverse `min/max` when the min is larger than the max:', function() { - assert.strictEqual(toRange(55, 10), '1[0-9]|[2-4][0-9]|5[0-5]'); + describe('ranges', () => { + it('should return the number when only one argument is passed:', () => { + assert.equal(toRange(5), '5'); }); - }); - describe('ranges', function() { - it('should return the number when only one argument is passed:', function() { - assert.strictEqual(toRange(5), '5'); + it('should return a single number when both numbers are equal', () => { + assert.equal(toRange('1', '1'), '1'); + assert.equal(toRange('65443', '65443'), '65443'); + assert.equal(toRange('192', '192'), '192'); + verifyRange(1, 1, 0, 100); + verifyRange(65443, 65443, 65000, 66000); + verifyRange(192, 192, 0, 1000); }); - it('should not return a range when both numbers are the same:', function() { - assert.strictEqual(toRange(5, 5), '5'); + it('should not return a range when both numbers are the same:', () => { + assert.equal(toRange(5, 5), '5'); }); - it('should support ranges than 10:', function() { - assert.strictEqual(toRange(1, 5), '[1-5]'); + it('should return regex character classes when both args are less than 10', () => { + assert.equal(toRange(0, 9), '[0-9]'); + assert.equal(toRange(1, 5), '[1-5]'); + assert.equal(toRange(1, 7), '[1-7]'); + assert.equal(toRange(2, 6), '[2-6]'); }); - it('should support strings:', function() { - assert.strictEqual(toRange('1', '5'), '[1-5]'); - assert.strictEqual(toRange('10', '50'), '1[0-9]|[2-4][0-9]|50'); + it('should support string numbers', () => { + assert.equal(toRange('1', '5'), '[1-5]'); + assert.equal(toRange('10', '50'), '(?:1[0-9]|[2-4][0-9]|50)'); }); - it('should support padded ranges:', function() { - assert.strictEqual(toRange('001', '005'), '0{2}[1-5]'); - assert.strictEqual(toRange('01', '05'), '0[1-5]'); - assert.strictEqual(toRange('001', '100'), '0{2}[1-9]|0[1-9][0-9]|100'); - assert.strictEqual(toRange('0001', '1000'), '0{3}[1-9]|0{2}[1-9][0-9]|0[1-9][0-9]{2}|1000'); + it('should support padded ranges:', () => { + assert.equal(toRange('001', '005'), '0{0,2}[1-5]'); + assert.equal(toRange('01', '05'), '0?[1-5]'); + assert.equal(toRange('001', '100'), '(?:0{0,2}[1-9]|0?[1-9][0-9]|100)'); + assert.equal(toRange('0001', '1000'), '(?:0{0,3}[1-9]|0{0,2}[1-9][0-9]|0?[1-9][0-9]{2}|1000)'); }); - it('should work when padding is imbalanced:', function() { - assert.strictEqual(toRange('001', '105'), '0{2}[1-9]|0[1-9][0-9]|10[0-5]'); - assert.strictEqual(toRange('01', '105'), '0{2}[1-9]|0[1-9][0-9]|10[0-5]'); - assert.strictEqual(toRange('010', '105'), '01[0-9]|0[2-9][0-9]|10[0-5]'); - assert.strictEqual(toRange('010', '1005'), '0{2}1[0-9]|0{2}[2-9][0-9]|0[1-9][0-9]{2}|100[0-5]'); - assert.strictEqual(toRange('0001', '1000'), toRange('001', '1000')); - assert.strictEqual(toRange('0001', '1000'), toRange('01', '1000')); + it('should work when padding is imbalanced:', () => { + assert.equal(toRange('001', '105'), '(?:0{0,2}[1-9]|0?[1-9][0-9]|10[0-5])'); + assert.equal(toRange('01', '105'), '(?:0{0,2}[1-9]|0?[1-9][0-9]|10[0-5])'); + assert.equal(toRange('010', '105'), '(?:0?1[0-9]|0?[2-9][0-9]|10[0-5])'); + assert.equal(toRange('010', '1005'), '(?:0{0,2}1[0-9]|0{0,2}[2-9][0-9]|0?[1-9][0-9]{2}|100[0-5])'); + assert.equal(toRange('0001', '1000'), toRange('001', '1000')); + assert.equal(toRange('0001', '1000'), toRange('01', '1000')); }); - it('should generate regex strings for negative patterns', function() { - assert.strictEqual(toRange(-1, 0), '-1|0'); - assert.strictEqual(toRange(-1, 1), '-1|[01]'); - assert.strictEqual(toRange(-4, -2), '-[2-4]'); - assert.strictEqual(toRange(-3, 1), '-[1-3]|[01]'); - assert.strictEqual(toRange(-2, 0), '-[12]|0'); - assert.strictEqual(toRange(-1, 3), '-1|[0-3]'); + it('should generate regex strings for negative patterns', () => { + assert.equal(toRange(-1, 0), '(?:-1|0)'); + assert.equal(toRange(-1, 1), '(?:-1|[01])'); + assert.equal(toRange(-4, -2), '-[2-4]'); + assert.equal(toRange(-3, 1), '(?:-[1-3]|[01])'); + assert.equal(toRange(-2, 0), '(?:-[12]|0)'); + assert.equal(toRange(-1, 3), '(?:-1|[0-3])'); matchRange(-1, -1, '-1', [-1], [-2, 0, 1]); - matchRange(-1, -10, '-[1-9]|-10', [-1, -5, -10], [-11, 0]); - matchRange(-1, 3, '-1|[0-3]', [-1, 0, 1, 2, 3], [-2, 4]); + matchRange(-1, -10, '(?:-[1-9]|-10)', [-1, -5, -10], [-11, 0]); + matchRange(-1, 3, '(?:-1|[0-3])', [-1, 0, 1, 2, 3], [-2, 4]); }); - it('should wrap patterns when options.capture is true', function() { - assert.strictEqual(toRange(-1, 0, {capture: true}), '(-1|0)'); - assert.strictEqual(toRange(-1, 1, {capture: true}), '(-1|[01])'); - assert.strictEqual(toRange(-4, -2, {capture: true}), '-[2-4]'); - assert.strictEqual(toRange(-3, 1, {capture: true}), '(-[1-3]|[01])'); - assert.strictEqual(toRange(-2, 0, {capture: true}), '(-[12]|0)'); - assert.strictEqual(toRange(-1, 3, {capture: true}), '(-1|[0-3])'); - }); - - it('should generate regex strings for positive patterns', function() { - assert.strictEqual(toRange(1, 1), '1'); - assert.strictEqual(toRange(0, 1), '0|1'); - assert.strictEqual(toRange(0, 2), '[0-2]'); - assert.strictEqual(toRange(65666, 65667), '65666|65667'); - assert.strictEqual(toRange(12, 3456), '1[2-9]|[2-9][0-9]|[1-9][0-9]{2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6]'); - assert.strictEqual(toRange(1, 3456), '[1-9]|[1-9][0-9]{1,2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6]'); - assert.strictEqual(toRange(1, 10), '[1-9]|10'); - assert.strictEqual(toRange(1, 19), '[1-9]|1[0-9]'); - assert.strictEqual(toRange(1, 99), '[1-9]|[1-9][0-9]'); - assert.strictEqual(toRange(1, 100), '[1-9]|[1-9][0-9]|100'); - assert.strictEqual(toRange(1, 1000), '[1-9]|[1-9][0-9]{1,2}|1000'); - assert.strictEqual(toRange(1, 10000), '[1-9]|[1-9][0-9]{1,3}|10000'); - assert.strictEqual(toRange(1, 100000), '[1-9]|[1-9][0-9]{1,4}|100000'); - assert.strictEqual(toRange(1, 9999999), '[1-9]|[1-9][0-9]{1,6}'); - assert.strictEqual(toRange(99, 100000), '99|[1-9][0-9]{2,4}|100000'); - - matchRange(99, 100000, '99|[1-9][0-9]{2,4}|100000', [99, 999, 989, 100, 9999, 9899, 10009, 10999, 100000], [0, 9, 100001, 100009]); - }); - - it('should optimize regexes', function() { - assert.strictEqual(toRange(-9, 9), '-[1-9]|[0-9]'); - assert.strictEqual(toRange(-19, 19), '-[1-9]|-?1[0-9]|[0-9]'); - assert.strictEqual(toRange(-29, 29), '-[1-9]|-?[12][0-9]|[0-9]'); - assert.strictEqual(toRange(-99, 99), '-[1-9]|-?[1-9][0-9]|[0-9]'); - assert.strictEqual(toRange(-999, 999), '-[1-9]|-?[1-9][0-9]{1,2}|[0-9]'); - assert.strictEqual(toRange(-9999, 9999), '-[1-9]|-?[1-9][0-9]{1,3}|[0-9]'); - assert.strictEqual(toRange(-99999, 99999), '-[1-9]|-?[1-9][0-9]{1,4}|[0-9]'); + it('should wrap patterns when options.capture is true', () => { + assert.equal(toRange(-1, 0, { capture: true }), '(-1|0)'); + assert.equal(toRange(-1, 1, { capture: true }), '(-1|[01])'); + assert.equal(toRange(-4, -2, { capture: true }), '(-[2-4])'); + assert.equal(toRange(-3, 1, { capture: true }), '(-[1-3]|[01])'); + assert.equal(toRange(-2, 0, { capture: true }), '(-[12]|0)'); + assert.equal(toRange(-1, 3, { capture: true }), '(-1|[0-3])'); + }); + + it('should generate regex strings for positive patterns', () => { + assert.equal(toRange(1, 1), '1'); + assert.equal(toRange(0, 1), '(?:0|1)'); + assert.equal(toRange(0, 2), '[0-2]'); + assert.equal(toRange(65666, 65667), '(?:65666|65667)'); + assert.equal(toRange(12, 3456), '(?:1[2-9]|[2-9][0-9]|[1-9][0-9]{2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6])'); + assert.equal(toRange(1, 3456), '(?:[1-9]|[1-9][0-9]{1,2}|[12][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6])'); + assert.equal(toRange(1, 10), '(?:[1-9]|10)'); + assert.equal(toRange(1, 19), '(?:[1-9]|1[0-9])'); + assert.equal(toRange(1, 99), '(?:[1-9]|[1-9][0-9])'); + assert.equal(toRange(1, 100), '(?:[1-9]|[1-9][0-9]|100)'); + assert.equal(toRange(1, 1000), '(?:[1-9]|[1-9][0-9]{1,2}|1000)'); + assert.equal(toRange(1, 10000), '(?:[1-9]|[1-9][0-9]{1,3}|10000)'); + assert.equal(toRange(1, 100000), '(?:[1-9]|[1-9][0-9]{1,4}|100000)'); + assert.equal(toRange(1, 9999999), '(?:[1-9]|[1-9][0-9]{1,6})'); + assert.equal(toRange(99, 100000), '(?:99|[1-9][0-9]{2,4}|100000)'); + + matchRange(99, 100000, '(?:99|[1-9][0-9]{2,4}|100000)', [99, 999, 989, 100, 9999, 9899, 10009, 10999, 100000], [0, 9, 100001, 100009]); + }); + + it('should optimize regexes', () => { + assert.equal(toRange(-9, 9), '(?:-[1-9]|[0-9])'); + assert.equal(toRange(-19, 19), '(?:-[1-9]|-?1[0-9]|[0-9])'); + assert.equal(toRange(-29, 29), '(?:-[1-9]|-?[12][0-9]|[0-9])'); + assert.equal(toRange(-99, 99), '(?:-[1-9]|-?[1-9][0-9]|[0-9])'); + assert.equal(toRange(-999, 999), '(?:-[1-9]|-?[1-9][0-9]{1,2}|[0-9])'); + assert.equal(toRange(-9999, 9999), '(?:-[1-9]|-?[1-9][0-9]{1,3}|[0-9])'); + assert.equal(toRange(-99999, 99999), '(?:-[1-9]|-?[1-9][0-9]{1,4}|[0-9])'); }); }); - describe('validate ranges', function() { - it('should support negative ranges:', function() { + describe('validate ranges', () => { + it('should match all numbers in the given range', () => { + let isMatch = matcher(1, 59); + for (let i = 0; i < 100; i++) { + if (i >= 1 && i <= 59) { + assert(isMatch(i)); + } else { + assert(!isMatch(i)); + } + } + }); + + it('should support negative ranges:', () => { verifyRange(-9, -1, -100, 100); verifyRange(-99, -1, -1000, 1000); verifyRange(-999, -1, -1000, 1000); @@ -209,7 +237,7 @@ verifyRange(-99999, -1, -100999, 100999); }); - it('should support negative-to-positive ranges:', function() { + it('should support negative-to-positive ranges:', () => { verifyRange(-9, 9, -100, 100); verifyRange(-99, 99, -1000, 1000); verifyRange(-999, 999, -1000, 1000); @@ -217,20 +245,11 @@ verifyRange(-99999, 99999, -100999, 100999); }); - it('should work when numbers are equal:', function() { - assert.strictEqual(toRange('1', '1'), '1'); - assert.strictEqual(toRange('65443', '65443'), '65443'); - assert.strictEqual(toRange('192', '192'), '192'); - verifyRange(1, 1, 0, 100); - verifyRange(65443, 65443, 65000, 66000); - verifyRange(192, 192, 0, 1000); - }); - - it('should support large numbers:', function() { - verifyRange(100019999300000, 100020000300000, 100019999999999, 100020000200000); + it('should support large numbers:', () => { + verifyRange(100019999300000, 100020000300000, 1000199992999900, 100020000200000); }); - it('should support large ranges:', function() { + it('should support large ranges:', () => { verifyRange(1, 100000, 1, 1000); verifyRange(1, 100000, 10000, 11000); verifyRange(1, 100000, 99000, 100000); @@ -241,7 +260,7 @@ verifyRange(10331, 20381, 0, 99999); }); - it('should support repeated digits:', function() { + it('should support repeated digits:', () => { verifyRange(111, 222, 0, 999); verifyRange(111, 333, 0, 999); verifyRange(111, 444, 0, 999); @@ -261,17 +280,17 @@ verifyRange(0, 999, -99, 999); }); - it('should support repeated zeros:', function() { + it('should support repeated zeros:', () => { verifyRange(10031, 20081, 0, 59999); verifyRange(10000, 20000, 0, 59999); }); - it('should support zero one:', function() { + it('should support zero one:', () => { verifyRange(10301, 20101, 0, 99999); - verifyRange(101010, 1010101, 0, 1299999); + verifyRange(101010, 101210, 101009, 101300); }); - it('should support repeated ones:', function() { + it('should support repeated ones:', () => { verifyRange(1, 11111, 0, 1000); verifyRange(1, 1111, 0, 1000); verifyRange(1, 111, 0, 1000); @@ -279,49 +298,49 @@ verifyRange(1, 1, 0, 1000); }); - it('should support small diffs:', function() { + it('should support small diffs:', () => { verifyRange(102, 103, 0, 1000); verifyRange(102, 110, 0, 1000); verifyRange(102, 130, 0, 1000); }); - it('should support random ranges:', function() { + it('should support random ranges:', () => { verifyRange(4173, 7981, 0, 99999); }); - it('should support one digit numbers:', function() { + it('should support one digit numbers:', () => { verifyRange(3, 7, 0, 99); }); - it('should support one digit at bounds:', function() { + it('should support one digit at bounds:', () => { verifyRange(1, 9, 0, 1000); }); - it('should support power of ten:', function() { + it('should support power of ten:', () => { verifyRange(1000, 8632, 0, 99999); }); - it('should not match the negative of the same number', function() { + it('should not match the negative of the same number', () => { verifyRange(1, 1000, -1000, 1000); verifyRange(1, 1000, '-1000', '1000'); }); - it('should work with numbers of varying lengths:', function() { + it('should work with numbers of varying lengths:', () => { verifyRange(1030, 20101, 0, 99999); verifyRange(13, 8632, 0, 10000); }); - it('should support small ranges:', function() { + it('should support small ranges:', () => { verifyRange(9, 11, 0, 100); verifyRange(19, 21, 0, 100); }); - it('should support big ranges:', function() { + it('should support big ranges:', () => { verifyRange(90, 98009, 0, 98999); verifyRange(999, 10000, 1, 20000); }); - it('should create valid regex ranges with zero-padding:', function() { + it('should create valid regex ranges with zero-padding:', () => { verifyZeros('001', '100', '001', 100); verifyZeros('001', '100', '001', '100'); verifyZeros('0001', '1000', '01', 1000); @@ -342,14 +361,14 @@ verifyZeros('0001', '1000', '-010', '1000'); }); - it('should create valid regex ranges with negative padding:', function() { + it('should create valid regex ranges with negative padding:', () => { verifyZeros('-00001', '-1000', -1000, 1000); verifyZeros('-0001', '-1000', -1000, 1000); verifyZeros('-001', '-1000', -1000, 1000); verifyZeros('-01', '-1000', -1000, 1000); }); - it('should create valid ranges with neg && pos zero-padding:', function() { + it('should create valid ranges with neg && pos zero-padding:', () => { verifyZeros('-01', '10', '-1', '01'); verifyZeros('-1000', '100', -1000, 1000); verifyZeros('-1000', '0100', '-010', '1000'); diff -Nru node-to-regex-range-3.0.0/.travis.yml node-to-regex-range-5.0.1/.travis.yml --- node-to-regex-range-3.0.0/.travis.yml 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/.travis.yml 2019-04-07 06:04:46.000000000 +0000 @@ -2,14 +2,10 @@ os: - linux - osx + - windows language: node_js node_js: - node + - '10' - '9' - '8' - - '7' - - '6' - - '5' - - '4' - - '0.12' - - '0.10' diff -Nru node-to-regex-range-3.0.0/.verb.md node-to-regex-range-5.0.1/.verb.md --- node-to-regex-range-3.0.0/.verb.md 2017-11-01 05:25:46.000000000 +0000 +++ node-to-regex-range-5.0.1/.verb.md 2019-04-07 06:04:46.000000000 +0000 @@ -8,8 +8,8 @@ **Example** ```js -var toRegexRange = require('{%= name %}'); -var regex = new RegExp(toRegexRange('15', '95')); +const toRegexRange = require('{%= name %}'); +const regex = new RegExp(toRegexRange('15', '95')); ``` A string is returned so that you can do whatever you need with it before passing it to `new RegExp()` (like adding `^` or `$` boundaries, defining flags, or combining it another string). @@ -46,13 +46,14 @@ ### Heavily tested -As of {%= date() %}, this library runs [2,783,483 test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are indeed correct. +As of {%= date() %}, this library runs [>1m test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are correct. -Tests run in ~870ms on my MacBook Pro, 2.5 GHz Intel Core i7. +Tests run in ~280ms on my MacBook Pro, 2.5 GHz Intel Core i7. -### Highly optimized +### Optimized + +Generated regular expressions are optimized: -Generated regular expressions are highly optimized: - duplicate sequences and character classes are reduced using quantifiers - smart enough to use `?` conditionals when number(s) or range(s) can be positive or negative - uses fragment caching to avoid processing the same exact string more than once @@ -66,20 +67,20 @@ Add this library to your javascript application with the following line of code ```js -var toRegexRange = require('{%= name %}'); +const toRegexRange = require('{%= name %}'); ``` The main export is a function that takes two integers: the `min` value and `max` value (formatted as strings or numbers). ```js -var source = toRegexRange('15', '95'); +const source = toRegexRange('15', '95'); //=> 1[5-9]|[2-8][0-9]|9[0-5] -var re = new RegExp('^' + source + '$'); -console.log(re.test('14')); //=> false -console.log(re.test('50')); //=> true -console.log(re.test('94')); //=> true -console.log(re.test('96')); //=> false +const regex = new RegExp(`^${source}$`); +console.log(regex.test('14')); //=> false +console.log(regex.test('50')); //=> true +console.log(regex.test('94')); //=> true +console.log(regex.test('96')); //=> false ``` ## Options @@ -96,7 +97,7 @@ console.log(toRegexRange('-10', '10')); //=> -[1-9]|-?10|[0-9] -console.log(toRegexRange('-10', '10', {capture: true})); +console.log(toRegexRange('-10', '10', { capture: true })); //=> (-[1-9]|-?10|[0-9]) ``` @@ -112,7 +113,7 @@ console.log(toRegexRange('0', '999999')); //=> [0-9]|[1-9][0-9]{1,5} -console.log(toRegexRange('0', '999999', {shorthand: true})); +console.log(toRegexRange('0', '999999', { shorthand: true })); //=> \d|[1-9]\d{1,5} ``` @@ -122,35 +123,32 @@ **Default**: `true` -This option only applies to **negative zero-padded ranges**. By default, when a negative zero-padded range is defined, the number of leading zeros is relaxed using `-0*`. - -```js -console.log(toRegexRange('-001', '100')); -//=> -0*1|0{2}[0-9]|0[1-9][0-9]|100 - -console.log(toRegexRange('-001', '100', {relaxZeros: false})); -//=> -0{2}1|0{2}[0-9]|0[1-9][0-9]|100 -``` - -
- Why are zeros relaxed for negative zero-padded ranges by default? - -Consider the following. +This option relaxes matching for leading zeros when when ranges are zero-padded. ```js -var regex = toRegexRange('-001', '100'); +const source = toRegexRange('-0010', '0010'); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> true +console.log(regex.test('-010')); //=> true +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> true +console.log(regex.test('010')); //=> true +console.log(regex.test('0010')); //=> true +``` + +When `relaxZeros` is false, matching is strict: + +```js +const source = toRegexRange('-0010', '0010', { relaxZeros: false }); +const regex = new RegExp(`^${source}$`); +console.log(regex.test('-10')); //=> false +console.log(regex.test('-010')); //=> false +console.log(regex.test('-0010')); //=> true +console.log(regex.test('10')); //=> false +console.log(regex.test('010')); //=> false +console.log(regex.test('0010')); //=> true ``` -_Note that `-001` and `100` are both three digits long_. - -In most zero-padding implementations, only a single leading zero is enough to indicate that zero-padding should be applied. Thus, the leading zeros would be "corrected" on the negative range in the example to `-01`, instead of `-001`, to make total length of each string no greater than the length of the largest number in the range (in other words, `-001` is 4 digits, but `100` is only three digits). - -If zeros were not relaxed by default, you might expect the resulting regex of the above pattern to match `-001` - given that it's defined that way in the arguments - _but it wouldn't_. It would, however, match `-01`. This gets even more ambiguous with large ranges, like `-01` to `1000000`. - -Thus, we relax zeros by default to provide a more predictable experience for users. - -
- ## Examples {%= examples() %} @@ -179,6 +177,10 @@ ## History +### v5.0.0 - 2019-04-07 + +Optimizations. Updated code to use newer ES features. + ### v2.0.0 - 2017-04-21 **New features** @@ -193,4 +195,4 @@ ## Attribution -Inspired by the python library [range-regex](https://github.com/dimka665/range-regex). +Inspired by the python library [range-regex](https://github.com/dimka665/range-regex). \ No newline at end of file