Implement minus 8 day rule

This commit is contained in:
Julia Friesel
2018-07-13 07:14:36 +02:00
parent d5aa903da4
commit 7382bff0dd
5 changed files with 308 additions and 85 deletions
+2 -1
View File
@@ -47,6 +47,7 @@
"no-var": "error", "no-var": "error",
"prefer-const": "error", "prefer-const": "error",
"no-trailing-spaces": "error", "no-trailing-spaces": "error",
"react/prop-types": 0 "react/prop-types": 0,
"max-len": "warn"
} }
} }
+26
View File
@@ -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
}
+11 -9
View File
@@ -1,20 +1,21 @@
import { LocalDate } from "js-joda" import { LocalDate } from "js-joda"
import apply8DayRule from './minus-8-day-rule'
export default function(cycle, previousCycles) { export default function(cycle, previousCycles) {
// TODO handle no previous cycles
let preOvuPhaseLength = 5 let preOvuPhaseLength = 5
//TODO make sure it handles weird cases like fhm < 9
const minus8DayRuleResult = apply8DayRule(previousCycles) const minus8DayRuleResult = apply8DayRule(previousCycles)
if (minus8DayRuleResult) preOvuPhaseLength = minus8DayRuleResult if (minus8DayRuleResult) preOvuPhaseLength = minus8DayRuleResult
const startDate = LocalDate.parse(cycle[0].date) const startDate = LocalDate.parse(cycle[0].date)
const preOvuPhaseEndDate = startDate.plusDays(preOvuPhaseLength - 1).toString() const preOvuEndDate = startDate.plusDays(preOvuPhaseLength - 1).toString()
const maybePreOvuDays = cycle.slice(0, 5).filter(d => d.date <= preOvuPhaseEndDate) const maybePreOvuDays = cycle.slice(0, preOvuPhaseLength).filter(d => {
return d.date <= preOvuEndDate
})
const preOvulatoryDays = getDaysUntilFertileMucus(maybePreOvuDays) const preOvulatoryDays = getDaysUntilFertileMucus(maybePreOvuDays)
let endDate let endDate
if (preOvulatoryDays.length === maybePreOvuDays.length) { if (preOvulatoryDays.length === maybePreOvuDays.length) {
endDate = preOvuPhaseEndDate endDate = preOvuEndDate
} else { } else {
endDate = preOvulatoryDays[preOvulatoryDays.length - 1].date endDate = preOvulatoryDays[preOvulatoryDays.length - 1].date
} }
@@ -31,11 +32,12 @@ export default function(cycle, previousCycles) {
} }
function getDaysUntilFertileMucus(days) { 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) { if (firstFertileMucusDayIndex > -1) {
return days.slice(0, firstFertileMucusDayIndex) return days.slice(0, firstFertileMucusDayIndex)
} }
return days return days
} }
function apply8DayRule(previousCycles) {}
+38 -9
View File
@@ -7,17 +7,31 @@ function convertToSymptoFormat(val) {
return sympto return sympto
} }
export const cycleWithTempShift = [36.6, 36.6, 36.6, 36.6, 36.6, 36.6, 36.8, 36.8, 36.8] export const cycleWithFhm = [
.map(num => ({ date: '2018-06-01', temperature: num })) { date: '2018-06-01', temperature: 36.6, bleeding: 2 },
.map(convertToSymptoFormat) { date: '2018-06-02', temperature: 36.65 },
cycleWithTempShift.unshift({date: '2018-05-30', bleeding: { value: 2 }}) { 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] export const cycleWithoutFhm = [
.map(num => ({ date: '2018-06-01', temperature: num })) { date: '2018-06-01', temperature: 36.6, bleeding: 2 },
.map(convertToSymptoFormat) { date: '2018-06-02', temperature: 36.65 },
cycleWithoutTempShift.unshift({date: '2018-05-30', bleeding: { value: 2 }}) { 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-01', temperature: 36.6, bleeding: 2 },
{ date: '2018-06-02', temperature: 36.65 }, { date: '2018-06-02', temperature: 36.65 },
{ date: '2018-06-04', temperature: 36.6 }, { 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-12', temperature: 36.8, mucus: 3 },
{ date: '2018-06-14', temperature: 36.9, mucus: 2 }, { date: '2018-06-14', 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) ].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)
+231 -66
View File
@@ -2,10 +2,10 @@ import chai from 'chai'
import getSensiplanStatus from '../../lib/sympto' import getSensiplanStatus from '../../lib/sympto'
import { AssertionError } from 'assert' import { AssertionError } from 'assert'
import { import {
cycleWithoutTempShift, cycleWithoutFhm,
cycleWithTempAndMucusShift, longAndComplicatedCycle,
cycleWithTempAndNoMucusShift, cycleWithTempAndNoMucusShift,
cycleWithTempShift, cycleWithFhm,
cycleWithoutAnyShifts, cycleWithoutAnyShifts,
fiveDayCycle, fiveDayCycle,
cycleWithEarlyMucus, cycleWithEarlyMucus,
@@ -14,7 +14,8 @@ import {
fhm5DaysAfterMucusPeak, fhm5DaysAfterMucusPeak,
mucusPeak5DaysAfterFhm, mucusPeak5DaysAfterFhm,
mucusPeakTwoDaysBeforeFhm, mucusPeakTwoDaysBeforeFhm,
fhmOnDay12 fhmOnDay12,
fhmOnDay15
} from './fixtures' } from './fixtures'
const expect = chai.expect const expect = chai.expect
@@ -24,7 +25,7 @@ describe('sympto', () => {
it('with no shifts detects only peri-ovulatory', function () { it('with no shifts detects only peri-ovulatory', function () {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: cycleWithoutAnyShifts, cycle: cycleWithoutAnyShifts,
previousCycles: [cycleWithoutTempShift] previousCycles: [cycleWithoutFhm,]
}) })
expect(status).to.eql({ 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({ const status = getSensiplanStatus({
cycle: cycleWithTempAndMucusShift, cycle: longAndComplicatedCycle,
previousCycles: [cycleWithoutTempShift] previousCycles: [cycleWithoutFhm,]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -51,14 +52,16 @@ describe('sympto', () => {
expect(status.phases.periOvulatory).to.eql({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { date: '2018-06-21', time: '18:00' }, 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({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-06-21', date: '2018-06-21',
time: '18:00' 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 () { it('according to 5-day-rule', function () {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: fiveDayCycle, cycle: fiveDayCycle,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(Object.keys(status.phases).length).to.eql(1) 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 () { it('according to 5-day-rule', function () {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: cycleWithTempAndNoMucusShift, cycle: cycleWithTempAndNoMucusShift,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(Object.keys(status.phases).length).to.eql(2) expect(Object.keys(status.phases).length).to.eql(2)
expect(status.assumeFertility).to.be.true() expect(status.assumeFertility).to.be.true()
expect(status.phases.preOvulatory).to.eql({ 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' }, start: { date: '2018-06-01' },
end: { date: '2018-06-05' } end: { date: '2018-06-05' }
}) })
expect(status.phases.periOvulatory).to.eql({ 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' } start: { date: '2018-06-06' }
}) })
}) })
it('according to 5-day-rule with shortened pre-phase', function () { it('according to 5-day-rule with shortened pre-phase', function () {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: cycleWithEarlyMucus, cycle: cycleWithEarlyMucus,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(Object.keys(status.phases).length).to.eql(2) 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 () { describe('with shifts detects pre- and peri-ovulatory phase', function () {
it('according to 5-day-rule', function () { it('according to 5-day-rule', function () {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: cycleWithTempAndMucusShift, cycle: longAndComplicatedCycle,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(Object.keys(status.phases).length).to.eql(3) expect(Object.keys(status.phases).length).to.eql(3)
expect(status.assumeFertility).to.be.false() expect(status.assumeFertility).to.be.false()
expect(status.phases.preOvulatory).to.eql({ 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' }, start: { date: '2018-06-01' },
end: { date: '2018-06-05' } end: { date: '2018-06-05' }
}) })
expect(status.phases.periOvulatory).to.eql({ 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' }, start: { date: '2018-06-06' },
end: { date: '2018-06-21', time: '18:00'} end: { date: '2018-06-21', time: '18:00'}
}) })
expect(status.phases.postOvulatory).to.eql({ 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'} start: { date: '2018-06-21', time: '18:00'}
}) })
}) })
@@ -147,10 +155,10 @@ describe('sympto', () => {
}) })
describe('combining first higher measurment and mucus peak', () => { 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({ const status = getSensiplanStatus({
cycle: mucusPeakAndFhmOnSameDay, cycle: mucusPeakAndFhmOnSameDay,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -160,28 +168,31 @@ describe('sympto', () => {
expect(status.phases.preOvulatory).to.eql({ expect(status.phases.preOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { date: '2018-06-05' }, 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({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-06' }, start: { date: '2018-06-06' },
end: { date: '2018-06-21', time: '18:00' }, end: { date: '2018-06-21', time: '18:00' },
cycleDays: mucusPeakAndFhmOnSameDay.filter(({date}) => { cycleDays: mucusPeakAndFhmOnSameDay
return date > '2018-06-05' && date <= '2018-06-21' .filter(({date}) => {
}) return date > '2018-06-05' && date <= '2018-06-21'
})
}) })
expect(status.phases.postOvulatory).to.eql({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-06-21', date: '2018-06-21',
time: '18:00' 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', () => { it('with fhM 2 days before mucus peak waits for end of mucus eval', () => {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: fhmTwoDaysBeforeMucusPeak, cycle: fhmTwoDaysBeforeMucusPeak,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -191,28 +202,31 @@ describe('sympto', () => {
expect(status.phases.preOvulatory).to.eql({ expect(status.phases.preOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { date: '2018-06-05' }, 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({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-06' }, start: { date: '2018-06-06' },
end: { date: '2018-06-26', time: '18:00' }, end: { date: '2018-06-26', time: '18:00' },
cycleDays: fhmTwoDaysBeforeMucusPeak.filter(({date}) => { cycleDays: fhmTwoDaysBeforeMucusPeak
return date > '2018-06-05' && date <= '2018-06-26' .filter(({date}) => {
}) return date > '2018-06-05' && date <= '2018-06-26'
})
}) })
expect(status.phases.postOvulatory).to.eql({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-06-26', date: '2018-06-26',
time: '18:00' 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', () => { it('with another mucus peak 5 days after fHM ignores it', () => {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: mucusPeak5DaysAfterFhm, cycle: mucusPeak5DaysAfterFhm,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -222,28 +236,31 @@ describe('sympto', () => {
expect(status.phases.preOvulatory).to.eql({ expect(status.phases.preOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { 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({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-02' }, start: { date: '2018-06-02' },
end: { date: '2018-06-22', time: '18:00' }, end: { date: '2018-06-22', time: '18:00' },
cycleDays: mucusPeak5DaysAfterFhm.filter(({date}) => { cycleDays: mucusPeak5DaysAfterFhm
return date > '2018-06-01' && date <= '2018-06-22' .filter(({date}) => {
}) return date > '2018-06-01' && date <= '2018-06-22'
})
}) })
expect(status.phases.postOvulatory).to.eql({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-06-22', date: '2018-06-22',
time: '18:00' 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', () => { it('with mucus peak 2 days before fhM waits for end of temp eval', () => {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: mucusPeakTwoDaysBeforeFhm, cycle: mucusPeakTwoDaysBeforeFhm,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -253,28 +270,31 @@ describe('sympto', () => {
expect(status.phases.preOvulatory).to.eql({ expect(status.phases.preOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { date: '2018-06-04' }, 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({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-05' }, start: { date: '2018-06-05' },
end: { date: '2018-07-03', time: '18:00' }, end: { date: '2018-07-03', time: '18:00' },
cycleDays: mucusPeakTwoDaysBeforeFhm.filter(({date}) => { cycleDays: mucusPeakTwoDaysBeforeFhm
return date > '2018-06-04' && date <= '2018-07-03' .filter(({date}) => {
}) return date > '2018-06-04' && date <= '2018-07-03'
})
}) })
expect(status.phases.postOvulatory).to.eql({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-07-03', date: '2018-07-03',
time: '18:00' 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', () => { it('with mucus peak 5 days before fhM waits for end of temp eval', () => {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: fhm5DaysAfterMucusPeak, cycle: fhm5DaysAfterMucusPeak,
previousCycles: [cycleWithTempShift] previousCycles: [cycleWithFhm]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -284,21 +304,24 @@ describe('sympto', () => {
expect(status.phases.preOvulatory).to.eql({ expect(status.phases.preOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { date: '2018-06-05' }, 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({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-06' }, start: { date: '2018-06-06' },
end: { date: '2018-06-21', time: '18:00' }, end: { date: '2018-06-21', time: '18:00' },
cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => { cycleDays: fhm5DaysAfterMucusPeak
return date > '2018-06-05' && date <= '2018-06-21' .filter(({date}) => {
}) return date > '2018-06-05' && date <= '2018-06-21'
})
}) })
expect(status.phases.postOvulatory).to.eql({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-06-21', date: '2018-06-21',
time: '18:00' 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', () => { describe('applying the minus-8 rule', () => {
it('shortens the pre-ovu phase if there is a previous <13 fhm', () => { it('shortens the pre-ovu phase if there is a previous <13 fhm', () => {
const status = getSensiplanStatus({ const status = getSensiplanStatus({
cycle: cycleWithTempAndMucusShift, cycle: longAndComplicatedCycle,
previousCycles: [fhmOnDay12, cycleWithTempShift] previousCycles: [fhmOnDay12, ...Array(13).fill(fhmOnDay15)]
}) })
expect(status.temperatureShift).to.be.an('object') expect(status.temperatureShift).to.be.an('object')
@@ -317,28 +340,170 @@ describe('sympto', () => {
expect(status.phases.preOvulatory).to.eql({ expect(status.phases.preOvulatory).to.eql({
start: { date: '2018-06-01' }, start: { date: '2018-06-01' },
end: { date: '2018-06-04' }, 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({ expect(status.phases.periOvulatory).to.eql({
start: { date: '2018-06-05' }, start: { date: '2018-06-05' },
end: { date: '2018-06-17', time: '18:00' }, end: { date: '2018-06-21', time: '18:00' },
cycleDays: fhm5DaysAfterMucusPeak.filter(({date}) => { cycleDays: longAndComplicatedCycle
return date > '2018-06-04' && date <= '2018-06-17' .filter(({date}) => {
}) return date > '2018-06-04' && date <= '2018-06-21'
})
}) })
expect(status.phases.postOvulatory).to.eql({ expect(status.phases.postOvulatory).to.eql({
start: { start: {
date: '2018-06-17', date: '2018-06-21',
time: '18:00' 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', () => { describe('when args are wrong', () => {