Skip to content

Add test detection and documentation#33

Open
mikalsande wants to merge 7 commits intozarifpour:mainfrom
mikalsande:runnables
Open

Add test detection and documentation#33
mikalsande wants to merge 7 commits intozarifpour:mainfrom
mikalsande:runnables

Conversation

@mikalsande
Copy link

@mikalsande mikalsande commented Nov 22, 2025

Add runnables.scm for detecting tests and add examples to the README for how to connect tasks with tags from runnables.scm and how to add keyboard shortcut to run the test under the cursor.

The foundry tasks have been tested, the others were generated so they may or may not work. They serve as useful examples though.

When testing it if you get Nothing to compile when running a test via the play button in the UI or the keyboard shortcut it means the mapping is working 👍 To get things to actually work we'd have to set up Foundry in the repo and I'm not sure that is helpful since there are many testing frameworks for Solidity.

Summary by CodeRabbit

  • Documentation

    • Added a Tasks section to the README with example task templates and development setup steps.
  • Examples

    • Added a comprehensive Solidity test example exercising state, transfers, events, mint/burn, revert cases, and fuzzed transfers.
  • New Features

    • Added editor task templates for running tests and analysis across multiple frameworks and enhanced Solidity test discovery to detect individual test functions and contract-wide tests.

- Info about runnables.scm
- How to link tasks to runnables via tags
- How to run tasks via keyboard shortcut
@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds a README "Tasks" section, a Forge Solidity test contract, Tree‑sitter runnable queries for Solidity test discovery, and a new .zed/tasks.json with editor task templates for multiple frameworks and security/lint tools.

Changes

Cohort / File(s) Summary
Documentation
README.md
Adds a "Tasks" section with example .zed/tasks.json entries, Forge JSON task examples (function & contract), a JSON keymap snippet for running tests for the symbol under cursor, and reorders development setup steps.
Solidity Tests
code/example.test.sol
Adds ComprehensiveExampleTest Forge test contract: setup, initial-state assertions, transfers (including event checks), owner-only minting and revert checks, burn behavior with insufficient-balance revert, and a fuzzed transfer test.
Runnables / Test Discovery
languages/solidity/runnables.scm
Adds Tree‑sitter query blocks to tag test function definitions (prefixes like test, testFail, testFuzz, invariant) as solidity-test and contract declarations as solidity-contract-test for selective execution.
Editor Tasks
.zed/tasks.json
Adds comprehensive task templates for Forge, Hardhat, Truffle, Brownie, Slither, and Solhint; tasks include symbol/contract/current-file/all targets with labels, commands, args, tags, reveal settings, and terminal usage.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Editor
  participant Scanner
  participant Tasks
  participant ForgeCLI
  participant TestVM

  Editor->>Scanner: Open/scan Solidity file
  Scanner-->>Editor: Report run-capabilities (solidity-test / solidity-contract-test)
  Editor->>Tasks: Trigger test task (keymap or run command)
  Tasks->>ForgeCLI: Invoke `forge test` with selector (function/contract/file/all)
  ForgeCLI->>TestVM: Execute tests (vm, expectEmit, expectRevert, fuzz)
  TestVM-->>ForgeCLI: Return results (pass/fail, events, reverts)
  ForgeCLI-->>Editor: Present test results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 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 'Add test detection and documentation' accurately summarizes the main changes: introducing test detection via runnables.scm and documentation updates in README with task examples.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@zarifpour
Copy link
Owner

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

✅ Actions performed

Review triggered.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74563f1 and 1d653d4.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • code/example.test.sol (1 hunks)
  • languages/solidity/runnables.scm (1 hunks)
🔇 Additional comments (3)
languages/solidity/runnables.scm (1)

12-17: LGTM!

The contract-wide test detection pattern correctly captures contract names and applies the appropriate tag for running all tests in a contract.

code/example.test.sol (2)

34-103: Excellent test coverage and structure.

The test suite demonstrates comprehensive testing patterns including:

  • State verification after operations
  • Event emission testing with vm.expectEmit
  • Access control testing with vm.prank
  • Custom error handling with abi.encodeWithSelector
  • Fuzz testing with proper input constraints

The tests are well-organized and follow clear naming conventions.


1-6: Import path is valid.

The contract file exists at code/example.sol, so the import statement is correct.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
code/example.test.sol (3)

27-50: Good coverage of initial state and transfer + event behavior

test_InitialState, test_Transfer, and test_Transfer_EmitEvent collectively check supply, balances, and the Transfer event, and the vm.expectEmit pattern is idiomatic. One optional improvement would be to also assert token.balanceOf(owner) in test_Transfer_EmitEvent to keep a pure “state + event” check in that test as well.


52-70: Mint tests are clear; consider verifying prank/expectRevert behavior

test_Mint_AsOwner and test_RevertWhen_MintNotOwner nicely validate both the happy path and the onlyOwner guard, including the revert message. Depending on Foundry’s semantics for vm.prank and vm.expectRevert, it can be safer to structure the sequence so it’s obvious the prank applies to the actual mint call, e.g.:

-        vm.prank(alice);
-
-        // Expect the "Not the owner" require message from onlyOwner modifier
-        vm.expectRevert("Not the owner");
-        token.mint(alice, amount);
+        // Expect the "Not the owner" require message from onlyOwner modifier
+        vm.prank(alice);
+        vm.expectRevert("Not the owner");
+        token.mint(alice, amount);

This makes the intent explicit and avoids any ambiguity about which call the prank targets.


95-102: Fuzz test is useful; consider asserting more invariants

The fuzzed testFuzz_Transfer correctly constrains amount and checks Alice’s balance. You might optionally extend it to also assert invariants like token.balanceOf(owner) == INITIAL_SUPPLY - amount or that totalSupply() remains constant to get extra confidence from each fuzz case.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d653d4 and 5fd3f11.

📒 Files selected for processing (2)
  • code/example.test.sol (1 hunks)
  • languages/solidity/runnables.scm (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • languages/solidity/runnables.scm
🔇 Additional comments (2)
code/example.test.sol (2)

7-25: Fixture setup and owner wiring look solid

State variables, INITIAL_SUPPLY, and setUp correctly align so that owner is the deployer and holds the full initial supply; this is a clean, reusable fixture for the rest of the tests.


72-93: Burn tests correctly exercise success and custom-error failure paths

test_Burn and test_RevertWhen_BurnInsufficientBalance validate both balance/supply reduction and the encoded InsufficientBalance custom error. The explicit abi.encodeWithSelector usage is precise and keeps the test tightly coupled to the contract’s error signature.

@mikalsande
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 24, 2025

✅ Actions performed

Review triggered.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd3f11 and 69cdeee.

📒 Files selected for processing (2)
  • .zed/tasks.json (1 hunks)
  • README.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md
🔇 Additional comments (3)
.zed/tasks.json (3)

17-48: Foundry/Forge tasks look solid.

Clear differentiation between symbol, contract, file, and all-tests execution using appropriate forge flags. Since these are framework-tested per the PR description, no concerns.


53-84: Verify intent: Hardhat symbol vs contract tasks use identical commands.

Lines 54-60 and 62-68 both execute hardhat test --grep $ZED_SYMBOL, but have different labels and tags ("symbol" vs "contract"). If intended, this works, but if the contract task should match contracts instead of test names, the command differs from the Foundry pattern (which uses --match-contract). Same pattern appears in Truffle (lines 90–104) and Brownie (lines 126–140).

Confirm these are intentionally identical or update contract tasks with framework-specific contract-filtering flags.


161-192: Clarify intent: Slither symbol and contract tasks use identical commands.

Lines 162–168 and 170–176 both run slither $ZED_FILE with identical args. If intended (to allow different keybinds via tags), this mirrors the Hardhat/Truffle/Brownie pattern. If not intentional, differentiate with framework-specific arguments (e.g., contract name filtering if slither supports it).

Aligns with similar pattern flagged in Hardhat/Truffle/Brownie review.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@zarifpour
Copy link
Owner

zarifpour commented Jan 23, 2026

Thank you for your contribution!

it's not clear to me how to use this, could you provide a screenshot or an example of the feature this adds?

@czepluch are you able to test this?

@czepluch
Copy link
Collaborator

I can give it a look a bit later today or tomorrow.

@czepluch
Copy link
Collaborator

Hey, so sorry about the slow response. Was starting a new job and things have been a bit hectic. Taking a look now.

@czepluch
Copy link
Collaborator

czepluch commented Feb 15, 2026

Thanks for working on this! I tested the extension locally and found a couple of issues that prevented the play buttons from appearing. I pushed a fix to your branch:

Tag mismatch: The tags in tasks.json (e.g. ["foundry", "test", "symbol"]) didn't match the tags set in runnables.scm (solidity-test, solidity-contract-test). Zed requires an exact match between the #set! tag in runnables.scm and the tags array in tasks.json for the play buttons to show up. Fixed all task definitions to use the correct tags.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.zed/tasks.json (1)

53-68: Hardhat symbol and contract tasks are identical.

Both tasks use --grep $ZED_SYMBOL with the same arguments, making them functionally identical. Unlike Foundry which has distinct --match-test vs --match-contract flags, Hardhat's --grep doesn't differentiate between test function names and contract names.

Consider either:

  1. Removing the redundant (contract) variant, or
  2. Adding a comment clarifying they exist for tag-based discovery purposes

The same pattern applies to Truffle (lines 89-104) and Brownie (lines 125-140).

♻️ Option: Consolidate to single symbol task
   {
     "label": "hardhat test: $ZED_SYMBOL",
     "command": "npx",
     "args": ["hardhat", "test", "--grep", "$ZED_SYMBOL"],
-    "tags": ["solidity-test"],
+    "tags": ["solidity-test", "solidity-contract-test"],
     "reveal": "always",
     "use_new_terminal": false
   },
-  {
-    "label": "hardhat test: $ZED_SYMBOL (contract)",
-    "command": "npx",
-    "args": ["hardhat", "test", "--grep", "$ZED_SYMBOL"],
-    "tags": ["solidity-contract-test"],
-    "reveal": "always",
-    "use_new_terminal": false
-  },

- Fix tasks.json tags to match runnables.scm tags (solidity-test,
  solidity-contract-test). Previously tags like ["foundry", "test",
  "symbol"] didn't match any runnable, so no play buttons appeared.

- Restructure runnables.scm query to follow the pattern used by
  Zed's built-in language extensions.

- Broaden test function regex from ^(test_) to ^test to match all
  Solidity test conventions: test_, testFuzz_, testFail_, testFork_.

- Add separate invariant pattern for invariant test detection.

- Consolidate duplicate security/linting tasks that were identical.
@czepluch
Copy link
Collaborator

@mikalsande can you please enable verified commits?

@czepluch
Copy link
Collaborator

Can you please pump the version @mikalsande?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants