Skip to content

Gate Zed and Rider coverage; replace the Zed tests that asserted nothing - #211

Merged
MelbourneDeveloper merged 2 commits into
mainfrom
coverage-gates-zed-rider
Aug 4, 2026
Merged

Gate Zed and Rider coverage; replace the Zed tests that asserted nothing#211
MelbourneDeveloper merged 2 commits into
mainfrom
coverage-gates-zed-rider

Conversation

@MelbourneDeveloper

Copy link
Copy Markdown
Collaborator

.config/coverage/thresholds.json gated five packages — sharplsp, vscode-extension, and the three sidecars. Neither editor integration was one of them.

What was unguarded

Zed shipped 23 unit tests that were never executed. make _lint-zed runs clippy --all-targets, which compiles them; make test had no Zed target. Unrun, they had rotted:

Test What it actually asserted
expected_version_matches_cargo_toml EXPECTED_VERSION == env!("CARGO_PKG_VERSION") — and EXPECTED_VERSION is that env. Tautology.
server_binary_name_is_sharplsp a const equals its own literal
expected_version_matches_extension_toml_version that the crate version is non-empty. Its doc comment claims it proves extension.toml/Cargo.toml parity; it never opens extension.toml.
missing_binary_error_... rebuilt the error string inside the test and asserted on its own copy — changing the real message in resolve_binary could not fail it

Rider had 2961 LOC of Kotlin, zero tests, and zero CI presence — not built, not linted, not tested on any PR. build.gradle.kts declared junit-jupiter, testFramework(TestFrameworkType.Platform), and tasks.test { useJUnitPlatform() } against no src/test directory at all.

What this adds

Package Tests Coverage Gate
sharplsp-zed 23 → 31 75.41% → 85.04% make _test-zed
sharplsp-rider 0 → 8 0% → 4.09% make _test-rider (Kover)

Zed — the parse → read → enrich → format pipeline moves out of the zed::Worktree shell into pipeline.rs (98.41%) so it is reachable from a test; cached_or, with_default_log_level and tree_output split out of the WASM API adapters. The version-parity test now actually parses extension.toml, and the missing-binary test asserts on the message cached_or really produces.

Rider — first tests cover NuGetState: the installed-list merge, case-insensitive id matching (the two LSP responses do not agree on casing), sort order, and pending flags. Kover is wired to the repo ratchet at its honest 4.09%.

Two build defects had to be fixed before any Rider test could run:

  • The platform test framework registers com.intellij.tests.JUnit5TestSessionListener, whose constructor loads junit.framework.TestCase. Without JUnit 4 on the runtime classpath it fails to instantiate and the task dies before a single test runs — NoClassDefFoundError, not a test failure.
  • That framework also puts junit-vintage on the classpath, built against a newer junit-platform-commons than junit-jupiter 5.11.3 ships (support.scanning.ClassFilter). Vintage throws during discovery, aborting the whole task. Discovery is now Jupiter-only.

failOnNoDiscoveredTests = true stops an empty test task reporting BUILD SUCCESSFUL — which is exactly how this harness stayed green while containing nothing.

CI

New ci-editors.yml runs both legs. RIDER_REQUIRED=1 turns "no JDK 21+ found" from a local convenience skip into a hard CI failure, so the gate cannot silently skip. The Rider job also builds the plugin — it was never compiled on a PR before, so a Kotlin break could reach main behind a fully green pipeline.

Also

  • default_threshold: 90 removed. check-coverage.mjs reads thresholds[project].line_percent and hard-fails on an unknown key; it never consulted default_threshold. Hard-failing on an ungated package is the correct strict behaviour and is what surfaced this gap.
  • The JDK-21 discovery loop was duplicated per Rider make target — now once, in tools/rider/gradle.sh.

Verified locally

[sharplsp-zed]   coverage: 85.0394% (threshold: 85.04%)   31 passed, 0 failed
[sharplsp-rider] coverage: 4.0919%  (threshold: 4.09%)     8 passed, 0 skipped

make _lint-zed clean. make _build-rider still produces dist/sharplsp-rider.zip through the shared script.

Remaining debt

Tracked in #210: 95.9% of the Rider plugin is still untested (LspBridge, the tree nodes, PackageCardRenderer, PackageDetailsPanel, settings persistence — most needs BasePlatformTestCase fixtures), and Zed's 85% is near its ceiling as structured, since the remainder only exists inside Zed's WASM host.

`.config/coverage/thresholds.json` gated five packages. Neither editor
integration was one of them.

Zed shipped 23 unit tests that were never executed: `make _lint-zed` runs
clippy `--all-targets`, which compiles them, and `make test` had no Zed
target. Unrun, they had rotted into tautologies —
`expected_version_matches_cargo_toml` asserted `EXPECTED_VERSION ==
env!("CARGO_PKG_VERSION")` where `EXPECTED_VERSION` *is* that env; the test
named for extension.toml/Cargo.toml version parity never opened
extension.toml; the missing-binary test rebuilt the error string inside
itself and asserted on its own copy.

Rider had 2961 LOC of Kotlin, zero tests, and zero CI presence — not built,
not linted, not tested. build.gradle.kts declared junit-jupiter, the platform
test framework, and a `test { useJUnitPlatform() }` block against no `src/test`
directory at all.

Zed: extract the parse -> read -> enrich -> format pipeline out of the
`zed::Worktree` shell into pipeline.rs so it is reachable from a test, and
split `cached_or` / `with_default_log_level` / `tree_output` out of the WASM
API adapters. Real tests replace the vacuous ones, including version parity
that actually parses extension.toml. 75.41% -> 85.04%.

Rider: first tests (NuGetState — installed-list merge, case-insensitive id
matching, sort order, pending flags), plus Kover wired to the repo ratchet at
its honest 4.09%. Two build fixes were needed before any test could run: the
platform's JUnit5TestSessionListener loads junit.framework.TestCase and dies
without JUnit 4 on the runtime classpath, and the junit-vintage it drags in
throws during discovery against junit-jupiter 5.11.3's older
junit-platform-commons. `failOnNoDiscoveredTests` now stops an empty test task
reporting BUILD SUCCESSFUL, which is how the harness stayed green while empty.

ci-editors.yml runs both. RIDER_REQUIRED=1 turns a missing JDK 21+ from a
local convenience skip into a hard CI failure.

Also: drop `default_threshold: 90`, which check-coverage.mjs never read, and
de-duplicate the JDK-21 discovery loop into tools/rider/gradle.sh.

Remaining debt tracked in #210.
The Zed workspace builds into src/editors/zed/target, so on a fresh checkout
the root target/ that holds every other coverage artifact does not exist and
llvm-cov fails with "No such file or directory" after all 31 tests pass.

Local runs missed it because target/ was already there from the Rust host
build.
@MelbourneDeveloper
MelbourneDeveloper merged commit e96c102 into main Aug 4, 2026
28 checks passed
@MelbourneDeveloper
MelbourneDeveloper deleted the coverage-gates-zed-rider branch August 4, 2026 09:58
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