Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-mcp

Model Context Protocol server for Pudu language documentation and compiler tools

0.1.1Apache-2.01

InstallClose

RenderTest.pudu

Pudu59 lines4.8 KB

GitHub ↗
1/** @Test.Domain.Lsp.RenderTest.Suite — language-server results as text */2module PuduLangMcp.Domain.Lsp.RenderTest34import Std.Io as Io5import Std.Json as Json6import Std.Result as Result7import Std.Test as Test8import PuduLangMcp.Domain.Lsp.Render as Render910/// JSON written as text, decoded.11fn value(text: Str) -> Json.Json {12  Result.unwrapOr(Json.decode(text), Json.Null)13}1415/// Shows a URI by its last path segment.16fn shortName(uri: Str) -> Str {17  uri.drop(uri.indexOf("/a/") + 3)18}1920/// Runs the suite.21fn main() -> Int {22  let range = "\"range\":\{\"start\":\{\"line\":6,\"character\":10\},\"end\":\{\"line\":6,\"character\":16\}\}"23  let location = value("\{\"uri\":\"file:///a/Sample.pudu\"," + range + "\}")24  let links = value("[\{\"targetUri\":\"file:///a/Other.pudu\",\"targetRange\":\{\"start\":\{\"line\":0,\"character\":0\},\"end\":\{\"line\":2,\"character\":1\}\}\}]")25  let edit = value("\{\"changes\":\{\"file:///a/Sample.pudu\":[\{" + range + ",\"newText\":\"twice\"\}]\}\}")26  let outline = value("[\{\"name\":\"Shape\",\"kind\":23,\"range\":\{\"start\":\{\"line\":1,\"character\":0\},\"end\":\{\"line\":4,\"character\":1\}\},\"children\":[\{\"name\":\"area\",\"kind\":6,\"detail\":\"Int\",\"range\":\{\"start\":\{\"line\":2,\"character\":2\},\"end\":\{\"line\":2,\"character\":9\}\}\}]\}]")27  let signature = value("\{\"signatures\":[\{\"label\":\"double(value: Int) -> Int\",\"documentation\":\{\"kind\":\"markdown\",\"value\":\"Doubles.\"\},\"parameters\":[\{\"label\":[7,17]\}]\}],\"activeSignature\":0,\"activeParameter\":0\}")28  let completion = value("[\{\"label\":\"alpha\",\"detail\":\"Int\"\},\{\"label\":\"beta\"\},\{\"label\":\"gamma\"\}]")29  let diagnostics = [value("\{" + range + ",\"severity\":2,\"code\":\"W3003\",\"message\":\"only propagates\"\}")]30  let checks = Test.suite("Domain.Lsp.Render", &[31      Test.equals("markup hover renders its value", &Render.hover(&value("\{\"contents\":\{\"kind\":\"markdown\",\"value\":\"x : Int\"\}\}")), &"x : Int"),32      Test.equals("a string hover renders as is", &Render.hover(&value("\{\"contents\":\"plain\"\}")), &"plain"),33      Test.equals("a list hover joins its parts", &Render.hover(&value("\{\"contents\":[\"a\",\{\"value\":\"b\"\}]\}")), &"a\n\nb"),34      Test.equals("a null hover says so", &Render.hover(&Json.Null), &"No information at this position."),35      Test.equals("a location renders 1-based", &Render.locations(&location, shortName).map(|held: Render.Location| Render.locationLine(&held)), &["Sample.pudu:7:11"]),36      Test.equals("location links are read", &Render.locations(&links, shortName).map(|held: Render.Location| Render.locationLine(&held)), &["Other.pudu:1:1"]),37      Test.equals("a location keeps its end line", &Render.locations(&links, shortName).map(|held: Render.Location| held.endLine), &[3]),38      Test.equals("null locations are none", &Render.locations(&Json.Null, shortName).length(), &0),39      Test.equals("a rename renders each edit", &Render.workspaceEdit(&edit, shortName), &"Sample.pudu:7:11-7:17 → twice"),40      Test.equals("no edits says so", &Render.workspaceEdit(&value("\{\}"), shortName), &"No edits."),41      Test.equals("an outline indents nested declarations", &Render.documentSymbols(&outline), &"struct Shape (line 2)\n  method area — Int (line 3)"),42      Test.equals("an empty outline says so", &Render.documentSymbols(&value("[]")), &"No declarations."),43      Test.equals("signature help names the active parameter", &Render.signatureHelp(&signature), &"double(value: Int) -> Int\nactive parameter: value: Int\nDoubles."),44      Test.equals("no signature says so", &Render.signatureHelp(&value("\{\"signatures\":[]\}")), &"No signature at this position."),45      Test.equals("completion is bounded with a count of the rest", &Render.completion(&completion, 2), &"alpha — Int\nbeta\n… and 1 more"),46      Test.equals("a completion list object is read", &Render.completion(&value("\{\"items\":[\{\"label\":\"x\"\}]\}"), 5), &"x"),47      Test.equals("no completions says so", &Render.completion(&value("[]"), 5), &"No completions at this position."),48      Test.equals("code actions render their titles and kinds", &Render.codeActions(&value("[\{\"title\":\"Remove import\",\"kind\":\"quickfix\"\}]")), &"Remove import (quickfix)"),49      Test.equals("diagnostics render position, severity, and code", &Render.diagnostics(&diagnostics), &"7:11 warning [W3003] only propagates"),50      Test.equals("workspace symbols render where they are", &Render.workspaceSymbols(&value("[\{\"name\":\"double\",\"kind\":12,\"location\":\{\"uri\":\"file:///a/Sample.pudu\"," + range + "\}\}]"), shortName), &"function double — Sample.pudu:7:11"),51      Test.equals("an unknown symbol kind is a symbol", &Render.documentSymbols(&value("[\{\"name\":\"x\",\"kind\":99\}]")), &"symbol x")52    ])53  let ran = Test.run(&checks)54  for failure in Test.failuresOf(&ran) {55    let _reported = Io.writeErrorLine(failure)56  }57  Test.report(&ran)58}59