Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-resilience

Resilience pipelines for Pudu: retry, circuit breaker, timeout, fallback, hedging, rate limiting, and chaos injection

0.1.0Apache-2.01

InstallClose

VaultTest.pudu

Pudu126 lines4.8 KB

GitHub ↗
1/** @Test.Package.VaultTest.Suite — the wiki vault mirrors the source tree */2module Package.VaultTest34import Std.Io as Io5import Std.List as List6import Std.Result as Result7import Std.Test as Test8import Std.Text as Text910/// Every file under a directory with the given ending, sorted.11fn files(directory: Str, ending: Str) -> Array[Str] {12  var found: Array[Str] = []13  for path in List.sortBy(&Result.unwrapOr(Io.listPaths(directory), []), fn(left: Str, right: Str) -> Bool { left < right }) {14    if path.endsWith(ending) {15      found = found.push(path)16    } else if !path.contains(".") {17      found = found.concat(files(path, ending))18    }19  }20  found21}2223/// The text of a file, or empty text when it cannot be read.24fn read(path: Str) -> Str { Result.unwrapOr(Io.read(path), "") }2526/// The mirrored page of a source file.27fn pageOf(source: Str) -> Str { "wiki/" + source.replace(".pudu", ".md") }2829/// The source file a mirrored page describes.30fn sourceOf(page: Str) -> Str { Text.stripPrefix(page, "wiki/").replace(".md", ".pudu") }3132/// The name a page answers to in links: its path under `wiki/` without `.md`.33fn nameOf(page: Str) -> Str { Text.stripPrefix(page, "wiki/").replace(".md", "") }3435/// A page's text before its `Referenced by` section.36fn bodyOf(text: Str) -> Str {37  match List.first(&text.split("\n## Referenced by")) {38    case Some(body) => body39    case None => text40  }41}4243/// A page's `Referenced by` section.44fn backlinksOf(text: Str) -> Str {45  match List.get(&text.split("\n## Referenced by"), 1) {46    case Some(section) => section47    case None => ""48  }49}5051/// Every link target in the text, without alias or heading.52fn links(text: Str) -> Array[Str] {53  var found: Array[Str] = []54  for piece in List.drop(&text.split("[["), 1) {55    if let Some(inside) = List.first(&piece.split("]]")) {56      if let Some(target) = List.first(&inside.split("|")) {57        if let Some(page) = List.first(&target.split("#")) { found = found.push(page) }58      }59    }60  }61  found62}6364/// The names every exported function of a source file declares.65fn exportedFunctions(source: Str) -> Array[Str] {66  var names: Array[Str] = []67  for line in read(source).split("\n") {68    if line.startsWith("export fn ") {69      let rest = Text.stripPrefix(line, "export fn ")70      if let Some(head) = List.first(&rest.split("(")) {71        if let Some(name) = List.first(&head.split("[")) { names = names.push(name) }72      }73    }74  }75  names76}7778/// The root page, which lists no backlinks.79const ROOT: Str = "00-INDEX"8081/// Runs the suite.82fn main() -> Int {83  let sources = files("src", ".pudu")84  let pages = files("wiki", ".md")85  let mirrored = files("wiki/src", ".md").filter(|page: Str| !page.endsWith("_MOC.md"))86  let names = pages.map(|page: Str| nameOf(page))87  let unmirrored = sources.filter(|source: Str| !List.contains(&mirrored, pageOf(source)))88  let unbacked = mirrored.filter(|page: Str| !List.contains(&sources, sourceOf(page)))89  let ungrilled = mirrored.filter(|page: Str| !read(page).contains("## Grill Log\n\n- **Q:**"))90  var unsigned: Array[Str] = []91  for source in sources {92    let page = read(pageOf(source))93    for name in exportedFunctions(source) {94      if !page.contains("export fn " + name + "(") && !page.contains("export fn " + name + "[") { unsigned = unsigned.push(source + ": " + name) }95    }96  }97  var broken: Array[Str] = []98  var missingBacklinks: Array[Str] = []99  for page in pages {100    let text = read(page)101    for target in links(bodyOf(text)) {102      if !List.contains(&names, target) {103        broken = broken.push(nameOf(page) + " -> " + target)104      } else if target != nameOf(page) && target != ROOT && !backlinksOf(read("wiki/" + target + ".md")).contains("[[" + nameOf(page) + "]]") {105        missingBacklinks = missingBacklinks.push(target + " <- " + nameOf(page))106      }107    }108  }109  let checks = Test.suite("Package.Vault", &[110      Test.that("the vault and the source tree are found", sources.length() > 1 && mirrored.length() > 1),111      Test.equals("every source file has its mirrored page", &unmirrored, &[]),112      Test.equals("every mirrored page has its source file", &unbacked, &[]),113      Test.equals("every mirrored page has a resolved Grill Log", &ungrilled, &[]),114      Test.equals("every exported function appears in its page's signatures", &unsigned, &[]),115      Test.equals("every link names a page", &broken, &[]),116      Test.equals("every page lists the pages linking to it", &missingBacklinks, &[]),117      Test.equals("a link keeps its target and drops its alias and heading", &links("see [[a/B|b]] and [[c#Grill Log]]"), &["a/B", "c"]),118      Test.equals("a function's name stops at its parameters", &exportedFunctions("src/PuduLangResilience/Utils/Template.pudu"), &["fill"])119    ])120  let ran = Test.run(&checks)121  for failure in Test.failuresOf(&ran) {122    let _reported = Io.writeErrorLine(failure)123  }124  Test.report(&ran)125}126