[Pkg-javascript-commits] [node-fill-range] 01/07: Import Upstream version 3.0.3

Praveen Arimbrathodiyil praveen at moszumanska.debian.org
Mon Oct 17 15:06:56 UTC 2016


This is an automated email from the git hooks/post-receive script.

praveen pushed a commit to branch master
in repository node-fill-range.

commit 70f50ad188643743c9f560a3a1b2bd214bfebca4
Author: Praveen Arimbrathodiyil <praveen at debian.org>
Date:   Mon Oct 17 20:23:25 2016 +0530

    Import Upstream version 3.0.3
---
 .editorconfig                |  13 +++
 .eslintrc.json               | 122 ++++++++++++++++++++++++++
 .gitattributes               |  10 +++
 .gitignore                   |  21 +++++
 .travis.yml                  |  12 +++
 .verb.md                     | 114 +++++++++++++++++++++++++
 LICENSE                      |  21 +++++
 README.md                    | 187 ++++++++++++++++++++++++++++++++++++++++
 benchmark/code/fill-range.js |   3 +
 benchmark/fixtures/1-100.js  |   1 +
 benchmark/fixtures/1-5.js    |   1 +
 benchmark/fixtures/2-20-2.js |   1 +
 benchmark/fixtures/a-z.js    |   1 +
 benchmark/index.js           |  30 +++++++
 benchmark/last.md            |  26 ++++++
 examples.js                  |  13 +++
 index.js                     | 199 +++++++++++++++++++++++++++++++++++++++++++
 package.json                 |  81 ++++++++++++++++++
 test/custom-expand.js        |  39 +++++++++
 test/errors.js               |  43 ++++++++++
 test/invalid.js              |  29 +++++++
 test/matching.js             |  62 ++++++++++++++
 test/options.js              |  56 ++++++++++++
 test/padding.js              |  48 +++++++++++
 test/ranges.js               | 106 +++++++++++++++++++++++
 test/special.js              |  36 ++++++++
 test/steps.js                |  85 ++++++++++++++++++
 test/support/exact.js        |  13 +++
 test/support/expand.js       |  12 +++
 test/verify-matches.js       | 114 +++++++++++++++++++++++++
 30 files changed, 1499 insertions(+)

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..818e072
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+root = true
+
+[*]
+indent_style = space
+end_of_line = lf
+charset = utf-8
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[{**/{actual,fixtures,expected,templates}/**,*.md}]
+trim_trailing_whitespace = false
+insert_final_newline = false
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..948dbdb
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,122 @@
+{
+  "ecmaFeatures": {
+    "modules": true,
+    "experimentalObjectRestSpread": true
+  },
+
+  "env": {
+    "browser": false,
+    "es6": true,
+    "node": true,
+    "mocha": true
+  },
+
+  "globals": {
+    "document": false,
+    "navigator": false,
+    "window": false
+  },
+
+  "rules": {
+    "accessor-pairs": 2,
+    "arrow-spacing": [2, { "before": true, "after": true }],
+    "block-spacing": [2, "always"],
+    "brace-style": [2, "1tbs", { "allowSingleLine": true }],
+    "comma-dangle": [2, "never"],
+    "comma-spacing": [2, { "before": false, "after": true }],
+    "comma-style": [2, "last"],
+    "constructor-super": 2,
+    "curly": [2, "multi-line"],
+    "dot-location": [2, "property"],
+    "eol-last": 2,
+    "eqeqeq": [2, "allow-null"],
+    "generator-star-spacing": [2, { "before": true, "after": true }],
+    "handle-callback-err": [2, "^(err|error)$" ],
+    "indent": [2, 2, { "SwitchCase": 1 }],
+    "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
+    "keyword-spacing": [2, { "before": true, "after": true }],
+    "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
+    "new-parens": 2,
+    "no-array-constructor": 2,
+    "no-caller": 2,
+    "no-class-assign": 2,
+    "no-cond-assign": 2,
+    "no-const-assign": 2,
+    "no-control-regex": 2,
+    "no-debugger": 2,
+    "no-delete-var": 2,
+    "no-dupe-args": 2,
+    "no-dupe-class-members": 2,
+    "no-dupe-keys": 2,
+    "no-duplicate-case": 2,
+    "no-empty-character-class": 2,
+    "no-eval": 2,
+    "no-ex-assign": 2,
+    "no-extend-native": 2,
+    "no-extra-bind": 2,
+    "no-extra-boolean-cast": 2,
+    "no-extra-parens": [2, "functions"],
+    "no-fallthrough": 2,
+    "no-floating-decimal": 2,
+    "no-func-assign": 2,
+    "no-implied-eval": 2,
+    "no-inner-declarations": [2, "functions"],
+    "no-invalid-regexp": 2,
+    "no-irregular-whitespace": 2,
+    "no-iterator": 2,
+    "no-label-var": 2,
+    "no-labels": 2,
+    "no-lone-blocks": 2,
+    "no-mixed-spaces-and-tabs": 2,
+    "no-multi-spaces": 2,
+    "no-multi-str": 2,
+    "no-multiple-empty-lines": [2, { "max": 1 }],
+    "no-native-reassign": 0,
+    "no-negated-in-lhs": 2,
+    "no-new": 2,
+    "no-new-func": 2,
+    "no-new-object": 2,
+    "no-new-require": 2,
+    "no-new-wrappers": 2,
+    "no-obj-calls": 2,
+    "no-octal": 2,
+    "no-octal-escape": 2,
+    "no-proto": 0,
+    "no-redeclare": 2,
+    "no-regex-spaces": 2,
+    "no-return-assign": 2,
+    "no-self-compare": 2,
+    "no-sequences": 2,
+    "no-shadow-restricted-names": 2,
+    "no-spaced-func": 2,
+    "no-sparse-arrays": 2,
+    "no-this-before-super": 2,
+    "no-throw-literal": 2,
+    "no-trailing-spaces": 0,
+    "no-undef": 2,
+    "no-undef-init": 2,
+    "no-unexpected-multiline": 2,
+    "no-unneeded-ternary": [2, { "defaultAssignment": false }],
+    "no-unreachable": 2,
+    "no-unused-vars": [2, { "vars": "all", "args": "none" }],
+    "no-useless-call": 0,
+    "no-with": 2,
+    "one-var": [0, { "initialized": "never" }],
+    "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
+    "padded-blocks": [0, "never"],
+    "quotes": [2, "single", "avoid-escape"],
+    "radix": 2,
+    "semi": [2, "always"],
+    "semi-spacing": [2, { "before": false, "after": true }],
+    "space-before-blocks": [2, "always"],
+    "space-before-function-paren": [2, "never"],
+    "space-in-parens": [2, "never"],
+    "space-infix-ops": 2,
+    "space-unary-ops": [2, { "words": true, "nonwords": false }],
+    "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
+    "use-isnan": 2,
+    "valid-typeof": 2,
+    "wrap-iife": [2, "any"],
+    "yoda": [2, "never"]
+  }
+}
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..4a3f1d3
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,10 @@
+# Enforce Unix newlines
+* text eol=lf
+
+# binaries
+*.ai binary
+*.psd binary
+*.jpg binary
+*.gif binary
+*.png binary
+*.jpeg binary
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7988154
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+# always ignore files
+*.DS_Store
+*.sublime-*
+
+# test related, or directories generated by tests
+test/actual
+actual
+coverage
+
+# npm
+node_modules
+npm-debug.log
+
+# misc
+_gh_pages
+benchmark
+bower_components
+vendor
+temp
+tmp
+TODO.md
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..04a029e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,12 @@
+sudo: false
+language: node_js
+node_js:
+  - node
+  - '6'
+  - '5'
+  - '0.12'
+matrix:
+  fast_finish: true
+  allow_failures:
+    - node_js: '4'
+    - node_js: '0.12'
diff --git a/.verb.md b/.verb.md
new file mode 100644
index 0000000..f022cb2
--- /dev/null
+++ b/.verb.md
@@ -0,0 +1,114 @@
+## Usage
+
+Expands numbers and letters, optionally using a `step` as the last argument. _(Numbers may be defined as JavaScript numbers or strings)_.
+
+```js
+var fill = require('{%= name %}');
+
+console.log(fill('a', 'e'));
+//=> ['a', 'b', 'c', 'd', 'e']
+
+console.log(fill(0, 25, 5));
+//=> [ 0, 5, 10, 15, 20, 25 ]
+
+console.log(fill('a', 'e', {toRegex: true}));
+//=> '[a-e]'
+
+console.log(fill('a', 'z', 3, {toRegex: true}));
+//=> 'a|d|g|j|m|p|s|v|y'
+
+console.log(fill('1', '100', {toRegex: true}));
+//=> '[1-9]|[1-9][0-9]|100'
+```
+
+Create regex-compatible ranges (returns a string, which can be used however you need to create a regex):
+
+```js
+console.log(fill('a', 'e', {toRegex: true}));
+//=> '[a-e]'
+
+console.log(fill('a', 'z', 3, {toRegex: true}));
+//=> 'a|d|g|j|m|p|s|v|y'
+
+console.log(fill('1', '100', {toRegex: true}));
+//=> '[1-9]|[1-9][0-9]|100'
+```
+
+**Params**
+
+```js
+fill(start, stop, step, options, fn);
+```
+
+ - `start`: **{String|Number}** the number or letter to start with
+ - `end`: **{String|Number}** the number or letter to end with
+ - `step`: **{String|Number}** optionally pass the step to use. works for letters or numbers.
+ - `options`: **{Object}**:
+    + `toRegex`: return a regex-compatible string (still returned as an array for consistency)
+    + `step`: pass the step on the options as an alternative to passing it as an argument
+    + `strict`: `undefined` by default, set to true to throw errors on invalid ranges. 
+ - `fn`: **{Function}** optionally [pass a function](#custom-function) to modify each character. This can also be defined as `options.transform`
+
+
+**Examples**
+
+```js
+fill(1, 3)
+//=> ['1', '2', '3']
+
+fill('1', '3')
+//=> ['1', '2', '3']
+
+fill('0', '-5')
+//=> [ '0', '-1', '-2', '-3', '-4', '-5' ]
+
+fill(-9, 9, 3)
+//=> [ '-9', '-6', '-3', '0', '3', '6', '9' ])
+
+fill('-1', '-10', '-2')
+//=> [ '-1', '-3', '-5', '-7', '-9' ]
+
+fill('1', '10', '2')
+//=> [ '1', '3', '5', '7', '9' ]
+
+fill('a', 'e')
+//=> ['a', 'b', 'c', 'd', 'e']
+
+fill('a', 'e', 2)
+//=> ['a', 'c', 'e']
+
+fill('A', 'E', 2)
+//=> ['A', 'C', 'E']
+```
+
+### Invalid ranges
+
+When an invalid range is passed, `null` is returned. 
+
+```js
+fill('1.1', '2');   // decimals not supported in ranges
+//=> null
+
+fill('a', '2');     // unmatched values
+//=> null
+
+fill(1, 10, 'foo'); // invalid step
+//=> null
+```
+
+If you want errors to be throw, set `options.strict` to true.
+
+
+### Custom function
+
+Optionally pass a custom function as last argument or on `options.transform`.
+
+```js
+// increase padding by two
+var arr = fill('01', '05', function(val, a, b, step, idx, arr, options) {
+  return repeat('0', (options.maxLength + 2) - val.length) + val;
+});
+
+console.log(arr);
+//=> ['0001', '0002', '0003', '0004', '0005']
+```
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..842218c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014-2016, Jon Schlinkert
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e069ea9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,187 @@
+# fill-range [![NPM version](https://img.shields.io/npm/v/fill-range.svg?style=flat)](https://www.npmjs.com/package/fill-range) [![NPM downloads](https://img.shields.io/npm/dm/fill-range.svg?style=flat)](https://npmjs.org/package/fill-range) [![Build Status](https://img.shields.io/travis/jonschlinkert/fill-range.svg?style=flat)](https://travis-ci.org/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`
+
+## Table of Contents
+
+- [Install](#install)
+- [Usage](#usage)
+  * [Invalid ranges](#invalid-ranges)
+  * [Custom function](#custom-function)
+- [About](#about)
+  * [Related projects](#related-projects)
+  * [Contributing](#contributing)
+  * [Building docs](#building-docs)
+  * [Running tests](#running-tests)
+  * [Author](#author)
+  * [License](#license)
+
+_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
+
+## Install
+
+Install with [npm](https://www.npmjs.com/):
+
+```sh
+$ npm install --save fill-range
+```
+
+## Usage
+
+Expands numbers and letters, optionally using a `step` as the last argument. _(Numbers may be defined as JavaScript numbers or strings)_.
+
+```js
+var fill = require('fill-range');
+
+console.log(fill('a', 'e'));
+//=> ['a', 'b', 'c', 'd', 'e']
+
+console.log(fill(0, 25, 5));
+//=> [ 0, 5, 10, 15, 20, 25 ]
+
+console.log(fill('a', 'e', {toRegex: true}));
+//=> '[a-e]'
+
+console.log(fill('a', 'z', 3, {toRegex: true}));
+//=> 'a|d|g|j|m|p|s|v|y'
+
+console.log(fill('1', '100', {toRegex: true}));
+//=> '[1-9]|[1-9][0-9]|100'
+```
+
+Create regex-compatible ranges (returns a string, which can be used however you need to create a regex):
+
+```js
+console.log(fill('a', 'e', {toRegex: true}));
+//=> '[a-e]'
+
+console.log(fill('a', 'z', 3, {toRegex: true}));
+//=> 'a|d|g|j|m|p|s|v|y'
+
+console.log(fill('1', '100', {toRegex: true}));
+//=> '[1-9]|[1-9][0-9]|100'
+```
+
+**Params**
+
+```js
+fill(start, stop, step, options, fn);
+```
+
+* `start`: **{String|Number}** the number or letter to start with
+* `end`: **{String|Number}** the number or letter to end with
+* `step`: **{String|Number}** optionally pass the step to use. works for letters or numbers.
+* `options`: **{Object}**:
+  - `toRegex`: return a regex-compatible string (still returned as an array for consistency)
+  - `step`: pass the step on the options as an alternative to passing it as an argument
+  - `strict`: `undefined` by default, set to true to throw errors on invalid ranges.
+* `fn`: **{Function}** optionally [pass a function](#custom-function) to modify each character. This can also be defined as `options.transform`
+
+**Examples**
+
+```js
+fill(1, 3)
+//=> ['1', '2', '3']
+
+fill('1', '3')
+//=> ['1', '2', '3']
+
+fill('0', '-5')
+//=> [ '0', '-1', '-2', '-3', '-4', '-5' ]
+
+fill(-9, 9, 3)
+//=> [ '-9', '-6', '-3', '0', '3', '6', '9' ])
+
+fill('-1', '-10', '-2')
+//=> [ '-1', '-3', '-5', '-7', '-9' ]
+
+fill('1', '10', '2')
+//=> [ '1', '3', '5', '7', '9' ]
+
+fill('a', 'e')
+//=> ['a', 'b', 'c', 'd', 'e']
+
+fill('a', 'e', 2)
+//=> ['a', 'c', 'e']
+
+fill('A', 'E', 2)
+//=> ['A', 'C', 'E']
+```
+
+### Invalid ranges
+
+When an invalid range is passed, `null` is returned.
+
+```js
+fill('1.1', '2');   // decimals not supported in ranges
+//=> null
+
+fill('a', '2');     // unmatched values
+//=> null
+
+fill(1, 10, 'foo'); // invalid step
+//=> null
+```
+
+If you want errors to be throw, set `options.strict` to true.
+
+### Custom function
+
+Optionally pass a custom function as last argument or on `options.transform`.
+
+```js
+// increase padding by two
+var arr = fill('01', '05', function(val, a, b, step, idx, arr, options) {
+  return repeat('0', (options.maxLength + 2) - val.length) + val;
+});
+
+console.log(arr);
+//=> ['0001', '0002', '0003', '0004', '0005']
+```
+
+## About
+
+### Related projects
+
+* [braces](https://www.npmjs.com/package/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://github.com/jonschlinkert/braces) | [homepage](https://github.com/jonschlinkert/braces "Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.")
+* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://github.com/jonschlinkert/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.")
+* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.")
+* [to-regex-range](https://www.npmjs.com/package/to-regex-range): Returns a regex-compatible range from two numbers, min and max, with 855,412 generated unit tests… [more](https://github.com/jonschlinkert/to-regex-range) | [homepage](https://github.com/jonschlinkert/to-regex-range "Returns a regex-compatible range from two numbers, min and max, with 855,412 generated unit tests to validate it's accuracy! Useful for creating regular expressions to validate numbers, ranges, years, etc. Ret [...]
+
+### Contributing
+
+Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
+
+### Building docs
+
+_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_
+
+To generate the readme and API documentation with [verb](https://github.com/verbose/verb):
+
+```sh
+$ npm install -g verb verb-generate-readme && verb
+```
+
+### Running tests
+
+Install dev dependencies:
+
+```sh
+$ npm install -d && npm test
+```
+
+### Author
+
+**Jon Schlinkert**
+
+* [github/jonschlinkert](https://github.com/jonschlinkert)
+* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
+
+### License
+
+Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert).
+Released under the [MIT license](https://github.com/jonschlinkert/fill-range/blob/master/LICENSE).
+
+***
+
+_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.1.30, on September 15, 2016._
\ No newline at end of file
diff --git a/benchmark/code/fill-range.js b/benchmark/code/fill-range.js
new file mode 100644
index 0000000..3e20024
--- /dev/null
+++ b/benchmark/code/fill-range.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('../..');
diff --git a/benchmark/fixtures/1-100.js b/benchmark/fixtures/1-100.js
new file mode 100644
index 0000000..df385d3
--- /dev/null
+++ b/benchmark/fixtures/1-100.js
@@ -0,0 +1 @@
+module.exports = ['1', '100'];
diff --git a/benchmark/fixtures/1-5.js b/benchmark/fixtures/1-5.js
new file mode 100644
index 0000000..a5e8d24
--- /dev/null
+++ b/benchmark/fixtures/1-5.js
@@ -0,0 +1 @@
+module.exports = ['1', '5'];
diff --git a/benchmark/fixtures/2-20-2.js b/benchmark/fixtures/2-20-2.js
new file mode 100644
index 0000000..cd570e2
--- /dev/null
+++ b/benchmark/fixtures/2-20-2.js
@@ -0,0 +1 @@
+module.exports = ['2', '20', '2'];
diff --git a/benchmark/fixtures/a-z.js b/benchmark/fixtures/a-z.js
new file mode 100644
index 0000000..9600cd4
--- /dev/null
+++ b/benchmark/fixtures/a-z.js
@@ -0,0 +1 @@
+module.exports = ['a', 'z'];
diff --git a/benchmark/index.js b/benchmark/index.js
new file mode 100644
index 0000000..2888f6e
--- /dev/null
+++ b/benchmark/index.js
@@ -0,0 +1,30 @@
+'use strict';
+
+var path = require('path');
+var util = require('util');
+var cyan = require('ansi-cyan');
+var argv = require('yargs-parser')(process.argv.slice(2));
+var Suite = require('benchmarked');
+
+function run(code, fixtures) {
+  var suite = new Suite({
+    cwd: __dirname,
+    fixtures: `fixtures/${fixtures}.js`,
+    code: `code/${code}*.js`
+  });
+
+  if (argv.dry) {
+    suite.dryRun(function(code, fixture) {
+      if (/special/.test(fixture.stem)) return;
+      console.log(cyan('%s > %s'), code.key, fixture.key);
+      var args = require(fixture.path);
+      var res = code.run.apply(null, args).length;
+      console.log(util.inspect(res, null, 10));
+      console.log();
+    });
+  } else {
+    suite.run();
+  }
+}
+
+run(argv._[0] || '*', argv._[1] || '**/{1,2,a}*');
diff --git a/benchmark/last.md b/benchmark/last.md
new file mode 100644
index 0000000..7bf8958
--- /dev/null
+++ b/benchmark/last.md
@@ -0,0 +1,26 @@
+#1: 1-100-logical-or.js
+  fill-range.js x 272,324 ops/sec ±0.86% (96 runs sampled)
+
+#2: 1-100.js
+  fill-range.js x 348,125 ops/sec ±0.90% (93 runs sampled)
+
+#3: 1-5.js
+  fill-range.js x 1,295,990 ops/sec ±0.95% (98 runs sampled)
+
+#4: 2-20-2.js
+  fill-range.js x 1,009,256 ops/sec ±0.70% (99 runs sampled)
+
+#5: a-z-character-class.js
+  fill-range.js x 1,360,704 ops/sec ±0.75% (93 runs sampled)
+
+#6: a-z.js
+  fill-range.js x 1,006,624 ops/sec ±0.76% (98 runs sampled)
+
+#7: options-num.js
+  fill-range.js x 1,063,593 ops/sec ±0.82% (97 runs sampled)
+
+#8: options-str.js
+  fill-range.js x 1,347,300 ops/sec ±0.88% (92 runs sampled)
+
+#9: random.js
+  fill-range.js x 580,981 ops/sec ±0.90% (88 runs sampled)
\ No newline at end of file
diff --git a/examples.js b/examples.js
new file mode 100644
index 0000000..44073ef
--- /dev/null
+++ b/examples.js
@@ -0,0 +1,13 @@
+var fill = require('./');
+
+console.log(fill(0, 25, 5));
+//=> [ 0, 5, 10, 15, 20, 25 ]
+
+console.log(fill('a', 'e', {toRegex: true}));
+//=> '[a-e]'
+
+console.log(fill('a', 'z', 3, {toRegex: true}));
+//=> 'a|d|g|j|m|p|s|v|y'
+
+console.log(fill('1', '100', {toRegex: true}));
+//=> '[1-9]|[1-9][0-9]|100'
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..ec822b3
--- /dev/null
+++ b/index.js
@@ -0,0 +1,199 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+var util = require('util');
+var isNumber = require('is-number');
+var extend = require('extend-shallow');
+var repeat = require('repeat-string');
+var toRegex = require('to-regex-range');
+
+/**
+ * Return a range of numbers or letters.
+ *
+ * @param  {String} `start` Start of the range
+ * @param  {String} `stop` End of the range
+ * @param  {String} `step` Increment or decrement to use.
+ * @param  {Function} `fn` Custom function to modify each element in the range.
+ * @return {Array}
+ */
+
+function fillRange(start, stop, step, options) {
+  if (typeof start === 'undefined') {
+    return [];
+  }
+
+  if (typeof stop === 'undefined' || start === stop) {
+    // special case, for handling negative zero
+    var isString = typeof start === 'string';
+    if (isNumber(start) && !toNumber(start)) {
+      return [isString ? '0' : 0];
+    }
+    return [start];
+  }
+
+  if (typeof step !== 'number' && typeof step !== 'string') {
+    options = step;
+    step = null;
+  }
+
+  if (typeof options === 'function') {
+    options = { transform: options };
+  }
+
+  var opts = extend({step: step}, options);
+  if (opts.step && !isValidNumber(opts.step)) {
+    if (opts.strict === true) {
+      throw new TypeError('expected options.step to be a number');
+    }
+    return [];
+  }
+
+  opts.isNumber = isValidNumber(start) && isValidNumber(stop);
+  if (!opts.isNumber && !isValid(start, stop)) {
+    if (opts.strict === true) {
+      throw new RangeError('invalid range arguments: ' + util.inspect([start, stop]));
+    }
+    return [];
+  }
+
+  opts.isPadded = isPadded(start) || isPadded(stop);
+  opts.toString = opts.stringify
+    || typeof opts.step === 'string'
+    || typeof start === 'string'
+    || typeof stop === 'string'
+    || !opts.isNumber;
+
+  if (opts.isPadded) {
+    opts.maxLength = Math.max(String(start).length, String(stop).length);
+  }
+
+  // support legacy minimatch/fill-range options
+  if (typeof opts.optimize === 'boolean') opts.toRegex = opts.optimize;
+  if (typeof opts.makeRe === 'boolean') opts.toRegex = opts.makeRe;
+  return expand(start, stop, opts);
+}
+
+function expand(start, stop, options) {
+  var a = options.isNumber ? toNumber(start) : start.charCodeAt(0);
+  var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0);
+
+  var step = Math.abs(toNumber(options.step)) || 1;
+  if (options.toRegex && step === 1) {
+    return toRange(a, b, options);
+  }
+
+  var zero = {greater: [], lesser: []};
+  var asc = a < b;
+  var arr = new Array(Math.round((asc ? b - a : a - b) / step));
+  var idx = 0;
+
+  while (asc ? a <= b : a >= b) {
+    var val = options.isNumber ? a : String.fromCharCode(a);
+    if (options.toRegex && (val >= 0 || !options.isNumber)) {
+      zero.greater.push(val);
+    } else {
+      zero.lesser.push(Math.abs(val));
+    }
+
+    if (options.isPadded) {
+      val = zeros(val, options);
+    }
+
+    if (options.toString) {
+      val = String(val);
+    }
+
+    if (typeof options.transform === 'function') {
+      arr[idx++] = options.transform(val, a, b, step, idx, arr, options);
+    } else {
+      arr[idx++] = val;
+    }
+
+    if (asc) {
+      a += step;
+    } else {
+      a -= step;
+    }
+  }
+
+  if (options.toRegex === true) {
+    return toSequence(arr, zero);
+  }
+  return arr;
+}
+
+function toRange(a, b, options) {
+  if (options.isNumber) {
+    return toRegex(Math.min(a, b), Math.max(a, b));
+  }
+  var start = String.fromCharCode(Math.min(a, b));
+  var stop = String.fromCharCode(Math.max(a, b));
+  return '[' + start + '-' + stop + ']';
+}
+
+function toSequence(arr, zeros) {
+  var greater = '', lesser = '';
+  if (zeros.greater.length) {
+    greater = zeros.greater.join('|');
+  }
+  if (zeros.lesser.length) {
+    lesser = '-(' + zeros.lesser.join('|') + ')';
+  }
+  if (greater && lesser) {
+    return greater + '|' + lesser;
+  }
+  return greater || lesser;
+}
+
+function zeros(val, options) {
+  if (options.isPadded) {
+    var str = String(val);
+    var len = str.length;
+    var dash = '';
+    if (str.charAt(0) === '-') {
+      dash = '-';
+      str = str.slice(1);
+    }
+    var diff = options.maxLength - len;
+    var pad = repeat('0', diff);
+    val = (dash + pad + str);
+  }
+  if (options.stringify) {
+    return String(val);
+  }
+  return val;
+}
+
+function toNumber(val) {
+  return Number(val) || 0;
+}
+
+function isPadded(str) {
+  return /^-*0\d+/.test(str);
+}
+
+function isValid(min, max) {
+  return (isValidNumber(min) || isValidLetter(min))
+      && (isValidNumber(max) || isValidLetter(max));
+}
+
+function isValidLetter(ch) {
+  return typeof ch === 'string' && ch.length === 1 && /^\w+$/.test(ch);
+}
+
+function isValidNumber(n) {
+  return isNumber(n) && !/\./.test(n);
+}
+
+/**
+ * Expose `fillRange`
+ * @type {Function}
+ */
+
+module.exports = fillRange;
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..f1c51d4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,81 @@
+{
+  "name": "fill-range",
+  "description": "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`",
+  "version": "3.0.3",
+  "homepage": "https://github.com/jonschlinkert/fill-range",
+  "author": "Jon Schlinkert (https://github.com/jonschlinkert)",
+  "contributors": [
+    "Jon Schlinkert <jon.schlinkert at sellside.com> (http://twitter.com/jonschlinkert)",
+    "Paul Miller <paul+gh at paulmillr.com> (paulmillr.com)"
+  ],
+  "repository": "jonschlinkert/fill-range",
+  "bugs": {
+    "url": "https://github.com/jonschlinkert/fill-range/issues"
+  },
+  "license": "MIT",
+  "files": [
+    "index.js"
+  ],
+  "main": "index.js",
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "dependencies": {
+    "extend-shallow": "^2.0.1",
+    "is-number": "^3.0.0",
+    "repeat-string": "^1.5.4",
+    "to-regex-range": "^0.2.0"
+  },
+  "devDependencies": {
+    "gulp-format-md": "^0.1.10",
+    "mocha": "^3.0.2"
+  },
+  "keywords": [
+    "array",
+    "alpha",
+    "alphabetical",
+    "bash",
+    "brace",
+    "expand",
+    "expansion",
+    "fill",
+    "glob",
+    "match",
+    "matches",
+    "matching",
+    "number",
+    "numerical",
+    "regex",
+    "range",
+    "ranges",
+    "sh"
+  ],
+  "verb": {
+    "related": {
+      "list": [
+        "braces",
+        "to-regex-range",
+        "expand-range",
+        "micromatch"
+      ]
+    },
+    "toc": true,
+    "layout": "default",
+    "tasks": [
+      "readme"
+    ],
+    "plugins": [
+      "gulp-format-md"
+    ],
+    "lint": {
+      "reflinks": true
+    },
+    "reflinks": [
+      "verb",
+      "verb-generate-readme"
+    ]
+  }
+}
diff --git a/test/custom-expand.js b/test/custom-expand.js
new file mode 100644
index 0000000..be4744b
--- /dev/null
+++ b/test/custom-expand.js
@@ -0,0 +1,39 @@
+'use strict';
+
+require('mocha');
+var repeat = require('repeat-string');
+var isNumber = require('is-number');
+var assert = require('assert');
+var exact = require('./support/exact');
+var fill = require('..');
+
+describe('custom function for expansions:', function() {
+  it('should expose the current value as the first param.', function() {
+    var arr = fill(1, 5, function(val, a, b, step, idx, arr, options) {
+      return val;
+    });
+    exact(arr, [1, 2, 3, 4, 5]);
+  });
+
+  it('should expose the `isNumber` boolean as the second param.', function() {
+    var arr = fill('a', 'e', function(val, a, b, step, idx, arr, options) {
+      return !isNumber ? String.fromCharCode(val) : val;
+    });
+    exact(arr, ['a', 'b', 'c', 'd', 'e']);
+  });
+
+  it('should expose padding `maxLength` on options', function() {
+    var arr = fill('01', '05', function(val, a, b, step, idx, arr, options) {
+      // increase padding by two
+      return repeat('0', (options.maxLength + 2) - val.length) + val;
+    });
+    exact(arr, ['0001', '0002', '0003', '0004', '0005']);
+  });
+
+  it('should expose the index as the fifth param.', function() {
+    var arr = fill('a', 'e', function(val, a, b, step, idx, arr, options) {
+      return val + (idx - 1);
+    });
+    exact(arr, ['a0', 'b1', 'c2', 'd3', 'e4']);
+  });
+});
diff --git a/test/errors.js b/test/errors.js
new file mode 100644
index 0000000..cb8ba2a
--- /dev/null
+++ b/test/errors.js
@@ -0,0 +1,43 @@
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var fill = require('..');
+
+describe('error handling', function() {
+  it('should throw when range arguments are invalid and `strict` is true.', function() {
+    assert.throws(function() {
+      fill('0a', '0z', {strict: true});
+    }, /invalid range arguments: \[ \'0a\', \'0z\' \]/);
+
+    assert.throws(function() {
+      fill('.', '*', 2, {strict: true});
+    }, /invalid range arguments: \[ \'\.\', \'\*\' \]/);
+
+    assert.throws(function() {
+      fill('!', '$', {strict: true});
+    }, /invalid range arguments: \[ \'\!\', \'\$\' \]/);
+  });
+
+  it('should throw when args are incompatible.', function() {
+    assert.throws(function() {
+      fill('a8', 10, {strict: true});
+    }, /invalid range arguments: \[ \'a8\', 10 \]/);
+
+    assert.throws(function() {
+      fill(1, 'zz', {strict: true});
+    }, /invalid range arguments: \[ 1, \'zz\' \]/);
+  });
+
+  it('should throw when the step is bad.', function() {
+    assert.throws(function() {
+      fill('1', '10', 'z', {strict: true});
+    }, /expected options\.step to be a number/);
+    assert.throws(function() {
+      fill('a', 'z', 'a', {strict: true});
+    }, /expected options\.step to be a number/);
+    assert.throws(function() {
+      fill('a', 'z', '0a', {strict: true});
+    }, /expected options\.step to be a number/);
+  });
+});
diff --git a/test/invalid.js b/test/invalid.js
new file mode 100644
index 0000000..85623b4
--- /dev/null
+++ b/test/invalid.js
@@ -0,0 +1,29 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var fill = require('..');
+
+describe('invalid ranges', function() {
+  it('should return an empty array when options.strict is not true', function() {
+    assert.deepEqual(fill('1.1', '2.1'), []);
+    assert.deepEqual(fill('1.2', '2'), []);
+    assert.deepEqual(fill('1.20', '2'), []);
+    assert.deepEqual(fill('1', '0f'), []);
+    assert.deepEqual(fill('1', '10', 'ff'), []);
+    assert.deepEqual(fill('1', '10.f'), []);
+    assert.deepEqual(fill('1', '10f'), []);
+    assert.deepEqual(fill('1', '20', '2f'), []);
+    assert.deepEqual(fill('1', '20', 'f2'), []);
+    assert.deepEqual(fill('1', '2f', '2'), []);
+    assert.deepEqual(fill('1', 'ff', '2'), []);
+    assert.deepEqual(fill('1', 'ff'), []);
+  });
+});
diff --git a/test/matching.js b/test/matching.js
new file mode 100644
index 0000000..b406e28
--- /dev/null
+++ b/test/matching.js
@@ -0,0 +1,62 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var expand = require('./support/expand');
+var exact = require('./support/exact');
+var fill = require('..');
+
+function toRegex() {
+  var str = fill.apply(null, arguments);
+  return new RegExp('^(' + str + ')$');
+}
+function matcher() {
+  var regex = toRegex.apply(null, arguments);
+  return function(num) {
+    return regex.test(String(num));
+  };
+}
+function isMatch() {
+  var args = [].slice.call(arguments);
+  var last = args.pop();
+  var fn = matcher.apply(null, args);
+  return fn(last);
+}
+
+describe('when options.toRegex is used', function() {
+  it('should create regex ranges for numbers in ascending order', function() {
+    assert(!isMatch(2, 8, {toRegex: true}, '10'));
+    assert(isMatch(2, 8, {toRegex: true}, '3'));
+    assert(isMatch(2, 10, {toRegex: true}, '10'));
+    assert(isMatch(2, 100, {toRegex: true}, '10'));
+    assert(!isMatch(2, 100, {toRegex: true}, '101'));
+  });
+
+  it('should create regex ranges with positive and negative numbers', function() {
+    assert(isMatch(-10, 10, {toRegex: true}, '10'));
+    assert(isMatch(-10, 10, 2, {toRegex: true}, '10'));
+  });
+
+  it('should create regex ranges for numbers in descending order', function() {
+    assert(isMatch(8, 2, {toRegex: true}, '2'));
+    assert(isMatch(8, 2, {toRegex: true}, '8'));
+    assert(!isMatch(8, 2, {toRegex: true}, '10'));
+  });
+
+  it('should create regex ranges when a step is given', function() {
+    assert(!isMatch(8, 2, {toRegex: true, step: 2}, '10'));
+    assert(!isMatch(8, 2, {toRegex: true, step: 2}, '3'));
+    assert(!isMatch(8, 2, {toRegex: true, step: 2}, '5'));
+    assert(isMatch(8, 2, {toRegex: true, step: 2}, '8'));
+    assert(!isMatch(2, 8, {toRegex: true, step: 2}, '10'));
+    assert(!isMatch(2, 8, {toRegex: true, step: 2}, '3'));
+    assert(isMatch(2, 8, {toRegex: true, step: 2}, '8'));
+  });
+});
diff --git a/test/options.js b/test/options.js
new file mode 100644
index 0000000..2275df8
--- /dev/null
+++ b/test/options.js
@@ -0,0 +1,56 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var exact = require('./support/exact');
+var fill = require('..');
+
+describe('options', function() {
+  describe('options.stringify', function() {
+    it('should cast values to strings', function() {
+      exact(fill('1', '10', '1', {stringify: true}), ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']);
+      exact(fill(2, 10, '2', {stringify: true}), ['2', '4', '6', '8', '10']);
+      exact(fill(2, 10, 1, {stringify: true}), ['2', '3', '4', '5', '6', '7', '8', '9', '10']);
+      exact(fill(2, 10, 3, {stringify: true}), ['2', '5', '8']);
+    });
+  });
+
+  describe('options.toRegex', function() {
+    it('should create regex ranges for numbers in ascending order', function() {
+      assert.equal(fill(2, 8, {toRegex: true}), '[2-8]');
+      assert.equal(fill(2, 10, {toRegex: true}), '[2-9]|10');
+      assert.equal(fill(2, 100, {toRegex: true}), '[2-9]|[1-9][0-9]|100');
+    });
+
+    it('should create regex ranges for alpha chars defined in ascending order', function() {
+      assert.equal(fill('a', 'b', {toRegex: true}), '[a-b]');
+      assert.equal(fill('A', 'b', {toRegex: true}), '[A-b]');
+      assert.equal(fill('Z', 'a', {toRegex: true}), '[Z-a]');
+    });
+
+    it('should create regex ranges for alpha chars defined in descending order', function() {
+      assert.equal(fill('z', 'A', {toRegex: true}), '[A-z]');
+    });
+
+    it('should create regex ranges with positive and negative numbers', function() {
+      assert.equal(fill(-10, 10, {toRegex: true}), '-[1-9]|-?10|[0-9]');
+      assert.equal(fill(-10, 10, 2, {toRegex: true}), '0|2|4|6|8|10|-(10|8|6|4|2)');
+    });
+
+    it('should create regex ranges for numbers in descending order', function() {
+      assert.equal(fill(8, 2, {toRegex: true}), '[2-8]');
+    });
+
+    it('should create regex ranges when a step is given', function() {
+      assert.equal(fill(8, 2, {toRegex: true, step: 2}), '8|6|4|2');
+      assert.equal(fill(2, 8, {toRegex: true, step: 2}), '2|4|6|8');
+    });
+  });
+});
diff --git a/test/padding.js b/test/padding.js
new file mode 100644
index 0000000..52fe751
--- /dev/null
+++ b/test/padding.js
@@ -0,0 +1,48 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var util = require('util');
+var assert = require('assert');
+var exact = require('./support/exact');
+var fill = require('..');
+
+describe('padding: numbers', function() {
+  it('should pad incremented numbers:', function() {
+    exact(fill('1', '3'), ['1', '2', '3']);
+    exact(fill('01', '03'), ['01', '02', '03']);
+    exact(fill('01', '3'), ['01', '02', '03']);
+    exact(fill('1', '03'), ['01', '02', '03']);
+    exact(fill('0001', '0003'), ['0001', '0002', '0003']);
+    exact(fill('-10', '00'), ['-10', '-09', '-08', '-07', '-06', '-05', '-04', '-03', '-02', '-01', '000']);
+    exact(fill('05', '010'), ['005','006','007','008','009','010']);
+    exact(fill('05', '100'), ['005','006','007','008','009','010','011','012','013','014','015','016','017','018','019','020','021','022','023','024','025','026','027','028','029','030','031','032','033','034','035','036','037','038','039','040','041','042','043','044','045','046','047','048','049','050','051','052','053','054','055','056','057','058','059','060','061','062','063','064','065','066','067','068','069','070','071','072','073','074','075','076','077','078','079','080','081', [...]
+  });
+
+  it('should pad decremented numbers:', function() {
+    exact(fill('03', '01'), ['03', '02', '01']);
+    exact(fill('3', '01'), ['03', '02', '01']);
+    exact(fill('003', '1'), ['003', '002', '001']);
+    exact(fill('003', '001'), ['003', '002', '001']);
+    exact(fill('3', '001'), ['003', '002', '001']);
+    exact(fill('03', '001'), ['003', '002', '001']);
+  });
+
+  it('should pad stepped numbers', function() {
+    exact(fill('1', '05', '3'), ['01','04']);
+    exact(fill('1', '005', '3'), ['001','004']);
+    exact(fill('00', '1000', '200'), ['0000','0200', '0400', '0600', '0800', '1000']);
+    exact(fill('0', '01000', '200'), ['00000','00200', '00400', '00600', '00800', '01000']);
+    exact(fill('001', '5', '3'), ['001','004']);
+    exact(fill('02', '10', 2), ['02', '04', '06', '08', '10']);
+    exact(fill('002', '10', 2), ['002', '004', '006', '008', '010']);
+    exact(fill('002', '010', 2), ['002', '004', '006', '008', '010']);
+    exact(fill('-04', 4, 2), ['-04', '-02', '000', '002', '004']);
+  });
+});
diff --git a/test/ranges.js b/test/ranges.js
new file mode 100644
index 0000000..1feeead
--- /dev/null
+++ b/test/ranges.js
@@ -0,0 +1,106 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var exact = require('./support/exact');
+var fill = require('..');
+
+describe('ranges', function() {
+  describe('alphabetical', function() {
+    it('should increment alphabetical ranges', function() {
+      exact(fill('a'), ['a']);
+      exact(fill('a', 'a'), ['a']);
+      exact(fill('a', 'b'), ['a', 'b']);
+      exact(fill('a', 'e'), ['a', 'b', 'c', 'd', 'e']);
+      exact(fill('A', 'E'), ['A', 'B', 'C', 'D', 'E']);
+    });
+
+    it('should decrement alphabetical ranges', function() {
+      exact(fill('E', 'A'), ['E', 'D', 'C', 'B', 'A']);
+      exact(fill('a', 'C'), ['a','`','_','^',']',"\\",'[','Z','Y','X','W','V','U','T','S','R','Q','P','O','N','M','L','K','J','I','H','G','F','E','D','C']);
+      exact(fill('z', 'm'), ['z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm']);
+    });
+  });
+
+  describe('alphanumeric', function() {
+    it('should increment alphanumeric ranges', function() {
+      exact(fill('9', 'B'), ['9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B']);
+      exact(fill('A', '10'), ['A', '@', '?', '>', '=', '<', ';', ':', '9', '8', '7', '6', '5', '4', '3', '2', '1']);
+      exact(fill('a', '10'), ['a', '`', '_', '^', ']', '\\', '[', 'Z', 'Y', 'X', 'W', 'V', 'U', 'T', 'S', 'R', 'Q', 'P', 'O', 'N', 'M', 'L', 'K', 'J', 'I', 'H', 'G', 'F', 'E', 'D', 'C', 'B', 'A', '@', '?', '>', '=', '<', ';', ':', '9', '8', '7', '6', '5', '4', '3', '2', '1']);
+    });
+
+    it('should step alphanumeric ranges', function() {
+      exact(fill('9', 'B', 3), [ '9', '<', '?', 'B' ]);
+    });
+
+    it('should decrement alphanumeric ranges', function() {
+      exact(fill('C', '9'), ['C', 'B', 'A', '@', '?', '>', '=', '<', ';', ':', '9']);
+    });
+  });
+
+  describe('ranges: letters', function() {
+    it('should increment alphabetical ranges', function() {
+      exact(fill('a'), ['a']);
+      exact(fill('a', 'a'), ['a']);
+      exact(fill('a', 'b'), ['a', 'b']);
+      exact(fill('a', 'e'), ['a', 'b', 'c', 'd', 'e']);
+      exact(fill('A', 'E'), ['A', 'B', 'C', 'D', 'E']);
+    });
+
+    it('should decrement alphabetical ranges', function() {
+      exact(fill('E', 'A'), ['E', 'D', 'C', 'B', 'A']);
+      exact(fill('a', 'C'), ['a','`','_','^',']',"\\",'[','Z','Y','X','W','V','U','T','S','R','Q','P','O','N','M','L','K','J','I','H','G','F','E','D','C']);
+      exact(fill('z', 'm'), ['z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm']);
+    });
+  });
+
+  describe('numbers', function() {
+    it('should increment numerical *string* ranges', function() {
+      exact(fill('1'), ['1']);
+      exact(fill('1', '1'), ['1']);
+      exact(fill('1', '2'), ['1', '2']);
+      exact(fill('1', '10'), ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']);
+      exact(fill('1', '3'), ['1', '2', '3']);
+      exact(fill('5', '8'), ['5', '6', '7', '8']);
+      exact(fill(1, '9'), ['1', '2', '3', '4', '5', '6', '7', '8', '9']);
+    });
+
+    it('should increment numerical *number* ranges', function() {
+      exact(fill(1, 3), [1, 2, 3]);
+      exact(fill(1, 9), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
+      exact(fill(5, 8), [5, 6, 7, 8]);
+    });
+
+    it('should increment numerical ranges that are a combination of number and string', function() {
+      exact(fill(1, '9'), ['1', '2', '3', '4', '5', '6', '7', '8', '9']);
+      exact(fill('2', 5), ['2', '3', '4', '5']);
+    });
+
+    it('should decrement numerical *string* ranges', function() {
+      exact(fill('0', '-5'), ['0', '-1', '-2', '-3', '-4', '-5']);
+      exact(fill('-1', '-5'), ['-1', '-2', '-3', '-4', '-5']);
+    });
+
+    it('should decrement numerical *number* ranges', function() {
+      exact(fill(-10, -1), [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1]);
+      exact(fill(0, -5), [0, -1, -2, -3, -4, -5]);
+    });
+
+    it('should handle *string* ranges ranges that are positive and negative:', function() {
+      exact(fill('9', '-4'), ['9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '-1', '-2', '-3', '-4']);
+      exact(fill('-5', '5'), ['-5', '-4', '-3', '-2', '-1', '0', '1', '2', '3', '4', '5']);
+    });
+
+    it('should handle *number* ranges ranges that are positive and negative:', function() {
+      exact(fill(9, -4), [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4]);
+      exact(fill(-5, 5), [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]);
+    });
+  });
+});
diff --git a/test/special.js b/test/special.js
new file mode 100644
index 0000000..fc3f0fc
--- /dev/null
+++ b/test/special.js
@@ -0,0 +1,36 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var exact = require('./support/exact');
+var fill = require('..');
+
+describe('special cases', function() {
+  describe('negative zero', function() {
+    it('should handle negative zero', function() {
+      exact(fill('-5', '-0', '-1'), ['-5', '-4', '-3', '-2', '-1', '0']);
+      exact(fill('1', '-0', 1), ['1', '0']);
+      exact(fill('1', '-0', 0), ['1', '0']);
+      exact(fill('1', '-0', '0'), ['1', '0']);
+      exact(fill('1', '-0', '1'), ['1', '0']);
+      exact(fill('-0', '-0', '1'), ['0']);
+      exact(fill('-0', '0', '1'), ['0']);
+      exact(fill('-0', '5', '1'), ['0', '1', '2', '3', '4', '5']);
+      exact(fill(-0, 5), [0, 1, 2, 3, 4, 5]);
+      exact(fill(5, -0, 5), [5, 0]);
+      exact(fill(5, -0, 2), [5, 3, 1]);
+      exact(fill(0, 5, 2), [0, 2, 4]);
+    });
+
+    it('should adjust padding for negative numbers:', function() {
+      exact(fill('-01', '5'), ['-01','000','001','002','003','004','005']);
+    });
+  });
+});
diff --git a/test/steps.js b/test/steps.js
new file mode 100644
index 0000000..88b5de5
--- /dev/null
+++ b/test/steps.js
@@ -0,0 +1,85 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var exact = require('./support/exact');
+var fill = require('..');
+
+describe('steps', function() {
+  describe('steps: numbers', function() {
+    it('should increment ranges using the given step', function() {
+      exact(fill('1', '10', '1'), ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']);
+      exact(fill('1', '10', '2'), ['1', '3', '5', '7', '9']);
+      exact(fill('0', '1000', '200'), ['0','200', '400', '600', '800', '1000']);
+      exact(fill('1', '10', 2), ['1', '3', '5', '7', '9']);
+      exact(fill('1', '20', '2'), ['1', '3', '5', '7', '9', '11', '13', '15', '17', '19']);
+      exact(fill('1', '20', '20'), ['1']);
+      exact(fill('10', '1', '2'), ['10', '8', '6', '4', '2']);
+      exact(fill('10', '1', '-2'), ['10', '8', '6', '4', '2']);
+      exact(fill('10', '1', '2'), ['10', '8', '6', '4', '2']);
+      exact(fill(2, 10, '2'), ['2', '4', '6', '8', '10']);
+      exact(fill(2, 10, 1), [2, 3, 4, 5, 6, 7, 8, 9, 10]);
+      exact(fill(2, 10, 2), [2, 4, 6, 8, 10]);
+      exact(fill(2, 10, 3), [2, 5, 8]);
+      exact(fill(0, 5, 2), [0, 2, 4]);
+      exact(fill(5, 0, 2), [5, 3, 1]);
+      exact(fill(1, 5, 2), [1, 3, 5]);
+      exact(fill(2, '10', '2'), ['2', '4', '6', '8', '10']);
+      exact(fill(2, '10', 1), ['2', '3', '4', '5', '6', '7', '8', '9', '10']);
+      exact(fill(2, '10', '2'), ['2', '4', '6', '8', '10']);
+      exact(fill('2', 10, '3'), ['2', '5', '8']);
+    });
+
+    it('should fill in negative ranges using the given step (strings)', function() {
+      exact(fill('0', '-10', '-2'), ['0', '-2', '-4', '-6', '-8', '-10']);
+      exact(fill('-0', '-10', '-2'), ['0', '-2', '-4', '-6', '-8', '-10']);
+      exact(fill('-1', '-10', '-2'), ['-1', '-3', '-5', '-7', '-9']);
+      exact(fill('-1', '-10', '2'), ['-1', '-3', '-5', '-7', '-9']);
+      exact(fill('1', '10', '2'), ['1', '3', '5', '7', '9']);
+      exact(fill('1', '20', '2'), ['1', '3', '5', '7', '9', '11', '13', '15', '17', '19']);
+      exact(fill('1', '20', '20'), ['1']);
+      exact(fill('10', '1', '-2'), ['10', '8', '6', '4', '2']);
+      exact(fill('-10', '0', '2'), ['-10', '-8', '-6', '-4', '-2', '0']);
+      exact(fill('-10', '-0', '2'), ['-10', '-8', '-6', '-4', '-2', '0']);
+      exact(fill('-0', '-10', '0'), ['0', '-1', '-2', '-3', '-4', '-5', '-6', '-7', '-8', '-9', '-10']);
+      exact(fill('0', '-10', '-0'), ['0', '-1', '-2', '-3', '-4', '-5', '-6', '-7', '-8', '-9', '-10']);
+    });
+
+    it('should fill in negative ranges using the given step (numbers)', function() {
+      exact(fill(-10, 0, 2), [-10, -8, -6, -4, -2, 0]);
+      exact(fill(-10, -2, 2), [-10, -8, -6, -4, -2]);
+      exact(fill(-2, -10, 1), [-2, -3, -4, -5, -6, -7, -8, -9, -10]);
+      exact(fill(0, -10, 2), [0, -2, -4, -6, -8, -10]);
+      exact(fill(-2, -10, 2), [-2, -4, -6, -8, -10]);
+      exact(fill(-2, -10, 3), [-2, -5, -8]);
+      exact(fill(-9, 9, 3), [-9, -6, -3, 0, 3, 6, 9]);
+    });
+
+    it('should fill in negative ranges when negative zero is passed', function() {
+      exact(fill(-10, -0, 2), [-10, -8, -6, -4, -2, 0]);
+      exact(fill(-0, -10, 2), [0, -2, -4, -6, -8, -10]);
+    });
+  });
+
+  describe('steps: letters', function() {
+    it('should use increments with alphabetical ranges', function() {
+      exact(fill('a', 'e', 2), ['a','c', 'e']);
+      exact(fill('E', 'A', 2), ['E', 'C', 'A']);
+    });
+  });
+
+  describe('options: step', function() {
+    it('should use the step defined on the options:', function() {
+      var opts = { step: 2 };
+      exact(fill('a', 'e', opts), ['a','c', 'e']);
+      exact(fill('E', 'A', opts), ['E', 'C', 'A']);
+    });
+  });
+});
diff --git a/test/support/exact.js b/test/support/exact.js
new file mode 100644
index 0000000..3636ea4
--- /dev/null
+++ b/test/support/exact.js
@@ -0,0 +1,13 @@
+'use strict';
+
+var util = require('util');
+var assert = require('assert');
+
+module.exports = function exact(a, b) {
+  assert(Array.isArray(a));
+  assert(Array.isArray(b));
+
+  var aString = util.inspect(a, null, 10);
+  var bString = util.inspect(b, null, 10);
+  assert.equal(aString, bString, aString + ' !== ' + bString);
+};
diff --git a/test/support/expand.js b/test/support/expand.js
new file mode 100644
index 0000000..7113323
--- /dev/null
+++ b/test/support/expand.js
@@ -0,0 +1,12 @@
+'use strict';
+
+module.exports = function toRange(start, stop, step) {
+  step = step || 1;
+  var arr = new Array((stop - start) / step);
+  var num = 0;
+
+  for (var i = start; i <= stop; i += step) {
+    arr[num++] = i;
+  }
+  return arr;
+};
diff --git a/test/verify-matches.js b/test/verify-matches.js
new file mode 100644
index 0000000..71995df
--- /dev/null
+++ b/test/verify-matches.js
@@ -0,0 +1,114 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-2015, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+require('mocha');
+var assert = require('assert');
+var expand = require('./support/expand');
+var exact = require('./support/exact');
+var fill = require('..');
+var count = 0;
+
+function toRegex() {
+  var str = fill.apply(null, arguments);
+  return new RegExp('^(' + str + ')$');
+}
+function matcher() {
+  var regex = toRegex.apply(null, arguments);
+  return function(num) {
+    return regex.test(String(num));
+  };
+}
+
+function verifyRange(min, max, from, to) {
+  var fn = matcher(min, max, {makeRe: true});
+  var range = expand(from, to);
+  var len = range.length, i = -1;
+
+  while (++i < len) {
+    var num = range[i];
+    if (min <= num && num <= max) {
+      assert(fn(num));
+    } else {
+      assert(!fn(num));
+    }
+    count++;
+  }
+}
+
+describe('validate ranges', function() {
+  after(function() {
+    var num = (+(+(count).toFixed(2))).toLocaleString();
+    console.log();
+    console.log('   ', num, 'patterns tested');
+  });
+
+  it('should support equal numbers:', function() {
+    verifyRange(1, 1, 0, 100);
+    verifyRange(65443, 65443, 65000, 66000);
+    verifyRange(192, 1000, 0, 1000);
+  });
+
+  it('should support large numbers:', function() {
+    verifyRange(100019999300000, 100020000300000, 100019999999999, 100020000100000);
+  });
+
+  it('should support repeated digits:', function() {
+    verifyRange(10331, 20381, 0, 99999);
+  });
+
+  it('should support repeated zeros:', function() {
+    verifyRange(10031, 20081, 0, 59999);
+    verifyRange(10000, 20000, 0, 59999);
+  });
+
+  it('should support zero one:', function() {
+    verifyRange(10301, 20101, 0, 99999);
+  });
+
+  it('should support repetead ones:', function() {
+    verifyRange(102, 111, 0, 1000);
+  });
+
+  it('should support small diffs:', function() {
+    verifyRange(102, 110, 0, 1000);
+    verifyRange(102, 130, 0, 1000);
+  });
+
+  it('should support random ranges:', function() {
+    verifyRange(4173, 7981, 0, 99999);
+  });
+
+  it('should support one digit numbers:', function() {
+    verifyRange(3, 7, 0, 99);
+  });
+
+  it('should support one digit at bounds:', function() {
+    verifyRange(1, 9, 0, 1000);
+  });
+
+  it('should support power of ten:', function() {
+    verifyRange(1000, 8632, 0, 99999);
+  });
+
+  it('should work with numbers of varying lengths:', function() {
+    verifyRange(1030, 20101, 0, 99999);
+    verifyRange(13, 8632, 0, 10000);
+  });
+
+  it('should support small ranges:', function() {
+    verifyRange(9, 11, 0, 100);
+    verifyRange(19, 21, 0, 100);
+  });
+
+  it('should support big ranges:', function() {
+    verifyRange(90, 98009, 0, 98999);
+    verifyRange(999, 10000, 1, 20000);
+  });
+});
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-fill-range.git



More information about the Pkg-javascript-commits mailing list