Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ jobs:
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v5

LSP:
name: Test LSP.jl
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v1
with:
version: "1.12" # most stable version
arch: x64
- uses: julia-actions/cache@v2
- name: test LSP
shell: julia --color=yes --project=. {0} # this is necessary for the next command to work on Windows
run: 'using Pkg; Pkg.activate(normpath(pwd(), "LSP")); Pkg.instantiate(); Pkg.test(; coverage=true)'
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v5

test_runserver:
name: Test runserver.jl
runs-on: ubuntu-latest
Expand Down
5 changes: 5 additions & 0 deletions LSP/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ uuid = "880dcf91-6fde-4251-87fc-bfd84012291a"
version = "0.1.0"
authors = ["Shuhei Kadowaki <aviatesk@gmail.com>"]

[workspace]
projects = ["test"]

[deps]
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"

[compat]
JSON3 = "1.14.3"
PrecompileTools = "1.3.3"
StructTypes = "1.11.0"
2 changes: 2 additions & 0 deletions LSP/src/LSP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ baremodule Communication
export Endpoint, send
end

include("precompile.jl")

for name in exports
Core.eval(@__MODULE__, Expr(:export, name))
end
Expand Down
65 changes: 65 additions & 0 deletions LSP/src/precompile.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
function test_roundtrip(f, s::AbstractString, Typ)
x = JSON3.read(s, Typ)
f(x)
s′ = to_lsp_json(x)
x′ = JSON3.read(s′, Typ)
f(x′)
end

function test_roundtrip(f, s::AbstractString)
x = to_lsp_object(s)
f(x)
s′ = to_lsp_json(x)
x′ = to_lsp_object(s′)
f(x′)
end

using PrecompileTools

@setup_workload let
uri = LSP.URIs2.filepath2uri(abspath(@__FILE__))
@compile_workload let
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"method": "textDocument/completion",
"params": {
"textDocument": {
"uri": "$uri"
},
"position": {
"line": 0,
"character": 0
},
"workDoneToken": "workDoneToken",
"partialResultToken": "partialResultToken"
}
}""") do req
@assert req isa CompletionRequest
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"method": "completionItem/resolve",
"params": {
"label": "label",
"textEdit": {
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 0
}
},
"newText": "newText"
}
}
}""") do req
@assert req isa CompletionResolveRequest
@assert req.params.textEdit isa TextEdit
end
end
end
9 changes: 9 additions & 0 deletions LSP/test/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[deps]
LSP = "880dcf91-6fde-4251-87fc-bfd84012291a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[sources]
LSP = {path = ".."}

[compat]
Test = "1"
235 changes: 235 additions & 0 deletions LSP/test/runtests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
using LSP
using LSP.URIs2
using LSP: to_lsp_json, test_roundtrip
using Test

@testset "LSP" begin
# De/serializing complex LSP objects
uri = filename2uri(@__FILE__)

test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"result": null
}""", DefinitionResponse) do res
@test res isa DefinitionResponse
@test_broken res.result === null # this null should be preserved through the roundtrip
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"result": {
"uri": "$uri",
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 5
}
}
}
}""", DefinitionResponse) do res
@test res isa DefinitionResponse
@test res.result isa Location
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"result": [{
"uri": "$uri",
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 5
}
}
}]
}""", DefinitionResponse) do res
@test res isa DefinitionResponse
@test res.result isa Vector{Location}
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"result": [{
"targetUri": "$uri",
"targetRange": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 5
}
},
"targetSelectionRange": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 5
}
}
}]
}""", DefinitionResponse) do res
@test res isa DefinitionResponse
@test res.result isa Vector{LocationLink}
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"error": {
"code": $(ErrorCodes.InvalidRequest),
"message": "Test message"
}
}""", DefinitionResponse) do res
@test res isa DefinitionResponse
@test res.result === nothing
@test res.error isa ResponseError
end

test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"method": "completionItem/resolve",
"params": {
"label": "label",
"textEdit": {
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 0
}
},
"newText": "newText"
}
}
}""", CompletionResolveRequest) do req
@test req isa CompletionResolveRequest
@test req.params.textEdit isa TextEdit
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"method": "completionItem/resolve",
"params": {
"label": "label",
"textEdit": {
"newText": "newText",
"insert": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 0
}
},
"replace": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 6
}
}
}
}
}""", CompletionResolveRequest) do req
@test req isa CompletionResolveRequest
@test req.params.textEdit isa InsertReplaceEdit
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"method": "completionItem/resolve",
"params": {
"label": "label",
"documentation": "documentation"
}
}""", CompletionResolveRequest) do req
@test req isa CompletionResolveRequest
@test req.params.documentation isa String
end
test_roundtrip("""{
"jsonrpc": "2.0",
"id": 0,
"method": "completionItem/resolve",
"params": {
"label": "label",
"documentation": {
"kind": "markdown",
"value": "value"
}
}
}""", CompletionResolveRequest) do req
@test req isa CompletionResolveRequest
@test req.params.documentation isa MarkupContent
end

test_roundtrip("""
{
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"processId": 42,
"clientInfo": {
"name": "Test client",
"version": "1.0"
},
"capabilities": {},
"workspaceFolders": []
}
}
""") do init_req
@test init_req isa InitializeRequest
@test init_req.jsonrpc == "2.0"
@test init_req.id == 0
@test init_req.method == "initialize"
@test init_req.params.processId == 42
@test init_req.params.clientInfo.name == "Test client"
@test init_req.params.clientInfo.version == "1.0"
@test init_req.params.capabilities == ClientCapabilities()
@test init_req.params.workspaceFolders isa Vector{WorkspaceFolder} && isempty(init_req.params.workspaceFolders)
end

# ResponseMessage should omit the `error` field on success, and omit `result` an error
@testset "ResponseMessage result field" begin
success_res = ResponseMessage(;
id = "id",
result = null)
success_res_s = to_lsp_json(success_res)
@test occursin("\"result\"", success_res_s) && occursin("null", success_res_s)
@test !occursin("\"error\"", success_res_s)
end
@testset "ResponseMessage error field" begin
error_res = ResponseMessage(;
id = "id",
result = nothing,
error = ResponseError(;
code = ErrorCodes.RequestFailed,
message = "test message",
data = :test_data))
error_res_s = to_lsp_json(error_res)
@test !occursin("\"result\"", error_res_s)
@test occursin("\"error\"", error_res_s)
end
end
3 changes: 3 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ JETLS = "a3b70258-0602-4ee2-b5a6-54c2470400db"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[sources]
JETLS = {path = ".."}

[compat]
InteractiveUtils = "1.11"
Pkg = "1.11.0"
Expand Down
Loading