diff --git a/src/season.js b/src/season.js index 10481cb..07003d7 100644 --- a/src/season.js +++ b/src/season.js @@ -61,14 +61,36 @@ class Season extends ExtDateTime { } set season(season) { - return this.values[1] = Number(season) + return validate(this.values[1] = Number(season)) } get values() { return V.get(this) } - // TODO next/prev + next(k = 1) { + let { season, year } = this + + switch (true) { + case (season >= 21 && season <= 36): + [year, season] = inc(year, season, k, season - (season - 21) % 4, 4) + break + case (season >= 37 && season <= 39): + [year, season] = inc(year, season, k, 37, 3) + break + case (season >= 40 && season <= 41): + [year, season] = inc(year, season, k, 40, 2) + break + default: + throw new RangeError(`Cannot compute next/prev for season ${season}`) + } + + return new Season(year, season) + } + + prev(k = 1) { + return this.next(-k) + } get min() { // eslint-disable-line complexity switch (this.season) { @@ -155,4 +177,15 @@ class Season extends ExtDateTime { } } +function validate(season) { + if (isNaN(season) || season < 21 || season === Infinity) + throw new RangeError(`invalid division of year: ${season}`) + return season +} + +function inc(year, season, by, base, size) { + const m = (season + by) - base + return [year + Math.floor(m / size), validate(base + (m % size + size) % size)] +} + module.exports = Season diff --git a/test/interval.js b/test/interval.js index 05d1560..1b1a6c6 100644 --- a/test/interval.js +++ b/test/interval.js @@ -74,9 +74,14 @@ describe('Interval', () => { expect(S80.toEDTF()).to.be.eql('1980-21/1980-24') }) - //it('includes', () => { - // expect(S80.includes(new Date(1980, 8))).to.be.true - // expect(S80.includes(new Season(1980, 22))).to.be.true - //}) + it('.covers', () => { + expect(S80.covers(new Season(1980, 22))).to.be.true + expect(S80.covers(new Date(1980, 8))).to.be.true + }) + + it('.includes', () => { + expect(S80.includes(new Season(1980, 22))).to.be.true + expect(S80.includes(new Date(1980, 8))).to.be.false + }) }) }) diff --git a/test/season.js b/test/season.js index e22f87f..cf901d5 100644 --- a/test/season.js +++ b/test/season.js @@ -20,6 +20,24 @@ describe('Season', () => { }) }) + describe('.next', () => { + it('positive', () => { + expect(new Season(2018, 21).next().toEDTF()).to.eql('2018-22') + expect(new Season(2018, 21).next(2).toEDTF()).to.eql('2018-23') + expect(new Season(2018, 21).next(3).toEDTF()).to.eql('2018-24') + expect(new Season(2018, 21).next(4).toEDTF()).to.eql('2019-21') + expect(new Season(2018, 25).next(9).toEDTF()).to.eql('2020-26') + }) + + it('negative', () => { + expect(new Season(2018, 24).next(-1).toEDTF()).to.eql('2018-23') + expect(new Season(2018, 24).next(-2).toEDTF()).to.eql('2018-22') + expect(new Season(2018, 24).next(-3).toEDTF()).to.eql('2018-21') + expect(new Season(2018, 24).next(-4).toEDTF()).to.eql('2017-24') + expect(new Season(2018, 24).next(-9).toEDTF()).to.eql('2016-23') + }) + }) + describe('.edtf', () => { it('default', () => expect(new Season().edtf).to.match(/^\d\d\d\d-21$/))