Skip to content

Commit

Permalink
Store date values (#7)
Browse files Browse the repository at this point in the history
* Created date backed reading history and removed unused types

* Move PageSelection out of Input

* Full Day unit test coverage

* Drop index.re from jest coverage, it's boilerplate  from create-react-scripts
  • Loading branch information
RawToast committed Mar 3, 2018
1 parent 7c88e6d commit 177e372
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 47 deletions.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"coverage": "react-scripts test --env=jsdom --coverage",
"ci": "react-scripts test --env=jsdom --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"eject": "react-scripts eject",
"prepare": "npm link bs-platform",
Expand All @@ -22,5 +23,10 @@
"bs-jest": "^0.3.2",
"bs-react-test-renderer": "^2.0.0",
"reason-react": "^0.3.2"
},
"jest": {
"collectCoverageFrom": [
"src/app/**/*.{re}"
]
}
}
13 changes: 13 additions & 0 deletions src/app/Day.re
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ module Day {
{ date: dateString(), entries: []};
};

let yesterday = () => {
let dateString = () =>
Js.Date.setHoursMSMs((Js.Date.now() -. 86400000.)
|> Js.Date.fromFloat, ~hours=0., ~minutes=0., ~seconds=0., ~milliseconds=0.,())
|> Js.Date.fromFloat
|> Js.Date.toISOString;

{ date: dateString(), entries: []};
};

let empty = { date: "", entries: []};

let createEntry = (nextId, pt, pageCount) => {
Expand All @@ -27,4 +37,7 @@ module Day {
let pageCount = (rd: day) => rd.entries
|> List.map(i => float_of_int(i.value) *. PageType.pageScore(i.kind))
|> List.fold_left((a, b) => a +. b, 0.);


let entries = (d) => d.entries
}
34 changes: 20 additions & 14 deletions src/app/Dokusho.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,47 @@ open Input;
open Entry;
open Types;
open Day;
open PageTypeSelection;

module Dokusho {
let component = ReasonReact.reducerComponent("Dokusho");
let initState = {
readingData: Day.now(),
let initState = () => {
readingData: { days : [Day.now()] },
selectedEntry: Book
};

let make = (_children) => {
...component,
initialState: () => initState,
initialState: () => initState(),
reducer: (action, { readingData, selectedEntry }) =>
switch action {
| ChangeSelection(pageType) =>
ReasonReact.Update({readingData: readingData, selectedEntry: pageType});
| AddEntry(pageTypeString, count) =>
ReasonReact.Update(
Day.createEntry(List.length(readingData.entries), pageTypeString, count) |>
Day.appendEntry(readingData) |>
(rd => {readingData: rd, selectedEntry: selectedEntry}));
| AddEntry(pageTypeString, count) =>
ReasonReact.Update(Day.createEntry(9, pageTypeString, count)
|> Day.appendEntry(Day.now())
|> (ne) => List.map(d => if(d.date != ne.date) d
else {
date: d.date,
entries: List.rev_append(ne.entries, d.entries)}
, readingData.days)
|> (ds) => { days: ds }
|> (rd) => { readingData: rd, selectedEntry: selectedEntry });
},
render: ({state: { readingData, selectedEntry}, reduce}) => {
let pageCount = Day.pageCount(readingData);
render: (self) => {
let pageCount = Day.pageCount(List.hd(self.state.readingData.days));

<div className="app">
<div className="title">
(ReasonReact.stringToElement("Dokusho"))
<Input
selection=selectedEntry
onSubmit=(reduce((text) => AddEntry(selectedEntry, int_of_string(text))))
onChangeSelection=(reduce(selected => ChangeSelection(selected)))
selection=self.state.selectedEntry
onSubmit=(self.reduce((text) => AddEntry(self.state.selectedEntry, int_of_string(text))))
/>
<PageTypeSelection onChangeSelect=(self.reduce(selected => ChangeSelection(selected))) />
</div>
<div className="entries">
(readingData.entries
(List.hd(self.state.readingData.days).entries
|> List.map((entry: entry) => <Entry key=(string_of_int(entry.id)) entry=entry />)
|> Array.of_list
|> ReasonReact.arrayToElement)
Expand Down
31 changes: 5 additions & 26 deletions src/app/Input.re
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
open DokuUtil;
open PageType;
open Types;

module Input = {
Expand All @@ -8,20 +7,16 @@ module Input = {
selection: pageType
};
let str = ReasonReact.stringToElement;
let numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
let component = ReasonReact.reducerComponent("Input");

let make = (~selection, ~onSubmit, ~onChangeSelection, _) => {
let make = (~selection, ~onSubmit, _) => {
...component,
initialState: () => { text: "", selection: selection},
reducer: (state: inputState, _text) => {
reducer: (state: inputState, _ext) => {
let filtered = DokuUtil.string_map_partial(
(c: char) =>
if (c == '1' || c == '2' || c == '3' || c == '4' || c == '5' ||
c == '6' || c == '7' || c == '8' || c == '9' || c == '0') {
Some(c)
} else {
None
},
if (Rationale.RList.contains(c, numbers)) Some(c) else None,
state.text
);
ReasonReact.Update({ text: filtered, selection: state.selection })
Expand All @@ -44,24 +39,8 @@ module Input = {
}
)
/>
<select
onChange=((evt) => {
let txt = DokuUtil.valueFromEvent(evt);

switch (PageType.findOptType(txt)) {
| Some(pt) =>
onChangeSelection(pt);
reduce(() => {text: txt, selection: pt})()
| None => ()
}
})
>
(List.map((pt: content) =>
<option key=pt.name value=pt.name>(str(pt.name))</option>, PageType.pageTypes)
|> Array.of_list
|> ReasonReact.arrayToElement)
</select>
</div>

}
};
};
33 changes: 33 additions & 0 deletions src/app/PageTypeSelection.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
open PageType;
open Types;
open DokuUtil;

module PageTypeSelection = {
type inputState = {
selection: pageType
};

let str = ReasonReact.stringToElement;
let component = ReasonReact.statelessComponent("PageTypeSelection");

let make = (~onChangeSelect, _) => {
...component,
render: (_) => {
<select
onChange=((evt) => {
switch ( evt |> DokuUtil.valueFromEvent
|> PageType.findOptType ) {
| Some(pt) =>
onChangeSelect(pt);
| None => ()
}
})>
((PageType.pageTypes |>
List.map((pt: content) =>
<option key=pt.name value=pt.name>(str(pt.name))</option>)
|> Array.of_list
|> ReasonReact.arrayToElement))
</select>
}
};
};
6 changes: 5 additions & 1 deletion src/app/Types.re
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ type day = {
entries: list(entry)
};

type readingHistory = {
days: list(day)
};

type mainState = {
readingData: day,
readingData: readingHistory,

selectedEntry: pageType
};
Expand Down
40 changes: 40 additions & 0 deletions src/test/Day_test.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
open Jest;

open Day;

describe("Day", () => {
open Expect;

describe("Day.today", () => {
let today = Day.now();
test("Creates a day with no entries", () =>
expect(today.entries |> List.length) |> toBe(0));

test("Creates a string representation of a date time", () =>
expect(today.date |> String.length ) |> toBe(24));
});

describe("Day.yesterday", () => {
let today = Day.yesterday();
test("Creates a day with no entries", () =>
expect(today.entries |> List.length) |> toBe(0));

test("Creates a string representation of a date time", () =>
expect(today.date |> String.length ) |> toBe(24));
});


describe("Day.entries", () => {
let today = Day.now();
test("Is a helper method to get the Day's entry list", () =>
expect(today.entries) |> toEqual(Day.entries(today)));
});

describe("Day.appendEntry", () => {
let today = Day.now();
let appendedDay = Day.createEntry(1, News, 1) |> Day.appendEntry(today);
test("Adds an entry to a day", () =>
expect(appendedDay.entries |> List.length) |> toBe(1));
});

});
18 changes: 13 additions & 5 deletions src/test/Dokusho_test.re
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ open Types;

describe("Dokusho", () => {
open ExpectJs;
open Day;

describe("Dokusho.initialState", () => {
test("Should have an empty list of entries", () =>
expect(Dokusho.initState.readingData.entries |> List.length) |> toBe(0));
describe("Dokusho.initialState", () => {

test("Should have today as the only day", () =>
expect(Dokusho.initState().readingData.days |> List.length) |> toBe(1));

test("Today should have an empty list of entries", () =>
expect(Dokusho.initState().readingData.days
|> List.hd
|> Day.entries
|> List.length)
|> toBe(0));

test("Should have Book selected", () =>
expect(Dokusho.initState.selectedEntry) |> toBe(Book));
expect(Dokusho.initState().selectedEntry) |> toBe(Book));
});

describe("Dokusho.make", () => {
Expand All @@ -21,5 +30,4 @@ describe("Dokusho.initialState", () => {
expect(Js.Undefined.return(component)) |> toBeDefined;
});
});

});
23 changes: 23 additions & 0 deletions src/test/PageTypeSelection_test.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
open Jest;

open PageTypeSelection;

describe("PageTypeSelection", () => {
open ExpectJs;

test("Renders when given an onChangeSelect function", () => {

let onChangeSelectFunction = (pt) => ();

let component = ReactShallowRenderer.renderWithRenderer(
<PageTypeSelection onChangeSelect=onChangeSelectFunction/>
);

expect(Js.Undefined.return(component)) |> toBeDefined;
});

describe("PageTypeSelection.str", () => {
test("Is an alias for ReasonReact.stringToElement", () =>
expect(PageTypeSelection.str("Hello")) |> toBe(ReasonReact.stringToElement("Hello")));
});
});
24 changes: 23 additions & 1 deletion src/test/PageType_test.re
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,33 @@ describe("PageType", () => {
test("Returns `None` when given an invalid string", () =>
expect(PageType.findOptType("ABC123")) |> toBe(None));

test("Returns some(pageType) when given valid input", () =>
test("Returns some(pageType) when given valid input", () =>
expect(PageType.findOptType("News")) |> toEqual(Some(News)));

test("Can find the Net pageType", () =>
expect(PageType.findOptType("Net")) |> toEqual(Some(Net)));

test("Can find the Lyric pageType", () =>
expect(PageType.findOptType("Lyric")) |> toEqual(Some(Lyric)));

test("Can find the manga pageType", () =>
expect(PageType.findOptType("Manga")) |> toEqual(Some(Manga)));

test("Can find the Book pageType", () =>
expect(PageType.findOptType("Book")) |> toEqual(Some(Book)));


test("Interacts with toString as expected", () =>
expect(PageType.findOptType(PageType.toString(Manga))) |> toEqual(Some(Manga)));
});

describe("PageType.pageTypes", () => {

test("Returns a list of page types", () =>
expect(PageType.pageTypes |> List.hd |> i => i.pageType) |> toBe(Book));

test("Including all page types", () =>
expect(PageType.pageTypes |> List.length) |> toBe(5));

});
});

0 comments on commit 177e372

Please sign in to comment.