-
Notifications
You must be signed in to change notification settings - Fork 4
X tdh #1510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
X tdh #1510
Changes from all commits
Commits
Show all changes
291 commits
Select commit
Hold shift + click to select a range
047defc
wip
simo6529 33c6801
wip
simo6529 032fc54
wip
simo6529 c5464cf
wip
simo6529 c86f2ba
wip
simo6529 998cf59
wip
simo6529 81c6497
wip
simo6529 6b63166
wip
simo6529 6fcc746
wip
simo6529 0538099
wip
simo6529 8201fba
wip
simo6529 af2fda8
wip
simo6529 87a2827
wip
simo6529 9a10321
wip
simo6529 742f732
wip
simo6529 d5c5dd8
wip
simo6529 73cc336
wip
simo6529 07d47de
wip
simo6529 15cf065
wip
simo6529 5dd45bc
wip
simo6529 6dac293
wip
simo6529 152673e
wip
simo6529 cd788f3
wip
simo6529 d7a1cec
wip
simo6529 fb67147
wip
simo6529 5a0b19f
wip
simo6529 d9cf437
wip
simo6529 fd6084e
wip
simo6529 59a526c
wip
simo6529 56bb055
wip
simo6529 815bb96
wip
simo6529 f1c9cca
wip
simo6529 6cea667
wip
simo6529 99e2e7d
wip
simo6529 de5bb1c
wip
simo6529 ba005eb
wip
simo6529 61c1dee
wip
simo6529 db5cd7c
wip
simo6529 c2619df
wip
simo6529 3fc8443
wip
simo6529 4bf24f9
wip
simo6529 7b66a36
wip
simo6529 e1f7f0e
wip
simo6529 6a8a7d9
wip
simo6529 e0c8ea8
wip
simo6529 8164819
wip
simo6529 ea2c197
wip
simo6529 0197e0b
wip
simo6529 533ad56
wip
simo6529 c9f4a48
wip
simo6529 3e7ec41
wip
simo6529 82128c0
wip
simo6529 722b5d9
wip
simo6529 fd227e3
Merge branch 'main' into xTDH
simo6529 c30eefd
Merge branch 'main' into xTDH
simo6529 33710a4
Merge branch 'main' into xTDH
simo6529 5462066
wip
simo6529 2bbd6b7
wip
simo6529 38786a7
wip
simo6529 238c88e
wip
simo6529 c8f1c44
Merge branch 'main' into xTDH
simo6529 dd85be3
wip
simo6529 c90cd90
wip
simo6529 09769ba
wip
simo6529 ae79b55
wip
simo6529 160aa92
wip
simo6529 636b23d
wip
simo6529 42a4e4f
Merge branch 'main' into xTDH
simo6529 1864fde
wip
simo6529 32886d8
Merge branch 'main' into xTDH
simo6529 ca9121c
Merge branch 'main' into xTDH
simo6529 d1f809a
Merge branch 'main' into xTDH
simo6529 24140bb
wip
simo6529 1282087
wip
simo6529 2c780b6
wip
simo6529 d12d098
wip
simo6529 c96801d
wip
simo6529 05ba7da
wip
simo6529 dff745f
wip
simo6529 b4ad619
wip
simo6529 17830da
wip
simo6529 cb88c5d
wip
simo6529 786c03f
wip
simo6529 66df3e3
wip
simo6529 8230da8
wip
simo6529 7b9fbff
wip
simo6529 6f6ff28
wip
simo6529 0671edd
wip
simo6529 ef3ee7c
wip
simo6529 f0de6ff
Merge branch 'main' into xTDH
simo6529 49046fd
wip
simo6529 6327ad5
Merge branch 'main' into xTDH
simo6529 a2323ba
Merge branch 'main' into xTDH
simo6529 8f1373f
wip
simo6529 01f27a9
wip
simo6529 2f6b0e2
wip
simo6529 f4dc71f
wip
simo6529 ae2d5ce
wip
simo6529 55b7604
wip
simo6529 c641fb9
wip
simo6529 871520c
Merge branch 'main' into xTDH
simo6529 8a6c7d3
wip
simo6529 be280bf
wip
simo6529 8c161d9
wip
simo6529 6a08edb
wip
simo6529 f6ecd5e
wip
simo6529 78bcb23
wip
simo6529 266305d
wip
simo6529 1d2790d
Merge branch 'main' into xTDH
simo6529 ca37420
wip
simo6529 fe5b1ff
wip
simo6529 824301e
wip
simo6529 30e8ffd
wip
simo6529 2d977da
wip
simo6529 6f73834
wip
simo6529 1834ad3
wip
simo6529 4238ce1
wip
simo6529 9bdcdef
wip
simo6529 774a5a9
wip
simo6529 b309010
wip
simo6529 6746420
wip
simo6529 dbed6cc
wip
simo6529 67282ef
wip
simo6529 5bb685e
wip
simo6529 36ae376
wip
simo6529 45034d3
wip
simo6529 4bd79a5
wip
simo6529 e7211c2
wip
simo6529 f62a3d2
wip
simo6529 4a8021e
wip
simo6529 4ddaa6d
wip
simo6529 fea7dbd
Merge branch 'main' into xTDH
simo6529 6bdef47
wip
simo6529 c7dab64
wip
simo6529 21f8467
wip
simo6529 c3289fa
wip
simo6529 f5356a0
wip
simo6529 b0cdaac
wip
simo6529 efc72c1
wip
simo6529 f53636e
wip
simo6529 704f24c
wip
simo6529 6b41163
Merge branch 'main' into xTDH
simo6529 755455a
wip
simo6529 9aac7b6
wip
simo6529 6eb177d
wip
simo6529 b9840e7
wip
simo6529 c58d21c
wip
simo6529 80289e6
wip
simo6529 fccf176
wip
simo6529 611dc17
wip
simo6529 5337de8
Merge branch 'main' into xTDH
simo6529 9040e75
wip
simo6529 156d310
wip
simo6529 d9cf862
wip
simo6529 5871101
wip
simo6529 6bc9dc8
wip
simo6529 6c14c26
wip
simo6529 25ed0fe
wip
simo6529 a82036e
Merge branch 'main' into xTDH
simo6529 00157c9
wip
simo6529 96a3896
Merge branch 'main' into xTDH
simo6529 1f9db66
wip
simo6529 9f59a15
wip
simo6529 b44e62c
wip
simo6529 99ad1ed
wip
simo6529 da571b1
wip
simo6529 3bbb008
wip
simo6529 df17fbf
wip
simo6529 90c2e49
wip
simo6529 ef4682c
wip
simo6529 43cf624
wip
simo6529 5496618
wip
simo6529 919f0a5
wip
simo6529 b344d1b
wip
simo6529 754ac11
wip
simo6529 663a82f
Merge branch 'main' into xTDH
simo6529 dd42697
wip
simo6529 6bde91c
wip
simo6529 ac863ed
wip
simo6529 92e4d63
wip
simo6529 9a64411
wip
simo6529 9f029d3
wip
simo6529 cb56d89
wip
simo6529 15498ba
wip
simo6529 3691b2f
wip
simo6529 ad33a72
wip
simo6529 88102b4
wip
simo6529 2e23535
wip
simo6529 690672c
wip
simo6529 694b4b4
wip
simo6529 b286821
wip
simo6529 8624379
wip
simo6529 200e953
wip
simo6529 867370d
wip
simo6529 6dc8c6f
wip
simo6529 18825b3
wip
simo6529 70bc4f0
wip
simo6529 270880d
Merge branch 'main' into xTDH
simo6529 7a749fe
wip
simo6529 7c08d3c
Merge branch 'main' into xTDH
simo6529 812fce6
wip
simo6529 d007575
wip
simo6529 418aa7f
wip
simo6529 b08f160
wip
simo6529 f1d4e35
wip
simo6529 a0fa9a0
wip
simo6529 f8855d3
wip
simo6529 e1784f1
wip
simo6529 e0bd253
wip
simo6529 67e944d
wip
simo6529 e31b5e5
wip
simo6529 201d50c
wip
simo6529 ab617fa
wip
simo6529 aa4b7fe
Merge branch 'main' into xTDH
simo6529 fd27404
wip
simo6529 9fcfbb6
wip
simo6529 2fda418
wip
simo6529 690c10a
wip
simo6529 0b20e7f
wip
simo6529 ee35b63
wip
simo6529 2c374c4
wip
simo6529 a3eb847
wip
ragnep cd51ff1
Merge branch 'xTDH-beta-badge' into xTDH
ragnep 9856ee1
wip
simo6529 b54603e
wip
ragnep 3928517
wip
simo6529 25070ef
wip
simo6529 ea31f94
wip
simo6529 7cdcd1b
wip
simo6529 574252a
wip
simo6529 12744b5
wip
simo6529 93b6c4a
wip
ragnep 38c8948
Merge branch 'xTDH' into xtdh-responsiveness
ragnep 12e0a45
wip
simo6529 f6f84dd
wip
simo6529 042ec50
wip
simo6529 3a5301d
wip
ragnep 4d49e7f
Merge branch 'xTDH' into xtdh-responsiveness
ragnep 8d5e950
wip
ragnep 5949f91
wip
simo6529 f1125ed
wip
ragnep 3f52692
wip
simo6529 af0c77b
wip
ragnep 949a26b
Merge branch 'xtdh-responsiveness' into xTDH
ragnep 7da7c61
wip
ragnep b1598a5
Merge branch 'main' into xTDH
simo6529 a08ae02
wip
simo6529 6cd0959
wip
simo6529 4281491
wip
ragnep ca27b2e
wip
ragnep File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,219 @@ | ||
| --- | ||
|
|
||
| # GEMINI.md – Agent Playbook for Next.js Frontend | ||
|
|
||
| PS! DO NOT RUN TESTS/BUILD/LINT IF NOT EXPLICITLY ASKED | ||
|
|
||
| This document is the contract for any coding agent (e.g. codex‑cli) working in this repo. It describes **how to run checks**, **what “good” looks like**, and the **modernization rules** tied to our stack (Next.js 16 + React 19.2). | ||
|
|
||
| --- | ||
|
|
||
| ## Quickstart | ||
|
|
||
| ### Setup | ||
|
|
||
| ```bash | ||
| npm install | ||
| ``` | ||
|
|
||
| ### Test | ||
|
|
||
| ```bash | ||
| npm run test | ||
| ``` | ||
|
|
||
| ### Lint & Format | ||
|
|
||
| ```bash | ||
| npm run lint | ||
| ``` | ||
|
|
||
| ### Type Check | ||
|
|
||
| ```bash | ||
| npm run type-check | ||
| ``` | ||
|
|
||
| > **Note on Next.js 16 & ESLint:** Starting with Next 16, `next lint` is removed. Use the ESLint CLI driven by `eslint-config-next` (flat config). Remove any `eslint` options from `next.config.*`. ([Next.js][1]) | ||
|
|
||
| --- | ||
|
|
||
| ## Programmatic Checks (must pass before completing any task) | ||
|
|
||
| Run all the following (unless you are only editing docs or non-code, in which case tests may be skipped): | ||
|
|
||
| ```bash | ||
| npm run test | ||
| npm run lint | ||
| npm run type-check | ||
| ``` | ||
|
|
||
| For small changes, you may run a faster coverage subset: | ||
|
|
||
| ```bash | ||
| npm run test:cov:changed | ||
| ``` | ||
|
|
||
| * `npm run test`: Executes all Jest tests and enforces **≥ 80% line coverage for files changed since `main`**. Fails if tests fail or coverage threshold is not met. | ||
| * `npm run test:cov:changed`: Jest on changed files only; still enforces the 80% threshold. | ||
| * `npm run lint`: Code must satisfy ESLint (Next’s Core Web Vitals + React Hooks). | ||
| * `npm run type-check`: Must pass `tsc --noEmit`. | ||
|
|
||
| If tests fail due to coverage, write meaningful tests until coverage ≥ 80%. If a test fails functionally, fix root cause (code or test) and re‑run until green. | ||
|
|
||
| --- | ||
|
|
||
| ## MCP: Enable Next.js DevTools for Agents (highly recommended) | ||
|
|
||
| Enable the **Next DevTools MCP server** so agents can query live routes, errors, logs, and Server Actions from a running `next dev`: | ||
|
|
||
| ```jsonc | ||
| // .mcp.json (project root) | ||
| { | ||
| "mcpServers": { | ||
| "next-devtools": { | ||
| "command": "npx", | ||
| "args": ["-y", "next-devtools-mcp@latest"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| * When `next dev` is running, `next-devtools-mcp` auto‑discovers and connects to the app. | ||
| * Available tools include: `get_errors`, `get_logs`, `get_page_metadata`, `get_project_metadata`, and `get_server_action_by_id`. Agents should use them **before** changing code when fixes might affect routing, hydration, or Server Actions. ([Next.js][2]) | ||
|
|
||
| --- | ||
|
|
||
| ## Agent Operating Principles | ||
|
|
||
| 1. **Fix with modernization** (no “make the warning go away”). Don’t add `// eslint-disable` unless explicitly instructed. Prefer refactors aligned with **React 19.2**, **React Compiler**, and **Next.js 16** conventions. ([React][3]) | ||
| 2. **Prefer Server over Client** where possible. Data reads: Server Components with inline fetches. Mutations: Server Functions / Server Actions (`'use server'`). Avoid client Effects for data fetching unless truly needed. ([Next.js][4]) | ||
| 3. **Effects are last resort.** If there’s no external system, remove the Effect and compute during render. If you must listen to external events but need the latest props/state without re‑running the Effect, use **`useEffectEvent`**. ([React][5]) | ||
| 4. **Use framework APIs:** internal links → `<Link>`, images → `next/image`, and adopt Next’s ESLint rules (Core Web Vitals). ([Next.js][1]) | ||
| 5. **Cache explicitly where it helps.** With Next 16, caching is **opt-in** via the `"use cache"` directive and related Cache Components features (see below). ([Next.js][6]) | ||
| 6. **Commit small, surgical diffs.** If you uncover a broader refactor, open a follow‑up ticket rather than ballooning a lint‑fix PR. | ||
|
|
||
| --- | ||
|
|
||
| ## Next.js 16: What this means for agents | ||
|
|
||
| * **Proxy instead of Middleware:** `middleware.ts` is **renamed to** `proxy.ts` (Node runtime). If you touch request‑boundary logic, ensure the file and exported function are named `proxy`. Legacy `middleware.ts` still exists for edge‑only cases but our default is `proxy.ts`. ([Next.js][6]) | ||
| * **ESLint changes:** `next lint` removed; use ESLint CLI with `eslint-config-next` flat config. ([Next.js][1]) | ||
| * **React Compiler (stable):** Supported in Next 16. It **auto‑memoizes components**, reducing the need for manual `useMemo`/`useCallback`. You may see lints originating from the compiler surfaced via `eslint-plugin-react-hooks`. Consider enabling the compiler in `next.config.ts` when CI is green: | ||
|
|
||
| ```ts | ||
| // next.config.ts | ||
| export default { reactCompiler: true } | ||
| ``` | ||
|
|
||
| ([Next.js][6]) | ||
| * **Cache Components / `"use cache"`:** Caching is explicit. You can place `"use cache"` at the top of a Server Component, route, or function to opt-in caching; configure `cacheComponents: true` in `next.config.ts` as needed. Prefer tagging/expiration APIs over ad-hoc hacks. ([Next.js][7]) | ||
| * **Turbopack default:** Dev and build use Turbopack by default in v16—don’t pass `--turbopack`. ([Next.js][8]) | ||
|
|
||
| --- | ||
|
|
||
| ## React 19.2: Effects guidance for agents | ||
|
|
||
| * **Remove unnecessary Effects.** If the Effect’s only job is to derive or sync internal state, calculate during render or use `useMemo` if truly expensive (the **Compiler** may remove that need). ([React][5]) | ||
| * **Use `useEffectEvent`** for non‑reactive logic inside Effects so you can read the latest props/state without turning them into dependencies or causing needless re‑runs. Keep the Effect’s dependency array minimal and stable. ([React][3]) | ||
| * **Let lints guide you.** `eslint-plugin-react-hooks` v6+ ships flat-config presets and **compiler‑powered** rules; don’t suppress—refactor. ([React][9]) | ||
|
|
||
| **Example (pattern to prefer):** | ||
|
|
||
| ```tsx | ||
| // BEFORE: re-runs on theme change, reconnects unnecessarily | ||
| useEffect(() => { | ||
| const c = connect(roomId) | ||
| c.on('connected', () => showToast('Connected!', theme)) | ||
| return () => c.disconnect() | ||
| }, [roomId, theme]) | ||
|
|
||
| // AFTER: stable effect with an Effect Event | ||
| import { useEffectEvent } from 'react' | ||
| const onConnected = useEffectEvent(() => showToast('Connected!', theme)) | ||
| useEffect(() => { | ||
| const c = connect(roomId) | ||
| c.on('connected', onConnected) | ||
| return () => c.disconnect() | ||
| }, [roomId]) | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Lint Rules → Modern Fixes (cheat‑sheet) | ||
|
|
||
| * **`react-hooks/exhaustive-deps`** | ||
|
|
||
| * If the Effect only derives state → **remove the Effect** and compute during render. | ||
| * If listening to an external system and you need fresh props/state → wrap non‑reactive logic in **`useEffectEvent`**. ([React][5]) | ||
|
|
||
| * **`@next/next/no-img-element`** → replace `<img>` with `<Image />` from `next/image`. ([Next.js][1]) | ||
|
|
||
| * **`@next/next/no-html-link-for-pages`** → use `<Link href="/path">` for internal navigation. ([Next.js][1]) | ||
|
|
||
| * **Data fetching in client Effects** → move reads to **Server Components**; mutations go through **Server Functions / Server Actions** (`'use server'`). ([Next.js][4]) | ||
|
|
||
| * **Request boundary logic** touching legacy `middleware.ts` → **rename to `proxy.ts`** and export `proxy`. ([Next.js][6]) | ||
|
|
||
| --- | ||
|
|
||
| ## Next.js Directory Structure | ||
|
|
||
| All production routes live under the App Router (`app/`). Add new routes there. | ||
|
|
||
| Routes in `app/` should export `generateMetadata` using our helper: | ||
|
|
||
| ```ts | ||
| import { getAppMetadata } from "@/components/providers/metadata"; | ||
| import type { Metadata } from "next"; | ||
|
|
||
| export async function generateMetadata(): Promise<Metadata> { | ||
| return getAppMetadata({ title: "My Page" }); | ||
| } | ||
| ``` | ||
|
|
||
| If you add or modify `proxy.ts`, keep it at the root (or `src/`) alongside `app/`/`pages/` and export `proxy`. ([Next.js][10]) | ||
|
|
||
| --- | ||
|
|
||
| ## Coding Conventions | ||
|
|
||
| * TypeScript + React functional components with hooks. | ||
| * Follow existing code style and naming conventions. | ||
| * Maintain clean code standards (measured by SonarQube). | ||
| * Tests live in `__tests__/` or `ComponentName.test.tsx`. | ||
| * Mock external dependencies and APIs in tests. | ||
| * When parsing Seize URLs (or similar), **do not** fall back to placeholder origins; fail fast if base origin is unavailable. | ||
|
|
||
| --- | ||
|
|
||
| ## Commit Guidelines | ||
|
|
||
| * Use **Conventional Commits** (`feat:`, `fix:`, etc.). | ||
| * **Do not squash**; keep a clear history. | ||
| * One logical change per commit. | ||
| * **DCO required** on every commit: | ||
|
|
||
| ```text | ||
| Signed-off-by: Your Full Name <your-GH-ID+username@users.noreply.github.com> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### Why the policy | ||
|
|
||
| * **Next DevTools MCP** gives agents live, app‑specific context (routes, errors, actions) for accurate fixes. ([Next.js][2]) | ||
| * **React 19.2 + Hooks v6** align lints with modern patterns, including `useEffectEvent` and compiler‑powered guidance. ([React][3]) | ||
| * **Next 16** introduces explicit caching (`"use cache"`), a clearer network boundary (`proxy.ts`), and stable React Compiler support, so “lint fixes” often become meaningful improvements. ([Next.js][6]) | ||
|
|
||
|
|
||
| [1]: https://nextjs.org/docs/app/api-reference/config/eslint "Configuration: ESLint | Next.js" | ||
| [2]: https://nextjs.org/docs/app/guides/mcp "Guides: Next.js MCP Server | Next.js" | ||
| [3]: https://react.dev/reference/react/experimental_useEffectEvent "useEffectEvent – React" | ||
| [4]: https://nextjs.org/docs/app/getting-started/server-and-client-components?utm_source=chatgpt.com "Getting Started: Server and Client Components" | ||
| [5]: https://react.dev/learn/you-might-not-need-an-effect "You Might Not Need an Effect – React" | ||
| [6]: https://nextjs.org/blog/next-16?utm_source=chatgpt.com "Next.js 16" | ||
| [7]: https://nextjs.org/docs/app/api-reference/directives/use-cache?utm_source=chatgpt.com "Directives: use cache" | ||
| [8]: https://nextjs.org/docs/app/guides/upgrading/version-16?utm_source=chatgpt.com "Upgrading: Version 16" | ||
| [9]: https://react.dev/blog/2025/10/01/react-19-2?utm_source=chatgpt.com "React 19.2" | ||
| [10]: https://nextjs.org/docs/app/getting-started/proxy?utm_source=chatgpt.com "Getting Started: Proxy" |
This file contains hidden or 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 |
|---|---|---|
| @@ -1,66 +1,134 @@ | ||
| # Test Guidelines for Codex | ||
| # Codex Testing Guidelines | ||
|
|
||
| ## Purpose and Structure | ||
| ## Purpose & Structure | ||
|
|
||
| The `__tests__` directory contains Jest test suites for this Next.js project. Tests mirror the source folders such as `components`, `contexts`, `hooks` and `utils` to keep structure familiar. Integration tests for API routes live under `app/api`. Fixtures and helpers used across tests reside in their respective subfolders. | ||
| * All tests live in `__tests__`, mirroring source folders (`components`, `contexts`, `hooks`, `utils`). | ||
| * API integration tests: `app/api`. | ||
| * Shared fixtures & helpers: relevant subfolders. | ||
| * Jest automatically picks up mocks from `__mocks__`. | ||
|
|
||
| ## Testing Frameworks and Tools | ||
| ## Tools | ||
|
|
||
| - **Jest** with the `ts-jest` preset for TypeScript support. | ||
| - **@testing-library/react** and **@testing-library/user-event** for React component tests. | ||
| - Additional mocks live in `__mocks__` and are automatically picked up by Jest. | ||
| * **Jest** + `ts-jest` (TypeScript). | ||
| * **@testing-library/react** + **user-event** (React tests). | ||
| * Coverage reports in `coverage/`. | ||
|
|
||
| ## Test Writing Guidelines | ||
| ## Writing Tests | ||
|
|
||
| - Prioritise meaningful coverage that validates business requirements over achieving raw coverage numbers. | ||
| - Use the **Arrange – Act – Assert** pattern and keep assertions focused on behaviour, not implementation details. | ||
| - Give each test a clear, descriptive name that conveys the scenario and expected outcome. | ||
| - Tests should remain independent, deterministic and fast. | ||
| * Focus on business value, not raw coverage. | ||
| * Follow **Arrange – Act – Assert**. | ||
| * One behaviour per test; clear, descriptive names. | ||
| * Keep tests independent, deterministic, and fast. | ||
| * Use realistic data. | ||
|
|
||
| ## Test Categorisation and Prioritisation | ||
| ### Test Types | ||
|
|
||
| Consider the following categories when writing tests: | ||
| * **Happy Path** – expected workflows. | ||
| * **Errors** – invalid input, unexpected scenarios. | ||
| * **Edge Cases** – boundaries, rare conditions. | ||
| * **Integration** – components & API interactions. | ||
| * **Performance/Security** – when relevant. | ||
|
|
||
| - **Happy Path Tests** – standard workflows with valid inputs. | ||
| - **Error Handling Tests** – behaviour with invalid inputs or unexpected scenarios. | ||
| - **Edge Case Tests** – boundary conditions and uncommon situations. | ||
| - **Integration Tests** – interactions between components or with API routes. | ||
| - **Performance & Security Tests** – only when relevant. | ||
| Prioritise high-risk areas first when time-boxed. | ||
|
|
||
| When time‑boxed, focus on high‑risk areas first, then fill coverage gaps and polish. | ||
| ## Time-Boxed Cycle (20 min) | ||
|
|
||
| ## Time‑Boxed Testing Approach | ||
| 1. **5–7 min**: core flows. | ||
| 2. **5–7 min**: edge cases & branches. | ||
| 3. **5–6 min**: clean up & refine. | ||
|
|
||
| A suggested 20‑minute cycle: | ||
| ## Quality Checklist | ||
|
|
||
| 1. **Initial Phase (5‑7 min)** – target high‑impact paths and core functionality. | ||
| 2. **Middle Phase (5‑7 min)** – add tests for edge cases or missing branches. | ||
| 3. **Final Phase (5‑6 min)** – clean up, improve readability and verify results. | ||
| * [ ] Clear, descriptive names | ||
| * [ ] Arrange – Act – Assert used | ||
| * [ ] Independent & fast | ||
| * [ ] One behaviour per test | ||
| * [ ] Production-like data | ||
|
|
||
| ## Test Quality Checklist | ||
| ## Running Tests | ||
|
|
||
| - [ ] Clear, descriptive test names | ||
| - [ ] Proper Arrange – Act – Assert structure | ||
| - [ ] Independent and deterministic | ||
| - [ ] Execute quickly and focus on one behaviour | ||
| - [ ] Use realistic, production‑like data | ||
| ```bash | ||
| npm run test:cov:changed # changed files only | ||
| npm run test # full suite | ||
| npm run lint | ||
| npm run type-check | ||
| ``` | ||
|
|
||
| ## Execution Instructions | ||
| --- | ||
|
|
||
| Run tests with: | ||
| # Coding Standards | ||
|
|
||
| ```bash | ||
| npm run test:cov:changed | ||
| ### Complexity | ||
|
|
||
| * Functions ≤ 15 cognitive complexity. | ||
| * Extract deep ternaries (>3 levels). | ||
| * Break down complex logic. | ||
|
|
||
| ### Modern Patterns | ||
|
|
||
| **Iteration** | ||
|
|
||
| ```ts | ||
| // ❌ Avoid | ||
| items.forEach(item => processItem(item)); | ||
|
|
||
| // ✅ Prefer | ||
| for (const item of items) { | ||
| processItem(item); | ||
| } | ||
| ``` | ||
|
|
||
| This command runs Jest only on files changed since `main`. Use `npm run test` if | ||
| you need to execute the entire suite. | ||
| * Allows `break/continue`. | ||
| * Works with async/await. | ||
|
|
||
| This command also checks coverage for modified files. Linting and type‑checking should pass as well: | ||
| **Array Access** | ||
|
|
||
| ```bash | ||
| npm run lint | ||
| npm run type-check | ||
| ```ts | ||
| // ✅ Prefer | ||
| const last = array.at(-1); | ||
| const secondLast = array.at(-2); | ||
| ``` | ||
|
|
||
| Coverage reports are generated in the `coverage` directory. A summary is printed in the terminal after tests complete. | ||
| **Strings** | ||
|
|
||
| ```ts | ||
| // ✅ Prefer | ||
| str.replaceAll('old', 'new'); | ||
| ``` | ||
|
|
||
| **Globals** | ||
|
|
||
| ```ts | ||
| // ✅ Prefer | ||
| globalThis.fetch(url); | ||
| ``` | ||
|
|
||
| **Imports** | ||
|
|
||
| * One import per module. | ||
| * Order: external → internal → types. | ||
| * No duplicates. | ||
|
|
||
| **Accessibility** | ||
|
|
||
| * Use semantic HTML (`<label>`, `<output>`) over ARIA when possible. | ||
| * Every form control must have a label. | ||
| * Test with keyboard + screen reader. | ||
|
|
||
| **Modern DOM** | ||
|
|
||
| ```ts | ||
| element.remove(); // instead of parent.removeChild(element) | ||
| ``` | ||
|
|
||
| **Error Handling** | ||
|
|
||
| * Catch only when meaningful. | ||
| * No empty `catch`. | ||
| * Log with context. | ||
|
|
||
| **Clarity** | ||
|
|
||
| * Avoid double negatives. | ||
| * Prefer explicit, remove redundant annotations. | ||
| * Use optional chaining (`?.`). | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.