diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..140f92d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..ef58ff9
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,6 @@
+{
+ "trailingComma": "es5",
+ "tabWidth": 4,
+ "semi": false,
+ "singleQuote": true
+}
diff --git a/package.json b/package.json
index a5b42cd..92943d8 100644
--- a/package.json
+++ b/package.json
@@ -2,14 +2,17 @@
"name": "frontend-exercise",
"version": "0.1.0",
"private": true,
+ "engines": {
+ "node": " >=18"
+ },
"dependencies": {
- "@testing-library/jest-dom": "^5.11.4",
- "@testing-library/react": "^11.1.0",
- "@testing-library/user-event": "^12.1.10",
- "react": "^17.0.1",
- "react-dom": "^17.0.1",
- "react-scripts": "4.0.1",
- "web-vitals": "^0.2.4"
+ "@testing-library/jest-dom": "^6.4.2",
+ "@testing-library/react": "^15.0.4",
+ "@testing-library/user-event": "^14.5.2",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-scripts": "5.0.1",
+ "web-vitals": "^3.5.2"
},
"scripts": {
"start": "react-scripts start",
@@ -34,5 +37,8 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "prettier": "3.2.5"
}
}
diff --git a/src/App.js b/src/App.js
index 05d26cf..1f4e528 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,16 +1,28 @@
+import { useEffect, useState } from 'react'
+import { numberFromWord } from './utils/numberFromWord'
+
function App() {
- const text = ''
+ const [value, setValue] = useState('one hundred twenty and one')
+ const [result, setResult] = useState(0)
+
+ useEffect(() => {
+ setResult(numberFromWord(value))
+ }, [value])
- return (
-
- )
+ return (
+
+
{
+ setValue(e.target.value)
+ }}
+ />
+
+
+ )
}
export default App
diff --git a/src/App.test.js b/src/App.test.js
deleted file mode 100644
index bad8e0c..0000000
--- a/src/App.test.js
+++ /dev/null
@@ -1,5 +0,0 @@
-describe('App', () => {
- it('should convert number to text', () => {
- expect(true).toBe(false)
- })
-})
diff --git a/src/constants/words.js b/src/constants/words.js
new file mode 100644
index 0000000..d5692bb
--- /dev/null
+++ b/src/constants/words.js
@@ -0,0 +1,40 @@
+export const words = {
+ zero: 0,
+ one: 1,
+ two: 2,
+ three: 3,
+ four: 4,
+ five: 5,
+ six: 6,
+ seven: 7,
+ eight: 8,
+ nine: 9,
+ ten: 10,
+ eleven: 11,
+ twelve: 12,
+ thirteen: 13,
+ fourteen: 14,
+ fifteen: 15,
+ sixteen: 16,
+ seventeen: 17,
+ eighteen: 18,
+ nineteen: 19,
+ twenty: 20,
+ thirty: 30,
+ forty: 40,
+ fifty: 50,
+ sixty: 60,
+ seventy: 70,
+ eighty: 80,
+ ninety: 90,
+}
+
+export const multipliers = {
+ hundred: 100,
+ thousand: 1000,
+ million: 1000000,
+ billion: 1000000000,
+}
+
+export const max = 999999999
+export const min = 0
diff --git a/src/utils/numberFromWord.js b/src/utils/numberFromWord.js
new file mode 100644
index 0000000..07233a2
--- /dev/null
+++ b/src/utils/numberFromWord.js
@@ -0,0 +1,52 @@
+import {
+ words as wordDictionary,
+ multipliers as multipliersDictionary,
+ min,
+ max,
+} from '../constants/words'
+
+export const numberFromWord = (string) => {
+ string = string.toLowerCase().replace(/-|\s+and\s+/g, ' ')
+ let words = string.split(/\s+/)
+ let current = 0
+ let result = 0
+ let lastMultiplier = 1
+ let lastWasNumber = false
+ let lastNumber = 0
+
+ for (let word of words) {
+ if (wordDictionary.hasOwnProperty(word)) {
+ // exception for wordDictionary[word] === 0
+ let numberValue = wordDictionary[word]
+ if (lastWasNumber) {
+ if (
+ !(lastNumber >= 20 && lastNumber < 100 && numberValue < 10)
+ ) {
+ return 'incorrect'
+ }
+ }
+ current = current + numberValue
+ lastWasNumber = true
+ lastNumber = numberValue
+ } else if (multipliersDictionary[word]) {
+ if (current === 0 && result === 0) {
+ return 'incorrect'
+ }
+ current = current * multipliersDictionary[word]
+ if (multipliersDictionary[word] > lastMultiplier) {
+ result = result + current
+ current = 0
+ }
+ lastMultiplier = multipliersDictionary[word]
+ lastWasNumber = false
+ } else {
+ return 'incorrect'
+ }
+ }
+
+ result = result + current
+ if (result < min || result > max) {
+ return 'incorrect'
+ }
+ return result
+}
diff --git a/src/utils/numberFromWord.test.js b/src/utils/numberFromWord.test.js
new file mode 100644
index 0000000..90a3749
--- /dev/null
+++ b/src/utils/numberFromWord.test.js
@@ -0,0 +1,78 @@
+import { numberFromWord } from './numberFromWord'
+
+describe('numberFromWord', () => {
+ describe('test outputs', () => {
+ it('zero => 0', () => {
+ const test = numberFromWord('zero')
+ expect(test).toBe(0)
+ })
+
+ it('one => 1', () => {
+ const test = numberFromWord('one')
+ expect(test).toBe(1)
+ })
+
+ it('one hundred => 100', () => {
+ const test = numberFromWord('one hundred')
+ expect(test).toBe(100)
+ })
+ it('one hundred twenty => 120', () => {
+ const test = numberFromWord('one hundred twenty')
+ expect(test).toBe(120)
+ })
+
+ it('three million one hundred thousand and ninety =≥ 3100090', () => {
+ const test = numberFromWord(
+ 'three million one hundred thousand and ninety'
+ )
+ expect(test).toBe(3100090)
+ })
+
+ it('two thousand and forty five => 2045', () => {
+ const test = numberFromWord('two thousand and forty five')
+ expect(test).toBe(2045)
+ })
+
+ it('fifty four => 54', () => {
+ const test = numberFromWord('fifty four')
+ expect(test).toBe(54)
+ })
+ })
+
+ describe('test edge cases', () => {
+ it('one hundred-twenty => 120', () => {
+ const test = numberFromWord('one hundred-twenty')
+ expect(test).toBe(120)
+ })
+
+ it('ONE HUNDRED-TWENTY => 120', () => {
+ const test = numberFromWord('ONE HUNDRED-TWENTY')
+ expect(test).toBe(120)
+ })
+
+ it('ONE HUNDRED and TWENTY => 120', () => {
+ const test = numberFromWord('ONE HUNDRED and TWENTY')
+ expect(test).toBe(120)
+ })
+
+ it('one one => incorrect', () => {
+ const test = numberFromWord('one one')
+ expect(test).toBe('incorrect')
+ })
+
+ it('one one => incorrect', () => {
+ const test = numberFromWord('one one')
+ expect(test).toBe('incorrect')
+ })
+
+ it('one billion => incorrect', () => {
+ const test = numberFromWord('one billion')
+ expect(test).toBe('incorrect')
+ })
+
+ it('one billion => incorrect', () => {
+ const test = numberFromWord('minus one')
+ expect(test).toBe('incorrect')
+ })
+ })
+})