Skip to content

test(theme): cover builtin theme registry - #1073

Open
mydd7 wants to merge 1 commit into
crynta:mainfrom
mydd7:test/coverage-18
Open

test(theme): cover builtin theme registry#1073
mydd7 wants to merge 1 commit into
crynta:mainfrom
mydd7:test/coverage-18

Conversation

@mydd7

@mydd7 mydd7 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What

Adds unit tests for the builtin theme registry in theme/themes/index.ts.
Test-only.

Why

listBuiltinThemes, getBuiltinTheme and getDefaultTheme back the theme
system, and a registration mistake (a duplicate theme id, or a DEFAULT_THEME_ID
that no theme actually uses) would silently degrade the default without any
compile error. Nothing tested those invariants.

How

Pure registry functions, tested directly.

Locked behavior:

  • A non-empty theme list with a unique id per theme.
  • Every listed theme is resolvable by its id via getBuiltinTheme, and an
    unknown id returns undefined.
  • getDefaultTheme resolves to a registered theme: DEFAULT_THEME_ID is present
    in the registry, so the result is the real default and not the BUILTIN[0]
    fallback.

Testing

Ran the full suite plus type-check and lint locally on Windows.

  • pnpm lint clean (unchanged: 103 pre-existing warnings, none introduced)
  • pnpm check-types clean
  • pnpm test clean (the new suite passes; see reviewer note on one
    pre-existing suite)
  • Manual smoke-test of the affected feature - N/A, test-only, no runtime change
  • (If you touched src-tauri/) cargo clippy - N/A, no Rust changes
  • (If you touched src-tauri/) cargo nextest - N/A, no Rust changes
  • (If you changed a #[tauri::command] signature) - N/A
  • (If UI) tested in pnpm tauri dev - N/A, no UI change
  • Platforms tested: Windows
  • Shells tested (if relevant): N/A

Screenshots / GIFs

N/A - no UI change.

Notes for reviewer

  • Test-only. No public API, behavior, dependency, or config change.
  • Branched a couple of commits behind current main on purpose (my token lacks
    the workflow scope). Only adds a new file; should merge cleanly.
  • Same unrelated pre-existing failure noted before: src/app/eager-budget.test.ts
    fails locally under Windows with git core.autocrlf=true; the committed blob is
    LF and it passes on CI.

Summary by CodeRabbit

  • Tests
    • Added coverage for the built-in theme registry.
    • Verified theme IDs are unique, themes resolve correctly, unknown IDs are handled safely, and the default theme is registered properly.

listBuiltinThemes, getBuiltinTheme and getDefaultTheme back the theme system but had no tests. Lock the registry invariants that catch registration mistakes: a non-empty list, a unique id per theme, every listed theme resolvable by its id, undefined for an unknown id, and the default theme resolving to a registered theme (DEFAULT_THEME_ID is present) rather than the BUILTIN[0] fallback.
@mydd7
mydd7 requested a review from crynta as a code owner July 29, 2026 05:46
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Vitest coverage for the builtin theme registry, including theme listing, unique IDs, ID-based lookup, unknown IDs, and default-theme resolution.

Changes

Builtin theme registry

Layer / File(s) Summary
Registry contract validation
src/modules/theme/themes/index.test.ts
Tests non-empty theme listings, unique theme IDs, lookup by ID, undefined for unknown IDs, and consistency between the default theme and DEFAULT_THEME_ID.

Estimated code review effort: 1 (Trivial) | ~3 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits and accurately describes the test-only change to the builtin theme registry.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/modules/theme/themes/index.test.ts`:
- Around line 2-3: Update the imports in the theme tests to use the frontend
`@/`... path alias for DEFAULT_THEME_ID from ../types and getBuiltinTheme,
getDefaultTheme, and listBuiltinThemes from ./index, removing these relative
module imports while preserving the imported symbols.
- Around line 25-29: Update the default-theme test to compare getDefaultTheme()
directly with getBuiltinTheme(DEFAULT_THEME_ID), ensuring it verifies the
registered-theme lookup path rather than only the ID. Add a focused assertion
for fallback behavior when the default lookup is missing only if that precedence
is an explicit contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: cacad1d6-d980-43c3-94ec-6a321da6aecf

📥 Commits

Reviewing files that changed from the base of the PR and between 2141d16 and cbb740d.

📒 Files selected for processing (1)
  • src/modules/theme/themes/index.test.ts

Comment on lines +2 to +3
import { DEFAULT_THEME_ID } from "../types";
import { getBuiltinTheme, getDefaultTheme, listBuiltinThemes } from "./index";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the frontend path alias for these imports.

Replace ../types and ./index with the corresponding @/... imports.

As per coding guidelines, frontend imports must use the @/... alias and must not use relative imports across modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/theme/themes/index.test.ts` around lines 2 - 3, Update the
imports in the theme tests to use the frontend `@/`... path alias for
DEFAULT_THEME_ID from ../types and getBuiltinTheme, getDefaultTheme, and
listBuiltinThemes from ./index, removing these relative module imports while
preserving the imported symbols.

Source: Coding guidelines

Comment on lines +25 to +29
it("resolves the default theme to a registered theme, not the fallback", () => {
const ids = listBuiltinThemes().map((t) => t.id);
expect(ids).toContain(DEFAULT_THEME_ID);
expect(getDefaultTheme().id).toBe(DEFAULT_THEME_ID);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate theme files =="
fd -a 'index\.(ts|tsx)$' src/modules || true
fd -a 'themes' src/modules || true

echo "== target test context =="
if [ -f src/modules/theme/themes/index.test.ts ]; then
  nl -ba src/modules/theme/themes/index.test.ts | sed -n '1,140p'
fi

echo "== find getDefaultTheme/getBuiltinTheme definitions =="
rg -n "getDefaultTheme|getBuiltinTheme|listBuiltinThemes|DEFAULT_THEME_ID|BUILTIN" src/modules/theme/themes src/modules/theme -S || true

Repository: crynta/terax-ai

Length of output: 1472


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== outline target module =="
ast-grep outline src/modules/theme/themes/index.ts --view expanded || true

echo "== relevant implementation =="
nl -ba src/modules/theme/themes/index.ts | sed -n '1,220p'

echo "== import shape in tests =="
nl -ba src/modules/theme/themes/index.test.ts | sed -n '1,220p'

Repository: crynta/terax-ai

Length of output: 543


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== target test context =="
sed -n '1,140p' src/modules/theme/themes/index.test.ts

echo "== implementation context =="
sed -n '1,120p' src/modules/theme/themes/index.ts

echo "== usages of default theme functions =="
rg -n "getDefaultTheme\(|getBuiltinTheme\(|listBuiltinThemes\(|DEFAULT_THEME_ID" .

echo "== static probe of implementation shape =="
python3 - <<'PY'
from pathlib import Path

path = Path("src/modules/theme/themes/index.ts")
text = path.read_text()
for needle in ["export function listBuiltinThemes", "export function getBuiltinTheme", "export function getDefaultTheme", "BUILTIN: Theme[]"]:
    idx = text.find(needle)
    start = max(0, text.rfind("\n", 0, idx) or idx)
    body = text[idx:text.find("\nexport function", idx + 1)]
    print(f"--- {needle} ---")
    print(body[:1000])
PY

Repository: crynta/terax-ai

Length of output: 5857


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== teraxDefault theme shape =="
sed -n '1,120p' src/modules/theme/themes/terax-default.ts

echo "== programmatic proof of fallback mask with current registry and target test =="
python3 <<'PY'
from pathlib import Path

text = Path("src/modules/theme/themes/index.ts").read_text()
for name in ["teraxDefault", "cola", "claude", "kanagawa", "tokyoNight"]:
    path = f"src/modules/theme/themes/{name}.ts"
    if path.exists():
        body = Path(path).read_text()
        for line in body.splitlines():
            if "export default" in line:
                print(f"{path}: {line.strip()}")
                break

def id_of(name):
    return next(l.strip() for l in Path(f"src/modules/theme/themes/{name}.ts").read_text().splitlines() if "id:" in l).split(sep=":", maxsplit=1)[1].strip().strip('"')

BUILTIN = list(["teraxDefault", "cola", "claude", "kanagawa", "tokyoNight"])
DEFAULT_THEME_ID = id_of("teraxDefault")
BY_ID = {i: name for name, i in enumerate(BUILTIN)}

def get_default_theme_current():
    return BY_ID.get(DEFAULT_THEME_ID, BUILTIN[0])

def always_fallback(theme_id):
    return BUILTIN[0]

current_id = BUILTIN[get_default_theme_current()]
fallback_id = BUILTIN[always_fallback(DEFAULT_THEME_ID)]

print("current DEFAULT_THEME_ID:", DEFAULT_THEME_ID)
print("default lookup found:", current_id == DEFAULT_THEME_ID)
print("always fallback returned:", fallback_id)
print("current test only checks returned id equals DEFAULT_THEME_ID:", current_id == current_id == DEFAULT_THEME_ID)
print("always fallback test would pass:", fallback_id == current_id == DEFAULT_THEME_ID)
print("identity guard would fail for always fallback:", current_id != fallback_id)
PY

Repository: crynta/terax-ai

Length of output: 700


Make the default-theme test assert the lookup path, not only the returned ID.

getDefaultTheme() falls back to BUILTIN[0], so comparing the result to DEFAULT_THEME_ID would also pass if the lookup were removed while terax-default stays first. Compare getDefaultTheme() with getBuiltinTheme(DEFAULT_THEME_ID) and add a small separate assertion for fallback behavior if missing lookup precedence is part of the contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/theme/themes/index.test.ts` around lines 25 - 29, Update the
default-theme test to compare getDefaultTheme() directly with
getBuiltinTheme(DEFAULT_THEME_ID), ensuring it verifies the registered-theme
lookup path rather than only the ID. Add a focused assertion for fallback
behavior when the default lookup is missing only if that precedence is an
explicit contract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant