Skip to content

Teach run-test-at-point four more languages - #2136

Merged
bbatsov merged 2 commits into
masterfrom
feature/test-at-point-rules
Jul 28, 2026
Merged

Teach run-test-at-point four more languages#2136
bbatsov merged 2 commits into
masterfrom
feature/test-at-point-rules

Conversation

@bbatsov

@bbatsov bbatsov commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Ruby, Rust, Elixir and Java join the Python, Go and JS/TS rules the feature
shipped with.

Three of them needed more than the (name, file) the rule contract hands to a
command function, and the ways round that are the interesting part:

  • Ruby writes RSpec and Minitest in the same major mode, so one rule matches
    both an it block and a test_-prefixed method, and the project type
    decides whether to spell rspec -e or ruby -Itest -n.
  • Java addresses a test as Class#method. Java requires the public class to
    be named after its file, so the class comes from the file name; the project
    type again picks between Maven's and Gradle's selector syntax.
  • ExUnit has no way to select a test by name from the command line at all,
    so Elixir tests are addressed as FILE:LINE. The command function runs in the
    buffer with point still on the test, so the line is there for the taking.
  • Rust needs the #[test] attribute to tell a test from an ordinary
    function, which means walking back over however many attributes are stacked
    above it - #[ignore] on top of #[test] still counts. The fake-treesit test
    harness grew treesit-node-prev-sibling for this.

All the specs use the existing fake-node harness, so they run without
tree-sitter or any grammar installed.

One thing the specs caught: I'd written the expected commands with shell
quoting (-e 'adds it'), but shell-quote-argument escapes (-e adds\ it).
The expectations go through shell-quote-argument now, which also keeps them
honest on a platform that quotes differently.

package-lint gains more "needs Emacs 29.1" notes for the treesit calls - the
same ones the existing rules already produce, and that step is report-only.
relint, the hard gate, stays clean.

bbatsov added 2 commits July 28, 2026 11:41
Ruby, Rust, Elixir and Java join Python, Go and JS/TS. Three of them
needed something beyond a name and a file:

Ruby's two frameworks share a major mode, so the rule matches both an
RSpec example and a Minitest method and the project type decides which
runner to spell. Java is addressed as Class#method, and since Java makes
the public class match its file the class comes from the file name; the
project type picks between Maven's and Gradle's selector syntax. ExUnit
has no name filter at all, so Elixir tests are addressed by line.

Rust needs the #[test] attribute to distinguish a test from an ordinary
function, which means walking back over the attributes stacked above it
- so the fake-treesit test harness grew node-prev-sibling.
The other treesit functions are declared for the benefit of an Emacs
built without tree-sitter; this one was not, so the 28.2 build failed to
byte-compile while a local 30.2 compiled it happily.
@bbatsov
bbatsov merged commit 727b62a into master Jul 28, 2026
10 checks passed
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