From 28b880a40cef7879985af92d85824ffd58035e59 Mon Sep 17 00:00:00 2001 From: Julia Friesel <julia.friesel@gmail.com> Date: Sat, 30 Jun 2018 13:50:01 +0200 Subject: [PATCH] Gather general cycle-related functions in cycle module --- components/chart/chart.js | 4 +- components/cycle-day-overview.js | 6 +- components/cycle-day.js | 4 +- components/home.js | 4 +- lib/cycle.js | 65 +++++++++++++++++++ lib/get-cycle-day-number.js | 23 ------- lib/get-last-menses-start.js | 34 ---------- test/{get-cycle-day.spec.js => cycle.spec.js} | 19 +++--- 8 files changed, 84 insertions(+), 75 deletions(-) create mode 100644 lib/cycle.js delete mode 100644 lib/get-cycle-day-number.js delete mode 100644 lib/get-last-menses-start.js rename test/{get-cycle-day.spec.js => cycle.spec.js} (77%) diff --git a/components/chart/chart.js b/components/chart/chart.js index 2c70ed19..877d231f 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 cc780dae..f8c3acae 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 7d46deaf..2d782202 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 60327e39..816a10c6 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 00000000..8dbe838c --- /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 164eb9c1..00000000 --- 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 7fb321ff..00000000 --- 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 8aaadddf..ae606328 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) }) -- GitLab