Skip to content

Commit

Permalink
Add positive/negative button
Browse files Browse the repository at this point in the history
  • Loading branch information
wyze committed Apr 4, 2017
1 parent 164e1d9 commit 7ce73e3
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 13 deletions.
24 changes: 24 additions & 0 deletions __tests__/components/GreenButton_test.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
open Jest;
open Expect;

let _ =

describe "GreenButton" (fun _ => {
test "renders" (fun _ => {
let action = Action.Add;
let dispatch = fun _ => ();
let tree = GreenButton.createElement ::action ::dispatch children::[] () |> Renderer.render;

expect tree |> toMatchSnapshot;
});

test "renders a class name" (fun _ => {
let action = Action.Add;
let className = Styles.make color::"rebeccapurple" () |> Styles.className;
let dispatch = fun _ => ();
let tree = GreenButton.createElement ::action ::className ::dispatch children::[] ()
|> Renderer.render;

expect tree |> toMatchSnapshot;
});
});
26 changes: 23 additions & 3 deletions __tests__/components/__snapshots__/buttons_test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@ exports[`Buttons renders 1`] = `
}
/>,
Array [
<OperationButton
<GreenButton
reasonProps={
Array [
2,
7,
"",
[Function],
]
}
/>,
0,
Array [
<OperationButton
reasonProps={
Array [
2,
"",
[Function],
]
}
/>,
0,
],
],
],
]
Expand All @@ -36,6 +47,15 @@ exports[`Buttons renders 1`] = `
]
}
/>
<GreenButton
reasonProps={
Array [
7,
"",
[Function],
]
}
/>
<OperationButton
reasonProps={
Array [
Expand Down
6 changes: 4 additions & 2 deletions __tests__/components/__snapshots__/clearButton_test.js.snap
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ClearButton renders 1`] = `
<OperationButton
<GreenButton
reasonProps={
Array [
1,
"css-1gxh4ww css-1eo5al3",
Object {
"data-css-galczn": "",
},
[Function],
]
}
Expand Down
2 changes: 1 addition & 1 deletion __tests__/components/__snapshots__/features_test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ exports[`Features renders 1`] = `
<Feature
reasonProps={
Array [
1,
0,
"Positive/Negative",
]
}
Expand Down
25 changes: 25 additions & 0 deletions __tests__/components/__snapshots__/greenButton_test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`GreenButton renders 1`] = `
<OperationButton
reasonProps={
Array [
0,
"css-h4v74b css-1eo5al3",
[Function],
]
}
/>
`;

exports[`GreenButton renders a class name 1`] = `
<OperationButton
reasonProps={
Array [
0,
"css-h4v74b css-1eo5al3 css-aori8y",
[Function],
]
}
/>
`;
97 changes: 97 additions & 0 deletions __tests__/reductive/store_test.re
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,101 @@ describe "store" (fun _ => {

expect actual |> toEqual expected;
});

test "reducer handles PosNeg action with initial state" (fun _ => {
let state: Store.state = Store.init;
let actual = Store.reducer state Action.PosNeg;
let expected: Store.state = { operations: [] };

expect actual |> toEqual expected;
});

test "reducer handles PosNeg action with Pending state" (fun _ => {
let state: Store.state = {
operations: [
Operation.create "4" "" Action.Pending 4,
]
};
let actual = Store.reducer state Action.PosNeg |> toTuple;
let expected = {
operations: [
( "-4", "", Action.Pending, -4 ),
]
};

expect actual |> toEqual expected;
});

test "reducer handles PosNeg action with no right value" (fun _ => {
let state: Store.state = {
operations: [
Operation.create "4" "" Action.Add 4,
]
};
let actual = Store.reducer state Action.PosNeg |> toTuple;
let expected = {
operations: [
( "4", "-4", Action.Add, 0 ),
]
};

expect actual |> toEqual expected;
});

test "reducer handles PosNeg action with non-Pending state" (fun _ => {
let state: Store.state = {
operations: [
Operation.create "4" "2" Action.Add 6,
]
};
let actual = Store.reducer state Action.PosNeg |> toTuple;
let expected = {
operations: [
( "4", "-2", Action.Add, 2 ),
]
};

expect actual |> toEqual expected;
});

test "reducer handles PosNeg -> Equals -> Equals" (fun _ => {
let state: Store.state = {
operations: [
Operation.create "-15" "-15" Action.Equals (-15),
Operation.create "5" "-3" Action.Multiply (-15),
]
};
let actual = Store.reducer state Action.Equals |> toTuple;
let expected = {
operations: [
( "45", "45", Action.Equals, 45 ),
( "-15", "-3", Action.Multiply, 45 ),
( "-15", "-15", Action.Equals, -15 ),
( "5", "-3", Action.Multiply, -15 ),
]
};

expect actual |> toEqual expected;
});

test "reducer handles Equals -> PosNeg -> Equals" (fun _ => {
let equals: Store.state = {
operations: [
Operation.create "-15" "-15" Action.Equals (-15),
Operation.create "5" "-3" Action.Multiply (-15),
]
};
let state = Store.reducer equals Action.PosNeg;
let actual = Store.reducer state Action.Equals |> toTuple;
let expected = {
operations: [
( "-45", "-45", Action.Equals, -45 ),
( "15", "-3", Action.Multiply, -45 ),
( "15", "15", Action.Equals, 15 ),
( "5", "-3", Action.Multiply, -15 ),
]
};

expect actual |> toEqual expected;
});
});
1 change: 1 addition & 0 deletions src/components/Buttons.re
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Buttons = {
<div>
<ButtonGroup>
<ClearButton dispatch />
<GreenButton dispatch action=PosNeg />
<OperationButton dispatch action=Divide />
</ButtonGroup>
<ButtonGroup>
Expand Down
7 changes: 2 additions & 5 deletions src/components/ClearButton.re
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ module ClearButton = {
};

let className: string =
Styles.merge [
Styles.make background::"#3bf3a9" flex::"75%" () |> Styles.className,
Styles.make color::"#3bf3a9" () |> Styles.hover,
];
Styles.make flex::"50%" () |> Styles.className;

let render { props: { dispatch } } =>
<OperationButton className dispatch action=Clear />;
<GreenButton className dispatch action=Clear />;
};

include ReactRe.CreateComponent ClearButton;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Features.re
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module Features = {
<Feature emoji=Checkmark text="Simple operations" />
<Feature emoji=Soon text="Decimals" />
<Feature emoji=Soon text="Percentage" />
<Feature emoji=Soon text="Positive/Negative" />
<Feature emoji=Checkmark text="Positive/Negative" />
<Feature emoji=Soon text="Advanced options" />
<Feature emoji=Soon text="Operation history" />
</div>;
Expand Down
25 changes: 25 additions & 0 deletions src/components/GreenButton.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module GreenButton = {
include ReactRe.Component;
let name = "GreenButton";

type props = {
action: Store.action,
className: string,
dispatch: Store.action => unit,
};

let getClassName className =>
Styles.merge [
Styles.make background::"#3bf3a9" () |> Styles.className,
Styles.make color::"#3bf3a9" () |> Styles.hover,
Util.strEmpty className ? Styles.empty : className,
];

let render { props: { action, className, dispatch } } =>
<OperationButton className=(getClassName className) dispatch action />;
};

include ReactRe.CreateComponent GreenButton;

let createElement ::action ::className="" ::dispatch =>
wrapProps { action, className, dispatch };
4 changes: 3 additions & 1 deletion src/reductive/action.re
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ type model =
| Pending
| Input string
| Multiply
| Subtract;
| Subtract
| PosNeg;

/* model -> (int -> int -> int) */
let toInfix action =>
Expand All @@ -28,5 +29,6 @@ let toText action =>
| Equals => "="
| Multiply => "&times;"
| Subtract => "&minus;"
| PosNeg => "+/&minus;"
| _ => ""
};
1 change: 1 addition & 0 deletions src/reductive/operation.re
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ let find lst predicate =>
let update input { left, right, symbol } =>
switch symbol {
| Pending => create (left ^ input) right symbol (left ^ input |> Util.toInt)
| Equals => create left right symbol (left |> Util.toInt)
| _ =>
execute (Action.toInfix symbol) left (right ^ input)
|> create left (right ^ input) symbol
Expand Down
27 changes: 27 additions & 0 deletions src/reductive/store.re
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ let addEquals lst (cur: Operation.model) => {
};
};

/* string -> string */
let flipNumber num => num |> Util.toInt |> (*) (-1) |> Util.toString;

/* list Operation.model -> Operation.model -> list Operation.model */
let doPosNeg lst (cur: Operation.model) => {
let { left, right, symbol }: Operation.model = cur;

let prev = switch right {
| "" => switch symbol {
| Pending => Operation.create (flipNumber left) right symbol 0
| _ => Operation.create left (flipNumber left) symbol 0
}
| _ => switch symbol {
| Equals => Operation.create (flipNumber left) (flipNumber right) symbol 0
| _ => Operation.create left (flipNumber right) symbol 0
}
} |> Operation.update "";

[ prev ] @ lst;
};

/* state -> action -> state */
let reducer state action => {
let cur = Operation.head state.operations;
Expand All @@ -37,6 +58,12 @@ let reducer state action => {
}
}
| Pending => state
| PosNeg => {
operations: switch cur.total {
| 0 => state.operations
| _ => doPosNeg old cur
}
}
| _ => {
operations: switch cur.symbol {
| Pending
Expand Down

0 comments on commit 7ce73e3

Please sign in to comment.