diff --git a/CHANGELOG.md b/CHANGELOG.md index 47bac15..60b63b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [3.1.1] +### Fixed +* Fixed intersection rules for zero-length ranges on start/end boundaries + ## [3.1.0] ### Added diff --git a/lib/moment-range.js b/lib/moment-range.js index 5ef79f1..6f865d0 100644 --- a/lib/moment-range.js +++ b/lib/moment-range.js @@ -154,19 +154,44 @@ export class DateRange { intersect(other) { const start = this.start.valueOf(); const end = this.end.valueOf(); - const oStart = other.start.valueOf(); - const oEnd = other.end.valueOf(); + const otherStart = other.start.valueOf(); + const otherEnd = other.end.valueOf(); + const isZeroLength = (start == end); + const isOtherZeroLength = (otherStart == otherEnd); + + // Zero-length ranges + if (isZeroLength) { + const point = start; + + if ((point == otherStart) || (point == otherEnd)) { + return null; + } + else if ((point > otherStart) && (point < otherEnd)) { + return this; + } + } + else if (isOtherZeroLength) { + const point = otherStart; + + if ((point == start) || (point == end)) { + return null; + } + else if ((point > start) && (point < end)) { + return other; + } + } - if ((start <= oStart) && (oStart < end) && (end < oEnd)) { - return new this.constructor(oStart, end); + // Non zero-length ranges + if ((start <= otherStart) && (otherStart < end) && (end < otherEnd)) { + return new this.constructor(otherStart, end); } - else if ((oStart < start) && (start < oEnd) && (oEnd <= end)) { - return new this.constructor(start, oEnd); + else if ((otherStart < start) && (start < otherEnd) && (otherEnd <= end)) { + return new this.constructor(start, otherEnd); } - else if ((oStart < start) && (start <= end) && (end < oEnd)) { + else if ((otherStart < start) && (start <= end) && (end < otherEnd)) { return this; } - else if ((start <= oStart) && (oStart <= oEnd) && (oEnd <= end)) { + else if ((start <= otherStart) && (otherStart <= otherEnd) && (otherEnd <= end)) { return other; } diff --git a/lib/moment-range_test.js b/lib/moment-range_test.js index 0ebdb8b..7f74e2f 100644 --- a/lib/moment-range_test.js +++ b/lib/moment-range_test.js @@ -750,6 +750,44 @@ describe('DateRange', function() { expect(range1.overlaps(range2, { adjacent: false })).to.be(false); expect(range1.overlaps(range2, { adjacent: true })).to.be(true); }); + + it('should not overlap zero-length ranges on the start date when `adjacent` is `false`', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const range1 = moment.range(a, a); + const range2 = moment.range(a, b); + + expect(range1.overlaps(range2)).to.be(false); + expect(range1.overlaps(range2, { adjacent: false })).to.be(false); + }); + + it('should overlap zero-length ranges on the start date when `adjacent` is `true`', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const range1 = moment.range(a, a); + const range2 = moment.range(a, b); + + expect(range1.overlaps(range2, { adjacent: true })).to.be(true); + }); + + it('should not overlap zero-length ranges on the end date when `adjacent` is `false`', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const range1 = moment.range(a, b); + const range2 = moment.range(b, b); + + expect(range1.overlaps(range2)).to.be(false); + expect(range1.overlaps(range2, { adjacent: false })).to.be(false); + }); + + it('should overlap zero-length ranges on the end date when `adjacent` is `true`', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const range1 = moment.range(a, b); + const range2 = moment.range(b, b); + + expect(range1.overlaps(range2, { adjacent: true })).to.be(true); + }); }); describe('#intersect()', function() { @@ -854,6 +892,42 @@ describe('DateRange', function() { expect(dr1.intersect(dr2).isSame(dr1)).to.be(true); }); + + it('should return `null` with [---{}] non-overlaps where (a=[], b={})', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const dr1 = moment.range(a, b); + const dr2 = moment.range(b, b); + + expect(dr1.intersect(dr2)).to.be(null); + }); + + it('should return `null` with [{}---] non-overlaps where (a=[], b={})', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const dr1 = moment.range(a, b); + const dr2 = moment.range(a, a); + + expect(dr1.intersect(dr2)).to.be(null); + }); + + it('should return `null` with {---[]} non-overlaps where (a=[], b={})', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const dr1 = moment.range(b, b); + const dr2 = moment.range(a, b); + + expect(dr1.intersect(dr2)).to.be(null); + }); + + it('should return `null` with {[]---} non-overlaps where (a=[], b={})', function() { + const a = moment.utc('2018-02-01T03:00:00'); + const b = moment.utc('2018-02-01T13:00:00'); + const dr1 = moment.range(a, a); + const dr2 = moment.range(a, b); + + expect(dr1.intersect(dr2)).to.be(null); + }); }); describe('#add()', function() {