요청 3: 요청 2 + "핵심 부분은 직접 짜 보고 싶어"
요청문: src/stock.mjs에 todayTasks(items, today) 함수를 만들어 줘. 아침에 카페 사장님이 보는 '오늘 할 일' 목록이야. 유통기한이 지난 것, 3일 안에 끝나는 것, 수량이 minQty보다 적은 것을 한 목록으로 합쳐서 급한 것부터 보여 주고 싶어. today는 'YYYY-MM-DD' 문자열이야. test/stock.test.mjs에 테스트도 추가하고 돌려 봐. 나는 코딩을 배우는 중이라 핵심 부분은 직접 짜 보고 싶어.
diff --git a/src/stock.mjs b/src/stock.mjs
index f81b897..ac6088b 100644
--- a/src/stock.mjs
+++ b/src/stock.mjs
@@ -19,3 +19,25 @@ export function orderList(items) {
.filter((it) => it.qty < it.minQty)
.map((it) => ({ name: it.name, need: it.minQty * 2 - it.qty, unit: it.unit }));
}
+
+// 오늘 할 일 한 건: { name, kind, days }
+// kind: 'expired'(유통기한 지남) | 'expiring'(3일 안에 끝남) | 'low'(minQty 미만)
+// days: 유통기한까지 남은 날 (지났으면 음수, 오늘이면 0)
+// 한 재료가 여러 조건에 걸리면 할 일도 여러 건 (예: 버리기 + 주문하기)
+export function todayTasks(items, today) {
+ const tasks = [];
+ for (const it of items) {
+ const days = daysBetween(today, it.expires);
+ if (days < 0) tasks.push({ name: it.name, kind: 'expired', days });
+ else if (days <= 3) tasks.push({ name: it.name, kind: 'expiring', days });
+ if (it.qty < it.minQty) tasks.push({ name: it.name, kind: 'low', days });
+ }
+ return tasks.sort(compareTasks);
+}
+
+// 급한 할 일이 앞에 오도록 두 할 일을 비교한다.
+// a가 먼저면 음수, b가 먼저면 양수, 순서 상관없으면 0.
+export function compareTasks(a, b) {
+ // TODO(직접 작성): 무엇이 "급한" 것인지 정해서 구현해 보세요.
+ return 0;
+}
diff --git a/test/stock.test.mjs b/test/stock.test.mjs
index 71de632..2cb7abd 100644
--- a/test/stock.test.mjs
+++ b/test/stock.test.mjs
@@ -1,5 +1,5 @@
import assert from 'node:assert/strict';
-import { lowStock, orderList, daysBetween } from '../src/stock.mjs';
+import { lowStock, orderList, daysBetween, todayTasks } from '../src/stock.mjs';
const items = [
{ name: '우유', qty: 3, unit: 'L', expires: '2026-10-20', minQty: 5 },
{ name: '원두', qty: 4, unit: 'kg', expires: '2027-01-10', minQty: 2 },
@@ -8,3 +8,35 @@ assert.deepEqual(lowStock(items), ['우유']);
assert.deepEqual(orderList(items), [{ name: '우유', need: 7, unit: 'L' }]);
assert.equal(daysBetween('2026-10-18', '2026-10-20'), 2);
console.log('기본 테스트 통과');
+
+// todayTasks — data.json과 같은 재고, 오늘은 2026-10-18
+const cafe = [
+ { name: '우유', qty: 3, unit: 'L', expires: '2026-10-20', minQty: 5 },
+ { name: '생크림', qty: 2, unit: '팩', expires: '2026-10-18', minQty: 2 },
+ { name: '딸기', qty: 1, unit: 'kg', expires: '2026-10-17', minQty: 1 },
+ { name: '원두', qty: 4, unit: 'kg', expires: '2027-01-10', minQty: 2 },
+ { name: '바닐라 시럽', qty: 1, unit: '병', expires: '2026-10-21', minQty: 1 },
+ { name: '치즈케이크', qty: 0, unit: '판', expires: '2026-10-19', minQty: 1 },
+];
+const tasks = todayTasks(cafe, '2026-10-18');
+const key = (t) => `${t.name}:${t.kind}`;
+
+// 1) 무엇이 목록에 들어가는지 (순서 무관)
+assert.deepEqual(tasks.map(key).sort(), [
+ '딸기:expired', // 어제 지남
+ '바닐라 시럽:expiring', // 딱 3일 남음 → 포함
+ '생크림:expiring', // 오늘까지 → 아직 지난 건 아님
+ '우유:expiring',
+ '우유:low',
+ '치즈케이크:expiring',
+ '치즈케이크:low', // 한 재료가 두 가지 할 일
+].sort());
+assert.ok(!tasks.some((t) => t.name === '원두'), '여유 있는 재료는 빠져야 함');
+assert.deepEqual(todayTasks([], '2026-10-18'), []);
+console.log('todayTasks 항목 테스트 통과');
+
+// 2) 급한 순서 (compareTasks를 구현하면 통과해야 함)
+assert.equal(key(tasks[0]), '딸기:expired', '지난 것이 맨 앞');
+const expiring = tasks.filter((t) => t.kind === 'expiring').map((t) => t.name);
+assert.deepEqual(expiring, ['생크림', '치즈케이크', '우유', '바닐라 시럽'], '남은 날이 적은 것부터');
+console.log('todayTasks 순서 테스트 통과');