diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..e13db26 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,29 @@ +{ + "browser": false, + "node": true, + "camelcase": true, + "eqeqeq": false, + "indent": 2, + "quotmark": "single", + "newcap": true, + "trailing": true, + "undef": true, + "unused": true, + "latedef": true, + "eqnull": true, + "globals": { + "describe" : true, + "xdescribe" : true, + "it" : true, + "xit" : true, + "expect" : true, + "assert" : true, + "beforeEach": true, + "before" : true, + "afterEach" : true, + "after" : true, + "chai" : true, + "mocha" : true, + "sinon" : true + } +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..20fd86b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.10 diff --git a/README.md b/README.md index 01b2b64..260eeeb 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,26 @@ date-range ========== Generate a range of dates + +## Install + +## API + +```javascript +var range = require('date-range'); + +var end = new Date(); +end.setHours(0); end.setMinutes(0); end.setSeconds(0); end.setMilliseconds(0); +var start = new Date(end - (range.DAY * 5)); + +console.log(range(start, end)); +/* +[ Wed Feb 26 2014 00:00:00 GMT-0500 (EST), + Thu Feb 27 2014 00:00:00 GMT-0500 (EST), + Fri Feb 28 2014 00:00:00 GMT-0500 (EST), + Sat Mar 01 2014 00:00:00 GMT-0500 (EST), + Sun Mar 02 2014 00:00:00 GMT-0500 (EST), + Mon Mar 03 2014 00:00:00 GMT-0500 (EST) ] +*/ + +``` diff --git a/index.js b/index.js index e69de29..a4906a4 100644 --- a/index.js +++ b/index.js @@ -0,0 +1,42 @@ +'use strict'; + +var toString = {}.toString; +function isDate(d) { + return toString.call(d) === '[object Date]'; +} + +/** + * Creates an array of dates + * + * @param {Date} start + * @param {Date} [end] + * @param {Number} [step] + * + * @return {Array} + */ +function range(start, end, step) { + end = end || new Date(); + step = step || range.defaultStep; + + if (!isDate(start) || !isDate(end)) throw new TypeError(); + + var length = Math.ceil((end - start) / step); + var out = new Array(length); + out[0] = start; + + for (var i = +start + step, j = 1; i < +end; i += step, j += 1) { + out[j] = new Date(i); + } + out[length] = end; + return out; +} + +range.MS = 1; +range.SEC = 1e3; +range.MIN = 60e3; +range.HOUR = range.MIN * 60; +range.DAY = range.HOUR * 24; + +range.defaultStep = range.DAY; + +module.exports = range; diff --git a/package.json b/package.json index b74ab43..342b4ef 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Generate a range of dates", "main": "index.js", "scripts": { - "test": "mocha --recursive -R test/" + "pretest": "jshint --reporter node_modules/jshint-stylish/stylish.js index.js test.js", + "test": "mocha test.js" }, "repository": { "type": "git", @@ -29,5 +30,11 @@ "bugs": { "url": "https://github.com/landau/date-range/issues" }, - "homepage": "https://github.com/landau/date-range" + "homepage": "https://github.com/landau/date-range", + "devDependencies": { + "jshint-stylish": "~0.1.5", + "mocha": "~1.17.1", + "jshint": "~2.4.4", + "should": "~3.1.3" + } } diff --git a/test.js b/test.js new file mode 100644 index 0000000..2b15126 --- /dev/null +++ b/test.js @@ -0,0 +1,71 @@ +/* jshint expr:true */ +/* jshint unused:false */ +'use strict'; + +var range = require('./'); +var should = require('should'); + +function setTime(d, v) { + v = v || 0; + ['Hours', 'Minutes', 'Seconds', 'Milliseconds'].forEach(function (m) { + d['set' + m](v); + }); + return d; +} + +describe('range', function () { + var d1 = new Date(); + setTime(d1); + var d2 = new Date(d1 - (range.DAY * 2)); // - 2 days + + it('should throw an error if start or end is not a date', function() { + + var errs = []; + + try { + range(d2, 'foo'); + } catch(e) { + errs.push(e); + } + + try { + range('foo', d1); + } catch(e) { + errs.push(e); + } + + errs.length.should.equal(2); + errs.every(function(v) { return v instanceof TypeError; }).should.be.true; + }); + + before(function() { + this.dr = range(new Date(d1 - (range.DAY * 3)), d1); + }); + + it('should return an array', function() { + this.dr.should.be.instanceof(Array); + }); + + it('should create an array of length 4', function() { + this.dr.length.should.equal(4); + }); + + it('should step by 1 day', function() { + this.dr.slice(1).every(function (d, i) { + return d - this.dr[i] === range.DAY; + }, this).should.be.true; + }); + + it('should default to new date for end', function() { + var dr = range(d2); + dr.length.should.equal(4); + }); + + it('should work with multiple step types', function() { + ['MS', 'SEC', 'MIN', 'HOUR', 'DAY'].forEach(function(m) { + var d = new Date(d1 - (range[m] * 5)); + var dr = range(d, d1, range[m]); + dr.length.should.equal(6); + }); + }); +});