Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fedbd9d
feat: document new suites/fixtures that can be supported
olisikh Feb 27, 2026
7badff8
cleaned up test-project
olisikh Feb 27, 2026
128eb52
feat(munit): support ecosystem suite detection
olisikh Feb 27, 2026
a2f1b3f
feat(specs2): add bang operator and textspec fallback discovery
olisikh Feb 27, 2026
1840345
delete TODO
olisikh Feb 27, 2026
43728eb
update build.sbt
olisikh Feb 27, 2026
c17efa6
feat(scalatest): add propspec and async/fixture suite detection
olisikh Feb 27, 2026
e3166ca
fix(specs2): drop unsupported bang and no-ref textspec paths
olisikh Feb 27, 2026
a5b8245
feat(scalatest): support wordspec funspec and featurespec
olisikh Feb 27, 2026
dffa7fe
chore: ignore local sbt caches in test-project
olisikh Feb 27, 2026
4ec949a
fix(discovery): support interpolated test names
olisikh Feb 27, 2026
ad8c556
fix(results): match interpolated test names
olisikh Feb 27, 2026
30f3c4a
fix(scalatest): make SampleRefSpec discoverable by sbt
olisikh Feb 27, 2026
fb0ecca
feat: add RefSpec and specs2 fragment discovery
olisikh Feb 27, 2026
e1c4d0d
fix(utest): handle interpolated test selectors
olisikh Feb 27, 2026
b234025
Fix utest interpolated result mapping for numeric names
olisikh Feb 27, 2026
f9bd9af
Fix specs2 fragment stdout fallback matching
olisikh Feb 27, 2026
71d8291
Fix FeatureSpec bloop stdout parsing
olisikh Feb 27, 2026
b1fdeb8
Avoid injecting sbt --batch into bloop commands
olisikh Feb 27, 2026
e943606
Improve munit bloop parsing for ScalaCheck failures
olisikh Feb 27, 2026
5961175
Narrow munit namespace selector for bloop
olisikh Feb 27, 2026
d938fa4
Restrict munit file runs to discovered suite
olisikh Feb 27, 2026
446b67c
Strip munit source snippets from diagnostics
olisikh Feb 27, 2026
7635fe2
Trim munit crash diagnostics to failure block
olisikh Feb 27, 2026
2a6e891
munit: use snippet line numbers for diagnostics
olisikh Feb 27, 2026
6b408fc
munit: strip colon-only snippet lines in diagnostics
olisikh Feb 27, 2026
1eef985
munit: fail when bloop runs no suites
olisikh Feb 27, 2026
4ad268d
munit: run suite for bloop single-test requests
olisikh Feb 27, 2026
2afcb7d
utest: map numeric junit ids using full namespace tests
olisikh Feb 27, 2026
6170e6b
fmt
olisikh Feb 27, 2026
40a3e50
docs: update README and wiki for latest suite behavior
olisikh Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ target
.bsp
.bloop
metals.sbt
.ivy2
.sbt-boot
.sbt-global

# LLM
.sisyphus
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ Support levels below describe **test execution + result reporting** in neotest.

| Library | Test type | Build tool | Support | Notes |
|---------|-----------|------------|---------|-------|
| ScalaTest | `AnyFunSuite`, `AnyFreeSpec`, `AnyFlatSpec` | `sbt` | **Full** | Stable path via JUnit XML reports. |
| ScalaTest | `AnyFunSuite`, `AnyFreeSpec`, `AnyFlatSpec` | `bloop` | **Limited** | Uses stdout parsing for results (with additional JUnit report flags passed to runner); matching is best-effort vs XML. |
| munit | `FunSuite` | `sbt` | **Full** | Stable path via JUnit XML reports. |
| munit | `FunSuite` | `bloop` | **Limited** | Uses stdout parsing; works for common output, but parser-based matching is inherently less stable than XML. |
| specs2 | `mutable.Specification` | `sbt` | **Limited** | General execution works, but single-test selection can still run a larger scope/spec. |
| specs2 | `mutable.Specification` | `bloop` | **Limited** | Uses stdout parsing; supports fail/crash markers, but matching remains best-effort. |
| ScalaTest | `AnyFunSuite`, `AnyFreeSpec`, `AnyFlatSpec`, `AnyPropSpec`, `AnyWordSpec`, `AnyFunSpec`, `AnyFeatureSpec`, `RefSpec` (+ `Async*` / `Fixture*` variants where applicable) | `sbt` | **Full** | Stable path via JUnit XML reports. |
| ScalaTest | `AnyFunSuite`, `AnyFreeSpec`, `AnyFlatSpec`, `AnyPropSpec`, `AnyWordSpec`, `AnyFunSpec`, `AnyFeatureSpec`, `RefSpec` (+ `Async*` / `Fixture*` variants where applicable) | `bloop` | **Limited** | Uses stdout parsing for results (with additional JUnit report flags passed to runner); matching is best-effort vs XML. |
| munit | `FunSuite`, `CatsEffectSuite`, `ScalaCheckSuite`, `DisciplineSuite`, `ZSuite`, `ZIOSuite` | `sbt` | **Full** | Stable path via JUnit XML reports. |
| munit | `FunSuite`, `CatsEffectSuite`, `ScalaCheckSuite`, `DisciplineSuite`, `ZSuite`, `ZIOSuite` | `bloop` | **Limited** | Uses stdout parsing; single-test runs are executed at suite scope for reliability, and `No test suites were run` is reported as failure. |
| specs2 | `Specification` (`>>`, `in`, basic `!` fragments) | `sbt` | **Limited** | General execution works, but single-test selection can still run a larger scope/spec. |
| specs2 | `Specification` (`>>`, `in`, basic `!` fragments) | `bloop` | **Limited** | Uses stdout parsing; supports fail/crash markers, but matching remains best-effort. |
| specs2 | text spec (`s2""" ... """`) | `sbt` | **Limited** | Execution works, but fine-grained single-test runs are limited. |
| specs2 | text spec (`s2""" ... """`) | `bloop` | **Limited** | Same single-test limits plus stdout parsing constraints. |
| zio-test | `ZIOSpecDefault` | `sbt` | **Full** | Stable path via JUnit XML reports. |
| zio-test | `ZIOSpecDefault` | `bloop` | **Not supported** | Automatically forced to `sbt` (`bloop` execution is disabled for this framework). |
| uTest | `TestSuite` | `sbt` | **Full** | Works for run/result flow; debug single-test remains constrained by uTest selector limitations. |
| uTest | `TestSuite` | `sbt` | **Full** | Works for run/result flow; interpolated names may run at suite scope with numeric JUnit result mapping; debug single-test remains constrained by uTest selector limitations. |
| uTest | `TestSuite` | `bloop` | **Not supported** | Known issue: uTest suites can't be discovered by bloop; tests will be run by sbt. |

> Recommendation: prefer `sbt` for stability. Use `bloop` when speed matters and current framework limitations are acceptable.
Expand Down
22 changes: 0 additions & 22 deletions TODO.md

This file was deleted.

7 changes: 4 additions & 3 deletions lua/neotest-scala/build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ function M.command_with_path(opts)
local root_path = opts.root_path
local project = opts.project
local test_path = opts.test_path
local extra_args = with_sbt_batch(opts.extra_args)
local extra_args = opts.extra_args
local tool_override = opts.tool_override
local build_tool = M.resolve_tool(root_path, tool_override)
local bloop_project = project .. "-test"
Expand All @@ -400,10 +400,11 @@ function M.command_with_path(opts)

return flatten({ "bloop", "test", bloop_project, "--only", test_path, extra_args })
else
local sbt_extra_args = with_sbt_batch(extra_args)
if not test_path then
return flatten({ "sbt", extra_args, project .. "/test" })
return flatten({ "sbt", sbt_extra_args, project .. "/test" })
end
return flatten({ "sbt", extra_args, project .. "/testOnly -- " .. '"' .. test_path .. '"' })
return flatten({ "sbt", sbt_extra_args, project .. "/testOnly -- " .. '"' .. test_path .. '"' })
end
end

Expand Down
25 changes: 23 additions & 2 deletions lua/neotest-scala/framework.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,35 @@ local FRAMEWORK_MARKERS = {
scalatest = {
"org%.scalatest",
"extends%s+AnyFunSuite",
"extends%s+.*FunSuite",
"extends%s+AsyncFunSuite",
"extends%s+FixtureAnyFunSuite",
"extends%s+AnyFreeSpec",
"extends%s+.*FreeSpec",
"extends%s+AsyncFreeSpec",
"extends%s+FixtureAnyFreeSpec",
"extends%s+AnyFlatSpec",
"extends%s+AsyncFlatSpec",
"extends%s+FixtureAnyFlatSpec",
"extends%s+AnyPropSpec",
"extends%s+FixtureAnyPropSpec",
"extends%s+AnyWordSpec",
"extends%s+AsyncWordSpec",
"extends%s+FixtureAnyWordSpec",
"extends%s+AnyFunSpec",
"extends%s+AsyncFunSpec",
"extends%s+FixtureAnyFunSpec",
"extends%s+AnyFeatureSpec",
"extends%s+AsyncFeatureSpec",
"extends%s+FixtureAnyFeatureSpec",
},
munit = {
"org%.scalameta%.munit",
"munit%.FunSuite",
"extends%s+FunSuite",
"extends%s+CatsEffectSuite",
"extends%s+ScalaCheckSuite",
"extends%s+DisciplineSuite",
"extends%s+ZSuite",
"extends%s+ZIOSuite",
},
specs2 = {
"org%.specs2",
Expand Down
Loading