Skip to content

#1867 test: add a regression suite and a CI job to run it - #1871

Merged
kRHYME7 merged 2 commits into
HyDE-Project:devfrom
RAprogramm:1867
Jul 29, 2026
Merged

#1867 test: add a regression suite and a CI job to run it#1871
kRHYME7 merged 2 commits into
HyDE-Project:devfrom
RAprogramm:1867

Conversation

@RAprogramm

@RAprogramm RAprogramm commented Jul 29, 2026

Copy link
Copy Markdown

Pull Request

Description

Fixes #1867

Stacked on #1870. The suite fails against dev as it stands, because the
defects it detects are the ones that pull request removes. Merge #1870 first.

What lands

tests/
  run.sh                  discovers and runs every case
  lib/common.sh           pass/fail/skip helpers
  lua/bind_harness.lua    keybind checks against a stubbed Hyprland API
  python/check_dots.py    installer metafile checks
  test_binds.sh
  test_dots.sh
  test_lua_syntax.sh
  test_shell.sh
  README.md
.github/workflows/test.yml

No framework is vendored. A case is an executable tests/test_*.sh that
prints its own diagnostics and exits non-zero, so adding a case is adding a
file.

What is checked

Case Checks
test_binds.sh No two binds share a combination once modifiers are folded to what Hyprland matches on; no keysym sits in a modifier position; no bind uses the code:NN form the Lua parser rejects; every bind carries a description; every hyde-shell command a bind runs resolves, either to a file in the tree or to a subcommand hyde-shell declares in its own header
test_dots.sh Every metafile under Scripts/dots parses, declares paths and target_root, uses a known action, points at a source directory that exists, and lists only known package managers
test_lua_syntax.sh Every shipped Lua file parses
test_shell.sh Every shipped shell script parses, and shellcheck reports no error-severity finding

The keybind case never talks to a compositor. hl is replaced by a recorder,
so the real key_binds.lua, hyde/binds.lua and hyde/dispatcher.lua are
executed and inspected without dispatching anything.

Effect on the tree

Three error-severity shellcheck findings existed and are fixed here, since a
linter that lands red is a linter nobody runs:

File Finding
Configs/.config/uwsm/env.d/01-gpu.sh no shebang, so the target shell was unknown (SC2148). Now carries the same #!/usr/bin/env sh as its sibling 00-hyde.sh
Configs/.local/lib/hyde/shutils/ocr.sh array expanded with [@] inside a string argument (SC2145), which splits the notification body across arguments. Now [*]
Configs/.local/lib/hyde/wallpaper.kon.sh array expanded with [@] inside [[ ]] (SC2199), so the substring test compared against an implicit concatenation. Now [*]

Verification

Against this branch:

$ sh tests/run.sh
test_binds
    149 bind(s) checked
  ok
test_dots
    25 metafile(s) checked
  ok
test_lua_syntax
    79 file(s) checked
  ok
test_shell
    101 file(s) parsed
  ok

4 case(s), 0 failed

Against dev as it stands, the same suite reports 23 keybind defects and the
three shellcheck findings, so the checks bite rather than pass vacuously:

    fail: "ALT_R + CONTROL_R" holds "ALT_R" where a modifier is expected
    fail: "SUPER + code:87" uses a keycode, which the Lua bind parser does not accept
    ...
    fail: combo CTRL + SUPER + LEFT is bound twice

Known gap

Fourteen metafile entries point at source paths that no longer exist in the
tree, most of them the legacy Hyprland .conf files that the Lua release
removed. The path-level existence check is deliberately left out of this pull
request so it does not carry a judgement about what should happen to those
entries. It is filed separately.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update (non-breaking change; modified files are limited to the documentations)
  • Technical debt (a code change that does not fix a bug or add a feature but makes something clearer for devs)
  • Other (provide details below)

Checklist

  • I have read the CONTRIBUTING document.
  • My code follows the code style of this project.
  • My commit message follows the commit guidelines.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added a changelog entry.
  • I have added necessary comments/documentation to my code.
  • I have added tests to cover my changes.
  • I have tested my code locally and it works as expected.
  • All new and existing tests passed.

tests/README.md documents how to run the suite and what each case covers.
The changelog entry covers only the two shellcheck fixes that a user can
notice; the suite itself is not user-facing.

Additional context

The suite is dependency-light on purpose: a POSIX runner, one Lua harness and
one Python checker, no framework to vendor and no compositor to talk to. A
case whose tool is missing reports itself as skipped instead of failing, so it
stays usable on a contributor's machine and runs in full in CI.

pre-commit run passes on the files this branch touches, and markdownlint
passes on the markdown it adds. The repository has 244 files with pre-existing
end-of-file and trailing-whitespace findings; folding those in would bury the
change, so they are left alone.

Summary by CodeRabbit

  • New Features
    • Enhanced Hyprland keybind handling with modifier normalization, improved duplicate/bind deduplication, and updated navigation/workspace shortcuts (including workspaces 11–20).
  • Bug Fixes
    • Fixed OCR notification language list rendering and adjusted wallpaper duplicate/hash matching behavior.
  • Documentation
    • Added documentation for running and understanding the test suite.
  • Chores
    • Added a CI “Tests” workflow and expanded automated checks for keybinds, Lua syntax, shell hygiene, and dot metafiles.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@RAprogramm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 77d1600e-d4cf-4e5b-8906-d9a531671a49

📥 Commits

Reviewing files that changed from the base of the PR and between 16c62b2 and 4a8e3ed.

📒 Files selected for processing (18)
  • .claude/worktrees/graceful-crafting-hanrahan
  • .github/workflows/test.yml
  • .gitignore
  • CHANGELOG.md
  • Configs/.config/uwsm/env.d/01-gpu.sh
  • Configs/.config/zsh/ohmyzsh
  • Configs/.local/lib/hyde/shutils/ocr.sh
  • Configs/.local/lib/hyde/wallpaper.kon.sh
  • tests/README.md
  • tests/lib/common.sh
  • tests/lua/bind_harness.lua
  • tests/python/check_dots.py
  • tests/run.sh
  • tests/test_binds.sh
  • tests/test_dots.sh
  • tests/test_git.sh
  • tests/test_lua_syntax.sh
  • tests/test_shell.sh
📝 Walkthrough

Walkthrough

Adds automated structural checks for binds, dot metafiles, Lua syntax, and shell scripts, wires them into GitHub Actions, improves Hyprland bind deduplication and keypad mappings, and corrects several shell script interpreter and expansion forms.

Changes

Validation and bind quality

Layer / File(s) Summary
Bind canonicalization and keymaps
Configs/.local/share/hypr/lua/hyde/binds.lua, Configs/.local/share/hypr/lua/key_binds.lua
Canonicalizes modifier combinations for deduplication, preserves registered spellings for unbinding, enables deduplication, and updates keybind and keypad workspace mappings.
Repository test suite
tests/*
Adds test helpers and checks for bind uniqueness, command resolution, TOML structure, Lua syntax, and shell parsing or ShellCheck findings, with accompanying documentation.
CI and shell corrections
.github/workflows/test.yml, Configs/.config/uwsm/env.d/01-gpu.sh, Configs/.local/lib/hyde/shutils/ocr.sh, Configs/.local/lib/hyde/wallpaper.kon.sh, CHANGELOG.md
Runs the test suite on pushes, pull requests, and manual dispatches; adds a shell shebang, adjusts two array expansions, and records the fixes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHub Actions
  participant tests/run.sh
  participant Test cases
  participant Repository
  GitHub Actions->>tests/run.sh: execute test suite
  tests/run.sh->>Test cases: discover and run test scripts
  Test cases->>Repository: inspect configuration and scripts
  Repository-->>Test cases: validation results
  Test cases-->>tests/run.sh: pass or fail status
  tests/run.sh-->>GitHub Actions: workflow status
Loading

Possibly related issues

Possibly related PRs

Suggested labels: bug

Poem

I’m a rabbit who hops through the tests,
Finding bind bugs and syntax pests.
Lua keys align, shells speak clear,
CI checks them far and near.
Carrots for every passing run! 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Most requested checks and CI are present, but the runner aggregates failures instead of exiting on the first one, and the workflow omits luarocks from the stated setup. Make tests/run.sh stop on the first failing case and update .github/workflows/test.yml to install lua, luarocks, and shellcheck as specified.
Docstring Coverage ⚠️ Warning Docstring coverage is 27.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed All changes support the test suite, CI job, or related fixes; no clearly unrelated code was added.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: a new regression test suite plus CI to run it.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 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 @.github/workflows/test.yml:
- Line 17: Update the actions/checkout@v4 step to set persist-credentials to
false, and ensure the workflow job permissions remain limited to contents: read
unless writable token access is explicitly required.

In `@Configs/.local/share/hypr/lua/hyde/binds.lua`:
- Around line 57-65: Update the modifier normalization logic before sorting so
duplicate normalized entries are removed, ensuring inputs such as repeated CTRL
produce the same canonical binding as a single CTRL. Preserve alias
normalization, deterministic sorting, and appending the uppercased key in the
existing return flow.

In `@tests/python/check_dots.py`:
- Around line 75-77: Update the source_root validation in the table-checking
logic to first require non-null values to be strings, then resolve REPO_ROOT /
source_root and reject any path whose resolved location escapes REPO_ROOT,
including absolute paths and parent-directory traversal; retain the
missing-directory failure for valid in-repository paths.

In `@tests/run.sh`:
- Around line 21-35: Update the test discovery and execution loop around
case_path so only regular executable test_*.sh files are included by checking
both -f and -x, then invoke each selected case directly instead of through sh,
preserving its shebang behavior.

In `@tests/test_shell.sh`:
- Around line 21-26: Update the ShellCheck invocation in the report block to
capture its exit status while preserving the captured output, then fail when
either xargs/ShellCheck returns non-zero or report is non-empty. Keep printing
report lines before calling fail when findings are present, and ensure the
status check distinguishes command failure from ShellCheck findings.
- Around line 7-13: The script-parsing loop currently validates every file with
bash regardless of its declared interpreter. Update the loop around scripts and
file to read each script’s shebang and run sh -n for /bin/sh or /usr/bin/env sh
declarations, otherwise bash -n for Bash declarations, preserving the existing
failure message and count behavior.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8182dfb2-90da-4987-b2b6-44057f5091b9

📥 Commits

Reviewing files that changed from the base of the PR and between bfa6487 and a056d85.

📒 Files selected for processing (15)
  • .github/workflows/test.yml
  • Configs/.config/uwsm/env.d/01-gpu.sh
  • Configs/.local/lib/hyde/shutils/ocr.sh
  • Configs/.local/lib/hyde/wallpaper.kon.sh
  • Configs/.local/share/hypr/lua/hyde/binds.lua
  • Configs/.local/share/hypr/lua/key_binds.lua
  • tests/README.md
  • tests/lib/common.sh
  • tests/lua/bind_harness.lua
  • tests/python/check_dots.py
  • tests/run.sh
  • tests/test_binds.sh
  • tests/test_dots.sh
  • tests/test_lua_syntax.sh
  • tests/test_shell.sh

Comment thread .github/workflows/test.yml
Comment thread Configs/.local/share/hypr/lua/hyde/binds.lua
Comment thread tests/python/check_dots.py Outdated
Comment thread tests/run.sh Outdated
Comment on lines +21 to +35
for case_path in "$tests_dir"/test_*.sh; do
[ -f "$case_path" ] || continue

case_name=$(basename "$case_path" .sh)
if [ -n "$filter" ]; then
case "$case_name" in
*"$filter"*) ;;
*) continue ;;
esac
fi

total=$((total + 1))
printf '%s\n' "$case_name"

if sh "$case_path"; then

@coderabbitai coderabbitai Bot Jul 29, 2026

Copy link
Copy Markdown
Contributor

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

Honor the documented executable-test contract.

The runner executes every regular test_*.sh via sh, including non-executable files and ignoring an executable test’s shebang. Filter on -x and execute the case directly.

Proposed fix
 for case_path in "$tests_dir"/test_*.sh; do
-    [ -f "$case_path" ] || continue
+    [ -f "$case_path" ] && [ -x "$case_path" ] || continue
 ...
-    if sh "$case_path"; then
+    if "$case_path"; then
📝 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
for case_path in "$tests_dir"/test_*.sh; do
[ -f "$case_path" ] || continue
case_name=$(basename "$case_path" .sh)
if [ -n "$filter" ]; then
case "$case_name" in
*"$filter"*) ;;
*) continue ;;
esac
fi
total=$((total + 1))
printf '%s\n' "$case_name"
if sh "$case_path"; then
for case_path in "$tests_dir"/test_*.sh; do
[ -f "$case_path" ] && [ -x "$case_path" ] || continue
case_name=$(basename "$case_path" .sh)
if [ -n "$filter" ]; then
case "$case_name" in
*"$filter"*) ;;
*) continue ;;
esac
fi
total=$((total + 1))
printf '%s\n' "$case_name"
if "$case_path"; then
🤖 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 `@tests/run.sh` around lines 21 - 35, Update the test discovery and execution
loop around case_path so only regular executable test_*.sh files are included by
checking both -f and -x, then invoke each selected case directly instead of
through sh, preserving its shebang behavior.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done. An executable case runs directly under its own shebang; a non-executable one still runs under sh so a forgotten chmod does not silently drop coverage.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- tests/run.sh ---'
nl -ba tests/run.sh | sed -n '1,100p'

Length of output: 472


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,100p' tests/run.sh

Length of output: 1689


@RAprogramm, verified: executable cases now run directly under their own shebang, while non-executable regular files fall back to sh as intended. That is a reasonable coverage-preserving alternative to the original executable-only proposal.

One small follow-up remains: tests/run.sh still documents a case as “any executable tests/test_*.sh,” which no longer matches the implementation. Please update that wording (and the corresponding tests/README.md wording, if present) to describe the fallback behavior.

Comment thread tests/test_shell.sh
Comment thread tests/test_shell.sh Outdated
@kRHYME7

kRHYME7 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

please resolve

@RAprogramm

Copy link
Copy Markdown
Author

Resolved — rebased onto dev after #1870 landed, conflict is gone.

While doing that CI caught something unrelated to the suite: checkout fails on this repo because the tree carries two gitlinks with no .gitmodules at all — .claude/worktrees/graceful-crafting-hanrahan and Configs/.config/zsh/ohmyzsh. Both came in with the Lua release and are in master too, so git submodule status fails for anyone who clones:

$ git submodule status
fatal: no submodule mapping found in .gitmodules for path 'Configs/.config/zsh/ohmyzsh'

Neither is referenced anywhere — zsh.toml does not deploy ohmyzsh, and oh-my-zsh plugins come from zinit snippets over the network. I dropped both, added .claude/ to .gitignore, and added tests/test_git.sh so a stray gitlink cannot come back unnoticed. Say the word if you would rather have that split into its own PR.

Also addressed the bot: workflow permissions and persist-credentials: false, the runner now honours the executable bit, shellcheck's exit status is checked, and source_root is constrained to the checkout. I turned down the one asking to parse each script under its declared shebang — Configs/.local/lib/hyde/pm.sh declares sh but uses arrays and local, and hyde-shell runs every .sh with bash anyway, so that check would land red on day one.

CI is green.

@RAprogramm

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
✅ 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.

@kRHYME7

kRHYME7 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

I usually avoid adding tests ( Before I have a lot of time reading any lapses). I thought I can remember what I wrote. But now I think adding test is fine for me and for new users.

@kRHYME7
kRHYME7 merged commit d5b2854 into HyDE-Project:dev Jul 29, 2026
6 checks passed
@RAprogramm

Copy link
Copy Markdown
Author

Thanks for merging, and for the honest read on tests.

The suite is deliberately cheap to live with: no framework, a case is one executable file in tests/, and anything whose tool is missing reports itself as skipped rather than failing, so it stays usable without the full toolchain locally. sh tests/run.sh is the whole interface.

It already runs on the other open PRs and passes there, so nothing extra is needed on your side.

@kRHYME7

kRHYME7 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Appreciated!

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants