From 833a47f5edce2276a803a8fd60d4c30f26e7cdee Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Wed, 30 Oct 2024 03:47:20 +0900 Subject: [PATCH 01/20] =?UTF-8?q?docs:=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=201=EC=B0=A8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 15bb106b5..c75f746d3 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ -# javascript-lotto-precourse +# ๐Ÿ’ธ ๋กœ๋˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + +## ์ž…๋ ฅ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ + +### ๊ตฌ์ž… ๊ธˆ์•ก ์ž…๋ ฅ + +1000์› ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. +- `[ERROR] 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.` + +### ๋ฐœํ–‰ํ•˜๊ธฐ + +๋‚˜๋ˆˆ ์ˆซ์ž๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•œ๋‹ค. +- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„ : 1-45 + +ํ•œ ๋ฒˆ ๋ฐœํ–‰ํ•  ๋•Œ ์ˆซ์ž์˜ ๊ฐœ์ˆ˜๋Š” 6๊ฐœ ์ด๋‹ค. + +### ๋‹น์ฒจ ๋ฒˆํ˜ธ, ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ + +๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. +- ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. +- ์˜ˆ์™ธ : ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` + +๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. +- ์˜ˆ์™ธ : ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` + +### ๋‹น์ฒจ + +1๋“ฑ ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹น์ฒจ์ž๋ฅผ ๊ฐ€๋ฆฐ๋‹ค. +- 6๊ฐœ ์ผ์น˜์™€ 5๊ฐœ ์ผ์น˜์— ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ž˜ ๊ตฌ๋ถ„ํ•ด์•ผํ•œ๋‹ค. + + +### ์ˆ˜์ต๋ฅ  + +๊ตฌ๋งคํ•œ ๋กœ๋˜๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜๊ธฐ +- ์ผ์น˜ํ•˜๋Š” ๊ฐฏ์ˆ˜ / ์ด ์ˆซ์ž ๋ฐœํ–‰ ๊ฐฏ์ˆ˜ * 100 = ์ˆ˜์ต๋ฅ  +- ์†Œ์ˆ˜์  ๋‘˜์งธ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + +
+ +## ์ถœ๋ ฅํ•˜๊ธฐ + +### ์ถœ๋ ฅ +- ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰๊ณผ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. +- ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. + +- ๋‹น์ฒจ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค. +- 0๊ฐœ ์ผ์น˜, (00000์›) - 0๊ฐœ +- ์ˆ˜์ต๋ฅ  ์†Œ์ˆ˜์  ๋‘˜์งธ ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผํ•œ๋‹ค. + +- ์˜ˆ์™ธ ์‚ฌํ•ญ ์‹œ ์—๋Ÿฌ ๋ฌธ๊ตฌ ์ถœ๋ ฅํ•ด์•ผํ•œ๋‹ค. From 6ba7cce17bf7add9382b1237a3c16c8eedb2ba81 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Sat, 2 Nov 2024 22:46:24 +0900 Subject: [PATCH 02/20] =?UTF-8?q?docs(input)=20:=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c75f746d3..a4dd58fb8 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ### ๊ตฌ์ž… ๊ธˆ์•ก ์ž…๋ ฅ 1000์› ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. -- `[ERROR] 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.` +- `[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.` ### ๋ฐœํ–‰ํ•˜๊ธฐ @@ -18,11 +18,14 @@ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. - ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. +- ์˜ˆ์™ธ : ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ : `[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` - ์˜ˆ์™ธ : ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` - ์˜ˆ์™ธ : ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. +- ์˜ˆ์™ธ : ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ : `[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` - ์˜ˆ์™ธ : ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` ### ๋‹น์ฒจ From 3d6b6fb533042581ba5d93337c4fc02381892451 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Sat, 2 Nov 2024 22:47:52 +0900 Subject: [PATCH 03/20] =?UTF-8?q?docs(input)=20:=20=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a4dd58fb8..7f59b0b89 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. - ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. - ์˜ˆ์™ธ : ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ : `[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` -- ์˜ˆ์™ธ : ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` - ์˜ˆ์™ธ : ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. From 46cf51d927cd9d10fe6f0c868cd34fd6b81539e7 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 19:50:52 +0900 Subject: [PATCH 04/20] =?UTF-8?q?docs:=20=EC=98=88=EC=99=B8=20=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7f59b0b89..e5c065252 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ 1๋“ฑ ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹น์ฒจ์ž๋ฅผ ๊ฐ€๋ฆฐ๋‹ค. - 6๊ฐœ ์ผ์น˜์™€ 5๊ฐœ ์ผ์น˜์— ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ž˜ ๊ตฌ๋ถ„ํ•ด์•ผํ•œ๋‹ค. +- 3๊ฐœ, 4๊ฐœ, 5๊ฐœ, 5๊ฐœ๋ž‘ ๋ณด๋„ˆ์Šค ๋งž์ถ˜๊ฒฝ์šฐ, 6๊ฐœ๋กœ ๋‚˜๋ˆ„๊ณ  if-else์กฐ๊ฑด๋ฌธ์œผ๋กœ ํ•ด๊ฒฐ(ํŠน์ • ๊ฒฝ์šฐ์—๋งŒ ์กฐ๊ฑด์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด ํ›„ ์กฐ๊ฑด ๋ฌด์‹œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.) ### ์ˆ˜์ต๋ฅ  From 4c73131b1ce1abbfe58005fc7d8c012eb96dc1e3 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 19:51:43 +0900 Subject: [PATCH 05/20] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80=20=EC=A4=91=EB=B3=B5=20=EC=88=AB?= =?UTF-8?q?=EC=9E=90=20=EB=B2=94=EC=9C=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Lotto.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Lotto.js b/src/Lotto.js index cb0b1527e..9ff27edf2 100644 --- a/src/Lotto.js +++ b/src/Lotto.js @@ -10,9 +10,19 @@ class Lotto { if (numbers.length !== 6) { throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 6๊ฐœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } + if (new Set(numbers).size !== numbers.length){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + } + if (numbers.some(num => isModuleNamespaceObject(num) || num < 1 || num > 45)){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + } } // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ + + getNumbers(){ + return this.#numbers; + } } export default Lotto; From 6ee93673dcd29cc117be7d6dbc8b5ec03dd8a380 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 19:52:14 +0900 Subject: [PATCH 06/20] =?UTF-8?q?feat(App)=20:=20App.js=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/App.js b/src/App.js index 091aa0a5d..733ec5883 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,51 @@ +import { Console } from "@woowacourse/mission-utils"; +import LottoManager from "./LottoManager"; +import InputValidator from "./InputValidator"; + class App { - async run() {} + run() { + this.askPurchaseAmount(); + } + + askPurchaseAmount() { + Console.readLineAsync('๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n', (input) => { + try { + const purchaseAmount = InputValidator.validatePurchaseAmount(input); + const lottoManager = new LottoManager(purchaseAmount); + this.askWinningNumbers(lottoManager); + } catch (error) { + this.handleError(error, this.askPurchaseAmount.bind(this)); + } + }); + } + + askWinningNumbers(lottoManager) { + Console.readLineAsync('๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n', (input) => { + try { + const winningNumbers = InputValidator.validateWinningNumbers(input); + this.askBonusNumber(lottoManager, winningNumbers); + } catch (error) { + this.handleError(error, () => this.askWinningNumbers(lottoManager)); + } + }); + } + + askBonusNumber(lottoManager, winningNumbers) { + Console.readLineAsync('๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n', (input) => { + try { + const bonusNumber = InputValidator.validateBonusNumber(input, winningNumbers); + lottoManager.checkResults(winningNumbers, bonusNumber); + Console.close(); + } catch (error) { + this.handleError(error, () => this.askBonusNumber(lottoManager, winningNumbers)); + } + }); + } + + handleError(error, retryFunction) { + Console.print(error.message); + retryFunction(); + } } export default App; From 9d5cb8956e724cbd017eae562f5c39c367b6702f Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 19:53:06 +0900 Subject: [PATCH 07/20] =?UTF-8?q?feat(InputValidator):=20input=20=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=9C=20=EC=98=88=EC=99=B8=20=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20input=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/InputValidator.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/InputValidator.js diff --git a/src/InputValidator.js b/src/InputValidator.js new file mode 100644 index 000000000..baa91f94f --- /dev/null +++ b/src/InputValidator.js @@ -0,0 +1,40 @@ +class InputValidator{ + static PurchaseAmount(input){ + const amount = parseInt(input, 10); + if(isNaN(amount) || amount % 1000 !== 0){ + throw new Error("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.") + } + return amount; + } + + static WinningNumbers(input){ + const numbers = input.split(',').map(Number); + if(numbers.length !== 6){ + throw new Error("ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค."); + } + if (new Set(numbers).size !== numbers.length){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + } + if (numbers.some(num => isModuleNamespaceObject(num) || num < 1 || num > 45)){ + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + } + } + + static bonusNumber(input, winningNumbers) { + const numbers = input.split(',').map(Number); + if (numbers.length !== 1) { + throw new Error("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + const bonusNumber = numbers[0]; + if (winningNumbers.includes(bonusNumber)) { + throw new Error("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค."); + } + if (isNaN(bonusNumber) || bonusNumber < 1 || bonusNumber > 45) { + throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + } + return bonusNumber; + } + +} + +export default InputValidator; \ No newline at end of file From fdd5363061218c359a8755a905d49173ba553321 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 19:54:21 +0900 Subject: [PATCH 08/20] =?UTF-8?q?feat(LottoManager):=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EA=B5=AC=EC=9E=85=ED=95=9C=20=EA=B0=AF?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80=20=EB=A1=9C=EB=98=90=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=EA=B0=92=20resultcalculator=EC=97=90=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EA=B3=A0=20=EA=B2=B0=EA=B3=BC=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/LottoManager.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/LottoManager.js diff --git a/src/LottoManager.js b/src/LottoManager.js new file mode 100644 index 000000000..615874446 --- /dev/null +++ b/src/LottoManager.js @@ -0,0 +1,31 @@ +import Lotto from "./Lotto"; +import {Random, Console} from '@woowacourse/mission-utils'; +import ResultCalculator from './ResultCalculator'; + +class LottoManager{ + constructor(purchaseAmount){ + this.lottos = this.generateLottos(purchaseAmount / 1000); + this.printLottos(); + } + + generateLottos(count){ + return Array.from({length: count}, () =>{ + const numbers = Random.pickUniqueNumbersInRange(1,45,6).sort((a,b) => a - b); + return new Lotto(numbers); + }); + } + + printLottos(){ + Console.print(`${this.lottos.length}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.\n`); + this.lottos.forEach((lotto) => { + Console.print(`[${lotto.getNumbers().join(', ')}]`); + }); + } + + checkResults(winningNumbers, bonusNumber) { + const resultCalculator = new ResultCalculator(this.lottos, winningNumbers, bonusNumber); + resultCalculator.printResults(); + } +} + +export default LottoManager; \ No newline at end of file From 1e2ab5e23739ff3e1b33e0f1b58c2b5e49b414b7 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 19:55:16 +0900 Subject: [PATCH 09/20] =?UTF-8?q?feat(ResultCalculator)=20:=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=EC=9D=98=20=EC=88=98=20=EB=82=98=EB=88=A0=EC=84=9C=20?= =?UTF-8?q?=EA=B0=81=EA=B0=81=20=EC=B6=94=EA=B0=80=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ResultCalculator.js | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/ResultCalculator.js diff --git a/src/ResultCalculator.js b/src/ResultCalculator.js new file mode 100644 index 000000000..778abe9b9 --- /dev/null +++ b/src/ResultCalculator.js @@ -0,0 +1,54 @@ +import {Console} from '@woowacourse/mission-utils'; + +class ResultCalculator { + constructor(lottos, winningNumbers, bonusNumber) { + this.lotto = lottos; + this.winningNumbers = winningNumbers; + this.bonusNumber = bonusNumber; + this.matchCounts = {3:0, 4:0, 5:0, 6:0, '5+bonus:':0}; + this.calculateResults(); + } + + calculateResults(){ + this.lottos.forEach((lotto) => { + const matchedCount = this.countMatches(lotto.getNumbers()); + this.updateMatchCounts(matchedCount, lotto); + }); + } + + countMatches(numbers){ + return numbers.filter((num) => this.winningNumbers.includes(num)).length; + } + + updateMatchCounts(matchedCount, lotto){ + if(matchedCount === 6) this.matchCount[6]++; + else if (matchedCount === 5 && lotto.getNumbers().includes(this.bonusNumber)) + this.matchCounts['5+bonus']++; + else if (matchedCount === 5) this.matchCounts[5]++; + else if (matchedCount === 4) this.matchCounts[4]++; + else if (matchedCount === 3) this.matchCounts[3]++; + } + + printResults() { + Console.print("๋‹น์ฒจ ํ†ต๊ณ„\n---"); + Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${this.matchCounts[3]}๊ฐœ`); + Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${this.matchCounts[4]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${this.matchCounts[5]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${this.matchCounts['5+bonus']}๊ฐœ`); + Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${this.matchCounts[6]}๊ฐœ`); + + const totalPrize = this.calculateTotalPrize(); + const profitRate = ((totalPrize / (this.lottos.length * 1000)) * 100).toFixed(1); + Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profitRate}%์ž…๋‹ˆ๋‹ค.`); + } + + calculateTotalPrize(){ + return (this.matchCounts[3] * 5000) + + (this.matchCounts[4] * 50000) + + (this.matchCounts[5] * 1500000) + + (this.matchCounts['5+bonus'] * 30000000) + + (this.matchCounts[6] * 2000000000); + } +} + +export default ResultCalculator; From 9ea636cbb1b5d12aad65bf569b17c46d1d09fc60 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 20:15:12 +0900 Subject: [PATCH 10/20] =?UTF-8?q?chore:=20MVC=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=ED=8C=A8=ED=84=B4=EC=9C=BC=EB=A1=9C=20=EC=9E=AC?= =?UTF-8?q?=EA=B5=AC=EC=84=B1=20models=20:=20lotto,=20lottomanager,=20resu?= =?UTF-8?q?ltcalculator=20views=20:=20consoleview=20utils=20:=20inputvalid?= =?UTF-8?q?ator=20inputvalidator-=20lotto=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 4 +-- src/LottoManager.js | 31 ------------------ src/ResultCalculator.js | 54 ------------------------------- src/{ => models}/Lotto.js | 0 src/models/LottoManager.js | 27 ++++++++++++++++ src/models/ResultCalculator.js | 35 ++++++++++++++++++++ src/{ => utils}/InputValidator.js | 17 ++++------ src/views/ConsoleView.js | 37 +++++++++++++++++++++ 8 files changed, 107 insertions(+), 98 deletions(-) delete mode 100644 src/LottoManager.js delete mode 100644 src/ResultCalculator.js rename src/{ => models}/Lotto.js (100%) create mode 100644 src/models/LottoManager.js create mode 100644 src/models/ResultCalculator.js rename src/{ => utils}/InputValidator.js (63%) create mode 100644 src/views/ConsoleView.js diff --git a/src/App.js b/src/App.js index 733ec5883..dc91f7b67 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,6 @@ import { Console } from "@woowacourse/mission-utils"; -import LottoManager from "./LottoManager"; -import InputValidator from "./InputValidator"; +import LottoManager from "./models/LottoManager"; +import InputValidator from "./utils/InputValidator"; class App { run() { diff --git a/src/LottoManager.js b/src/LottoManager.js deleted file mode 100644 index 615874446..000000000 --- a/src/LottoManager.js +++ /dev/null @@ -1,31 +0,0 @@ -import Lotto from "./Lotto"; -import {Random, Console} from '@woowacourse/mission-utils'; -import ResultCalculator from './ResultCalculator'; - -class LottoManager{ - constructor(purchaseAmount){ - this.lottos = this.generateLottos(purchaseAmount / 1000); - this.printLottos(); - } - - generateLottos(count){ - return Array.from({length: count}, () =>{ - const numbers = Random.pickUniqueNumbersInRange(1,45,6).sort((a,b) => a - b); - return new Lotto(numbers); - }); - } - - printLottos(){ - Console.print(`${this.lottos.length}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.\n`); - this.lottos.forEach((lotto) => { - Console.print(`[${lotto.getNumbers().join(', ')}]`); - }); - } - - checkResults(winningNumbers, bonusNumber) { - const resultCalculator = new ResultCalculator(this.lottos, winningNumbers, bonusNumber); - resultCalculator.printResults(); - } -} - -export default LottoManager; \ No newline at end of file diff --git a/src/ResultCalculator.js b/src/ResultCalculator.js deleted file mode 100644 index 778abe9b9..000000000 --- a/src/ResultCalculator.js +++ /dev/null @@ -1,54 +0,0 @@ -import {Console} from '@woowacourse/mission-utils'; - -class ResultCalculator { - constructor(lottos, winningNumbers, bonusNumber) { - this.lotto = lottos; - this.winningNumbers = winningNumbers; - this.bonusNumber = bonusNumber; - this.matchCounts = {3:0, 4:0, 5:0, 6:0, '5+bonus:':0}; - this.calculateResults(); - } - - calculateResults(){ - this.lottos.forEach((lotto) => { - const matchedCount = this.countMatches(lotto.getNumbers()); - this.updateMatchCounts(matchedCount, lotto); - }); - } - - countMatches(numbers){ - return numbers.filter((num) => this.winningNumbers.includes(num)).length; - } - - updateMatchCounts(matchedCount, lotto){ - if(matchedCount === 6) this.matchCount[6]++; - else if (matchedCount === 5 && lotto.getNumbers().includes(this.bonusNumber)) - this.matchCounts['5+bonus']++; - else if (matchedCount === 5) this.matchCounts[5]++; - else if (matchedCount === 4) this.matchCounts[4]++; - else if (matchedCount === 3) this.matchCounts[3]++; - } - - printResults() { - Console.print("๋‹น์ฒจ ํ†ต๊ณ„\n---"); - Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${this.matchCounts[3]}๊ฐœ`); - Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${this.matchCounts[4]}๊ฐœ`); - Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${this.matchCounts[5]}๊ฐœ`); - Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${this.matchCounts['5+bonus']}๊ฐœ`); - Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${this.matchCounts[6]}๊ฐœ`); - - const totalPrize = this.calculateTotalPrize(); - const profitRate = ((totalPrize / (this.lottos.length * 1000)) * 100).toFixed(1); - Console.print(`์ด ์ˆ˜์ต๋ฅ ์€ ${profitRate}%์ž…๋‹ˆ๋‹ค.`); - } - - calculateTotalPrize(){ - return (this.matchCounts[3] * 5000) + - (this.matchCounts[4] * 50000) + - (this.matchCounts[5] * 1500000) + - (this.matchCounts['5+bonus'] * 30000000) + - (this.matchCounts[6] * 2000000000); - } -} - -export default ResultCalculator; diff --git a/src/Lotto.js b/src/models/Lotto.js similarity index 100% rename from src/Lotto.js rename to src/models/Lotto.js diff --git a/src/models/LottoManager.js b/src/models/LottoManager.js new file mode 100644 index 000000000..7c745985e --- /dev/null +++ b/src/models/LottoManager.js @@ -0,0 +1,27 @@ +import Lotto from "./Lotto"; +import { Random } from "@woowacourse/mission-utils"; +import ResultCalculator from "./ResultCalculator"; + +class LottoManager { + constructor(purchaseAmount) { + this.lottos = this.generateLottos(purchaseAmount / 1000); + } + + generateLottos(count) { + return Array.from({ length: count }, () => { + const numbers = Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b); + return new Lotto(numbers); + }); + } + + getLottos() { + return this.lottos; + } + + calculateResults(winningNumbers, bonusNumber) { + const resultCalculator = new ResultCalculator(this.lottos, winningNumbers, bonusNumber); + return resultCalculator.getResults(); + } +} + +export default LottoManager; diff --git a/src/models/ResultCalculator.js b/src/models/ResultCalculator.js new file mode 100644 index 000000000..233c79c61 --- /dev/null +++ b/src/models/ResultCalculator.js @@ -0,0 +1,35 @@ +class ResultCalculator { + constructor(lottos, winningNumbers, bonusNumber) { + this.lottos = lottos; + this.winningNumbers = winningNumbers; + this.bonusNumber = bonusNumber; + this.matchCounts = { 3: 0, 4: 0, 5: 0, 6: 0, "5+bonus": 0 }; + this.calculateResults(); + } + + calculateResults() { + this.lottos.forEach((lotto) => { + const matchedCount = this.countMatches(lotto.getNumbers()); + this.updateMatchCounts(matchedCount, lotto); + }); + } + + countMatches(numbers) { + return numbers.filter((num) => this.winningNumbers.includes(num)).length; + } + + updateMatchCounts(matchedCount, lotto) { + if (matchedCount === 6) this.matchCounts[6]++; + else if (matchedCount === 5 && lotto.getNumbers().includes(this.bonusNumber)) this.matchCounts["5+bonus"]++; + else if (matchedCount === 5) this.matchCounts[5]++; + else if (matchedCount === 4) this.matchCounts[4]++; + else if (matchedCount === 3) this.matchCounts[3]++; + } + + getResults() { + return this.matchCounts; + } + } + + export default ResultCalculator; + \ No newline at end of file diff --git a/src/InputValidator.js b/src/utils/InputValidator.js similarity index 63% rename from src/InputValidator.js rename to src/utils/InputValidator.js index baa91f94f..dde0b7e15 100644 --- a/src/InputValidator.js +++ b/src/utils/InputValidator.js @@ -1,3 +1,5 @@ +import Lotto from "../models/Lotto"; + class InputValidator{ static PurchaseAmount(input){ const amount = parseInt(input, 10); @@ -7,17 +9,10 @@ class InputValidator{ return amount; } - static WinningNumbers(input){ - const numbers = input.split(',').map(Number); - if(numbers.length !== 6){ - throw new Error("ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค."); - } - if (new Set(numbers).size !== numbers.length){ - throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") - } - if (numbers.some(num => isModuleNamespaceObject(num) || num < 1 || num > 45)){ - throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") - } + static validateWinningNumbers(input) { + const numbers = input.split(",").map(Number); + const lotto = new Lotto(numbers); // Lotto ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ ์ˆ˜ํ–‰ + return lotto.getNumbers(); } static bonusNumber(input, winningNumbers) { diff --git a/src/views/ConsoleView.js b/src/views/ConsoleView.js new file mode 100644 index 000000000..5c0fe17e6 --- /dev/null +++ b/src/views/ConsoleView.js @@ -0,0 +1,37 @@ +import { Console } from "@woowacourse/mission-utils"; + +const ConsoleView = { + askPurchaseAmount(callback) { + Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", callback); + }, + + askWinningNumbers(callback) { + Console.readLineAsync("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", callback); + }, + + askBonusNumber(callback) { + Console.readLineAsync("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", callback); + }, + + showLottos(lottos) { + Console.print(`${lottos.length}๊ฐœ๋ฅผ ๊ตฌ๋งคํ–ˆ์Šต๋‹ˆ๋‹ค.`); + lottos.forEach((lotto) => { + Console.print(`[${lotto.getNumbers().join(", ")}]`); + }); + }, + + showResults(results) { + Console.print("๋‹น์ฒจ ํ†ต๊ณ„\n---"); + Console.print(`3๊ฐœ ์ผ์น˜ (5,000์›) - ${results[3]}๊ฐœ`); + Console.print(`4๊ฐœ ์ผ์น˜ (50,000์›) - ${results[4]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜ (1,500,000์›) - ${results[5]}๊ฐœ`); + Console.print(`5๊ฐœ ์ผ์น˜, ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ (30,000,000์›) - ${results["5+bonus"]}๊ฐœ`); + Console.print(`6๊ฐœ ์ผ์น˜ (2,000,000,000์›) - ${results[6]}๊ฐœ`); + }, + + showError(error) { + Console.print(error.message); + }, +}; + +export default ConsoleView; From 5c1a274265edd8c75449827d6ee05b654fe9c297 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 21:55:39 +0900 Subject: [PATCH 11/20] docs(design): readme.md design --- README.md | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index e5c065252..8668f48f7 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,58 @@ # ๐Ÿ’ธ ๋กœ๋˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -## ์ž…๋ ฅ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ -### ๊ตฌ์ž… ๊ธˆ์•ก ์ž…๋ ฅ +[๐Ÿฃ ์ž…๋ ฅ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ](#๊ตฌ์ž…-๊ธˆ์•ก-์ž…๋ ฅ)  +[๐Ÿ’ฐ ๋ฐœํ–‰ํ•˜๊ธฐ](#๋ฐœํ–‰ํ•˜๊ธฐ)  +[๐ŸŽ‰ ๋‹น์ฒจ ๊ณ„์‚ฐํ•˜๊ธฐ](#๋‹น์ฒจ)  +[๐Ÿ“ˆ ์ˆ˜์ต๋ฅ ](#-์ˆ˜์ต๋ฅ )  +[๐Ÿค‘ ์ถœ๋ ฅํ•˜๊ธฐ](#-์ถœ๋ ฅํ•˜๊ธฐ) -1000์› ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. -- `[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.` -### ๋ฐœํ–‰ํ•˜๊ธฐ +## ๐Ÿฃ ์ž…๋ ฅ ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ธฐ +### ๊ตฌ์ž… ๊ธˆ์•ก ์ž…๋ ฅ -๋‚˜๋ˆˆ ์ˆซ์ž๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•œ๋‹ค. -- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„ : 1-45 +1000์› ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•œ๋‹ค. -ํ•œ ๋ฒˆ ๋ฐœํ–‰ํ•  ๋•Œ ์ˆซ์ž์˜ ๊ฐœ์ˆ˜๋Š” 6๊ฐœ ์ด๋‹ค. +- `[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.` ### ๋‹น์ฒจ ๋ฒˆํ˜ธ, ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์ž…๋ ฅ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค. - ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์ˆซ์ž 6๊ฐœ์™€ ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ 1๊ฐœ๋ฅผ ๋ฝ‘๋Š”๋‹ค. -- ์˜ˆ์™ธ : ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ : `[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` -- ์˜ˆ์™ธ : ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` -- ์˜ˆ์™ธ : ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` + +- ์˜ˆ์™ธ : **๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ** :
`[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ 6๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ** :
`[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ** :
`[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. -- ์˜ˆ์™ธ : ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ : `[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` -- ์˜ˆ์™ธ : ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ : `[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` -- ์˜ˆ์™ธ : ์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ : `[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ** :
`[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋˜๋Š” ๊ฒฝ์šฐ**:
`[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.` +- ์˜ˆ์™ธ : **์ˆซ์ž ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ** :
`[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.` + +## ๐Ÿ’ฐ ๋ฐœํ–‰ํ•˜๊ธฐ + +๋‚˜๋ˆˆ ์ˆซ์ž๋งŒํผ ๋กœ๋˜๋ฅผ ๋ฐœํ–‰ํ•œ๋‹ค. +- ๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ์ˆซ์ž ๋ฒ”์œ„ : 1-45 + +ํ•œ ๋ฒˆ ๋ฐœํ–‰ํ•  ๋•Œ ์ˆซ์ž์˜ ๊ฐœ์ˆ˜๋Š” 6๊ฐœ ์ด๋‹ค. + -### ๋‹น์ฒจ +## ๐ŸŽ‰ ๋‹น์ฒจ ๊ณ„์‚ฐํ•˜๊ธฐ 1๋“ฑ ๋ถ€ํ„ฐ 5๋“ฑ๊นŒ์ง€ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋‹น์ฒจ์ž๋ฅผ ๊ฐ€๋ฆฐ๋‹ค. - 6๊ฐœ ์ผ์น˜์™€ 5๊ฐœ ์ผ์น˜์— ๋ณด๋„ˆ์Šค ๋ณผ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ž˜ ๊ตฌ๋ถ„ํ•ด์•ผํ•œ๋‹ค. -- 3๊ฐœ, 4๊ฐœ, 5๊ฐœ, 5๊ฐœ๋ž‘ ๋ณด๋„ˆ์Šค ๋งž์ถ˜๊ฒฝ์šฐ, 6๊ฐœ๋กœ ๋‚˜๋ˆ„๊ณ  if-else์กฐ๊ฑด๋ฌธ์œผ๋กœ ํ•ด๊ฒฐ(ํŠน์ • ๊ฒฝ์šฐ์—๋งŒ ์กฐ๊ฑด์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด ํ›„ ์กฐ๊ฑด ๋ฌด์‹œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.) +- 3๊ฐœ, 4๊ฐœ, 5๊ฐœ, 5๊ฐœ๋ž‘ ๋ณด๋„ˆ์Šค ๋งž์ถ˜๊ฒฝ์šฐ, 6๊ฐœ๋กœ ๋‚˜๋ˆ„๊ณ  `if-else`์กฐ๊ฑด๋ฌธ์œผ๋กœ ํ•ด๊ฒฐ(ํŠน์ • ๊ฒฝ์šฐ์—๋งŒ ์กฐ๊ฑด์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด ํ›„ ์กฐ๊ฑด ๋ฌด์‹œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.) -### ์ˆ˜์ต๋ฅ  +## ๐Ÿ“ˆ ์ˆ˜์ต๋ฅ  -๊ตฌ๋งคํ•œ ๋กœ๋˜๋ฒˆํ˜ธ์™€ ๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜๊ธฐ -- ์ผ์น˜ํ•˜๋Š” ๊ฐฏ์ˆ˜ / ์ด ์ˆซ์ž ๋ฐœํ–‰ ๊ฐฏ์ˆ˜ * 100 = ์ˆ˜์ต๋ฅ  -- ์†Œ์ˆ˜์  ๋‘˜์งธ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ +- $(๋‹น์ฒจย ์ดย ๊ธˆ์•ก/๊ตฌ์ž…ย ๊ธˆ์•ก) ร— 100 = ์ˆ˜์ต๋ฅ $ +- ์†Œ์ˆ˜์  **๋‘˜์งธ์ž๋ฆฌ**์—์„œ ๋ฐ˜์˜ฌ๋ฆผ
-## ์ถœ๋ ฅํ•˜๊ธฐ +## ๐Ÿค‘ ์ถœ๋ ฅํ•˜๊ธฐ -### ์ถœ๋ ฅ - ๋ฐœํ–‰ํ•œ ๋กœ๋˜ ์ˆ˜๋Ÿ‰๊ณผ ๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. - ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜์—ฌ ๋ณด์—ฌ์ค€๋‹ค. From d5369916ffc593f38b93e22a48ac3166a2ff05de Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 21:56:11 +0900 Subject: [PATCH 12/20] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/ApplicationTest.js | 35 ++++++++++++++++++++++++++++++++--- __tests__/LottoTest.js | 11 +++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index 872380c9c..ddf6bf76c 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -1,4 +1,4 @@ -import App from "../src/App.js"; +import App from "../src/controllers/App.js"; import { MissionUtils } from "@woowacourse/mission-utils"; const mockQuestions = (inputs) => { @@ -91,7 +91,36 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { }); }); - test("์˜ˆ์™ธ ํ…Œ์ŠคํŠธ", async () => { - await runException("1000j"); + test("๊ตฌ์ž… ๊ธˆ์•ก์ด 1000์› ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + await runException("1500"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + await runException("1,2,3,4,5,46"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ 6๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + await runException("1,2,3,4,5"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์„ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + await runException("1,2,3,4,5,5"); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + await runException("7,8"); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + const winningNumbers = "1,2,3,4,5,6"; + mockQuestions(["1000", winningNumbers, "5"]); // ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋กœ ๋‹น์ฒจ ๋ฒˆํ˜ธ์— ํฌํ•จ๋œ 5๋ฅผ ์ž…๋ ฅ + const logSpy = getLogSpy(); + const app = new App(); + await app.run(); + expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.")); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { + await runException("50"); }); }); diff --git a/__tests__/LottoTest.js b/__tests__/LottoTest.js index 409aaf69b..0af31be43 100644 --- a/__tests__/LottoTest.js +++ b/__tests__/LottoTest.js @@ -1,4 +1,4 @@ -import Lotto from "../src/Lotto"; +import Lotto from "../src/models/Lotto"; describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { test("๋กœ๋˜ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ˆ˜๊ฐ€ 6๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { @@ -14,5 +14,12 @@ describe("๋กœ๋˜ ํด๋ž˜์Šค ํ…Œ์ŠคํŠธ", () => { }).toThrow("[ERROR]"); }); - // TODO: ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ + test("๋กœ๋˜ ๋ฒˆํ˜ธ๊ฐ€ 1~45 ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.", () => { + expect(() => { + new Lotto([0, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + expect(() => { + new Lotto([1, 2, 3, 4, 5, 46]); + }).toThrow("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); }); From 4e4daed698d39280d36f3f7b57192ea66fb93718 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 21:57:49 +0900 Subject: [PATCH 13/20] =?UTF-8?q?refactor(App)=20:=20controller=EB=A1=9C?= =?UTF-8?q?=20=EC=98=AE=EA=B9=80=20import=EB=AC=B8=EC=97=90=20=EA=B0=81?= =?UTF-8?q?=EC=9E=90=20js=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/App.js | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/controllers/App.js diff --git a/src/controllers/App.js b/src/controllers/App.js new file mode 100644 index 000000000..3adf84620 --- /dev/null +++ b/src/controllers/App.js @@ -0,0 +1,45 @@ +import { Console } from "@woowacourse/mission-utils"; +import LottoManager from "../models/LottoManager.js"; +import InputValidator from "../utils/InputValidator.js"; +import ConsoleView from "../views/ConsoleView.js"; + +class App { + async run() { + ConsoleView.askPurchaseAmount((input) => this.handlePurchaseAmout(input)); + } + + handlePurchaseAmount(input) { + try { + const purchaseAmount = InputValidator.validatePurchaseAmount(input); + this.lottoManager = new LottoManager(purchaseAmount); + ConsoleView.showLottos(this.lottoManager.getLottos()); + ConsoleView.askWinningNumbers((input) => this.handleWinningNumbers(input)); + } catch (error) { + ConsoleView.showError(error); + ConsoleView.askPurchaseAmount((input) => this.handlePurchaseAmount(input)); + } + } + + handleWinningNumbers(input) { + try { + const winningNumbers = InputValidator.validateWinningNumbers(input); + ConsoleView.askBonusNumber((input) => this.handleBonusNumber(input, winningNumbers)); + } catch (error) { + ConsoleView.showError(error); + ConsoleView.askWinningNumbers((input) => this.handleWinningNumbers(input)); + } + } + + handleBonusNumber(input, winningNumbers) { + try { + const bonusNumber = InputValidator.validateBonusNumber(input); + const results = this.lottoManager.calculateResults(winningNumbers, bonusNumber); + ConsoleView.showResults(results); + } catch (error) { + ConsoleView.showError(error); + ConsoleView.askBonusNumber((input) => this.handleBonusNumber(input, winningNumbers)); + } + } +} + +export default App; From 3d92fcc6f88e399328d99530e40d7d2c25ac4ed2 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 21:59:16 +0900 Subject: [PATCH 14/20] =?UTF-8?q?refactor:=20app.js=20=EC=9C=84=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 02a1d389e..2a799ed85 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import App from "./App.js"; +import App from "./controllers/App.js"; const app = new App(); await app.run(); From 588943f30c3deb4fa89530a5f5b7da2b369201dd Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 22:00:11 +0900 Subject: [PATCH 15/20] =?UTF-8?q?remove:=20=EC=9C=84=EC=B9=98=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.js | 51 --------------------------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 src/App.js diff --git a/src/App.js b/src/App.js deleted file mode 100644 index dc91f7b67..000000000 --- a/src/App.js +++ /dev/null @@ -1,51 +0,0 @@ -import { Console } from "@woowacourse/mission-utils"; -import LottoManager from "./models/LottoManager"; -import InputValidator from "./utils/InputValidator"; - -class App { - run() { - this.askPurchaseAmount(); - } - - askPurchaseAmount() { - Console.readLineAsync('๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n', (input) => { - try { - const purchaseAmount = InputValidator.validatePurchaseAmount(input); - const lottoManager = new LottoManager(purchaseAmount); - this.askWinningNumbers(lottoManager); - } catch (error) { - this.handleError(error, this.askPurchaseAmount.bind(this)); - } - }); - } - - askWinningNumbers(lottoManager) { - Console.readLineAsync('๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n', (input) => { - try { - const winningNumbers = InputValidator.validateWinningNumbers(input); - this.askBonusNumber(lottoManager, winningNumbers); - } catch (error) { - this.handleError(error, () => this.askWinningNumbers(lottoManager)); - } - }); - } - - askBonusNumber(lottoManager, winningNumbers) { - Console.readLineAsync('๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n', (input) => { - try { - const bonusNumber = InputValidator.validateBonusNumber(input, winningNumbers); - lottoManager.checkResults(winningNumbers, bonusNumber); - Console.close(); - } catch (error) { - this.handleError(error, () => this.askBonusNumber(lottoManager, winningNumbers)); - } - }); - } - - handleError(error, retryFunction) { - Console.print(error.message); - retryFunction(); - } -} - -export default App; From 9c59a953c19ad442b1d45e9567ff6ff42fa1436d Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 22:01:23 +0900 Subject: [PATCH 16/20] =?UTF-8?q?refactor:=20import=20=EB=AC=B8=EC=97=90?= =?UTF-8?q?=EC=84=9C=20js=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/models/Lotto.js | 2 +- src/models/LottoManager.js | 4 ++-- src/utils/InputValidator.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/models/Lotto.js b/src/models/Lotto.js index 9ff27edf2..979eb751f 100644 --- a/src/models/Lotto.js +++ b/src/models/Lotto.js @@ -13,7 +13,7 @@ class Lotto { if (new Set(numbers).size !== numbers.length){ throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” ์ค‘๋ณต ์—†๋Š” 6๊ฐœ์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") } - if (numbers.some(num => isModuleNamespaceObject(num) || num < 1 || num > 45)){ + if (numbers.some(num => num < 1 || num > 45)){ throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") } } diff --git a/src/models/LottoManager.js b/src/models/LottoManager.js index 7c745985e..2f0c40aac 100644 --- a/src/models/LottoManager.js +++ b/src/models/LottoManager.js @@ -1,6 +1,6 @@ -import Lotto from "./Lotto"; +import Lotto from "./Lotto.js"; import { Random } from "@woowacourse/mission-utils"; -import ResultCalculator from "./ResultCalculator"; +import ResultCalculator from "./ResultCalculator.js"; class LottoManager { constructor(purchaseAmount) { diff --git a/src/utils/InputValidator.js b/src/utils/InputValidator.js index dde0b7e15..6a25b3591 100644 --- a/src/utils/InputValidator.js +++ b/src/utils/InputValidator.js @@ -1,4 +1,4 @@ -import Lotto from "../models/Lotto"; +import Lotto from "../models/Lotto.js"; class InputValidator{ static PurchaseAmount(input){ From ff4aa0eca684c1843f12b356069e32644ae09920 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 23:29:10 +0900 Subject: [PATCH 17/20] =?UTF-8?q?refactor:=20indent=20depth=20=EC=B5=9C?= =?UTF-8?q?=EB=8C=80=202=EB=A1=9C=20=EC=A4=84=EC=9D=B4=EA=B8=B0=20bonus=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=EC=97=90=EC=84=9C=203=EC=9D=B4=EC=83=81?= =?UTF-8?q?=EC=9D=B4=20=EB=90=90=EC=97=88=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/InputValidator.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/utils/InputValidator.js b/src/utils/InputValidator.js index 6a25b3591..d84f5c84e 100644 --- a/src/utils/InputValidator.js +++ b/src/utils/InputValidator.js @@ -1,35 +1,42 @@ import Lotto from "../models/Lotto.js"; -class InputValidator{ - static PurchaseAmount(input){ +class InputValidator { + static PurchaseAmount(input) { const amount = parseInt(input, 10); - if(isNaN(amount) || amount % 1000 !== 0){ - throw new Error("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.") + if (isNaN(amount) || amount % 1000 !== 0) { + throw new Error("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); } return amount; } - static validateWinningNumbers(input) { + static WinningNumbers(input) { const numbers = input.split(",").map(Number); - const lotto = new Lotto(numbers); // Lotto ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ ์ˆ˜ํ–‰ + const lotto = new Lotto(numbers); return lotto.getNumbers(); } static bonusNumber(input, winningNumbers) { const numbers = input.split(',').map(Number); + this.checkBonusNumberCount(numbers); + const bonusNumber = numbers[0]; + this.checkBonusNumberValidity(bonusNumber, winningNumbers); + return bonusNumber; + } + + static checkBonusNumberCount(numbers) { if (numbers.length !== 1) { throw new Error("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } - const bonusNumber = numbers[0]; + } + + static checkBonusNumberValidity(bonusNumber, winningNumbers) { if (winningNumbers.includes(bonusNumber)) { throw new Error("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค."); } if (isNaN(bonusNumber) || bonusNumber < 1 || bonusNumber > 45) { throw new Error("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); } - return bonusNumber; } - } -export default InputValidator; \ No newline at end of file +export default InputValidator; From 7a7c9558cbede9d9b9f9fa5aafa4d16335ab308a Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 23:29:42 +0900 Subject: [PATCH 18/20] =?UTF-8?q?test:=20=EC=9E=85=EB=A0=A5=20=EA=B0=92=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/InputValidatorTest.js | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 __tests__/InputValidatorTest.js diff --git a/__tests__/InputValidatorTest.js b/__tests__/InputValidatorTest.js new file mode 100644 index 000000000..87a4a4b8b --- /dev/null +++ b/__tests__/InputValidatorTest.js @@ -0,0 +1,45 @@ +import InputValidator from "../src/utils/InputValidator"; + +describe('์ž…๋ ฅ ๊ฐ’ ์œ ํšจ์„ฑ ํ…Œ์ŠคํŠธ', () => { + test("๊ตฌ์ž… ๊ธˆ์•ก์ด 1000์› ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.PurchaseAmount("1500"); + }).toThrow("[ERROR] ๊ตฌ์ž… ๊ธˆ์•ก์ด 1000 ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค."); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.WinningNumbers("1,2,3,4,5,46"); + }).toThrow("[ERROR]"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ 6๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.WinningNumbers("1,2,3,4,5"); + }).toThrow("[ERROR]"); + }); + + test("๋‹น์ฒจ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์„ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.WinningNumbers("1,2,3,4,5,5"); + }).toThrow("[ERROR]"); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.bonusNumber("7,8", [1, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๊ฐœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.bonusNumber("5", [1, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค."); + }); + + test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", () => { + expect(() => { + InputValidator.bonusNumber("50", [1, 2, 3, 4, 5, 6]); + }).toThrow("[ERROR] ๋กœ๋˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ 45 ์‚ฌ์ด์˜ ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."); + }); +}); From d2c8fa8ff7be6f70fb3ab944fce3779c6b0fa03e Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 23:58:39 +0900 Subject: [PATCH 19/20] =?UTF-8?q?refactor:=20readLineAsync=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/App.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/controllers/App.js b/src/controllers/App.js index 3adf84620..08e9cfe2d 100644 --- a/src/controllers/App.js +++ b/src/controllers/App.js @@ -5,12 +5,13 @@ import ConsoleView from "../views/ConsoleView.js"; class App { async run() { - ConsoleView.askPurchaseAmount((input) => this.handlePurchaseAmout(input)); + ConsoleView.askPurchaseAmount((input) => this.handlePurchaseAmount(input)); } handlePurchaseAmount(input) { try { - const purchaseAmount = InputValidator.validatePurchaseAmount(input); + const purchaseAmount = InputValidator.PurchaseAmount(input); + console.log("๊ตฌ์ž… ๊ธˆ์•ก ์œ ํšจ์„ฑ ํ†ต๊ณผ:", purchaseAmount); // ๋””๋ฒ„๊น… ๋กœ๊ทธ this.lottoManager = new LottoManager(purchaseAmount); ConsoleView.showLottos(this.lottoManager.getLottos()); ConsoleView.askWinningNumbers((input) => this.handleWinningNumbers(input)); @@ -22,7 +23,8 @@ class App { handleWinningNumbers(input) { try { - const winningNumbers = InputValidator.validateWinningNumbers(input); + const winningNumbers = InputValidator.WinningNumbers(input); + console.log("๋‹น์ฒจ ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ํ†ต๊ณผ:", winningNumbers); // ๋””๋ฒ„๊น… ๋กœ๊ทธ ConsoleView.askBonusNumber((input) => this.handleBonusNumber(input, winningNumbers)); } catch (error) { ConsoleView.showError(error); @@ -32,7 +34,8 @@ class App { handleBonusNumber(input, winningNumbers) { try { - const bonusNumber = InputValidator.validateBonusNumber(input); + const bonusNumber = InputValidator.BonusNumber(input); + console.log("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ํ†ต๊ณผ:", bonusNumber); // ๋””๋ฒ„๊น… ๋กœ๊ทธ const results = this.lottoManager.calculateResults(winningNumbers, bonusNumber); ConsoleView.showResults(results); } catch (error) { From 79c706ba56ba7285e4e31d7c405dac88bf3a48c6 Mon Sep 17 00:00:00 2001 From: K0seoyoung Date: Mon, 4 Nov 2024 23:59:33 +0900 Subject: [PATCH 20/20] refactor --- __tests__/ApplicationTest.js | 34 +--------------------------------- src/views/ConsoleView.js | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/__tests__/ApplicationTest.js b/__tests__/ApplicationTest.js index ddf6bf76c..8390d0be4 100644 --- a/__tests__/ApplicationTest.js +++ b/__tests__/ApplicationTest.js @@ -6,7 +6,6 @@ const mockQuestions = (inputs) => { MissionUtils.Console.readLineAsync.mockImplementation(() => { const input = inputs.shift(); - return Promise.resolve(input); }); }; @@ -91,36 +90,5 @@ describe("๋กœ๋˜ ํ…Œ์ŠคํŠธ", () => { }); }); - test("๊ตฌ์ž… ๊ธˆ์•ก์ด 1000์› ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - await runException("1500"); - }); - - test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - await runException("1,2,3,4,5,46"); - }); - - test("๋‹น์ฒจ ๋ฒˆํ˜ธ๊ฐ€ 6๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - await runException("1,2,3,4,5"); - }); - - test("๋‹น์ฒจ ๋ฒˆํ˜ธ์— ์ค‘๋ณต๋œ ์ˆซ์ž๊ฐ€ ์žˆ์„ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - await runException("1,2,3,4,5,5"); - }); - - test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ 1๊ฐœ๊ฐ€ ์•„๋‹ ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - await runException("7,8"); - }); - - test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - const winningNumbers = "1,2,3,4,5,6"; - mockQuestions(["1000", winningNumbers, "5"]); // ๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋กœ ๋‹น์ฒจ ๋ฒˆํ˜ธ์— ํฌํ•จ๋œ 5๋ฅผ ์ž…๋ ฅ - const logSpy = getLogSpy(); - const app = new App(); - await app.run(); - expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("[ERROR] ๋‹น์ฒจ ๋ฒˆํ˜ธ์™€ ์ค‘๋ณต๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.")); - }); - - test("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๊ฐ€ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ", async () => { - await runException("50"); - }); + }); diff --git a/src/views/ConsoleView.js b/src/views/ConsoleView.js index 5c0fe17e6..d811e9023 100644 --- a/src/views/ConsoleView.js +++ b/src/views/ConsoleView.js @@ -1,16 +1,22 @@ import { Console } from "@woowacourse/mission-utils"; const ConsoleView = { - askPurchaseAmount(callback) { - Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", callback); + askPurchaseAmount() { + return new Promise((resolve) => { + Console.readLineAsync("๊ตฌ์ž…๊ธˆ์•ก์„ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", resolve); + }); }, - askWinningNumbers(callback) { - Console.readLineAsync("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", callback); + askWinningNumbers() { + return new Promise((resolve) => { + Console.readLineAsync("๋‹น์ฒจ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", resolve); + }); }, - askBonusNumber(callback) { - Console.readLineAsync("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", callback); + askBonusNumber() { + return new Promise((resolve) => { + Console.readLineAsync("๋ณด๋„ˆ์Šค ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.\n", resolve); + }); }, showLottos(lottos) { @@ -30,7 +36,7 @@ const ConsoleView = { }, showError(error) { - Console.print(error.message); + Console.print(`[ERROR] ${error.message}`); }, };