Implement 5-day-rule
This commit is contained in:
+14
-7
@@ -1,5 +1,7 @@
|
|||||||
import getTemperatureShift from './temperature'
|
import getTemperatureShift from './temperature'
|
||||||
import getMucusShift from './mucus'
|
import getMucusShift from './mucus'
|
||||||
|
import getPreOvulatoryPhase from './pre-ovulatory'
|
||||||
|
import { LocalDate } from 'js-joda'
|
||||||
|
|
||||||
export default function ({ cycle, previousCycle }) {
|
export default function ({ cycle, previousCycle }) {
|
||||||
// TODO check for basic stuff, throw if nonexistent
|
// TODO check for basic stuff, throw if nonexistent
|
||||||
@@ -8,8 +10,7 @@ export default function ({ cycle, previousCycle }) {
|
|||||||
phases: {
|
phases: {
|
||||||
periOvulatory: {
|
periOvulatory: {
|
||||||
start: {
|
start: {
|
||||||
date: null,
|
date: null
|
||||||
time: '00:00'
|
|
||||||
},
|
},
|
||||||
cycleDays: null
|
cycleDays: null
|
||||||
}
|
}
|
||||||
@@ -18,13 +19,19 @@ export default function ({ cycle, previousCycle }) {
|
|||||||
|
|
||||||
// if there was no first higher measurement in the previous cycle,
|
// if there was no first higher measurement in the previous cycle,
|
||||||
// no infertile preovulatory phase may be assumed
|
// no infertile preovulatory phase may be assumed
|
||||||
|
if (getTemperatureShift(previousCycle).detected && !cycle[0].mucus) {
|
||||||
|
status.phases.preOvulatory = getPreOvulatoryPhase(cycle)
|
||||||
|
}
|
||||||
|
|
||||||
if (getTemperatureShift(previousCycle).detected) {
|
const periPhase = status.phases.periOvulatory
|
||||||
// add preOvulatory phase
|
if (status.phases.preOvulatory) {
|
||||||
|
const prePhase = status.phases.preOvulatory
|
||||||
|
periPhase.start.date = LocalDate.parse(prePhase.end.date).plusDays(1).toString()
|
||||||
|
const lastPreDay = prePhase.cycleDays[prePhase.cycleDays.length - 1]
|
||||||
|
periPhase.cycleDays = cycle.slice(cycle.indexOf(lastPreDay) + 1)
|
||||||
} else {
|
} else {
|
||||||
const first = cycle[0]
|
periPhase.start.date = cycle[0].date
|
||||||
status.phases.periOvulatory.start.date = first.date
|
periPhase.cycleDays = [...cycle]
|
||||||
status.phases.periOvulatory.cycleDays = [...cycle]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const temperatureShift = getTemperatureShift(cycle)
|
const temperatureShift = getTemperatureShift(cycle)
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
export default function(cycle) {
|
||||||
|
const fiveDayRuleDays = cycle.slice(0, 5)
|
||||||
|
const preOvulatoryDays = getDaysUntilFertileMucus(fiveDayRuleDays)
|
||||||
|
return {
|
||||||
|
cycleDays: preOvulatoryDays,
|
||||||
|
start: {
|
||||||
|
date: preOvulatoryDays[0].date
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
date: preOvulatoryDays[preOvulatoryDays.length - 1].date,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDaysUntilFertileMucus(days) {
|
||||||
|
const firstFertileMucusDayIndex = days.findIndex(day => day.mucus && day.mucus.value > 1)
|
||||||
|
if (firstFertileMucusDayIndex > -1) {
|
||||||
|
return days.slice(0, firstFertileMucusDayIndex)
|
||||||
|
}
|
||||||
|
return days
|
||||||
|
}
|
||||||
+50
-44
@@ -4,7 +4,9 @@ import getSensiplanStatus from '../../lib/sympto'
|
|||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
function convertToSymptoFormat(val, i) {
|
function convertToSymptoFormat(val, i) {
|
||||||
const sympto = { date: i }
|
++i
|
||||||
|
const dayString = i < 10 ? `0${i}` : i
|
||||||
|
const sympto = { date: `2018-06-${dayString}` }
|
||||||
if (val.temperature) sympto.temperature = { value: val.temperature }
|
if (val.temperature) sympto.temperature = { value: val.temperature }
|
||||||
if (val.mucus) sympto.mucus = { value: val.mucus }
|
if (val.mucus) sympto.mucus = { value: val.mucus }
|
||||||
if (val.bleeding) sympto.bleeding = { value: val.bleeding }
|
if (val.bleeding) sympto.bleeding = { value: val.bleeding }
|
||||||
@@ -49,6 +51,31 @@ const cycleWithTempAndMucusShift = [
|
|||||||
{ temperature: 36.9, mucus: 1 }
|
{ temperature: 36.9, mucus: 1 }
|
||||||
].map(convertToSymptoFormat)
|
].map(convertToSymptoFormat)
|
||||||
|
|
||||||
|
const cycleWithTempAndNoMucusShift = [
|
||||||
|
{ temperature: 36.6, bleeding: 2 },
|
||||||
|
{ temperature: 36.65 },
|
||||||
|
{ temperature: 36.5 },
|
||||||
|
{ temperature: 36.6 },
|
||||||
|
{ temperature: 36.55 },
|
||||||
|
{ temperature: 36.7, mucus: 0 },
|
||||||
|
{ temperature: 36.75, mucus: 0 },
|
||||||
|
{ temperature: 36.45, mucus: 1 },
|
||||||
|
{ temperature: 36.5, mucus: 4 },
|
||||||
|
{ temperature: 36.4, mucus: 2 },
|
||||||
|
{ temperature: 36.5, mucus: 3 },
|
||||||
|
{ temperature: 36.55, mucus: 3 },
|
||||||
|
{ temperature: 36.45, mucus: 3 },
|
||||||
|
{ temperature: 36.5, mucus: 4 },
|
||||||
|
{ temperature: 36.55, mucus: 4 },
|
||||||
|
{ temperature: 36.7, mucus: 3 },
|
||||||
|
{ temperature: 36.65, mucus: 3 },
|
||||||
|
{ temperature: 36.75, mucus: 4 },
|
||||||
|
{ temperature: 36.8, mucus: 4 },
|
||||||
|
{ temperature: 36.85, mucus: 4 },
|
||||||
|
{ temperature: 36.8, mucus: 4 },
|
||||||
|
{ temperature: 36.9, mucus: 4 }
|
||||||
|
].map(convertToSymptoFormat)
|
||||||
|
|
||||||
describe('sympto', () => {
|
describe('sympto', () => {
|
||||||
describe('evaluating mucus and temperature shift together', () => {
|
describe('evaluating mucus and temperature shift together', () => {
|
||||||
describe('with no previous higher measurement', () => {
|
describe('with no previous higher measurement', () => {
|
||||||
@@ -74,10 +101,7 @@ describe('sympto', () => {
|
|||||||
assumeFertility: true,
|
assumeFertility: true,
|
||||||
phases: {
|
phases: {
|
||||||
periOvulatory: {
|
periOvulatory: {
|
||||||
start: {
|
start: { date: '2018-06-01' },
|
||||||
date: 0,
|
|
||||||
time: '00:00'
|
|
||||||
},
|
|
||||||
cycleDays: cycle
|
cycleDays: cycle
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -95,15 +119,12 @@ describe('sympto', () => {
|
|||||||
expect(status.assumeFertility).to.be.true()
|
expect(status.assumeFertility).to.be.true()
|
||||||
expect(Object.keys(status.phases)).to.eql(['periOvulatory', 'postOvulatory'])
|
expect(Object.keys(status.phases)).to.eql(['periOvulatory', 'postOvulatory'])
|
||||||
expect(status.phases.periOvulatory).to.eql({
|
expect(status.phases.periOvulatory).to.eql({
|
||||||
start: {
|
start: { date: '2018-06-01' },
|
||||||
date: 0,
|
|
||||||
time: '00:00'
|
|
||||||
},
|
|
||||||
cycleDays: cycleWithTempAndMucusShift.slice(0, 21)
|
cycleDays: cycleWithTempAndMucusShift.slice(0, 21)
|
||||||
})
|
})
|
||||||
expect(status.phases.postOvulatory).to.eql({
|
expect(status.phases.postOvulatory).to.eql({
|
||||||
start: {
|
start: {
|
||||||
date: 20,
|
date: '2018-06-21',
|
||||||
time: '18:00'
|
time: '18:00'
|
||||||
},
|
},
|
||||||
cycleDays: cycleWithTempAndMucusShift.slice(20)
|
cycleDays: cycleWithTempAndMucusShift.slice(20)
|
||||||
@@ -111,42 +132,27 @@ describe('sympto', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('with shifts', () => {
|
describe('with previous higher measurement', () => {
|
||||||
it.skip('reports fertile when mucus reaches best quality again within temperature evaluation phase', function () {
|
describe('with no shifts detects pre- and periovulatory phase', function () {
|
||||||
const status = getSensiplanStatus(temperatures)
|
it('according to 5-day-rule', function () {
|
||||||
expect(status).to.eql({
|
const status = getSensiplanStatus({
|
||||||
assumeFertility: false,
|
cycle: cycleWithTempAndNoMucusShift,
|
||||||
phases: {
|
previousCycle: cycleWithTempShift
|
||||||
preOvulatory:
|
})
|
||||||
{ startDate: 0, startTime: '00:00' },
|
|
||||||
periOvulatory: 'TODO',
|
expect(Object.keys(status.phases)).to.eql(['periOvulatory', 'preOvulatory'])
|
||||||
postOvulatory: { startDate: 17, startTime: '18:00' }
|
expect(status.assumeFertility).to.be.true()
|
||||||
},
|
expect(status.phases.preOvulatory).to.eql({
|
||||||
temperatureShift: {
|
cycleDays: cycleWithTempAndNoMucusShift.slice(0,5),
|
||||||
detected: true,
|
start: { date: '2018-06-01' },
|
||||||
ltl: 36.55,
|
end: { date: '2018-06-05' }
|
||||||
rule: 0,
|
})
|
||||||
firstHighMeasurementDay: {
|
expect(status.phases.periOvulatory).to.eql({
|
||||||
date: 15,
|
cycleDays: cycleWithTempAndNoMucusShift.slice(5),
|
||||||
temperature: { value: 36.7 },
|
start: { date: '2018-06-06' }
|
||||||
mucus: { value: 3 }
|
|
||||||
},
|
|
||||||
evaluationCompleteDay: {
|
|
||||||
date: 17,
|
|
||||||
temperature: { value: 36.75 },
|
|
||||||
mucus: { value: 4 },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mucusShift: {
|
|
||||||
detected: true,
|
|
||||||
mucusPeak: {
|
|
||||||
date: 17,
|
|
||||||
mucus: { value: 4 },
|
|
||||||
temperature: { value: 36.75 },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user