diff --git a/.eslintrc b/.eslintrc index 24f9ab5..40d7e9b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -47,6 +47,7 @@ "no-var": "error", "prefer-const": "error", "no-trailing-spaces": "error", - "react/prop-types": 0 + "react/prop-types": 0, + "max-len": "warn" } } \ No newline at end of file diff --git a/lib/sympto/minus-8-day-rule.js b/lib/sympto/minus-8-day-rule.js new file mode 100644 index 0000000..2964b37 --- /dev/null +++ b/lib/sympto/minus-8-day-rule.js @@ -0,0 +1,26 @@ +import { LocalDate } from 'js-joda' +import getNfpStatus from './index' + +export default function (previousCycles) { + const fhms = previousCycles + .map(cycle => { + const status = getNfpStatus({ cycle }) + if (status.temperatureShift) { + const day = status.temperatureShift.firstHighMeasurementDay + const firstCycleDayDate = LocalDate.parse(cycle[0].date) + const fhmDate = LocalDate.parse(day.date) + return fhmDate.compareTo(firstCycleDayDate) + 1 + } + return null + }) + .filter(val => typeof val === 'number') + + const preOvuLength = Math.min(...fhms) - 8 + + // pre ovu length may only be lengthened if we have more than 12 previous fhms + // if pre ovu length is less than 5, it shortened even with fewer prev fhms + if (preOvuLength < 5) return preOvuLength + if (fhms.length >= 12) return preOvuLength + + return null +} \ No newline at end of file diff --git a/lib/sympto/pre-ovulatory.js b/lib/sympto/pre-ovulatory.js index 7d6e15a..01efb19 100644 --- a/lib/sympto/pre-ovulatory.js +++ b/lib/sympto/pre-ovulatory.js @@ -1,20 +1,21 @@ import { LocalDate } from "js-joda" +import apply8DayRule from './minus-8-day-rule' export default function(cycle, previousCycles) { - // TODO handle no previous cycles let preOvuPhaseLength = 5 - //TODO make sure it handles weird cases like fhm < 9 const minus8DayRuleResult = apply8DayRule(previousCycles) if (minus8DayRuleResult) preOvuPhaseLength = minus8DayRuleResult const startDate = LocalDate.parse(cycle[0].date) - const preOvuPhaseEndDate = startDate.plusDays(preOvuPhaseLength - 1).toString() - const maybePreOvuDays = cycle.slice(0, 5).filter(d => d.date <= preOvuPhaseEndDate) + const preOvuEndDate = startDate.plusDays(preOvuPhaseLength - 1).toString() + const maybePreOvuDays = cycle.slice(0, preOvuPhaseLength).filter(d => { + return d.date <= preOvuEndDate + }) const preOvulatoryDays = getDaysUntilFertileMucus(maybePreOvuDays) let endDate if (preOvulatoryDays.length === maybePreOvuDays.length) { - endDate = preOvuPhaseEndDate + endDate = preOvuEndDate } else { endDate = preOvulatoryDays[preOvulatoryDays.length - 1].date } @@ -31,11 +32,12 @@ export default function(cycle, previousCycles) { } function getDaysUntilFertileMucus(days) { - const firstFertileMucusDayIndex = days.findIndex(day => day.mucus && day.mucus.value > 1) + const firstFertileMucusDayIndex = days.findIndex(day => { + return day.mucus && day.mucus.value > 1 + }) + if (firstFertileMucusDayIndex > -1) { return days.slice(0, firstFertileMucusDayIndex) } return days -} - -function apply8DayRule(previousCycles) {} \ No newline at end of file +} \ No newline at end of file diff --git a/test/sympto/fixtures.js b/test/sympto/fixtures.js index 5ac51be..ce096fa 100644 --- a/test/sympto/fixtures.js +++ b/test/sympto/fixtures.js @@ -7,17 +7,31 @@ function convertToSymptoFormat(val) { return sympto } -export const cycleWithTempShift = [36.6, 36.6, 36.6, 36.6, 36.6, 36.6, 36.8, 36.8, 36.8] - .map(num => ({ date: '2018-06-01', temperature: num })) - .map(convertToSymptoFormat) -cycleWithTempShift.unshift({date: '2018-05-30', bleeding: { value: 2 }}) +export const cycleWithFhm = [ + { date: '2018-06-01', temperature: 36.6, bleeding: 2 }, + { date: '2018-06-02', temperature: 36.65 }, + { date: '2018-06-04', temperature: 36.6 }, + { date: '2018-06-05', temperature: 36.55 }, + { date: '2018-06-06', temperature: 36.7, mucus: 0 }, + { date: '2018-06-13', temperature: 36.8, mucus: 4 }, + { date: '2018-06-15', temperature: 36.9, mucus: 2 }, + { date: '2018-06-17', temperature: 36.9, mucus: 2 }, + { date: '2018-06-17', temperature: 36.9, mucus: 2 }, + { date: '2018-06-18', temperature: 36.9, mucus: 2 } +].map(convertToSymptoFormat) -export const cycleWithoutTempShift = [36.6, 36.6, 36.6, 36.6, 36.6, 36.6, 36.8, 36.8] - .map(num => ({ date: '2018-06-01', temperature: num })) - .map(convertToSymptoFormat) -cycleWithoutTempShift.unshift({date: '2018-05-30', bleeding: { value: 2 }}) +export const cycleWithoutFhm = [ + { date: '2018-06-01', temperature: 36.6, bleeding: 2 }, + { date: '2018-06-02', temperature: 36.65 }, + { date: '2018-06-04', temperature: 36.6 }, + { date: '2018-06-05', temperature: 36.55 }, + { date: '2018-06-06', temperature: 36.7, mucus: 0 }, + { date: '2018-06-09', temperature: 36.8, mucus: 4 }, + { date: '2018-06-10', temperature: 36.9, mucus: 2 }, + { date: '2018-06-13', temperature: 36.9, mucus: 2 } +].map(convertToSymptoFormat) -export const cycleWithTempAndMucusShift = [ +export const longAndComplicatedCycle = [ { date: '2018-06-01', temperature: 36.6, bleeding: 2 }, { date: '2018-06-02', temperature: 36.65 }, { date: '2018-06-04', temperature: 36.6 }, @@ -224,4 +238,19 @@ export const fhmOnDay12 = [ { date: '2018-06-12', temperature: 36.8, mucus: 3 }, { date: '2018-06-14', temperature: 36.9, mucus: 2 }, { date: '2018-06-17', temperature: 36.9, mucus: 2 }, + { date: '2018-06-18', temperature: 36.9, mucus: 2 }, ].map(convertToSymptoFormat) + +export const fhmOnDay15 = [ + { date: '2018-06-01', temperature: 36.6, bleeding: 2 }, + { date: '2018-06-02', temperature: 36.65 }, + { date: '2018-06-04', temperature: 36.6 }, + { date: '2018-06-05', temperature: 36.55 }, + { date: '2018-06-06', temperature: 36.7, mucus: 0 }, + { date: '2018-06-09', temperature: 36.5, mucus: 2 }, + { date: '2018-06-10', temperature: 36.4, mucus: 3 }, + { date: '2018-06-15', temperature: 36.8, mucus: 3 }, + { date: '2018-06-16', temperature: 36.9, mucus: 2 }, + { date: '2018-06-17', temperature: 36.9, mucus: 2 }, + { date: '2018-06-18', temperature: 36.9, mucus: 2 }, +].map(convertToSymptoFormat) \ No newline at end of file diff --git a/test/sympto/index.spec.js b/test/sympto/index.spec.js index 4b00183..bbb66d4 100644 --- a/test/sympto/index.spec.js +++ b/test/sympto/index.spec.js @@ -2,10 +2,10 @@ import chai from 'chai' import getSensiplanStatus from '../../lib/sympto' import { AssertionError } from 'assert' import { - cycleWithoutTempShift, - cycleWithTempAndMucusShift, + cycleWithoutFhm, + longAndComplicatedCycle, cycleWithTempAndNoMucusShift, - cycleWithTempShift, + cycleWithFhm, cycleWithoutAnyShifts, fiveDayCycle, cycleWithEarlyMucus, @@ -14,7 +14,8 @@ import { fhm5DaysAfterMucusPeak, mucusPeak5DaysAfterFhm, mucusPeakTwoDaysBeforeFhm, - fhmOnDay12 + fhmOnDay12, + fhmOnDay15 } from './fixtures' const expect = chai.expect @@ -24,7 +25,7 @@ describe('sympto', () => { it('with no shifts detects only peri-ovulatory', function () { const status = getSensiplanStatus({ cycle: cycleWithoutAnyShifts, - previousCycles: [cycleWithoutTempShift] + previousCycles: [cycleWithoutFhm,] }) expect(status).to.eql({ @@ -38,10 +39,10 @@ describe('sympto', () => { }) }) - it('with shifts detects only peri-ovulatory and post-ovulatory', function () { + it('with shifts detects only peri-ovulatory and post-ovulatory', () => { const status = getSensiplanStatus({ - cycle: cycleWithTempAndMucusShift, - previousCycles: [cycleWithoutTempShift] + cycle: longAndComplicatedCycle, + previousCycles: [cycleWithoutFhm,] }) expect(status.temperatureShift).to.be.an('object') @@ -51,14 +52,16 @@ describe('sympto', () => { expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-21', time: '18:00' }, - cycleDays: cycleWithTempAndMucusShift.filter(({date}) => date <= '2018-06-21') + cycleDays: longAndComplicatedCycle + .filter(({date}) => date <= '2018-06-21') }) expect(status.phases.postOvulatory).to.eql({ start: { date: '2018-06-21', time: '18:00' }, - cycleDays: cycleWithTempAndMucusShift.filter(({date}) => date >= '2018-06-21') + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21') }) }) }) @@ -67,7 +70,7 @@ describe('sympto', () => { it('according to 5-day-rule', function () { const status = getSensiplanStatus({ cycle: fiveDayCycle, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(Object.keys(status.phases).length).to.eql(1) @@ -80,29 +83,31 @@ describe('sympto', () => { }) }) - describe('with no shifts detects pre- and peri-ovulatory phase', function () { + describe('with no shifts detects pre- and peri-ovulatory phase', () => { it('according to 5-day-rule', function () { const status = getSensiplanStatus({ cycle: cycleWithTempAndNoMucusShift, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(Object.keys(status.phases).length).to.eql(2) expect(status.assumeFertility).to.be.true() expect(status.phases.preOvulatory).to.eql({ - cycleDays: cycleWithTempAndNoMucusShift.filter(({date}) => date <= '2018-06-05'), + cycleDays: cycleWithTempAndNoMucusShift + .filter(({date}) => date <= '2018-06-05'), start: { date: '2018-06-01' }, end: { date: '2018-06-05' } }) expect(status.phases.periOvulatory).to.eql({ - cycleDays: cycleWithTempAndNoMucusShift.filter(({date}) => date > '2018-06-05'), + cycleDays: cycleWithTempAndNoMucusShift + .filter(({date}) => date > '2018-06-05'), start: { date: '2018-06-06' } }) }) it('according to 5-day-rule with shortened pre-phase', function () { const status = getSensiplanStatus({ cycle: cycleWithEarlyMucus, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(Object.keys(status.phases).length).to.eql(2) @@ -121,24 +126,27 @@ describe('sympto', () => { describe('with shifts detects pre- and peri-ovulatory phase', function () { it('according to 5-day-rule', function () { const status = getSensiplanStatus({ - cycle: cycleWithTempAndMucusShift, - previousCycles: [cycleWithTempShift] + cycle: longAndComplicatedCycle, + previousCycles: [cycleWithFhm] }) expect(Object.keys(status.phases).length).to.eql(3) expect(status.assumeFertility).to.be.false() expect(status.phases.preOvulatory).to.eql({ - cycleDays: cycleWithTempAndMucusShift.filter(({date}) => date <= '2018-06-05'), + cycleDays: longAndComplicatedCycle + .filter(({date}) => date <= '2018-06-05'), start: { date: '2018-06-01' }, end: { date: '2018-06-05' } }) expect(status.phases.periOvulatory).to.eql({ - cycleDays: cycleWithTempAndMucusShift.filter(({date}) => date > '2018-06-05' && date <= '2018-06-21'), + cycleDays: longAndComplicatedCycle + .filter(({date}) => date > '2018-06-05' && date <= '2018-06-21'), start: { date: '2018-06-06' }, end: { date: '2018-06-21', time: '18:00'} }) expect(status.phases.postOvulatory).to.eql({ - cycleDays: cycleWithTempAndMucusShift.filter(({date}) => date >= '2018-06-21'), + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21'), start: { date: '2018-06-21', time: '18:00'} }) }) @@ -147,10 +155,10 @@ describe('sympto', () => { }) describe('combining first higher measurment and mucus peak', () => { - it('with fhM + mucus peak on same day finds correct start of post-ovu phase', () => { + it('with fhM + mucus peak on same day finds start of postovu phase', () => { const status = getSensiplanStatus({ cycle: mucusPeakAndFhmOnSameDay, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(status.temperatureShift).to.be.an('object') @@ -160,28 +168,31 @@ describe('sympto', () => { expect(status.phases.preOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-05' }, - cycleDays: mucusPeakAndFhmOnSameDay.filter(({date}) => date <= '2018-06-05') + cycleDays: mucusPeakAndFhmOnSameDay + .filter(({date}) => date <= '2018-06-05') }) expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-06' }, end: { date: '2018-06-21', time: '18:00' }, - cycleDays: mucusPeakAndFhmOnSameDay.filter(({date}) => { - return date > '2018-06-05' && date <= '2018-06-21' - }) + cycleDays: mucusPeakAndFhmOnSameDay + .filter(({date}) => { + return date > '2018-06-05' && date <= '2018-06-21' + }) }) expect(status.phases.postOvulatory).to.eql({ start: { date: '2018-06-21', time: '18:00' }, - cycleDays: mucusPeakAndFhmOnSameDay.filter(({date}) => date >= '2018-06-21') + cycleDays: mucusPeakAndFhmOnSameDay + .filter(({date}) => date >= '2018-06-21') }) }) it('with fhM 2 days before mucus peak waits for end of mucus eval', () => { const status = getSensiplanStatus({ cycle: fhmTwoDaysBeforeMucusPeak, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(status.temperatureShift).to.be.an('object') @@ -191,28 +202,31 @@ describe('sympto', () => { expect(status.phases.preOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-05' }, - cycleDays: fhmTwoDaysBeforeMucusPeak.filter(({date}) => date <= '2018-06-05') + cycleDays: fhmTwoDaysBeforeMucusPeak + .filter(({date}) => date <= '2018-06-05') }) expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-06' }, end: { date: '2018-06-26', time: '18:00' }, - cycleDays: fhmTwoDaysBeforeMucusPeak.filter(({date}) => { - return date > '2018-06-05' && date <= '2018-06-26' - }) + cycleDays: fhmTwoDaysBeforeMucusPeak + .filter(({date}) => { + return date > '2018-06-05' && date <= '2018-06-26' + }) }) expect(status.phases.postOvulatory).to.eql({ start: { date: '2018-06-26', time: '18:00' }, - cycleDays: fhmTwoDaysBeforeMucusPeak.filter(({date}) => date >= '2018-06-26') + cycleDays: fhmTwoDaysBeforeMucusPeak + .filter(({date}) => date >= '2018-06-26') }) }) it('with another mucus peak 5 days after fHM ignores it', () => { const status = getSensiplanStatus({ cycle: mucusPeak5DaysAfterFhm, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(status.temperatureShift).to.be.an('object') @@ -222,28 +236,31 @@ describe('sympto', () => { expect(status.phases.preOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-01' }, - cycleDays: mucusPeak5DaysAfterFhm.filter(({date}) => date <= '2018-06-01') + cycleDays: mucusPeak5DaysAfterFhm + .filter(({date}) => date <= '2018-06-01') }) expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-02' }, end: { date: '2018-06-22', time: '18:00' }, - cycleDays: mucusPeak5DaysAfterFhm.filter(({date}) => { - return date > '2018-06-01' && date <= '2018-06-22' - }) + cycleDays: mucusPeak5DaysAfterFhm + .filter(({date}) => { + return date > '2018-06-01' && date <= '2018-06-22' + }) }) expect(status.phases.postOvulatory).to.eql({ start: { date: '2018-06-22', time: '18:00' }, - cycleDays: mucusPeak5DaysAfterFhm.filter(({date}) => date >= '2018-06-22') + cycleDays: mucusPeak5DaysAfterFhm + .filter(({date}) => date >= '2018-06-22') }) }) it('with mucus peak 2 days before fhM waits for end of temp eval', () => { const status = getSensiplanStatus({ cycle: mucusPeakTwoDaysBeforeFhm, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(status.temperatureShift).to.be.an('object') @@ -253,28 +270,31 @@ describe('sympto', () => { expect(status.phases.preOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-04' }, - cycleDays: mucusPeakTwoDaysBeforeFhm.filter(({date}) => date <= '2018-06-04') + cycleDays: mucusPeakTwoDaysBeforeFhm + .filter(({date}) => date <= '2018-06-04') }) expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-05' }, end: { date: '2018-07-03', time: '18:00' }, - cycleDays: mucusPeakTwoDaysBeforeFhm.filter(({date}) => { - return date > '2018-06-04' && date <= '2018-07-03' - }) + cycleDays: mucusPeakTwoDaysBeforeFhm + .filter(({date}) => { + return date > '2018-06-04' && date <= '2018-07-03' + }) }) expect(status.phases.postOvulatory).to.eql({ start: { date: '2018-07-03', time: '18:00' }, - cycleDays: mucusPeakTwoDaysBeforeFhm.filter(({date}) => date >= '2018-07-03') + cycleDays: mucusPeakTwoDaysBeforeFhm + .filter(({date}) => date >= '2018-07-03') }) }) it('with mucus peak 5 days before fhM waits for end of temp eval', () => { const status = getSensiplanStatus({ cycle: fhm5DaysAfterMucusPeak, - previousCycles: [cycleWithTempShift] + previousCycles: [cycleWithFhm] }) expect(status.temperatureShift).to.be.an('object') @@ -284,21 +304,24 @@ describe('sympto', () => { expect(status.phases.preOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-05' }, - cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => date <= '2018-06-05') + cycleDays: fhm5DaysAfterMucusPeak + .filter(({date}) => date <= '2018-06-05') }) expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-06' }, end: { date: '2018-06-21', time: '18:00' }, - cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => { - return date > '2018-06-05' && date <= '2018-06-21' - }) + cycleDays: fhm5DaysAfterMucusPeak + .filter(({date}) => { + return date > '2018-06-05' && date <= '2018-06-21' + }) }) expect(status.phases.postOvulatory).to.eql({ start: { date: '2018-06-21', time: '18:00' }, - cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => date >= '2018-06-21') + cycleDays: fhm5DaysAfterMucusPeak + .filter(({date}) => date >= '2018-06-21') }) }) }) @@ -306,8 +329,8 @@ describe('sympto', () => { describe('applying the minus-8 rule', () => { it('shortens the pre-ovu phase if there is a previous <13 fhm', () => { const status = getSensiplanStatus({ - cycle: cycleWithTempAndMucusShift, - previousCycles: [fhmOnDay12, cycleWithTempShift] + cycle: longAndComplicatedCycle, + previousCycles: [fhmOnDay12, ...Array(13).fill(fhmOnDay15)] }) expect(status.temperatureShift).to.be.an('object') @@ -317,28 +340,170 @@ describe('sympto', () => { expect(status.phases.preOvulatory).to.eql({ start: { date: '2018-06-01' }, end: { date: '2018-06-04' }, - cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => date <= '2018-06-04') + cycleDays: longAndComplicatedCycle + .filter(({date}) => date <= '2018-06-04') }) expect(status.phases.periOvulatory).to.eql({ start: { date: '2018-06-05' }, - end: { date: '2018-06-17', time: '18:00' }, - cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => { - return date > '2018-06-04' && date <= '2018-06-17' - }) + end: { date: '2018-06-21', time: '18:00' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => { + return date > '2018-06-04' && date <= '2018-06-21' + }) }) expect(status.phases.postOvulatory).to.eql({ start: { - date: '2018-06-17', + date: '2018-06-21', time: '18:00' }, - cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => date >= '2018-06-17') + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21') + }) + }) + it('shortens pre-ovu phase with prev <13 fhm even with <12 cycles', () => { + const status = getSensiplanStatus({ + cycle: longAndComplicatedCycle, + previousCycles: Array(11).fill(fhmOnDay12) + }) + + expect(status.temperatureShift).to.be.an('object') + expect(status.mucusShift).to.be.an('object') + expect(status.assumeFertility).to.be.false() + expect(Object.keys(status.phases).length).to.eql(3) + expect(status.phases.preOvulatory).to.eql({ + start: { date: '2018-06-01' }, + end: { date: '2018-06-04' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date <= '2018-06-04') + }) + expect(status.phases.periOvulatory).to.eql({ + start: { date: '2018-06-05' }, + end: { date: '2018-06-21', time: '18:00' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => { + return date > '2018-06-04' && date <= '2018-06-21' + }) + }) + expect(status.phases.postOvulatory).to.eql({ + start: { + date: '2018-06-21', + time: '18:00' + }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21') + }) + }) + it('shortens the pre-ovu phase if mucus occurs', () => { + const status = getSensiplanStatus({ + cycle: cycleWithEarlyMucus, + previousCycles: Array(11).fill(fhmOnDay12) + }) + + expect(status.assumeFertility).to.be.true() + expect(Object.keys(status.phases).length).to.eql(2) + expect(status.phases.preOvulatory).to.eql({ + start: { date: '2018-06-01' }, + end: { date: '2018-06-01' }, + cycleDays: cycleWithEarlyMucus + .filter(({date}) => date <= '2018-06-01') + }) + expect(status.phases.periOvulatory).to.eql({ + start: { date: '2018-06-02' }, + cycleDays: cycleWithEarlyMucus + .filter(({date}) => { + return date > '2018-06-01' + }) + }) + }) + it('lengthens the pre-ovu phase if >= 12 cycles with fhm > 13', () => { + const status = getSensiplanStatus({ + cycle: longAndComplicatedCycle, + previousCycles: Array(12).fill(fhmOnDay15) + }) + + expect(status.assumeFertility).to.be.false() + expect(Object.keys(status.phases).length).to.eql(3) + expect(status.phases.preOvulatory).to.eql({ + start: { date: '2018-06-01' }, + end: { date: '2018-06-07' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date <= '2018-06-07') + }) + expect(status.phases.periOvulatory).to.eql({ + start: { date: '2018-06-08' }, + end: { date: '2018-06-21', time: '18:00' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => { + return date > '2018-06-07' && date <= '2018-06-21' + }) + }) + expect(status.phases.postOvulatory).to.eql({ + start: { + date: '2018-06-21', + time: '18:00' + }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21') + }) + }) + + it('does not lengthen the pre-ovu phase if < 12 cycles', () => { + const status = getSensiplanStatus({ + cycle: longAndComplicatedCycle, + previousCycles: Array(11).fill(fhmOnDay15) + }) + + expect(status.assumeFertility).to.be.false() + expect(Object.keys(status.phases).length).to.eql(3) + expect(status.phases.preOvulatory).to.eql({ + start: { date: '2018-06-01' }, + end: { date: '2018-06-05' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date <= '2018-06-05') + }) + expect(status.phases.periOvulatory).to.eql({ + start: { date: '2018-06-06' }, + end: { date: '2018-06-21', time: '18:00' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => { + return date > '2018-06-05' && date <= '2018-06-21' + }) + }) + expect(status.phases.postOvulatory).to.eql({ + start: { + date: '2018-06-21', + time: '18:00' + }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21') + }) + }) + + it('does not detect any pre-ovu phase if prev cycle had no fhm', () => { + const status = getSensiplanStatus({ + cycle: longAndComplicatedCycle, + previousCycles: [...Array(12).fill(fhmOnDay15), cycleWithoutFhm] + }) + + expect(status.assumeFertility).to.be.false() + expect(Object.keys(status.phases).length).to.eql(2) + expect(status.phases.periOvulatory).to.eql({ + start: { date: '2018-06-01' }, + end: { date: '2018-06-21', time: '18:00' }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => { + return date >= '2018-06-01' && date <= '2018-06-21' + }) + }) + expect(status.phases.postOvulatory).to.eql({ + start: { + date: '2018-06-21', + time: '18:00' + }, + cycleDays: longAndComplicatedCycle + .filter(({date}) => date >= '2018-06-21') }) }) - it('shortens the pre-ovu phase if there is a previous <13 fhm with less than 12 cycles') - it('shortens the pre-ovu phase if mucus occurs') - it('lengthens the pre-ovu phase if >= 12 cycles') - it('does not lengthen the pre-ovu phase if < 12 cycles') - it('does not lengthen the pre-ovu phase if < 12 cycles') }) describe('when args are wrong', () => {