Skip to content

Add JS unit tests and GitHub Actions CI - #4

Merged
markrcote merged 3 commits into
mainfrom
claude/js-unit-tests
Jun 2, 2026
Merged

Add JS unit tests and GitHub Actions CI#4
markrcote merged 3 commits into
mainfrom
claude/js-unit-tests

Conversation

@markrcote

Copy link
Copy Markdown
Owner

Extracts the timer logic from the inline <script> in index.html into a standalone timer.js that can be imported by Jest. Adds 20 tests and a CI workflow.

What changed

  • app/src/main/assets/timer.js — new file with all timer logic (formatTime, initTimer). initTimer accepts injectable opts (now, onRestEnd, onExerciseComplete) so tests can control the clock and assert on callbacks without a real browser. Exports via module.exports when running in Node.
  • app/src/main/assets/index.html — inline script replaced with <script src="timer.js"> + a small wiring block that calls initTimer and attaches event listeners.
  • tests/timer.test.js — 20 Jest tests across three suites:
    • formatTime — boundary and padding cases
    • initTimer state — set counting, rest start/block/reset, exercise completion, setConfig
    • Wall-clock timer — restEndTime set correctly, timeRemaining derived from clock, rest expiry, foreground chime fires, background chime suppressed
  • package.json + package-lock.json — Jest dev dependency
  • .github/workflows/js-tests.yml — runs npm ci && npm test on every push and PR

Test run

Tests: 20 passed, 20 total
Time:  0.494 s

https://claude.ai/code/session_01NRGYpoWMBRkqdbZsKa887v


Generated by Claude Code

Extracts timer logic from the inline <script> in index.html into a
standalone timer.js that exports formatTime and initTimer for testing.
initTimer accepts injectable opts (now, onRestEnd, onExerciseComplete)
so tests can control the clock and assert on callbacks without needing
a real browser.

20 Jest tests cover: formatTime formatting, set-counter state
transitions, rest-timer start/block/reset, exercise completion, and the
wall-clock accuracy + background-chime-suppression behaviour.

GitHub Actions workflow runs the suite on every push and PR.

https://claude.ai/code/session_01NRGYpoWMBRkqdbZsKa887v

Copilot AI 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.

Pull request overview

Extracts the timer logic from the HTML inline script into a standalone JS module that can be unit-tested in Node, adds a Jest test suite, and wires up GitHub Actions CI to run those tests on pushes/PRs.

Changes:

  • Added app/src/main/assets/timer.js containing formatTime and initTimer with injectable dependencies for deterministic tests.
  • Updated app/src/main/assets/index.html to load timer.js and delegate UI behavior to initTimer.
  • Added Jest setup (package.json, package-lock.json), a 20-test suite (tests/timer.test.js), and a CI workflow (.github/workflows/js-tests.yml); updated .gitignore for node_modules.

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/src/main/assets/timer.js New extracted timer module with callbacks/clock injection for testability.
app/src/main/assets/index.html Loads the new module and wires DOM events to initTimer methods.
tests/timer.test.js Jest unit tests for formatting and timer state/wall-clock behavior.
package.json Adds Jest as a dev dependency and defines the npm test script/config.
package-lock.json Locks Jest and its dependency graph for reproducible installs.
.github/workflows/js-tests.yml Runs npm ci + npm test in GitHub Actions.
.gitignore Ignores node_modules for the new JS toolchain.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/src/main/assets/timer.js Outdated
Comment thread app/src/main/assets/timer.js Outdated
Comment thread tests/timer.test.js
Comment thread app/src/main/assets/timer.js
Comment thread app/src/main/assets/index.html Outdated
- Stringify textContent assignments (TARGET_SETS, setCount) — DOM always
  coerces to string; being explicit avoids type mismatches in plain-object
  test mocks and matches real browser behaviour
- Close AudioContext after all tones finish to avoid hitting browser
  limits on concurrent contexts
- Store button elements in variables before passing to initTimer so
  addEventListener calls reuse the same references instead of doing
  redundant getElementById lookups
- Update test expectation for setTotalDisplay to match string '5'

https://claude.ai/code/session_01NRGYpoWMBRkqdbZsKa887v

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated 2 comments.

Comment thread app/src/main/assets/timer.js
Comment thread tests/timer.test.js
Use Math.ceil instead of Math.round so the rest countdown never hits zero
while up to ~0.5s of time still remains. Update makeDom() in tests to match
index.html's initial state (timerLabel/resetBtn hidden, timerLabel text set).

https://claude.ai/code/session_01RkZzre56VRXz3JYn2v3U4P

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated 2 comments.

Comment thread app/src/main/assets/timer.js
Comment on lines +172 to +174
if (typeof module !== 'undefined') {
module.exports = { formatTime, initTimer };
}
@markrcote
markrcote merged commit 9a1c53b into main Jun 2, 2026
3 checks passed
@markrcote
markrcote deleted the claude/js-unit-tests branch June 2, 2026 01:48
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.

3 participants