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

LayoutTest.pudu

Pudu69 lines2.5 KB

GitHub ↗
1/** @Test.Package.LayoutTest.Suite — every shipped module stays under the package's module root */2module Package.LayoutTest34import Std.Io as Io5import Std.List as List6import Std.Result as Result7import Std.Test as Test8import Std.Text as Text910/// The module root the manifest declares.11const ROOT: Str = "PuduLangMcp"1213/// The executable entry, the one module allowed beside the root.14const ENTRY: Str = "src/Main.pudu"1516/// Every source file under a directory, sorted.17fn sources(directory: Str) -> Array[Str] {18  var found: Array[Str] = []19  for path in List.sortBy(&Result.unwrapOr(Io.listPaths(directory), []), fn(left: Str, right: Str) -> Bool { left < right }) {20    if path.endsWith(".pudu") {21      found = found.push(path)22    } else if !path.contains(".") {23      found = found.concat(sources(path))24    }25  }26  found27}2829/// The name a file's `module` line declares, or empty text when it has none.30fn declared(path: Str) -> Str {31  let text = Result.unwrapOr(Io.read(path), "")32  match List.find(&text.split("\n"), |line: Str| line.startsWith("module ")) {33    case Some(line) => Text.stripPrefix(line, "module ").trim()34    case None => ""35  }36}3738/// Whether a module name is the root or inside it.39fn owned(name: Str) -> Bool {40  name == ROOT || name.startsWith(ROOT + ".")41}4243/// The module name a path under `src/` must declare.44fn expected(path: Str) -> Str {45  Text.stripPrefix(path, "src/").replace(".pudu", "").replace("/", ".")46}4748/// Runs the suite.49fn main() -> Int {50  let shipped = sources("src").filter(|path: Str| path != ENTRY)51  let outside = shipped.filter(|path: Str| !owned(declared(path)))52  let misnamed = shipped.filter(|path: Str| declared(path) != expected(path))53  let manifest = Result.unwrapOr(Io.read("pudu.toml"), "")54  let checks = Test.suite("Package.Layout", &[55      Test.that("the source tree is found", shipped.length() > 1),56      Test.equals("every shipped module is under the package root", &outside, &[]),57      Test.equals("every module is named after its path", &misnamed, &[]),58      Test.that("the manifest declares the same root", manifest.contains("root = \"" + ROOT + "\"")),59      Test.equals("the entry stays the executable's Main", &declared(ENTRY), &"Main"),60      Test.that("a name beside the root is refused", !owned("App.Context") && !owned("PuduLangMcpExtra")),61      Test.that("the root and its children are owned", owned(ROOT) && owned(ROOT + ".App.Context"))62    ])63  let report = Test.run(&checks)64  for failure in Test.failuresOf(&report) {65    let _reported = Io.writeErrorLine(failure)66  }67  Test.report(&report)68}69