Skip to content

Commit

Permalink
create calculator app
Browse files Browse the repository at this point in the history
- create initial components
- create initial css
- finished component functions and related tests
- add keyboard listeners
  • Loading branch information
calebpollman committed Oct 17, 2018
1 parent 4e8a1fe commit 6f4a33b
Show file tree
Hide file tree
Showing 30 changed files with 7,743 additions and 2,637 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -21,4 +21,5 @@ yarn-debug.log*
yarn-error.log*

# post
post.md
/post
old_post.md
28 changes: 27 additions & 1 deletion README.md
@@ -1 +1,27 @@
# Using AWS Lambda and API Gateway with React
# TDD React

## Local Setup

```sh
$ git clone git@github.com:calebpollman/react-calculator.git
```

```sh
$ cd react-calculator
```

```sh
$ yarn install
```

## Run Locally

```sh
$ yarn start
```

## Run Tests

```sh
$ yarn test
```
21 changes: 15 additions & 6 deletions package.json
@@ -1,18 +1,27 @@
{
"name": "aws-lambda-with-api-gateway-and-react",
"name": "tdd-react-calculator",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0"
"react": "^16.5.2",
"react-dom": "^16.5.2"
},
"devDependencies": {
"react-scripts": "1.1.0"
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"react-scripts": "2.0.5",
"react-test-renderer": "^16.5.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
Binary file modified public/favicon.png 100644 → 100755
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/index.html
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
<link href="https://fonts.googleapis.com/css?family=Orbitron:400,700,900" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Orbitron:400,700" rel="stylesheet">
<title>Issa Calculator</title>
</head>
<body>
Expand Down
15 changes: 0 additions & 15 deletions src/App.js

This file was deleted.

4 changes: 2 additions & 2 deletions src/App.css → src/components/App/App.css
@@ -1,7 +1,7 @@
.App {
.app-container {
align-items: center;
display: flex;
height: 100vh;
justify-content: center;
width: 100vw;
}
}
13 changes: 13 additions & 0 deletions src/components/App/App.jsx
@@ -0,0 +1,13 @@
import React from 'react';
import Calculator from '../Calculator/Calculator';
import './App.css';

const App = () => {
return (
<div className="app-container">
<Calculator />
</div>
);
}

export default App;
23 changes: 23 additions & 0 deletions src/components/App/App.spec.js
@@ -0,0 +1,23 @@
import React from 'react';
import {shallow} from 'enzyme';
import App from './App';
import Calculator from '../Calculator/Calculator';

describe('App', () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<App />);
});

it('should render correctly', () => {
expect(wrapper).toMatchSnapshot();
});

it('should render a <div />', () => {
expect(wrapper.find('div').length).toEqual(1);
});

it('should render the Calculator Component', () => {
expect(wrapper.containsMatchingElement(<Calculator />)).toEqual(true);
});
});
75 changes: 75 additions & 0 deletions src/components/App/__snapshots__/App.spec.js.snap
@@ -0,0 +1,75 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`App should render correctly 1`] = `
ShallowWrapper {
Symbol(enzyme.__root__): [Circular],
Symbol(enzyme.__unrendered__): <App />,
Symbol(enzyme.__renderer__): Object {
"batchedUpdates": [Function],
"getNode": [Function],
"render": [Function],
"simulateError": [Function],
"simulateEvent": [Function],
"unmount": [Function],
},
Symbol(enzyme.__node__): Object {
"instance": null,
"key": undefined,
"nodeType": "host",
"props": Object {
"children": <Calculator />,
"className": "app-container",
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": "div",
},
Symbol(enzyme.__nodes__): Array [
Object {
"instance": null,
"key": undefined,
"nodeType": "host",
"props": Object {
"children": <Calculator />,
"className": "app-container",
},
"ref": null,
"rendered": Object {
"instance": null,
"key": undefined,
"nodeType": "class",
"props": Object {},
"ref": null,
"rendered": null,
"type": [Function],
},
"type": "div",
},
],
Symbol(enzyme.__options__): Object {
"adapter": ReactSixteenAdapter {
"options": Object {
"enableComponentDidUpdateOnSetState": true,
"lifecycles": Object {
"componentDidUpdate": Object {
"onSetState": true,
},
"getDerivedStateFromProps": true,
"getSnapshotBeforeUpdate": true,
"setState": Object {
"skipsComponentDidUpdateOnNullish": true,
},
},
},
},
},
}
`;
8 changes: 5 additions & 3 deletions src/components/Calculator/Calculator.css
@@ -1,4 +1,6 @@
.calculator-container {
height: 60%;
width: 24%;
}
background-color: var(--calculator-background-color);
height: var(--calculator-height);
width: var(--calculator-width);
}

142 changes: 132 additions & 10 deletions src/components/Calculator/Calculator.jsx
@@ -1,16 +1,138 @@
import React from 'react';
import React, { Component } from 'react';
import './Calculator.css';

import Display from '../Display/Display';
import Keypad from '../Keypad/Keypad';
import './Calculator.css';

class Calculator extends Component {
state = {
displayValue: '0',
numbers: ['9', '8', '7', '6', '5', '4', '3', '2', '1', '.', '0', 'ce'],
operators: ['/', 'x', '-', '+'],
selectedOperator: '',
storedValue: '',
}

componentWillMount = () => {
document.addEventListener('keydown', this.handleKeyPress);
}

componentWillUnmount = () => {
document.removeEventListener('keydown', this.handleKeyPress);
}

handleKeyPress = (event) => {
const { numbers, operators } = this.state;

if (event.key === 'Backspace') this.updateDisplay(event, 'ce');
if (event.key === 'Enter' || event.key === '=') this.callOperator(event);

numbers.forEach((number) => {
if (event.key === number) {
this.updateDisplay(event, number);
}
});

operators.forEach((operator) => {
if (event.key === operator) {
this.setOperator(event, operator);
}
});
}

callOperator = () => {
let { displayValue, selectedOperator, storedValue } = this.state;
const updateStoredValue = displayValue;

displayValue = parseInt(displayValue, 10);
storedValue = parseInt(storedValue, 10);

switch (selectedOperator) {
case '+':
displayValue = storedValue + displayValue;
break;
case '-':
displayValue = storedValue - displayValue;
break;
case 'x':
displayValue = storedValue * displayValue;
break;
case '/':
displayValue = storedValue / displayValue;
break;
default:
displayValue = '0';
}

displayValue = displayValue.toString();
selectedOperator = '';
if (displayValue === 'NaN' || displayValue === 'Infinity') displayValue = '0';

this.setState({ displayValue, selectedOperator, storedValue: updateStoredValue });
}

const Calculator = () => {
return (
<div className="calculator-container">
<Display />
<Keypad />
</div>
);
handleKeyPress = event => {
const { numbers, operators } = this.state;

if (event.key === 'Backspace') this.updateDisplay('ce');
if (event.key === 'Enter' || event.key === '=') this.callOperator();

numbers.forEach(number => {
if (event.key === number) this.updateDisplay(number);
});

operators.forEach(operator => {
if (event.key === operator) this.setOperator(operator);
});
}

setOperator = value => {
let { displayValue, selectedOperator, storedValue } = this.state;

if (selectedOperator === '') {
storedValue = displayValue;
displayValue = '0';
selectedOperator = value;
} else {
selectedOperator = value;
}

this.setState({ displayValue, selectedOperator, storedValue });
}

updateDisplay = value => {
let { displayValue } = this.state;

if (value === '.' && displayValue.includes('.')) value = '';

if (value === 'ce') {
displayValue = displayValue.substr(0, displayValue.length - 1);
if (displayValue === '') displayValue = '0';
} else {
displayValue === '0' ? displayValue = value : displayValue += value;
}

this.setState({ displayValue });
}

render() {
const { displayValue, numbers, operators } = this.state;

return (
<div className="calculator-container">
<Display displayValue={displayValue} />
<Keypad
handleKeyPress={this.handleKeyPress}
operators={operators}
callOperator={this.callOperator}
numbers={numbers}
setOperator={this.setOperator}
updateDisplay={this.updateDisplay}
/>
</div>
);
}
}
export default Calculator;

export default Calculator;

0 comments on commit 6f4a33b

Please sign in to comment.