How to Write Unit and Integration Tests for the i-have-adhd Extension
The i-have-adhd repository ships a complete test suite that demonstrates both unit-style tests for individual components and integration-style smoke tests that exercise the extension through the Pi and OMP runtimes.
The ayghri/i-have-adhd repository provides a fully functional harness to write unit or integration tests for the i-have-adhd extension. By mirroring the existing patterns in tests/ and scripts/, you can validate everything from front-matter stripping to full command-toggle workflows in isolated agent environments.
Unit Test Architecture and Key Files
The unit test layer focuses on pure functions and small behaviors without spawning a full runtime. The extension entry point in extensions/i-have-adhd.ts exports stripFrontmatter for front-matter stripping, while extensions/context-compat.ts provides contextMessages and latestMarkerIsActive for state inspection.
The primary unit-level test files are:
tests/test_always_on_hooks.py— Validates platform-specific hook scripts that inject the ADHD banner when an opt-in flag is present.tests/test_opencode_plugin.py— Covers the OpenCode plugin version of the extension.tests/test_omp_package.py— Ensures the extension manifest is correctly declared for both Pi and OMP runtimes.
These files use standard unittest.TestCase classes and import utilities directly from the extensions/ package using the repository’s module path structure.
Writing a New Unit Test
When you add a pure-function change, create a new unittest.TestCase in the tests/ directory and import the target function from its module path. For example, stripFrontmatter as implemented in extensions/i-have-adhd.ts can be tested like this:
import unittest
from extensions.i_have_adhd import stripFrontmatter # type: ignore
class FrontMatterTest(unittest.TestCase):
def test_strips_simple_frontmatter(self):
src = "---\nname: demo\n---\nHello world"
self.assertEqual(stripFrontmatter(src), "Hello world")
This pattern follows the existing hook tests in tests/test_always_on_hooks.py, which rely on repository-relative imports and runtime-agnostic helpers such as run_hook and run_codex_hook to execute scripts in isolation.
Integration Test Architecture
Integration tests spin up a temporary Pi or OMP agent, load the extension, issue commands, and assert on the resulting session state. The main driver is scripts/check_pi_extension.py, which defines the RpcClient class and provides verification helpers like message_count, latest_enabled, and status_texts.
The integration layer validates end-to-end behaviors such as:
- Command registration, confirming that
/i-have-adhdappears in the available command list. - Toggling ADHD mode on and off via RPC prompts.
- Verifying that UI status texts and session entry markers update correctly after each command.
Writing a New Integration Smoke Test
To cover end-to-end behavior, extend the pattern used in scripts/check_pi_extension.py. The following skeleton builds an isolated environment, instantiates an RpcClient, and asserts that toggling the extension off clears the UI status and adds the disabled marker:
import unittest
from pathlib import Path
from scripts.check_pi_extension import RpcClient, build_isolated_env, status_texts, message_count
class IHaveADHDSmokeTest(unittest.TestCase):
def test_toggle_off(self):
from scripts.check_pi_extension import ROOT
env = build_isolated_env(agent_dir="tmp-agent")
client = RpcClient(
"pi",
env,
"--no-session",
"-e",
str(ROOT / "extensions/i-have-adhd.ts")
)
try:
cmds, _ = client.request("commands", {"type": "get_commands"})
self.assertIn("i-have-adhd", {c["name"] for c in cmds["data"]["commands"]})
client.request("toggle-on", {"type": "prompt", "message": "/i-have-adhd"})
off_evt = client.request("toggle-off", {"type": "prompt", "message": "/i-have-adhd"})[1]
self.assertIn(None, status_texts(off_evt))
entries, _ = client.request("entries", {"type": "get_entries"})
self.assertEqual(message_count(entries, "i-have-adhd-disabled"), 1)
finally:
client.close()
Key steps in this flow:
- Isolate the environment —
build_isolated_envcreates a temporary agent directory. - Instantiate the client —
RpcClientlaunches the Pi or OMP runtime with the extension entry point loaded. - Verify registration — Query the command list to ensure
i-have-adhdis present. - Drive the toggle — Send prompt messages via RPC and inspect UI events using
status_texts. - Assert on session state — Fetch entries and use
message_countto confirm markers such asi-have-adhd-disabledappear exactly once.
Testing the Always-On Hook Scripts
The always-on hook scripts inject the ADHD banner when an opt-in flag is detected. The file tests/test_always_on_hooks.py already verifies that these scripts correctly strip front-matter and respect the opt-in flag across supported runtimes.
To add coverage for a new runtime, extend the test class with a new case that invokes your hook via the existing run_hook helper:
def test_new_runtime_respects_opt_in(self):
command = ["node", self.plugin_root / "hooks" / "custom-runtime.mjs"]
result = self.run_hook(command)
self.assertEqual(0, result.returncode)
This approach keeps hook tests runtime-agnostic by relying on standard subprocess execution and output assertions.
Running the Tests Locally
Execute the unit tests using Python’s built-in discovery:
python3 -m unittest discover -s tests -v
Run the integration smoke tests directly from the driver script for either runtime:
python3 scripts/check_pi_extension.py --runtime pi
python3 scripts/check_pi_extension.py --runtime omp
Both commands print a confirmation message when the extension behaves as expected. New test files added under tests/ are picked up automatically as long as they follow the test_*.py naming convention.
Summary
- The
ayghri/i-have-adhdrepository separates unit tests for pure functions and hooks from integration smoke tests that drive the full Pi or OMP runtime. - Write unit tests by importing functions such as
stripFrontmatterfromextensions.i_have_adhdinto standardunittestclasses. - Write integration tests by reusing
RpcClient,build_isolated_env,status_texts, andmessage_countfromscripts/check_pi_extension.py. - Validate always-on hooks with the
run_hookhelper intests/test_always_on_hooks.pyto assert correct front-matter handling and opt-in behavior. - Run the full suite with
python3 -m unittest discover -s tests -vand the RPC driver withpython3 scripts/check_pi_extension.py.
Frequently Asked Questions
How do I write unit tests for the i-have-adhd extension?
Create a Python file under tests/ that imports the function you want to exercise from the extensions/ package. Use the standard unittest library and assert on return values from pure functions like stripFrontmatter, following the pattern established in tests/test_always_on_hooks.py.
How do I write integration tests for the i-have-adhd extension?
Use the RpcClient class defined in scripts/check_pi_extension.py to spin up a temporary Pi or OMP agent with the extension loaded. Send RPC commands to trigger /i-have-adhd, then inspect the returned events with helpers like status_texts and message_count to verify session state changes.
What is the fastest way to run the i-have-adhd test suite?
Run python3 -m unittest discover -s tests -v for unit tests, or execute python3 scripts/check_pi_extension.py --runtime pi (or --runtime omp) for integration smoke tests. Both commands report pass or fail status directly in the terminal.
Where are the main source files for the i-have-adhd extension?
The entry point is extensions/i-have-adhd.ts, which registers commands and manages rule injection. Context utilities such as contextMessages and latestMarkerIsActive live in extensions/context-compat.ts, and both are exercised by the existing unit and integration tests according to the ayghri/i-have-adhd source code.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →