write-test
/write-test
Use when adding or modifying JETLS tests. Covers test file and module structure, `@testset` organization, `let` blocks, `withserver` usage, cached syntax trees in helpers that call features directly, and when subroutine tests are sufficient for language-server features.
- Author
- aviatesk ↗
- Repository
- JETLS.jl ↗
- Licence
- MIT
- Last repository change
- 27.10.2026
Assessment and security
- Files in this package
- 1
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 27.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
Use when adding or modifying JETLS tests. Covers test file and module structure, `@testset` organization, `let` blocks, `withserver` usage, cached syntax trees in helpers that call features directly, and when subroutine tests are sufficient for language-server features.
Original author description
Use when adding or modifying JETLS tests. Covers test file and module structure, `@testset` organization, `let` blocks, `withserver` usage, cached syntax trees in helpers that call features directly, and when subroutine tests are sufficient for language-server features.
How it works
- Test file structure
- Organizing test code
- Language-server feature tests
- After writing tests
SKILL.md preview
---
name: write-test
description: >
Use when adding or modifying JETLS tests. Covers test file and module
structure, `@testset` organization, `let` blocks, `withserver` usage,
cached syntax trees in helpers that call features directly, and when
subroutine tests are sufficient for language-server features.
---
# Write JETLS tests
Use this skill when you add new tests or modify existing JETLS test code.
## Test file structure
Test code for new language server features should be written in files that
define independent module spaces with a `test_` prefix. Include those files
from `JETLSCore/test/runtests.jl`.
This lets each test file run independently from the REPL.
For example, `JETLSCore/test/test_completions.jl` should look like:
```julia
module test_completions
using Test
...
end # module test_completions
```
Then include it from `JETLSCore/test/runtests.jl` like this:
```julia
@testset "JETLS.jl" begin
...
@testset "completions" include("test_completions.jl")
...
end
```
## Organizing test code
Use `@testset "testset name"` to organize tests cleanly.
For code clarity, avoid placing `using`, `import`, or `struct` definitions
inside `@testset` blocks unless it is specifically necessary.
Prefer top-level definitions.
Use `let` blocks to avoid unintentionally reusing names across test cases,
unless a helper function or `do` block already provides local scope.
Example:
```julia
module test_completions
using Test
using JETLSCore: some_completion_func
function testcase_util(s::AbstractString)
...
end
function with_testcase(s::AbstractString)
...
end
@testset "some_completion_func" begin
let s = "..."
ret = some_completion_func(testcase_util(s))
@test test_with(ret)
end
let s = "..."
ret = some_completion_func(testcase_util(s))
@test test_with(ret)
end
with_testcase(s) do case
ret = some_completion_func(case)
@test test_with(ret)
end
end
end # module test_completions
```
## Language-server feature tests
Testing language server functionality is challenging. To fully test such
functionality, you need to start a server loop and send requests that mimic
realistic user interactions.
For those tests, use `withserver` from
[`JETLSCore/test/setup.jl`](../../../JETLSCore/test/setup.jl).
Refer to [`JETLSCore/test/test_full_lifecycle.jl`](../../../JETLSCore/test/test_full_lifecycle.jl)
as an example.
A good pattern is [`JETLSCore/test/test_definition.jl`](../../../JETLSCore/test/test_definition.jl):
it keeps the full `withserver` coverage to one `request/response sanity` test
for the `DidOpen` → analysis → `DefinitionRequest` path, while most cases use
`definition_test` to call `find_definition` directly and assert on returned
locations. Prefer this split for LSP handlers.
### Cached syntax trees
Requests on a synchronized document share the cached syntax tree of its
`FileInfo` without copying it, so no feature may mutate that tree. Under
`JETLS_TEST_MODE`, JETLS records a fingerprint of each cached tree and
`JETLSCore.check_syntax_tree0(fi)` throws if the tree has changed since.
`withserver` runs this check for every open document when the test finishes.
Helpers that construct their own `FileInfo` and call a feature directly
should construct it with `cache_tree0 = true`, as `cache_file_info!` does for
synchronized documents, and call `JETLSCore.check_syntax_tree0(fi)` after the
feature call:
```julia
function find_definition(text::AbstractString, pos::Position)
server = JETLSCore.Server()
filename = joinpath(@__DIR__, "testfile_$(gensym(:definition)).jl")
fi = JETLSCore.FileInfo(#=version=#0, text, filename; cache_tree0 = true)
furi = filename2uri(filename)
JETLSCore.store!(server.state.file_cache) do cache
Base.PersistentDict(cache, furi => fi), nothing
end
result = JETLSCore.find_definition(server, furi, fi, pos)
JETLSCore.check_syntax_tree0(fi)
return result
end
```
Leave `cache_tree0` unset when the `FileInfo` is only used to convert
positions or stands for a file that is not open in the editor, since JETLS
doesn't cache a tree for such files in production either.
## After writing tests
When you add or modify tests, use the [`run-test`](../run-test/SKILL.md)
workflow to run the most specific relevant test command.
Versions
| Repository | Score | Licence |
|---|---|---|
| This page · aviatesk/JETLS.jl | 95 | MIT |
| markneonin/paneline | 96 | MIT |
Database snapshot: 13.11.2026 · package version 64f9a5ab0b5e (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100run-test
Use when choosing or running JETLS tests after code changes. Prefer component-specific tests, avoid the full suite unless needed, and use TestRunner for focused iteration. - 100testing
Helps write and organize tests. Use when creating unit tests, integration tests, or E2E tests. Covers test patterns, mocking strategies, and test organization. - 90write-tests
Writes or changes tests in this repository to its quality bar, with the right helpers and layer. Use when adding, fixing or reviewing tests, when a change "needs a test", or when deciding whether a test may change. - 100write-e2e-test
Write a Playwright E2E test for Bruno. Use when adding or modifying tests under tests/, creating a new test suite, or reproducing a bug as an e2e spec. - 100write-tests
Write unit and integration tests. Use when the user says "write tests for this", "add test coverage", "how do I test this", "TDD", "red green refactor", "unit test this function", "test this module", "I need tests for", or has code that lacks tests - even if they don't explicitly say "write tests". - 100generate
Generate Playwright tests. Use when user says "write tests", "generate tests", "add tests for", "test this component", "e2e test", "create test for", "test this page", or "test this feature".