diff --git a/get-cycle-day-number.js b/get-cycle-day-number.js new file mode 100644 index 0000000..ff07b0c --- /dev/null +++ b/get-cycle-day-number.js @@ -0,0 +1,46 @@ +export default function (cycleDays, targetDay) { + const lastFirstBleedingday = findLastFirstBleedingDay(cycleDays) + + if (!lastFirstBleedingday) return + + const diffInDays = targetDay.diff(lastFirstBleedingday.date, 'days') + + // cycle starts at day 1 + return diffInDays + 1 +} + +function findLastFirstBleedingDay(cycleDays) { + // sort the cycle days in descending order + // so we travel into the past as we iterate + // over the array + cycleDays.sort((a,b) => b.date - a.date) + + let sawBleeding = false + + for (let i = 0; i < cycleDays.length; i++) { + const cycleDay = cycleDays[i] + + // we have detected the day before the beginning + // of a bleeding period, so the previous cycle day in the array + // was the first day of bleeding + if (sawBleeding && (!isBleedingDay(cycleDay))) { + return cycleDays[i - 1] + } + + // if we get to the earliest cycle day and there was + // bleeding on that day, it's the first bleeding day for us + if (i === cycleDays.length - 1 && isBleedingDay(cycleDay)) { + return cycleDay + } + + if (isBleedingDay(cycleDay)) { + sawBleeding = true + } + } +} + +function isBleedingDay(cycleDay) { + return cycleDay.bleeding + && cycleDay.bleeding.value + && !cycleDay.exclude +} \ No newline at end of file diff --git a/test/app.spec.js b/test/app.spec.js deleted file mode 100644 index 019e3fa..0000000 --- a/test/app.spec.js +++ /dev/null @@ -1,5 +0,0 @@ -import { expect } from 'chai' - -it('says hello world', function () { - expect(1 + 5).to.eql(6) -}) diff --git a/test/get-cycle-day.spec.js b/test/get-cycle-day.spec.js new file mode 100644 index 0000000..a5572fd --- /dev/null +++ b/test/get-cycle-day.spec.js @@ -0,0 +1,136 @@ +import { expect } from 'chai' +import moment from 'moment' + +import getCycleDayNumber from '../get-cycle-day-number' + +describe('getCycleDay returns the cycle day', () => { + it('if the last data entered is a bleeding day', function () { + const cycleDays = [{ + date: moment([2018, 5, 2]) + }, { + date: moment([2018, 5, 3]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 4]) + }, { + date: moment([2018, 5, 9]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 10]), + bleeding: { + value: 2 + } + }] + const targetDate = moment([2018, 5, 17]) + const result = getCycleDayNumber(cycleDays, targetDate) + expect(result).to.eql(9) + }) + + it('if the last data entered is a non-bleeding day', function () { + const cycleDays = [{ + date: moment([2018, 5, 2]) + }, { + date: moment([2018, 5, 3]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 4]) + }, { + date: moment([2018, 5, 9]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 10]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 13]) + }, { + date: moment([2018, 5, 14]) + }] + + const targetDate = moment([2018, 5, 17]) + const result = getCycleDayNumber(cycleDays, targetDate) + expect(result).to.eql(9) + }) + + it('works if the cycle days are not sorted by date', function () { + const cycleDays = [{ + date: moment([2018, 5, 13]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 9]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 3]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 4]) + }, { + date: moment([2018, 5, 10]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 2]) + }] + + const targetDate = moment([2018, 5, 17]) + const result = getCycleDayNumber(cycleDays, targetDate) + expect(result).to.eql(9) + }) + + it('if there are only bleeding days', function () { + const cycleDays = [{ + date: moment([2018, 5, 9]), + bleeding: { + value: 2 + } + }, { + date: moment([2018, 5, 10]), + bleeding: { + value: 2 + } + }] + const targetDate = moment([2018, 5, 17]) + const result = getCycleDayNumber(cycleDays, targetDate) + expect(result).to.eql(9) + }) +}) + +describe('getCycleDay returns undefined', () => { + it('if there are no bleeding days', function () { + const cycleDays = [{ + date: moment([2018, 5, 2]) + }, { + date: moment([2018, 5, 4]) + }, { + date: moment([2018, 5, 9]), + }, { + date: moment([2018, 5, 10]), + }] + const targetDate = moment([2018, 5, 17]) + const result = getCycleDayNumber(cycleDays, targetDate) + expect(result).to.be.undefined + }) + + it('if there are no cycle days', function () { + const cycleDays = [] + const targetDate = moment([2018, 5, 17]) + const result = getCycleDayNumber(cycleDays, targetDate) + expect(result).to.be.undefined + }) +}) \ No newline at end of file