From 987f364f5690c9e7ada1fa7d88b70b14e989c8bd Mon Sep 17 00:00:00 2001 From: bramski Date: Tue, 3 Feb 2015 18:31:25 -0800 Subject: [PATCH] Fix a problem with intervals when not dealing with days. Add tests to verify this. --- moment-recur.js | 5 ++++- moment-recur.min.js | 2 +- tests/spec/jasmine-event-recur.js | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/moment-recur.js b/moment-recur.js index e873aad..a2af24a 100644 --- a/moment-recur.js +++ b/moment-recur.js @@ -42,7 +42,10 @@ } else { diff = date.diff(start, type, true); } - diff = parseInt(diff); + if( type == 'days') { + // if we are dealing with days, we deal with whole days only. + diff = parseInt(diff); + } // Check to see if any of the units provided match the date for (var unit in units) { diff --git a/moment-recur.min.js b/moment-recur.min.js index e788f09..d591c9c 100644 --- a/moment-recur.min.js +++ b/moment-recur.min.js @@ -1 +1 @@ -!function(a,b){"object"==typeof exports?module.exports=b(require("moment")):"function"==typeof define&&define.amd?define("moment-recur",["moment"],b):a.moment=b(a.moment)}(this,function(a){var b;if(b="undefined"!=typeof module&&null!==module&&null!=module.exports,"undefined"==typeof a)throw Error("Can't find moment");var c=function(){function a(a,b){for(var c in a)if(a.hasOwnProperty(c)&&parseInt(c,10)<=0)throw Error("Intervals must be greater than zero");return{measure:b.toLowerCase(),units:a}}function b(a,b,c,d){var e=null;e=d.isBefore(c)?c.diff(d,a,!0):d.diff(c,a,!0),e=parseInt(e);for(var f in b)if(b.hasOwnProperty(f)&&(f=parseInt(f,10),e%f===0))return!0;return!1}return{create:a,match:b}}(),d=function(){function b(a,b,c){c.forEach(function(c){if(a>c||c>b)throw Error("Value should be in range "+a+" to "+b)})}function c(b,c){var d,e,f,g={};for(d in b)b.hasOwnProperty(d)&&(e=parseInt(d,10),isNaN(e)&&(e=d),f=a().set(c,e).get(c),g[f]=b[d]);return g}function d(a,d){var e=[];"daysOfWeek"===d&&(a=c(a,"days")),"monthsOfYear"===d&&(a=c(a,"months"));for(var f in a)hasOwnProperty.call(a,f)&&e.push(f);return b(g[d].low,g[d].high,e),{measure:d,units:a}}function e(a,b,c){var d=f[a],e=c[d]();if(b[e])return!0;if("date"===d&&e==c.add(1,"months").date(0).format("D")&&31>e)for(;31>=e;){if(b[e])return!0;e++}return!1}var f={daysOfMonth:"date",daysOfWeek:"day",weeksOfMonth:"monthWeek",weeksOfYear:"weeks",monthsOfYear:"months"},g={daysOfMonth:{low:1,high:31},daysOfWeek:{low:0,high:6},weeksOfMonth:{low:0,high:4},weeksOfYear:{low:0,high:52},monthsOfYear:{low:0,high:11}};return{create:d,match:e}}(),e=function(){function b(){var a,b=m[this.measure];if(!(this instanceof o))throw Error("Private method trigger() was called directly or not called as instance of Recur!");if("undefined"==typeof this.units||null===this.units||!this.measure)return this;if("calendar"!==b&&"interval"!==b)throw Error("Invlid measure provided: "+this.measure);if("interval"===b){if(!this.start)throw Error("Must have a start date set to set an interval!");a=c.create(this.units,this.measure)}"calendar"===b&&(a=d.create(this.units,this.measure)),this.units=null,this.measure=null;for(var e=0;ethis.end)throw Error("Start date cannot be later than end date.");if("all"!==c&&!(a>0))return f;for(d=(this.from||this.start).clone(),"all"===c&&this.matches(d,!1)&&(e=b?d.format(b):d.clone(),f.push(e));f.length<(null===a?f.length+1:a)&&("next"===c||"all"===c?d.add(1,"day"):d.subtract(1,"day"),this.matches(d,"all"===c?!1:!0)&&(e=b?d.format(b):d.clone(),f.push(e)),!("all"===c&&d>=this.end)););return f}function f(a,b,c){return a&&c.isBefore(a)?!1:b&&c.isAfter(b)?!1:!0}function g(a){var b={};if("[object Array]"==Object.prototype.toString.call(a))a.forEach(function(a){b[a]=!0});else if(a===Object(a))b=a;else{if("[object Number]"!=Object.prototype.toString.call(a)&&"[object String]"!=Object.prototype.toString.call(a))throw Error("Provide an array, object, string or number when passing units!");b[a]=!0}return b}function h(b,c){for(var d=0,e=b.length;e>d;d++)if(a(b[d]).isSame(c))return!0;return!1}function j(a){switch(a){case"day":return"days";case"week":return"weeks";case"month":return"months";case"year":return"years";case"dayOfWeek":return"daysOfWeek";case"dayOfMonth":return"daysOfMonth";case"weekOfMonth":return"weeksOfMonth";case"weekOfYear":return"weeksOfYear";case"monthOfYear":return"monthsOfYear";default:return a}}function k(a,b,e){var f,g,h,i;for(f=0,g=a.length;g>f;f++)if(h=a[f],i=m[h.measure],"interval"===i){if(!c.match(h.measure,h.units,e,b))return!1}else{if("calendar"!==i)return!1;if(!d.match(h.measure,h.units,b))return!1}return!0}function l(a){return function(b){return this.every.call(this,b,a),this}}var m={days:"interval",weeks:"interval",months:"interval",years:"interval",daysOfWeek:"calendar",daysOfMonth:"calendar",weeksOfMonth:"calendar",weeksOfYear:"calendar",monthsOfYear:"calendar"},n={days:"day",weeks:"week",months:"month",years:"year",daysOfWeek:"dayOfWeek",daysOfMonth:"dayOfMonth",weeksOfMonth:"weekOfMonth",weeksOfYear:"weekOfYear",monthsOfYear:"monthOfYear"},o=function(b){b.start&&(this.start=a(b.start).dateOnly()),b.end&&(this.end=a(b.end).dateOnly()),this.rules=b.rules||[];var c=b.exceptions||[];for(this.exceptions=[],i=0;ic;c++)b.exceptions.push(this.exceptions[c].format("L"));return b.rules=this.rules,b},o.prototype.repeats=function(){return this.rules.length>0?!0:!1},o.prototype.every=function(a,c){return"undefined"!=typeof a&&null!==a&&(this.units=g(a)),"undefined"!=typeof c&&null!==c&&(this.measure=j(c)),b.call(this)},o.prototype.except=function(b){return b=a(b).dateOnly(),this.exceptions.push(b),this},o.prototype.forget=function(b){var c,d,e=a(b);if(e.isValid()){for(e=e.dateOnly(),c=0,d=this.exceptions.length;d>c;c++)if(e.isSame(this.exceptions[c]))return this.exceptions.splice(c,1),this;return this}for(c=0,d=this.rules.length;d>c;c++)this.rules[c].measure===j(b)&&this.rules.splice(c,1)},o.prototype.matches=function(b,c){var d=a(b).dateOnly();if(!d.isValid())throw Error("Invalid date supplied to match method: "+b);return c||f(this.start,this.end,d)?h(this.exceptions,d)?!1:k(this.rules,d,this.start)?!0:!1:!1},o.prototype.next=function(a,b){return e.call(this,a,b,"next")},o.prototype.previous=function(a,b){return e.call(this,a,b,"previous")},o.prototype.all=function(a){return e.call(this,null,a,"all")};for(var p in n)m.hasOwnProperty(p)&&(o.prototype[p]=o.prototype[n[p]]=l(p));return o}();return a.recur=function(b,c){return new e(b!==Object(b)||a.isMoment(b)?{start:b,end:c}:b)},a.fn.recur=function(b,c){return b!==Object(b)||a.isMoment(b)?(c||(c=b,b=void 0),b||(b=this),new e({start:b,end:c,moment:this})):("undefined"==typeof b.start&&(b.start=this),new e(b))},a.fn.monthWeek=function(){var a=this.clone().startOf("month").startOf("week"),b=this.clone().startOf("week");return b.diff(a,"weeks")},a.fn.dateOnly=function(){return this.hours(0).minutes(0).seconds(0).milliseconds(0).add("minute",this.utcOffset()).utcOffset(0)},a}); \ No newline at end of file +!function(a,b){"object"==typeof exports?module.exports=b(require("moment")):"function"==typeof define&&define.amd?define("moment-recur",["moment"],b):a.moment=b(a.moment)}(this,function(a){var b;if(b="undefined"!=typeof module&&null!==module&&null!=module.exports,"undefined"==typeof a)throw Error("Can't find moment");var c=function(){function a(a,b){for(var c in a)if(a.hasOwnProperty(c)&&parseInt(c,10)<=0)throw Error("Intervals must be greater than zero");return{measure:b.toLowerCase(),units:a}}function b(a,b,c,d){var e=null;e=d.isBefore(c)?c.diff(d,a,!0):d.diff(c,a,!0),"days"==a&&(e=parseInt(e));for(var f in b)if(b.hasOwnProperty(f)&&(f=parseInt(f,10),e%f===0))return!0;return!1}return{create:a,match:b}}(),d=function(){function b(a,b,c){c.forEach(function(c){if(a>c||c>b)throw Error("Value should be in range "+a+" to "+b)})}function c(b,c){var d,e,f,g={};for(d in b)b.hasOwnProperty(d)&&(e=parseInt(d,10),isNaN(e)&&(e=d),f=a().set(c,e).get(c),g[f]=b[d]);return g}function d(a,d){var e=[];"daysOfWeek"===d&&(a=c(a,"days")),"monthsOfYear"===d&&(a=c(a,"months"));for(var f in a)hasOwnProperty.call(a,f)&&e.push(f);return b(g[d].low,g[d].high,e),{measure:d,units:a}}function e(a,b,c){var d=f[a],e=c[d]();if(b[e])return!0;if("date"===d&&e==c.add(1,"months").date(0).format("D")&&31>e)for(;31>=e;){if(b[e])return!0;e++}return!1}var f={daysOfMonth:"date",daysOfWeek:"day",weeksOfMonth:"monthWeek",weeksOfYear:"weeks",monthsOfYear:"months"},g={daysOfMonth:{low:1,high:31},daysOfWeek:{low:0,high:6},weeksOfMonth:{low:0,high:4},weeksOfYear:{low:0,high:52},monthsOfYear:{low:0,high:11}};return{create:d,match:e}}(),e=function(){function b(){var a,b=m[this.measure];if(!(this instanceof o))throw Error("Private method trigger() was called directly or not called as instance of Recur!");if("undefined"==typeof this.units||null===this.units||!this.measure)return this;if("calendar"!==b&&"interval"!==b)throw Error("Invlid measure provided: "+this.measure);if("interval"===b){if(!this.start)throw Error("Must have a start date set to set an interval!");a=c.create(this.units,this.measure)}"calendar"===b&&(a=d.create(this.units,this.measure)),this.units=null,this.measure=null;for(var e=0;ethis.end)throw Error("Start date cannot be later than end date.");if("all"!==c&&!(a>0))return f;for(d=(this.from||this.start).clone(),"all"===c&&this.matches(d,!1)&&(e=b?d.format(b):d.clone(),f.push(e));f.length<(null===a?f.length+1:a)&&("next"===c||"all"===c?d.add(1,"day"):d.subtract(1,"day"),this.matches(d,"all"===c?!1:!0)&&(e=b?d.format(b):d.clone(),f.push(e)),!("all"===c&&d>=this.end)););return f}function f(a,b,c){return a&&c.isBefore(a)?!1:b&&c.isAfter(b)?!1:!0}function g(a){var b={};if("[object Array]"==Object.prototype.toString.call(a))a.forEach(function(a){b[a]=!0});else if(a===Object(a))b=a;else{if("[object Number]"!=Object.prototype.toString.call(a)&&"[object String]"!=Object.prototype.toString.call(a))throw Error("Provide an array, object, string or number when passing units!");b[a]=!0}return b}function h(b,c){for(var d=0,e=b.length;e>d;d++)if(a(b[d]).isSame(c))return!0;return!1}function j(a){switch(a){case"day":return"days";case"week":return"weeks";case"month":return"months";case"year":return"years";case"dayOfWeek":return"daysOfWeek";case"dayOfMonth":return"daysOfMonth";case"weekOfMonth":return"weeksOfMonth";case"weekOfYear":return"weeksOfYear";case"monthOfYear":return"monthsOfYear";default:return a}}function k(a,b,e){var f,g,h,i;for(f=0,g=a.length;g>f;f++)if(h=a[f],i=m[h.measure],"interval"===i){if(!c.match(h.measure,h.units,e,b))return!1}else{if("calendar"!==i)return!1;if(!d.match(h.measure,h.units,b))return!1}return!0}function l(a){return function(b){return this.every.call(this,b,a),this}}var m={days:"interval",weeks:"interval",months:"interval",years:"interval",daysOfWeek:"calendar",daysOfMonth:"calendar",weeksOfMonth:"calendar",weeksOfYear:"calendar",monthsOfYear:"calendar"},n={days:"day",weeks:"week",months:"month",years:"year",daysOfWeek:"dayOfWeek",daysOfMonth:"dayOfMonth",weeksOfMonth:"weekOfMonth",weeksOfYear:"weekOfYear",monthsOfYear:"monthOfYear"},o=function(b){b.start&&(this.start=a(b.start).dateOnly()),b.end&&(this.end=a(b.end).dateOnly()),this.rules=b.rules||[];var c=b.exceptions||[];for(this.exceptions=[],i=0;ic;c++)b.exceptions.push(this.exceptions[c].format("L"));return b.rules=this.rules,b},o.prototype.repeats=function(){return this.rules.length>0?!0:!1},o.prototype.every=function(a,c){return"undefined"!=typeof a&&null!==a&&(this.units=g(a)),"undefined"!=typeof c&&null!==c&&(this.measure=j(c)),b.call(this)},o.prototype.except=function(b){return b=a(b).dateOnly(),this.exceptions.push(b),this},o.prototype.forget=function(b){var c,d,e=a(b);if(e.isValid()){for(e=e.dateOnly(),c=0,d=this.exceptions.length;d>c;c++)if(e.isSame(this.exceptions[c]))return this.exceptions.splice(c,1),this;return this}for(c=0,d=this.rules.length;d>c;c++)this.rules[c].measure===j(b)&&this.rules.splice(c,1)},o.prototype.matches=function(b,c){var d=a(b).dateOnly();if(!d.isValid())throw Error("Invalid date supplied to match method: "+b);return c||f(this.start,this.end,d)?h(this.exceptions,d)?!1:k(this.rules,d,this.start)?!0:!1:!1},o.prototype.next=function(a,b){return e.call(this,a,b,"next")},o.prototype.previous=function(a,b){return e.call(this,a,b,"previous")},o.prototype.all=function(a){return e.call(this,null,a,"all")};for(var p in n)m.hasOwnProperty(p)&&(o.prototype[p]=o.prototype[n[p]]=l(p));return o}();return a.recur=function(b,c){return new e(b!==Object(b)||a.isMoment(b)?{start:b,end:c}:b)},a.fn.recur=function(b,c){return b!==Object(b)||a.isMoment(b)?(c||(c=b,b=void 0),b||(b=this),new e({start:b,end:c,moment:this})):("undefined"==typeof b.start&&(b.start=this),new e(b))},a.fn.monthWeek=function(){var a=this.clone().startOf("month").startOf("week"),b=this.clone().startOf("week");return b.diff(a,"weeks")},a.fn.dateOnly=function(){return this.tz&&"function"==typeof a.tz?a.tz(this.format("YYYY/MM/DD"),"UTC"):this.hours(0).minutes(0).seconds(0).milliseconds(0).add("minute",this.utcOffset()).utcOffset(0)},a}); \ No newline at end of file diff --git a/tests/spec/jasmine-event-recur.js b/tests/spec/jasmine-event-recur.js index 58d325a..0b8b7cd 100755 --- a/tests/spec/jasmine-event-recur.js +++ b/tests/spec/jasmine-event-recur.js @@ -143,6 +143,7 @@ describe("An interval", function() { it("can be weekly", function() { var recurrence = moment(startDate).recur().every(2).weeks(); expect(recurrence.matches( moment(startDate).add(2, "weeks") )).toBe(true); + expect(recurrence.matches( moment(startDate).add(2, "days") )).toBe(false); expect(recurrence.matches( moment(startDate).add(3, "weeks") )).toBe(false); }); @@ -150,19 +151,23 @@ describe("An interval", function() { var recurrence = moment(startDate).recur().every(3).months(); expect(recurrence.matches( moment(startDate).add(3, "months") )).toBe(true); expect(recurrence.matches( moment(startDate).add(2, "months") )).toBe(false); + expect(recurrence.matches( moment(startDate).add(2, "days"))).toBe(false); }); it("can be yearly", function() { var recurrence = moment(startDate).recur().every(2).years(); expect(recurrence.matches( moment(startDate).add(2, "year") )).toBe(true); expect(recurrence.matches( moment(startDate).add(3, "year") )).toBe(false); + expect(recurrence.matches( moment(startDate).add(2, "days") )).toBe(false); }); it("can be an array of intervals", function() { var recurrence = moment(startDate).recur().every([3,5]).days(); expect(recurrence.matches( moment(startDate).add(3, "days"))).toBe(true); expect(recurrence.matches( moment(startDate).add(5, "days"))).toBe(true); + expect(recurrence.matches( moment(startDate).add(10, "days"))).toBe(true); expect(recurrence.matches( moment(startDate).add(4, "days"))).toBe(false); + expect(recurrence.matches( moment(startDate).add(8, "days"))).toBe(false); }); }); @@ -184,10 +189,15 @@ describe("The Calendar Interval", function() { }); it("daysOfMonth should work", function() { - var recurrence = moment.recur().every([1, 10]).daysOfMonth(); - expect(recurrence.matches( moment().date(1) )).toBe(true); - expect(recurrence.matches( moment().date(10) )).toBe(true); - expect(recurrence.matches( moment().date(15) )).toBe(false); + var recurrence = moment('2015-01-01').recur().every([1, 10]).daysOfMonth(); + expect(recurrence.matches( moment('2015-01-01'))).toBe(true); + expect(recurrence.matches( moment('2015-01-02'))).toBe(false); + expect(recurrence.matches( moment('2015-01-10'))).toBe(true); + expect(recurrence.matches( moment('2015-01-15'))).toBe(false); + expect(recurrence.matches( moment('2015-02-01'))).toBe(true); + expect(recurrence.matches( moment('2015-02-02'))).toBe(false); + expect(recurrence.matches( moment('2015-02-10'))).toBe(true); + expect(recurrence.matches( moment('2015-02-15'))).toBe(false); }); it("weeksOfMonth should work", function() {