diff --git a/components/chart/chart.js b/components/chart/chart.js index 2c70ed19a6fb35d6cb9526b81e82910b4db6576b..877d231fc3aa907a16d60a6fcef9929a92e657c0 100644 --- a/components/chart/chart.js +++ b/components/chart/chart.js @@ -11,11 +11,11 @@ import Svg,{ } from 'react-native-svg' import { LocalDate } from 'js-joda' import { getCycleDay, getOrCreateCycleDay, cycleDaysSortedByDate } from '../../db' -import getCycleDayNumberModule from '../../lib/get-cycle-day-number' +import cycleModule from '../../lib/cycle' import styles from './styles' import config from './config' -const getCycleDayNumber = getCycleDayNumberModule() +const getCycleDayNumber = cycleModule().getCycleDayNumber const yAxis = makeYAxis(config) diff --git a/components/cycle-day-overview.js b/components/cycle-day-overview.js index cc780dae120d2f70332d08aa886448f87f18ba16..f8c3acaef232b03ce00a88b495b7d32a57b41a68 100644 --- a/components/cycle-day-overview.js +++ b/components/cycle-day-overview.js @@ -6,14 +6,16 @@ import { } from 'react-native' import styles from '../styles/index' import { bleeding as labels} from '../labels/labels' -import cycleDayModule from '../lib/get-cycle-day-number' +import cycleModule from '../lib/cycle' import { bleedingDaysSortedByDate } from '../db' -const getCycleDayNumber = cycleDayModule() +const getCycleDayNumber = cycleModule().getCycleDayNumber export default class DayView extends Component { constructor(props) { super(props) + console.log('new') + console.log(props.cycleDay) this.cycleDay = props.cycleDay this.showView = props.showView this.state = { diff --git a/components/cycle-day.js b/components/cycle-day.js index 7d46deaff6a993da2c09a21b1f6c68f1d9402b1a..2d782202327f596293491fd885863f9c0cb04ad6 100644 --- a/components/cycle-day.js +++ b/components/cycle-day.js @@ -3,14 +3,14 @@ import { View, Text } from 'react-native' -import cycleDayModule from '../lib/get-cycle-day-number' +import cycleModule from '../lib/cycle' import DayView from './cycle-day-overview' import BleedingEditView from './bleeding' import TemperatureEditView from './temperature' import { formatDateForViewHeader } from '../labels/format' import styles from '../styles/index' -const getCycleDayNumber = cycleDayModule() +const getCycleDayNumber = cycleModule().getCycleDayNumber export default class Day extends Component { constructor(props) { diff --git a/components/home.js b/components/home.js index 60327e39712c80d7ac8f3999cd3def152538b850..816a10c63538968280430f8695ce0bd3c89b87ce 100644 --- a/components/home.js +++ b/components/home.js @@ -6,10 +6,10 @@ import { } from 'react-native' import { LocalDate } from 'js-joda' import styles from '../styles/index' -import cycleDayModule from '../lib/get-cycle-day-number' +import cycleModule from '../lib/cycle' import { getOrCreateCycleDay, bleedingDaysSortedByDate, deleteAll } from '../db' -const getCycleDayNumber = cycleDayModule() +const getCycleDayNumber = cycleModule().getCycleDayNumber export default class Home extends Component { constructor(props) { diff --git a/lib/cycle.js b/lib/cycle.js new file mode 100644 index 0000000000000000000000000000000000000000..8dbe838ccd5cfad8542dbbdd1a3f305214d44aef --- /dev/null +++ b/lib/cycle.js @@ -0,0 +1,65 @@ +import * as joda from 'js-joda' + +const LocalDate = joda.LocalDate + +export default function config(opts = {}) { + let bleedingDaysSortedByDate + if (!opts.bleedingDaysSortedByDate) { + // we only want to require (and run) the db module when not running the tests + bleedingDaysSortedByDate = require('../db').bleedingDaysSortedByDate + } else { + bleedingDaysSortedByDate = opts.bleedingDaysSortedByDate + } + const maxBreakInBleeding = opts.maxBreakInBleeding || 1 + + function getLastMensesStart(targetDateString) { + const targetDate = LocalDate.parse(targetDateString) + const withWrappedDates = bleedingDaysSortedByDate + .filter(day => !day.bleeding.exclude) + .map(day => { + day.wrappedDate = LocalDate.parse(day.date) + return day + }) + + const firstBleedingDayBeforeTargetDayIndex = withWrappedDates.findIndex(day => { + return ( + day.wrappedDate.isEqual(targetDate) || + day.wrappedDate.isBefore(targetDate) + ) + }) + + if (firstBleedingDayBeforeTargetDayIndex < 0) return null + const previousBleedingDays = withWrappedDates.slice(firstBleedingDayBeforeTargetDayIndex) + + const lastPeriodStart = previousBleedingDays.find((day, i) => { + return thereIsNoPreviousBleedingDayWithinTheThreshold(day, previousBleedingDays.slice(i + 1)) + }) + + function thereIsNoPreviousBleedingDayWithinTheThreshold(bleedingDay, previousBleedingDays) { + const periodThreshold = bleedingDay.wrappedDate.minusDays(maxBreakInBleeding + 1) + return !previousBleedingDays.some(({ wrappedDate }) => wrappedDate.equals(periodThreshold) || wrappedDate.isAfter(periodThreshold)) + } + + return lastPeriodStart + } + + function getCycleDayNumber(targetDateString) { + const lastMensesStart = getLastMensesStart(targetDateString) + if (!lastMensesStart) return null + const targetDate = joda.LocalDate.parse(targetDateString) + const diffInDays = lastMensesStart.wrappedDate.until(targetDate, joda.ChronoUnit.DAYS) + + // cycle starts at day 1 + return diffInDays + 1 + } + + function getPreviousDaysInCycle() { + return [] + } + + return { + getCycleDayNumber, + getLastMensesStart, + getPreviousDaysInCycle + } +} diff --git a/lib/get-cycle-day-number.js b/lib/get-cycle-day-number.js deleted file mode 100644 index 164eb9c1876fea0c5dc59aae6f537e7e9d8de933..0000000000000000000000000000000000000000 --- a/lib/get-cycle-day-number.js +++ /dev/null @@ -1,23 +0,0 @@ -import * as joda from 'js-joda' -import getLastMensesStart from './get-last-menses-start' - -export default function config(opts = {}) { - let bleedingDaysSortedByDate - if (!opts.bleedingDaysSortedByDate) { - // we only want to require (and run) the db module when not running the tests - bleedingDaysSortedByDate = require('../db').bleedingDaysSortedByDate - } else { - bleedingDaysSortedByDate = opts.bleedingDaysSortedByDate - } - const maxBreakInBleeding = opts.maxBreakInBleeding || 1 - - return function(targetDateString) { - const lastMensesStart = getLastMensesStart(targetDateString, bleedingDaysSortedByDate, maxBreakInBleeding) - if (!lastMensesStart) return null - const targetDate = joda.LocalDate.parse(targetDateString) - const diffInDays = lastMensesStart.wrappedDate.until(targetDate, joda.ChronoUnit.DAYS) - - // cycle starts at day 1 - return diffInDays + 1 - } -} \ No newline at end of file diff --git a/lib/get-last-menses-start.js b/lib/get-last-menses-start.js deleted file mode 100644 index 7fb321fff21fe609d2f1c224383a86d0ccd9e5e3..0000000000000000000000000000000000000000 --- a/lib/get-last-menses-start.js +++ /dev/null @@ -1,34 +0,0 @@ -import * as joda from 'js-joda' - -const LocalDate = joda.LocalDate - -export default function getLastMensesStart(targetDateString, bleedingDaysSortedByDate, maxBreakInBleeding) { - const targetDate = LocalDate.parse(targetDateString) - const withWrappedDates = bleedingDaysSortedByDate - .filter(day => !day.bleeding.exclude) - .map(day => { - day.wrappedDate = LocalDate.parse(day.date) - return day - }) - - const firstBleedingDayBeforeTargetDayIndex = withWrappedDates.findIndex(day => { - return ( - day.wrappedDate.isEqual(targetDate) || - day.wrappedDate.isBefore(targetDate) - ) - }) - - if (firstBleedingDayBeforeTargetDayIndex < 0) return null - const previousBleedingDays = withWrappedDates.slice(firstBleedingDayBeforeTargetDayIndex) - - const lastPeriodStart = previousBleedingDays.find((day, i) => { - return thereIsNoPreviousBleedingDayWithinTheThreshold(day, previousBleedingDays.slice(i + 1), maxBreakInBleeding) - }) - - return lastPeriodStart -} - -function thereIsNoPreviousBleedingDayWithinTheThreshold(bleedingDay, earlierCycleDays, allowedBleedingBreak) { - const periodThreshold = bleedingDay.wrappedDate.minusDays(allowedBleedingBreak + 1) - return !earlierCycleDays.some(({ wrappedDate }) => wrappedDate.equals(periodThreshold) || wrappedDate.isAfter(periodThreshold)) -} \ No newline at end of file diff --git a/test/get-cycle-day.spec.js b/test/cycle.spec.js similarity index 77% rename from test/get-cycle-day.spec.js rename to test/cycle.spec.js index 8aaadddf7f7ec310a3c3e9ad91673a7fb024c016..ae60632821cd4b1b2d5f3ebf4180758a61c36618 100644 --- a/test/get-cycle-day.spec.js +++ b/test/cycle.spec.js @@ -1,13 +1,12 @@ import chai from 'chai' import dirtyChai from 'dirty-chai' +import cycleModule from '../lib/cycle' const expect = chai.expect chai.use(dirtyChai) -import getCycleDayNumberModule from '../lib/get-cycle-day-number' - describe('getCycleDay', () => { - it('works for a simple example', function () { + it('works for a simple example', () => { const bleedingDays = [{ date: '2018-05-10', bleeding: { @@ -24,7 +23,7 @@ describe('getCycleDay', () => { value: 2 } }] - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays}) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays}).getCycleDayNumber const targetDate = '2018-05-17' const result = getCycleDayNumber(targetDate) expect(result).to.eql(9) @@ -50,7 +49,7 @@ describe('getCycleDay', () => { } }] const targetDate = '2018-05-17' - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays}) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays}).getCycleDayNumber const result = getCycleDayNumber(targetDate) expect(result).to.eql(15) }) @@ -74,7 +73,7 @@ describe('getCycleDay', () => { }] const targetDate = '2018-04-27' - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays}) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays}).getCycleDayNumber const result = getCycleDayNumber(targetDate) expect(result).to.eql(18) }) @@ -88,7 +87,7 @@ describe('getCycleDay', () => { }] const targetDate = '2018-05-13' - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays}) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays}).getCycleDayNumber const result = getCycleDayNumber(targetDate) expect(result).to.eql(1) }) @@ -98,7 +97,7 @@ describe('getCycleDay returns null', () => { it('if there are no bleeding days', function () { const bleedingDays = [] const targetDate = '2018-05-17' - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays}) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays}).getCycleDayNumber const result = getCycleDayNumber(targetDate) expect(result).to.be.null() }) @@ -121,7 +120,7 @@ describe('getCycleDay with cycle thresholds', () => { }] const targetDate = '2018-05-17' - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays, maxBreakInBleeding }) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays, maxBreakInBleeding }).getCycleDayNumber const result = getCycleDayNumber(targetDate) expect(result).to.eql(8) }) @@ -139,7 +138,7 @@ describe('getCycleDay with cycle thresholds', () => { } }] const targetDate = '2018-05-17' - const getCycleDayNumber = getCycleDayNumberModule({bleedingDaysSortedByDate: bleedingDays, maxBreakInBleeding }) + const getCycleDayNumber = cycleModule({bleedingDaysSortedByDate: bleedingDays, maxBreakInBleeding }).getCycleDayNumber const result = getCycleDayNumber(targetDate) expect(result).to.eql(4) })