Add getMensesDaysAfter
This commit is contained in:
+32
-9
@@ -135,23 +135,45 @@ export default function config(opts) {
|
|||||||
|
|
||||||
function isMensesStart(cycleDay) {
|
function isMensesStart(cycleDay) {
|
||||||
if (!cycleDay.bleeding || cycleDay.bleeding.exclude) return false
|
if (!cycleDay.bleeding || cycleDay.bleeding.exclude) return false
|
||||||
const bleedingDays = bleedingDaysSortedByDate
|
if (noBleedingDayWithinThresholdBefore(cycleDay)) return true
|
||||||
if (noBleedingDayWithinThreshold(cycleDay)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
function noBleedingDayWithinThreshold(day) {
|
function noBleedingDayWithinThresholdBefore(cycleDay) {
|
||||||
const localDate = LocalDate.parse(day.date)
|
const localDate = LocalDate.parse(cycleDay.date)
|
||||||
const threshold = localDate.minusDays(maxBreakInBleeding + 1).toString()
|
const threshold = localDate.minusDays(maxBreakInBleeding + 1).toString()
|
||||||
|
const bleedingDays = bleedingDaysSortedByDate
|
||||||
const index = bleedingDays.findIndex(day => day.date === cycleDay.date)
|
const index = bleedingDays.findIndex(day => day.date === cycleDay.date)
|
||||||
const previousBleedingDays = bleedingDays.slice(index + 1)
|
const candidates = bleedingDays.slice(index + 1)
|
||||||
return !previousBleedingDays.some(day => {
|
return !candidates.some(day => {
|
||||||
return day.date >= threshold && !day.bleeding.exclude
|
return day.date >= threshold && !day.bleeding.exclude
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMensesDaysAfter(bleedingDay) {
|
||||||
|
const bleedingDays = bleedingDaysSortedByDate.filter(d => {
|
||||||
|
return !d.bleeding.exclude
|
||||||
|
})
|
||||||
|
const startIndex = bleedingDays.findIndex(day => {
|
||||||
|
return day.date === bleedingDay.date
|
||||||
|
})
|
||||||
|
return recurse(bleedingDay, startIndex, [])
|
||||||
|
|
||||||
|
function recurse(day, i, mensesDays) {
|
||||||
|
if (i === 0) return mensesDays
|
||||||
|
const next = bleedingDays[i - 1]
|
||||||
|
if (!isWithinThreshold(day, next)) return mensesDays
|
||||||
|
mensesDays.unshift(next)
|
||||||
|
return recurse(next, i - 1, mensesDays)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWithinThreshold(cycleDay, nextCycleDay) {
|
||||||
|
const localDate = LocalDate.parse(cycleDay.date)
|
||||||
|
const threshold = localDate.plusDays(maxBreakInBleeding + 1).toString()
|
||||||
|
return nextCycleDay.date <= threshold
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getCycleLength(cycleStartDates) {
|
function getCycleLength(cycleStartDates) {
|
||||||
const cycleLengths = []
|
const cycleLengths = []
|
||||||
for (let i = 0; i < cycleStartDates.length - 1; i++) {
|
for (let i = 0; i < cycleStartDates.length - 1; i++) {
|
||||||
@@ -208,6 +230,7 @@ export default function config(opts) {
|
|||||||
getAllMensesStarts,
|
getAllMensesStarts,
|
||||||
getCycleLength,
|
getCycleLength,
|
||||||
getPredictedMenses,
|
getPredictedMenses,
|
||||||
isMensesStart
|
isMensesStart,
|
||||||
|
getMensesDaysAfter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -827,4 +827,176 @@ describe('isMensesStart', () => {
|
|||||||
const start = isMensesStart(cycleDaysSortedByDate[2])
|
const start = isMensesStart(cycleDaysSortedByDate[2])
|
||||||
expect(start).to.be.true()
|
expect(start).to.be.true()
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('getMensesDaysAfter', () => {
|
||||||
|
it('works for simple menses start', () => {
|
||||||
|
const cycleDaysSortedByDate = [
|
||||||
|
{
|
||||||
|
date: '2018-05-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-02',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-01',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-04-30',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const { getMensesDaysAfter } = cycleModule({
|
||||||
|
cycleDaysSortedByDate,
|
||||||
|
bleedingDaysSortedByDate: cycleDaysSortedByDate.filter(d => d.bleeding)
|
||||||
|
})
|
||||||
|
const days = getMensesDaysAfter(cycleDaysSortedByDate[3])
|
||||||
|
expect(days).to.eql([
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-02',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('ignores excluded values', () => {
|
||||||
|
const cycleDaysSortedByDate = [
|
||||||
|
{
|
||||||
|
date: '2018-05-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-02',
|
||||||
|
bleeding: { value: 1, exclude: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-01',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-04-30',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const { getMensesDaysAfter } = cycleModule({
|
||||||
|
cycleDaysSortedByDate,
|
||||||
|
bleedingDaysSortedByDate: cycleDaysSortedByDate.filter(d => d.bleeding)
|
||||||
|
})
|
||||||
|
const days = getMensesDaysAfter(cycleDaysSortedByDate[3])
|
||||||
|
expect(days).to.eql([
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns empty when there are no bleeding days after', () => {
|
||||||
|
const cycleDaysSortedByDate = [
|
||||||
|
{
|
||||||
|
date: '2018-05-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-01',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-04-30',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const { getMensesDaysAfter } = cycleModule({
|
||||||
|
cycleDaysSortedByDate,
|
||||||
|
bleedingDaysSortedByDate: cycleDaysSortedByDate.filter(d => d.bleeding)
|
||||||
|
})
|
||||||
|
const days = getMensesDaysAfter(cycleDaysSortedByDate[3])
|
||||||
|
expect(days).to.eql([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns empty when there are no bleeding days within threshold', () => {
|
||||||
|
const cycleDaysSortedByDate = [
|
||||||
|
{
|
||||||
|
date: '2018-05-04',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-02',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-01',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-04-30',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const { getMensesDaysAfter } = cycleModule({
|
||||||
|
cycleDaysSortedByDate,
|
||||||
|
bleedingDaysSortedByDate: cycleDaysSortedByDate.filter(d => d.bleeding)
|
||||||
|
})
|
||||||
|
const days = getMensesDaysAfter(cycleDaysSortedByDate[3])
|
||||||
|
expect(days).to.eql([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('includes days within the treshold', () => {
|
||||||
|
const cycleDaysSortedByDate = [
|
||||||
|
{
|
||||||
|
date: '2018-05-04',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-05',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-01',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-04-30',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const { getMensesDaysAfter } = cycleModule({
|
||||||
|
cycleDaysSortedByDate,
|
||||||
|
bleedingDaysSortedByDate: cycleDaysSortedByDate.filter(d => d.bleeding)
|
||||||
|
})
|
||||||
|
const days = getMensesDaysAfter(cycleDaysSortedByDate[3])
|
||||||
|
expect(days).to.eql([
|
||||||
|
{
|
||||||
|
date: '2018-05-05',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: '2018-05-03',
|
||||||
|
bleeding: { value: 1 }
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user