Skip to content

1.0.0 - #81

Open
rtuszik wants to merge 14 commits into
mainfrom
organize
Open

1.0.0#81
rtuszik wants to merge 14 commits into
mainfrom
organize

Conversation

@rtuszik

@rtuszik rtuszik commented May 28, 2026

Copy link
Copy Markdown
Owner

TODO:

  • update readme to reflect new package structure
  • allow invocation with uv run koalakeys

@socket-security

socket-security Bot commented May 28, 2026

Copy link
Copy Markdown

@socket-security

socket-security Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: pypi prek is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: pyproject.tomlpypi/prek@0.3.6

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore pypi/prek@0.3.6. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/koalakeys
   generate_cheatsheet.py2014279%58–59, 111–113, 128–129, 150–152, 200–202, 211–213, 223–224, 228, 232, 238–239, 252–278
   logger.py35391%21, 42–43
   template_renderer.py16288%20–21
   theming.py1731691%111, 134, 163–166, 168, 174, 177, 181, 211, 225, 230, 255, 278, 288
   validate_yaml.py1893084%133–135, 234–261, 265–272
TOTAL6149385% 

Tests Skipped Failures Errors Time
158 0 💤 0 ❌ 0 🔥 1.953s ⏱️

@rtuszik rtuszik changed the title Organize 1.0.0 Jun 9, 2026
@rtuszik

rtuszik commented Jun 22, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get PR details
gh pr view 81 --repo rtuszik/KoalaKeys

echo "---FILES CHANGED---"
gh pr diff 81 --repo rtuszik/KoalaKeys --name-only

echo "---PR COMMENTS---"
gh pr view 81 --repo rtuszik/KoalaKeys --comments

Length of output: 31529


🏁 Script executed:

#!/bin/bash
# Check pyproject.toml for scripts/entry points
cat pyproject.toml

echo "---README---"
cat README.md | head -100

Length of output: 5139



@rtuszik, happy to help! I noticed a few things worth addressing before this is ready to merge:

Outstanding TODOs

  1. README not updated – The README still references the old invocation path (uv run src/generate_cheatsheet.py) and the old src/ structure. It needs to be updated to reflect the new src/koalakeys/ package layout.

  2. uv run koalakeys not yet wired uppyproject.toml is missing a [project.scripts] entry. You'll need something like:

    [project.scripts]
    koalakeys = "koalakeys:main"

    (adjust the entry point to match your actual main() function location in src/koalakeys/__init__.py or generate_cheatsheet.py).

Other things to check

  • Version mismatch: pyproject.toml has version = "0.6.0" but the PR is titled 1.0.0. Was the bump forgotten?
  • prek dependency: Socket Security flagged prek@0.3.6 as 90% likely containing obfuscated code. It's only a dev dependency, but worth verifying it's intentional/safe before merging.

Would you like me to do a full review of all the changes now?

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a full theming system (theming.py) with six built-in themes (Catppuccin, Dracula, Gruvbox, Nord, Rose Pine, Solarized) and user-theme inheritance. Relocates layout/template/theme assets into the koalakeys package, rewrites the HTML generator's styling pipeline, overhauling CSS/HTML/Jinja templates to consume --kk-* CSS variables. Extends YAML schema and validation with theme/custom_css fields, adds integration and Playwright browser tests, and hardens CI with pinned action SHAs and a pre-commit Ruff configuration.

Changes

Theming System and Package Restructure

Layer / File(s) Summary
Theming module: contracts, validators, and resolution
src/koalakeys/theming.py
Adds ThemeError, ResolvedTheme dataclass (with render_token_css(), both_modes, default_is_dark), token format validators, sanitize_css, built-in/user theme loaders, mode-narrowing, and the resolve_theme() entry point.
Built-in theme YAML definitions
src/koalakeys/themes/catppuccin.yaml, src/koalakeys/themes/dracula.yaml, src/koalakeys/themes/gruvbox.yaml, src/koalakeys/themes/nord.yaml, src/koalakeys/themes/rose-pine.yaml, src/koalakeys/themes/solarized.yaml
Adds six built-in theme files, each specifying default_mode, typography/layout settings, and full light/dark colour token palettes.
Layout data files relocated into package
src/koalakeys/layouts/keyboard_layouts.yaml, src/koalakeys/layouts/system_mappings.yaml
Adds condensed keyboard layout and system modifier mapping YAML files under the koalakeys package, replacing the removed src/layouts/ equivalents.
Schema extension and YAML validation updates
docs/schema/cheatsheet.schema.json, src/koalakeys/validate_yaml.py
Extends the schema with theme, custom_css, and custom_css_inline properties; adds validate_styling validator; refactors validate_yaml to use an aggregated validators list; updates file-open calls to explicit UTF-8 encoding.
Generator: path constants, styling pipeline, and shortcut parsing
src/koalakeys/generate_cheatsheet.py
Refactors path setup to PACKAGE_DIR/PROJECT_ROOT constants, rewrites shortcut parsing helpers, adds load_custom_css_file and apply_styling, wires the styling pipeline into generate_html, and changes error handling to OSError.
Templates, CSS, and JS: theme-aware rendering
src/koalakeys/templates/base.html, src/koalakeys/templates/cheatsheets/cheatsheet-template.html, src/koalakeys/templates/cheatsheets/components/body.html, src/koalakeys/templates/cheatsheets/scripts/main.js, src/koalakeys/templates/cheatsheets/assets/cheatsheets.css, src/koalakeys/templates/index/assets/index.css
Replaces hardcoded font/body-class with overridable template blocks; adds cheatsheet-template.html injecting token and custom CSS; adds 468-line cheatsheets.css and 396-line index.css built on --kk-* variables; gates dark-mode toggle and JS initialisation on theme_both_modes.
Module import and logger cleanup
src/koalakeys/logger.py, src/koalakeys/template_renderer.py
Adds from __future__ import annotations, switches to koalakeys.* qualified imports, and replaces Optional[...] annotations with ... | None syntax.
Tests: theming, validation, and generator unit tests
tests/test_theming.py, tests/test_generate_cheatsheet.py, tests/test_validate_yaml.py, tests/test_replace_shortcut_names.py, tests/test_template_renderer.py
Adds test_theming.py covering built-in integrity, user-theme behaviour, token validation, sanitisation, and ResolvedTheme semantics; adds TestThemeIntegration/TestCustomCssFile to the generator tests; adds TestValidateStyling to validation tests; updates all import paths to koalakeys.*.
Tests: integration and browser end-to-end tests
tests/conftest.py, tests/test_integration.py, tests/test_browser.py, pytest.ini
Adds isolated_output fixture; adds test_integration.py covering main() and generate_index(); adds Playwright test_browser.py with four interaction tests (load, render, key highlight, search filter); configures pytest.ini to exclude browser-marked tests by default.

CI Hardening and Tooling

Layer / File(s) Summary
GitHub Actions SHA pinning and Playwright CI step
.github/actions/setup-python/action.yml, .github/workflows/lint.yml, .github/workflows/pytest.yml
Pins actions/checkout and actions/setup-python to commit SHAs across all workflows; adds persist-credentials: false and permissions: contents: read; inserts Playwright Chromium install and browser-test step into pytest.yml; pins the coverage comment action SHA.
Pre-commit, pyproject.toml, and Ruff config
.pre-commit-config.yml, pyproject.toml
Adds .pre-commit-config.yml with Ruff check and format hooks at v0.15.4; updates dev dependencies (adds prek>=0.3.6, bumps pytest-cov to >=7.1.0); replaces Ruff lint ignore list with extend-select enabling F, W, E, I, UP, C4, FA, ISC, RET, SIM, TD, C90, and others.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~110 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title '1.0.0' is vague and does not convey meaningful information about the changeset; it appears to be only a version number without describing the actual changes made. Use a descriptive title summarising the main change, such as 'Reorganise package structure and add theming support' or 'Release version 1.0.0 with major package refactoring'.
Description check ❓ Inconclusive The description mentions outstanding TODOs but does not clearly explain what has been done in this PR or the main changes being made, making it unclear what the changeset actually accomplishes. Provide a description summarising the primary changes made in this PR, including the package restructuring and theming implementation, not just outstanding work.
✅ Passed checks (2 passed)
Check name Status Explanation
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch organize

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.0)
src/koalakeys/templates/cheatsheets/scripts/main.js

File contains syntax errors that prevent linting: Line 75: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{ keyboard_layout | tojson; Line 122: Expected a statement but instead found '}

  // Call generateKeyboard on page load
  document.addEventListener("; Line 128: Expected a statement but instead found '%'.; Line 128: expected `(` but instead found `theme_both_modes`; Line 128: Expected an expression but instead found '}'.; Line 145: Expected a statement but instead found '% endif %'.; Line 162: Expected a statement but instead found '%'.; Line 162: expected `(` but instead found `theme_both_modes`; Line 162: Expected an expression but instead found '}'.; Line 175: Expected a statement but instead found '% endif %'.; Line 241: Expected a statement but instead found '%'.; Line 241: expected `(` but instead found `not`; Line 241: expected `)` but instead found `allow_text`; Line 241: Expected an expression but instead found '}'.; Line 260: Expected a statement but instead found '% endif %'.

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 and usage tips.

@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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
pyproject.toml (2)

3-3: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align package version with the 1.0.0 release intent.

Line 3 still declares 0.6.0, which conflicts with the stated release target and can break release automation and artefact labelling.

Proposed change
-version = "0.6.0"
+version = "1.0.0"

1-8: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a CLI script entry for uv run koalakeys.

[project.scripts] is missing, so the uv run koalakeys objective will not work.

Proposed change
 [project]
 name = "koalakeys"
 version = "0.6.0"
 description = "Build interactive, portable cheatsheets from YAML."
 readme = "README.md"
 requires-python = ">=3.9"
 dependencies = ["jinja2>=3.1.6", "python-dotenv>=1.1.1", "ruamel-yaml>=0.18.14"]
+
+[project.scripts]
+koalakeys = "koalakeys.<module_with_main>:main"
🧹 Nitpick comments (2)
.github/workflows/pytest.yml (1)

18-20: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Remove the duplicated non-browser test run.

Line 18-Line 20 already runs pytest, then Line 32-Line 38 runs it again with coverage. Keeping only the coverage run avoids duplicate CI time.

Proposed change
-            - run: |
-                uv run pytest
-
             # Browser/Playwright tests are excluded by default (pytest.ini) and run
             # only on pull requests, where we install Chromium for them.
             - name: Install Playwright browser
               if: github.event_name == 'pull_request'
               run: |
                 uv run playwright install --with-deps chromium

Also applies to: 32-38

tests/conftest.py (1)

9-16: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consolidate isolated_output into one fixture definition.

Line 9 introduces a shared fixture, but there is also an isolated_output fixture in tests/test_generate_cheatsheet.py (Lines 10-16 in graph context). Keeping both increases drift risk and can create subtle shadowing differences; prefer using only the conftest.py fixture.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f15c7b39-fc7a-4cef-ac6b-5dc0bba20052

📥 Commits

Reviewing files that changed from the base of the PR and between 7ccb4b1 and 3c140bb.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/actions/setup-python/action.yml
  • .github/workflows/lint.yml
  • .github/workflows/pytest.yml
  • .pre-commit-config.yml
  • docs/schema/cheatsheet.schema.json
  • pyproject.toml
  • pytest.ini
  • src/koalakeys/__init__.py
  • src/koalakeys/generate_cheatsheet.py
  • src/koalakeys/layouts/keyboard_layouts.yaml
  • src/koalakeys/layouts/system_mappings.yaml
  • src/koalakeys/logger.py
  • src/koalakeys/template_renderer.py
  • src/koalakeys/templates/base.html
  • src/koalakeys/templates/cheatsheets/assets/cheatsheets.css
  • src/koalakeys/templates/cheatsheets/cheatsheet-template.html
  • src/koalakeys/templates/cheatsheets/components/body.html
  • src/koalakeys/templates/cheatsheets/scripts/main.js
  • src/koalakeys/templates/index/assets/index.css
  • src/koalakeys/templates/index/components/body.html
  • src/koalakeys/templates/index/components/footer.html
  • src/koalakeys/templates/index/index_template.html
  • src/koalakeys/templates/index/scripts/main.js
  • src/koalakeys/themes/catppuccin.yaml
  • src/koalakeys/themes/dracula.yaml
  • src/koalakeys/themes/gruvbox.yaml
  • src/koalakeys/themes/nord.yaml
  • src/koalakeys/themes/rose-pine.yaml
  • src/koalakeys/themes/solarized.yaml
  • src/koalakeys/theming.py
  • src/koalakeys/validate_yaml.py
  • src/layouts/keyboard_layouts.yaml
  • src/layouts/system_mappings.yaml
  • src/templates/cheatsheets/assets/cheatsheets.css
  • src/templates/cheatsheets/cheatsheet-template.html
  • src/templates/index/assets/index.css
  • tests/__init__.py
  • tests/conftest.py
  • tests/test_browser.py
  • tests/test_generate_cheatsheet.py
  • tests/test_integration.py
  • tests/test_replace_shortcut_names.py
  • tests/test_template_renderer.py
  • tests/test_theming.py
  • tests/test_validate_yaml.py
💤 Files with no reviewable changes (6)
  • src/templates/index/assets/index.css
  • tests/init.py
  • src/layouts/keyboard_layouts.yaml
  • src/templates/cheatsheets/cheatsheet-template.html
  • src/layouts/system_mappings.yaml
  • src/templates/cheatsheets/assets/cheatsheets.css

Comment on lines +29 to +31
THEMES_DIR = PROJECT_ROOT / "themes"
STYLES_DIR = PROJECT_ROOT / "styles"
LAYOUTS_DIR = PACKAGE_DIR / "layouts"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Theme lookup path is inconsistent with the relocated package assets.

Line 29 points to PROJECT_ROOT / "themes", but this PR moves themes into the package namespace. That can cause resolve_theme(...) to miss theme files and make generate_html(...) return None on otherwise valid input.

💡 Proposed fix
-THEMES_DIR = PROJECT_ROOT / "themes"
+THEMES_DIR = PACKAGE_DIR / "themes"

Comment on lines +31 to +41
margin-bottom: 10px;
font-weight: 700;
font-size: 2.2rem;
position: absolute;
left: 50%;
right: 0;
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100vw;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "cheatsheets.css" -type f

Repository: rtuszik/KoalaKeys

Length of output: 122


🏁 Script executed:

cat -n src/koalakeys/templates/cheatsheets/assets/cheatsheets.css | sed -n '25,50p'

Repository: rtuszik/KoalaKeys

Length of output: 776


🏁 Script executed:

cat -n src/koalakeys/templates/cheatsheets/assets/cheatsheets.css | sed -n '110,165p'

Repository: rtuszik/KoalaKeys

Length of output: 1438


🌐 Web query:

CSS word-wrap property deprecated MDN

💡 Result:

CSS word-wrap is not a separate modern property; it’s a legacy name/alias of overflow-wrap, so it is effectively deprecated in favor of overflow-wrap. MDN’s overflow-wrap documentation notes that the property was originally a nonstandard Microsoft extension called “word-wrap” and that it has since been renamed to overflow-wrap, with “word-wrap” being an alias. [1] The CSS Text Module Level 3 specification similarly states that UAs must treat word-wrap as a legacy name alias of overflow-wrap. [2] So: prefer overflow-wrap (e.g., overflow-wrap: anywhere / break-word) rather than word-wrap. [1][2]

Citations:


Remove redundant margin and deprecated word-wrap declarations.

The h1 rule has margin-bottom: 10px; on line 31 immediately overridden by margin: 0; on line 37. The .shortcut-key (lines 117–118) and .shortcut-description (lines 158–159) blocks both declare the legacy word-wrap alias alongside the modern overflow-wrap property. Remove the dead declarations to reduce lint noise and improve code clarity.

Suggested patch
 h1 {
 	color: var(--kk-accent);
 	text-align: center;
-	margin-bottom: 10px;
 	font-weight: 700;
 	font-size: 2.2rem;
 	position: absolute;
 	left: 50%;
 	right: 0;
 	margin: 0;
@@
 .shortcut-key {
@@
-	word-wrap: break-word;
 	overflow-wrap: break-word;
@@
 .shortcut-description {
@@
-	word-wrap: break-word;
 	overflow-wrap: break-word;
🧰 Tools
🪛 Stylelint (17.13.0)

[error] 37-37: Overridden property "margin-bottom" by shorthand "margin" (declaration-block-no-shorthand-property-overrides)

(declaration-block-no-shorthand-property-overrides)

Source: Linters/SAST tools

Comment on lines +99 to +110
#dark-mode-toggle {
background: none;
border: none;
cursor: pointer;
font-size: 24px;
color: var(--text);
transition: color 0.3s;
}

body.dark-mode #dark-mode-toggle {
color: var(--mocha-text);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n src/koalakeys/templates/index/assets/index.css | sed -n '95,115p'

Repository: rtuszik/KoalaKeys

Length of output: 546


🏁 Script executed:

cat -n src/koalakeys/templates/index/assets/index.css | head -50

Repository: rtuszik/KoalaKeys

Length of output: 1679


🏁 Script executed:

rg "(?:--text|--latte-text|:root)" src/koalakeys/templates/index/assets/index.css -A 2 -B 2

Repository: rtuszik/KoalaKeys

Length of output: 846


Use the defined --latte-text token for the toggle colour in light mode.

Line 104 references var(--text), which is not defined in the CSS variables. This causes the colour to depend on fallback or inheritance rather than the intended design token. Replace it with --latte-text to match the pattern used elsewhere in the stylesheet and the corresponding dark-mode rule.

Suggested patch
 `#dark-mode-toggle` {
 	background: none;
 	border: none;
 	cursor: pointer;
 	font-size: 24px;
-	color: var(--text);
+	color: var(--latte-text);
 	transition: color 0.3s;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#dark-mode-toggle {
background: none;
border: none;
cursor: pointer;
font-size: 24px;
color: var(--text);
transition: color 0.3s;
}
body.dark-mode #dark-mode-toggle {
color: var(--mocha-text);
}
`#dark-mode-toggle` {
background: none;
border: none;
cursor: pointer;
font-size: 24px;
color: var(--latte-text);
transition: color 0.3s;
}
body.dark-mode `#dark-mode-toggle` {
color: var(--mocha-text);
}

Comment thread src/koalakeys/theming.py
Comment on lines +145 to +148
if key in RESERVED_KEYS:
if key in MODES and value:
modes[key] = {k: _validate_token_value(k, v) for k, v in value.items()}
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard mode blocks before iterating .items()

Line 147 can raise an uncaught exception when a theme defines light/dark as a non-mapping value. This bypasses ThemeError handling and can crash generation.

Suggested fix
         if key in RESERVED_KEYS:
             if key in MODES and value:
-                modes[key] = {k: _validate_token_value(k, v) for k, v in value.items()}
+                if not isinstance(value, dict):
+                    raise ThemeError(f"Theme mode '{key}' must be a mapping of token -> value")
+                modes[key] = {k: _validate_token_value(k, v) for k, v in value.items()}
             continue

Comment thread src/koalakeys/theming.py
Comment on lines +223 to +225
if narrowed is not None:
if not isinstance(narrowed, list) or not set(narrowed) <= set(MODES):
raise ThemeError(f"User theme '{name}': 'modes' must be a subset of {list(MODES)}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Harden modes narrowing type checks

Line 224 can throw TypeError for unhashable entries (for example nested lists) before you raise ThemeError. Validate element types explicitly first.

Suggested fix
     if narrowed is not None:
-        if not isinstance(narrowed, list) or not set(narrowed) <= set(MODES):
+        if (
+            not isinstance(narrowed, list)
+            or not all(isinstance(mode, str) for mode in narrowed)
+            or not set(narrowed) <= set(MODES)
+        ):
             raise ThemeError(f"User theme '{name}': 'modes' must be a subset of {list(MODES)}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if narrowed is not None:
if not isinstance(narrowed, list) or not set(narrowed) <= set(MODES):
raise ThemeError(f"User theme '{name}': 'modes' must be a subset of {list(MODES)}")
if narrowed is not None:
if (
not isinstance(narrowed, list)
or not all(isinstance(mode, str) for mode in narrowed)
or not set(narrowed) <= set(MODES)
):
raise ThemeError(f"User theme '{name}': 'modes' must be a subset of {list(MODES)}")

Comment on lines +141 to +150
validators = [
validate_required_keys,
validate_title,
validate_render_options,
validate_styling,
validate_layout,
validate_shortcuts,
]
results = [validator(data) for validator in validators]
is_valid = all(results)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a top-level mapping guard before running validator list

The new aggregated execution can crash on non-object YAML (for example a list), because validators like validate_render_options call data.get(...). Fail fast with a type check before invoking validators.

Suggested fix
     if data is None:
         logger.error(f"Empty YAML file: {file_path}")
         return False
+    if not isinstance(data, dict):
+        logger.error(f"Top-level YAML must be a mapping/object: {file_path}")
+        return False
 
     validators = [
         validate_required_keys,
         validate_title,
         validate_render_options,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
validators = [
validate_required_keys,
validate_title,
validate_render_options,
validate_styling,
validate_layout,
validate_shortcuts,
]
results = [validator(data) for validator in validators]
is_valid = all(results)
if data is None:
logger.error(f"Empty YAML file: {file_path}")
return False
if not isinstance(data, dict):
logger.error(f"Top-level YAML must be a mapping/object: {file_path}")
return False
validators = [
validate_required_keys,
validate_title,
validate_render_options,
validate_styling,
validate_layout,
validate_shortcuts,
]
results = [validator(data) for validator in validators]
is_valid = all(results)

Comment thread tests/test_browser.py
class TestCheatsheetInBrowser:
def test_loads_without_console_errors(self, page):
assert page.console_errors == [], f"unexpected JS errors: {page.console_errors}"
assert "Full Featured Test" in page.title() or page.locator("h1").count() >= 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the always-true fallback in the page title assertion.

Line 56 uses page.locator("h1").count() >= 0, which always passes and can hide a broken render path.

Proposed fix
-        assert "Full Featured Test" in page.title() or page.locator("h1").count() >= 0
+        assert "Full Featured Test" in page.title() or page.locator("h1").count() > 0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert "Full Featured Test" in page.title() or page.locator("h1").count() >= 0
assert "Full Featured Test" in page.title() or page.locator("h1").count() > 0

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