
LayoutTest.pudu
Pudu69 lines2.5 KB
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 Text91011const ROOT: Str = "PuduLangMcp"121314const ENTRY: Str = "src/Main.pudu"151617fn 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}282930fn 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}373839fn owned(name: Str) -> Bool {40 name == ROOT || name.startsWith(ROOT + ".")41}424344fn expected(path: Str) -> Str {45 Text.stripPrefix(path, "src/").replace(".pudu", "").replace("/", ".")46}474849fn 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