라이프스타일

할 일 필터 구현

start에서 Active/Completed 필터를 구현하고 데이터 형식과 정상 및 경계 사례를 검증합니다.

읽는 데 약 14분 · 실습 30 분

직접 제작한 흐름도이며 제품 화면이 아닙니다.
사진: Mokaair (© Mokaair)
전체 목차:Codex 학습 센터: 전체 튜토리얼 목차

실습 · Desktop / CLI / VS Code / JetBrains / cloud

이 글의 목차
  1. 목표와 준비
  2. 1단계: 미완성 기준 만들기
  3. 2단계: 사례로 완료 조건 고정
  4. 3단계: 최소 기능 변경 구현
  5. 4단계: 데이터, 화면, 범위 검증
  6. 반례 확인: 전체 개수와 같은 제목의 작업
  7. 실패 해결, 전달과 복원

목표와 준비

이 단락의 학습 자료:

은 계획 검토가 중심이었습니다. 이번에는 실패에서 완성까지 증거를 봅니다. 한 줄 표시뿐 아니라 숨겨진 데이터 유지/순서/같은 제목의 식별을 확인합니다.

1단계: 미완성 기준 만들기

ZIP start 다섯 파일을 새 codex-feature-lab으로 복사합니다. expected/이전 수정을 사용하지 않고 Windows PowerShell은 Get-Location, macOS/Linux는 pwd로 경로를 확인합니다. 원본을 남기고 기존 테스트 2통과1실패를 확인합니다.

터미널: 기존 테스트 · sh
node --test core.test.mjs

선택지/change 이벤트가 이미 있음을 확인합니다. 부족한 것은 visibleTasks이며 UI 재작성/framework는 필요 없습니다. 프런트 파일명이라도 변경 시작이 화면인 것은 아닙니다. 실패를 남기고 assertion 삭제를 수정으로 삼지 않습니다.

2단계: 사례로 완료 조건 고정

다음을 filter.test.mjs로 추가하고 기존 테스트는 덮어쓰지 않습니다. 동명 Read의 a/c ID와 순서, All 전체 유지, 세 빈 목록을 확인합니다. 동결 입력으로 직접 변경도 쉽게 탐지합니다.

새 파일: filter.test.mjs · javascript
import test from "node:test";
import assert from "node:assert/strict";
import { visibleTasks } from "./core.mjs";

const tasks = Object.freeze([
  Object.freeze({ id: "a", title: "Read", completed: true }),
  Object.freeze({ id: "b", title: "Build", completed: false }),
  Object.freeze({ id: "c", title: "Read", completed: true }),
]);
const ids = (items) => items.map((item) => item.id);

test("filters preserve identity and order with duplicate titles", () => {
  assert.deepEqual(ids(visibleTasks(tasks, "active")), ["b"]);
  assert.deepEqual(ids(visibleTasks(tasks, "completed")), ["a", "c"]);
  assert.deepEqual(ids(tasks), ["a", "b", "c"]);
});

test("All retains every task without changing its completion state", () => {
  assert.deepEqual(ids(visibleTasks(tasks, "all")), ["a", "b", "c"]);
  assert.deepEqual(tasks.map((task) => task.completed), [true, false, true]);
});

test("every filter accepts an empty list", () => {
  for (const filter of ["all", "active", "completed"]) {
    assert.deepEqual(visibleTasks(Object.freeze([]), filter), []);
  }
});
터미널: 기존 및 추가 테스트 · sh
node --test core.test.mjs filter.test.mjs

start는 4통과2실패이며 기존 필터와 새 첫 테스트가 실패합니다. All/빈 입력은 원래 통과합니다. 새 테스트 탐지력을 확인합니다. 구문/파일 누락은 준비 오류로 예상한 기능 실패와 구분합니다.

3단계: 최소 기능 변경 구현

데스크톱은 codex-feature-lab을 로컬 프로젝트로 추가해 작업을 만들고, CLI는 같은 실습 경로에서 codex를 실행합니다. 경로를 확인한 뒤 전체 요청을 보냅니다. 이제 core.mjs만 변경 가능하며 새 테스트도 고정입니다. 다른 변경은 구체적 이유를 요청하고 전체 정리를 맡기지 않습니다. 글만으로 추측하지 말고 테스트를 읽게 합니다.

Codex 프롬프트: 필터 구현 · text
Implement the missing filters in this codex-feature-lab.
Read index.html, app.js, core.mjs, core.test.mjs and filter.test.mjs first.
Modify only visibleTasks in core.mjs: all keeps every task, active returns unfinished tasks, completed returns finished tasks. Preserve original order, IDs and input data. Do not edit tests, add dependencies or change UI/storage.
Run node --test core.test.mjs filter.test.mjs. Inspect the final diff and report actual results and any unperformed browser checks. Stop and explain if the requested scope cannot satisfy the tests. Do not publish or deploy.

filter는 원래 객체를 고른 새 배열을 만들고 객체를 바꾸지 않습니다. All은 원배열을 반환해도 되며 불필요한 깊은 복사는 요구하지 않습니다. !task.completed와 task.completed 차이를 이해해 확인합니다.

참고 수정: core.mjs의 visibleTasks · javascript
export function visibleTasks(tasks, filter) {
  if (filter === "active") return tasks.filter((task) => !task.completed);
  if (filter === "completed") return tasks.filter((task) => task.completed);
  return tasks;
}

4단계: 데이터, 화면, 범위 검증

같은 명령으로 6통과를 확인합니다. 원래 다섯 파일은 core.mjs만 변경, filter.test.mjs만 추가입니다. 삭제된 assertion은 복원해 재시험하고 무관한 추가도 확인합니다. 구현 완료와 검수 완료는 따로 기록합니다.

실습에서 Windows는 py -m http.server 4173 --bind 127.0.0.1, macOS/Linux는 python3로 시작하고 http://127.0.0.1:4173을 엽니다. 자신의 이전 미리 보기 충돌만 해결합니다. HTML 직접 열기는 module 제한이 있으므로 이전 화면이면 경로/새로 고침을 확인합니다.

필요한 이전 실습 기록을 보존하고 About this exercise의 Reset practice data를 누릅니다. All tasks에서 빈 목록을 확인한 뒤 Read/Build/Read를 추가하고 첫째/셋째를 완료합니다. 표와 All 전체를 확인하고 동명은 원래 위치/상태로 구분합니다. 첫째 완료를 해제하면 Completed는 원래 셋째만, Active는 원래 첫째와 Build입니다. All과 새로 고침으로 저장도 확인합니다.

확인점AllActiveCompleted
원래 첫째/셋째 완료Read, Build, ReadBuildRead, Read
원래 첫째 완료 해제Read, Build, ReadRead, Build원래 셋째 Read
실습 데이터 리셋 후비어 있음비어 있음비어 있음

반례 확인: 전체 개수와 같은 제목의 작업

Read, Build, Read 세 개 중 첫 번째와 세 번째를 완료하면 All/Active/Completed의 표시 행은 3/1/2지만 개수 표시는 모두 1 active / 3 total이어야 합니다. 첫 번째 완료를 취소하면 행은 3/2/1, 개수 표시는 모두 2 active / 3 total이 됩니다. app.js는 전체 tasks를 셉니다. 핵심 필터 테스트 통과만으로 화면 개수를 검증할 수 없으므로 실제 UI 결과를 별도로 기록합니다.

여섯 테스트가 통과하면 수정된 core.mjs를 연습 폴더 밖에 복사해 둡니다. Completed 분기만 아래 잘못된 행으로 임시 교체하고 두 테스트 파일을 실행합니다. 완료 상태로 필터링한 뒤 title로 중복을 제거하여 ID c가 사라지므로 5개 통과, 1개 실패가 예상됩니다. 원래 테스트 세 개만 실행하면 두 작업의 제목이 달라 여전히 통과합니다. 실패한 실제 ID를 확인한 뒤 저장한 수정본으로 core.mjs를 즉시 복원하면 테스트 파일을 바꾸지 않고 6개 통과, 0개 실패로 돌아와야 합니다.

의도한 오류: core.mjs의 Completed 분기를 임시 교체 · javascript
if (filter === "completed") return tasks.filter((task) => task.completed).filter((task, index, selected) => selected.findIndex((other) => other.title === task.title) === index);

반례가 통과하면 filter.test.mjs가 실행됐는지, 세 번째 작업이 다른 ID의 Read인지, 수정한 복사본을 테스트했는지 확인합니다. 구문 또는 모듈 누락 오류라면 파일을 복원하고 교체 위치를 확인하세요. 이는 중복 제거 결함을 잡았다는 증거가 아닙니다. 이 연습은 테스트 범위를 확인하며 UI 수정이나 오류 버전 커밋은 필요하지 않습니다.

실패 해결, 전달과 복원

사라지면 선택 결과를 tasks/저장에 다시 넣었는지, 동명 오류면 ID 대신 title을 썼는지 봅니다. 핵심 통과인데 화면이 오래되면 import/HTTP/캐시를 확인하고 표의 실패 행/재현 순서를 전달합니다.

6개 테스트/화면 사례/최종 차이/미실행을 전달합니다. 반복은 미리 보기 종료 후 core.mjs만 start로 복원하며 새 테스트 포함은 4통과2실패, 기존만은 2통과1실패입니다. 명령 차이를 구분합니다. 그림 1은 사례 고정, 2는 제한 변경, 3은 회귀/복원이며 독자의 Codex 실행을 주장하지 않습니다.

직접 제작한 흐름도이며 제품 화면이 아닙니다.
직접 제작한 흐름도이며 제품 화면이 아닙니다. · 사진: Mokaair (© Mokaair)
자세한 설명 보기

Three numbered stages: identify the starting point, perform the exercise, and verify the result. Original illustration, not a product screenshot.

Completed는 Read 두 개를 표시하고 전체 작업은 세 개로 유지됩니다.
참고 수정의 실제 화면입니다. Completed에 서로 다른 ID의 Read 두 개가 남고 전체는 1 active / 3 total입니다. Windows / Edge 153.0.4234.32, 2026-09-14. 가상 데이터와 반응형 화면이며 실제 휴대전화가 아닙니다. 실습 사이트로 Codex UI나 모델 실행 증거가 아닙니다. · 사진: Mokaair (© Mokaair)
Completed는 Read 두 개를 표시하고 전체 작업은 세 개로 유지됩니다.
참고 수정의 실제 화면입니다. Completed에 서로 다른 ID의 Read 두 개가 남고 전체는 1 active / 3 total입니다. Windows / Edge 153.0.4234.32, 2026-09-14. 가상 데이터와 반응형 화면이며 실제 휴대전화가 아닙니다. 실습 사이트로 Codex UI나 모델 실행 증거가 아닙니다. · 사진: Mokaair (© Mokaair)

전체 목차

  • 라이프스타일

    Codex 학습 센터: 전체 튜토리얼 목차

    설치와 첫 작업부터 MD 지침과 고급 연동까지 60개 강의, 열 개 단원을 계획합니다. 수준, 환경, 목표, 명령으로 다음 글을 찾고 미게시 항목의 상태를 확인할 수 있습니다.

  • 라이프스타일

    Worktree와 작업 격리

    Worktree는 하나의 Git 저장소에 다른 브랜치의 작업 폴더를 만듭니다. 파일이 분리되어도 DB, 포트와 외부 서비스는 공유될 수 있습니다.

  • 라이프스타일

    실습: 작은 웹사이트 만들기

    brief.md에서 Small Steps 할 일 사이트를 계획하고 추가·완료·삭제·필터·로컬 저장을 구현합니다. HTML·CSS·데이터 함수·화면 이벤트·시험을 분리하고 Node와 브라우저로 검증한 뒤 재시작·복원 인계 기록을 남깁니다.

  • 라이프스타일

    사용량과 효율: 재작업 줄이기

    조건, 모델 선택, 시간, 결과를 기록해 불필요한 재시도와 과도한 문맥을 줄입니다.

최신 여행 소식·가이드

출처

라이프스타일