This repository has been archived by the owner on Mar 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial structure and the start of the calculate function
- Loading branch information
0 parents
commit 0d693c3
Showing
20 changed files
with
8,059 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
end_of_line = lf | ||
indent_size = 2 | ||
indent_style = space | ||
insert_final_newline = true | ||
max_line_length = 120 | ||
tab_width = 2 | ||
|
||
[*.css] | ||
indent_size = 2 | ||
tab_width = 2 | ||
|
||
[{*.ts,*.tsx,*.js}] | ||
indent_size = 2 | ||
tab_width = 2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.idea | ||
node_modules | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
trailingComma: "es5" | ||
tabWidth: 2 | ||
semi: false | ||
singleQuote: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
Simple Calculator | ||
================= | ||
|
||
This project depends on having Node JS (https://nodejs.org/en/) | ||
and Yarn (https://classic.yarnpkg.com/en/) installed | ||
on the system. | ||
|
||
Installation | ||
------------ | ||
|
||
Install the necessary dependencies using yarn. | ||
|
||
```sh | ||
yarn | ||
``` | ||
|
||
Development Server | ||
------------------ | ||
|
||
```sh | ||
yarn start | ||
``` | ||
|
||
Production Build | ||
---------------- | ||
|
||
This build the project into the `./dist` directory | ||
|
||
```sh | ||
NODE_ENV=production yarn build | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
declare module '*.svg' { | ||
const ReactComponent: React.ComponentType<React.ImgHTMLAttributes<HTMLImageElement>> | ||
export = ReactComponent | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "simple-calculator", | ||
"version": "1.0.0", | ||
"description": "Simple calculator in React", | ||
"main": "src/index.tsx", | ||
"scripts": { | ||
"clean": "", | ||
"start": "webpack-dev-server", | ||
"build": "webpack", | ||
"test": "jest" | ||
}, | ||
"author": "Dave Taylor <[email protected]>", | ||
"license": "GPL-3.0", | ||
"dependencies": { | ||
"react": "^16.12.0", | ||
"react-dom": "^16.12.0" | ||
}, | ||
"devDependencies": { | ||
"@svgr/webpack": "^5.1.0", | ||
"@types/jest": "^25.1.2", | ||
"@types/react": "^16.9.19", | ||
"@types/react-dom": "^16.9.5", | ||
"html-webpack-plugin": "^3.2.0", | ||
"jest": "^25.1.0", | ||
"prettier": "^1.19.1", | ||
"ts-jest": "^25.2.0", | ||
"ts-loader": "^6.2.1", | ||
"ts-node": "^8.6.2", | ||
"tslint": "^6.0.0", | ||
"typescript": "^3.7.5", | ||
"webpack": "^4.41.6", | ||
"webpack-cli": "^3.3.11", | ||
"webpack-dev-server": "^3.10.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { calculate, isOperand, splitIntoCalculationParts } from '../calculate' | ||
import { split } from 'ts-node' | ||
|
||
describe('calculate', () => { | ||
describe('isOperand', () => { | ||
it.each(['/', '*', '+', '-'])('should see %s as a valid operand', (operand: string) => { | ||
expect(isOperand(operand)).toEqual(true) | ||
}) | ||
it.each(['a', '"', '_', 'x'])('should see %s as an invalid operand', (operand: string) => { | ||
expect(isOperand(operand)).toEqual(false) | ||
}) | ||
}) | ||
|
||
describe('splitIntoCalculationParts', () => { | ||
it('should split the calculation into numer and operand parts', function() { | ||
expect(splitIntoCalculationParts('2 / 2 * 2 + 2 - 2')).toEqual([2, '/', 2, '*', 2, '+', 2, '-', 2]) | ||
}) | ||
it('should not be affected by whitespace', function() { | ||
expect(splitIntoCalculationParts('2*2-1')).toEqual([2, '*', 2, '-', 1]) | ||
}) | ||
}) | ||
describe('Single operator calculations', () => { | ||
it.each([ | ||
['2 + 2', 4], | ||
['2+2', 4], | ||
['2+ 2', 4], | ||
['2 +2', 4], | ||
['2 - 2', 0], | ||
['2 * 2', 4], | ||
['2 / 2', 1], | ||
])('should calculate %s to equal %s', function(calculation, expected) { | ||
expect(calculate(calculation)).toEqual(expected) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
export interface ICalculateResult { | ||
result?: number | ||
error?: string | ||
} | ||
|
||
export type TOperand = '/' | '*' | '+' | '-' | ||
export type TCalculationPart = number | TOperand | ||
|
||
export const isOperand = (char: string): char is TOperand => /^[\/*+\-]$/.test(char) | ||
const isValid = (calculation: string) => /^[0-9\s\/\-+*]+[0-9]$/g.test(calculation) | ||
|
||
const getNumber = (withoutSpaces: string) => (lastOperandIndex: number, currentIndex?: number) => { | ||
const lastNumberString = withoutSpaces.substring(lastOperandIndex + 1, currentIndex) | ||
return parseFloat(lastNumberString) | ||
} | ||
|
||
export const splitIntoCalculationParts = (calculation: string): any[] => { | ||
const withoutSpaces = calculation.replace(/\s/g, '') | ||
const getLastNumber = getNumber(withoutSpaces) | ||
const parts: TCalculationPart[] = [] | ||
let lastOperandIndex = -1 | ||
for (let i = 0; i < withoutSpaces.length; i += 1) { | ||
const char = withoutSpaces[i] | ||
if (isOperand(char)) { | ||
parts.push(getLastNumber(lastOperandIndex, i)) | ||
parts.push(char) | ||
lastOperandIndex = i | ||
} | ||
} | ||
if (lastOperandIndex < withoutSpaces.length) { | ||
parts.push(getLastNumber(lastOperandIndex)) | ||
} | ||
return parts | ||
} | ||
|
||
const findAndCalculate = (parts: TCalculationPart[], operand: TOperand): TCalculationPart[] => {} | ||
|
||
export const calculate = (calculation: string) => { | ||
if (isValid(calculation)) { | ||
const parts = splitIntoCalculationParts(calculation) | ||
// find first operator and replace numbers with result | ||
const div = findAndCalculate(parts, '/') | ||
return { result: 10 } | ||
} else { | ||
return { error: 'Only supports simple calculation' } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React, { CSSProperties } from 'react' | ||
|
||
const buttonStyle: CSSProperties = {} | ||
|
||
export const Button = (props: React.ButtonHTMLAttributes<HTMLButtonElement>) => { | ||
return <button style={buttonStyle} {...props} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React, { CSSProperties } from 'react' | ||
import { Header } from '../Header/index' | ||
import { CalculatorForm } from '../CalculatorForm/index' | ||
import { EQUAL_EXPERTS_BLUE } from '../../tokens' | ||
|
||
const appStyle: CSSProperties = { | ||
maxWidth: '300px', | ||
margin: '0 auto', | ||
border: `solid 1px ${EQUAL_EXPERTS_BLUE}`, | ||
} | ||
|
||
export const CalculatorApp = () => { | ||
return ( | ||
<div style={appStyle}> | ||
<Header /> | ||
<CalculatorForm /> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { CSSProperties, FormEvent, RefObject, useRef, useState } from 'react' | ||
import { PROXIMITY_1 } from '../../tokens' | ||
import { calculate, ICalculateResult } from '../../calculate' | ||
import { Button } from '../Button/index' | ||
|
||
const formStyle: CSSProperties = { | ||
padding: PROXIMITY_1, | ||
display: 'flex', | ||
flexDirection: 'column', | ||
} | ||
|
||
const labelStyle: CSSProperties = { | ||
padding: `${PROXIMITY_1} 0 ${PROXIMITY_1} 0`, | ||
} | ||
|
||
const inputStyle: CSSProperties = { | ||
display: 'block', | ||
} | ||
|
||
const errorStyle: CSSProperties = { | ||
color: '#900', | ||
} | ||
|
||
let buttonGridStyle: CSSProperties = { | ||
display: 'grid', | ||
gridTemplateColumns: '1fr 1fr 1fr', | ||
} | ||
|
||
export const CalculatorForm = () => { | ||
const inputRef: RefObject<HTMLInputElement> = useRef<HTMLInputElement>(null) | ||
const [{ result, error }, setResult] = useState<ICalculateResult>({}) | ||
const onSubmit = (e: FormEvent) => { | ||
const calc = inputRef.current ? inputRef.current.value : '' | ||
setResult(calculate(calc)) | ||
e.preventDefault() | ||
} | ||
const onButtonClick = (e: MouseEvent) => {} | ||
return ( | ||
<form style={formStyle} onSubmit={onSubmit}> | ||
<label style={labelStyle} htmlFor="calculation"> | ||
Expression: | ||
</label> | ||
<input style={inputStyle} ref={inputRef} id="calculation" name="calculation" type="text" /> | ||
{error && ( | ||
<label style={{ ...labelStyle, ...errorStyle }} htmlFor="calculation"> | ||
{error} | ||
</label> | ||
)} | ||
{result && ( | ||
<label style={labelStyle} htmlFor="calculation"> | ||
`The result is: ${result}` | ||
</label> | ||
)} | ||
<div style={buttonGridStyle}> | ||
<Button>7</Button> | ||
<Button>8</Button> | ||
<Button>9</Button> | ||
<Button>4</Button> | ||
<Button>5</Button> | ||
<Button>6</Button> | ||
<Button>1</Button> | ||
<Button>2</Button> | ||
<Button>3</Button> | ||
<Button>0</Button> | ||
</div> | ||
<div style={buttonGridStyle}> | ||
<Button>/</Button> | ||
<Button>x</Button> | ||
<Button>-</Button> | ||
<Button>+</Button> | ||
</div> | ||
</form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React, { CSSProperties } from 'react' | ||
|
||
import EqualExpertsLogo from './logo.svg' | ||
import { EQUAL_EXPERTS_BLUE, PROXIMITY_1 } from '../../tokens' | ||
|
||
const headerStyle: CSSProperties = { | ||
display: 'grid', | ||
gridTemplateColumns: '100px auto', | ||
gridGap: PROXIMITY_1, | ||
alignItems: 'center', | ||
backgroundColor: EQUAL_EXPERTS_BLUE, | ||
padding: PROXIMITY_1, | ||
color: 'white', | ||
} | ||
|
||
const h1Style: CSSProperties = { | ||
fontSize: '16px', | ||
margin: '0', | ||
padding: '0', | ||
} | ||
|
||
export const Header = () => ( | ||
<header style={headerStyle}> | ||
<EqualExpertsLogo /> | ||
<h1 style={h1Style}>Calculator</h1> | ||
</header> | ||
) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react' | ||
import ReactDOM from 'react-dom' | ||
import { CalculatorApp } from './components/CalculatorApp' | ||
|
||
const reactElement = document.createElement('div') | ||
document.body.appendChild(reactElement) | ||
ReactDOM.render(<CalculatorApp />, reactElement) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
export const EQUAL_EXPERTS_BLUE = '#1795d4' | ||
|
||
export const PROXIMITY_1 = '16px' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"compilerOptions": { | ||
"strict": true, | ||
"module": "ESNext", | ||
"target": "ESNext", | ||
"jsx": "react", | ||
"allowSyntheticDefaultImports": true | ||
}, | ||
"include": [ | ||
"./global.d.ts", | ||
"src/" | ||
] | ||
} |
Oops, something went wrong.