
ReferencesTest.pudu
Pudu72 lines5.0 KB
1/** @Docgen.References.Tests — identities stay unique and maps round-trip */2module PuduLangDocgen.ReferencesTest34import Std.Io as Io5import Std.Map as Map6import Std.Option as Option7import Std.Test as Test8import PuduLangDocgen.Constants.Codes as Codes9import PuduLangDocgen as Docgen10import PuduLangDocgen.References as References111213fn reference(uid: Str, href: Str) -> Docgen.Reference {14 let parts = uid.split(".")15 Docgen.Reference{uid: uid, name: parts[parts.length() - 1], fullName: uid, href: href, kind: "module"}16}171819fn read(origin: Str, text: Str) -> Array[Docgen.Reference] {20 match References.parse(origin, text) {21 case Ok(found) => found22 case Err(_) => []23 }24}252627fn unresolved(uid: Str) -> Docgen.Diagnostic {28 Docgen.warning(Codes.XREF_UNRESOLVED, "page.md", 3, References.UNRESOLVED + uid)29}303132fn refused(text: Str) -> Str {33 match References.parse("xrefmap.yml", text) {34 case Ok(_) => "accepted"35 case Err(reason) => reason36 }37}383940fn main() -> Int {41 let own = [reference("A.B", "a/b.html"), reference("A.C", "a/c.html")]42 let (found, problems) = References.registry(&own, &[reference("A.B", "https://x/b"), reference("Ext.D", "https://x/d")])43 let (_dup, duplicates) = References.registry(&[reference("A.B", "one.html"), reference("A.B", "two.html")], &[])44 let yaml = References.toYaml(&own.push(reference("Q.\"quoted\": yes", "q.html")), "https://site.example/")45 let checks = Test.suite("References", &[46 Test.equals("own identity wins", &Option.map(Map.get(&found, "A.B"), |held: Docgen.Reference| held.href), &Some("a/b.html")),47 Test.equals("external added", &Option.map(Map.get(&found, "Ext.D"), |held: Docgen.Reference| held.href), &Some("https://x/d")),48 Test.equals("no problems", &problems, &[]),49 Test.equals("duplicate identity refused", &duplicates.map(|held: Docgen.Diagnostic| held.code), &[Codes.UID_DUPLICATE]),50 Test.equals("yaml map", &References.toYaml(&[reference("A.B", "a/b.html")], ""), &"### YamlMime:XRefMap\nsorted: true\nreferences:\n- uid: A.B\n name: B\n fullName: A.B\n href: a/b.html\n type: module\n"),51 Test.equals("yaml round trip with base", &read("xrefmap.yml", yaml).map(|held: Docgen.Reference| held.href), &["https://site.example/a/b.html", "https://site.example/a/c.html", "https://site.example/q.html"]),52 Test.equals("quoted scalars survive", &read("xrefmap.yml", yaml)[2].uid, &"Q.\"quoted\": yes"),53 Test.equals("json round trip", &read("xrefmap.json", References.toJson(&own, "")).map(|held: Docgen.Reference| held.uid), &["A.B", "A.C"]),54 Test.equals("relative to remote origin", &read("https://docs.example/v1/xrefmap.yml", "references:\n- uid: X\n href: x.html")[0].href, &"https://docs.example/v1/x.html"),55 Test.equals("name defaults to uid", &read("m.yml", "references:\n- uid: X\n href: x.html")[0].name, &"X"),56 Test.equals("unsafe href refused", &refused("references:\n- uid: X\n href: javascript:x"), &"reference X has an unsafe href"),57 Test.equals("missing uid refused", &refused("references:\n- href: x.html"), &"a reference has no uid"),58 Test.equals("not a mapping refused", &refused("- a"), &"cross-reference map must be a mapping with references"),59 Test.equals("service list answer", &read("https://xref.example/query?uid=X", "[\{\"uid\": \"X\", \"name\": \"Ex\", \"href\": \"https://docs.example/x.html\"\}]").map(|held: Docgen.Reference| (held.uid, held.name, held.href)), &[("X", "Ex", "https://docs.example/x.html")]),60 Test.equals("empty service answer", &read("https://xref.example/query?uid=X", "[]"), &[]),61 Test.equals("service answer not a list of mappings", &refused("[1]"), &"each reference must be a mapping"),62 Test.equals("service address encodes the identity", &References.serviceAddress("https://xref.example/query?uid=\{uid\}&v=\{uid\}", "List<T>.Add"), &"https://xref.example/query?uid=List%3CT%3E.Add&v=List%3CT%3E.Add"),63 Test.equals("service address without slot unchanged", &References.serviceAddress("https://xref.example/all", "X"), &"https://xref.example/all"),64 Test.equals("unresolved identities once each", &References.unresolved(&[unresolved("A"), Docgen.warning(Codes.LINK_BROKEN, "p.md", 1, References.UNRESOLVED + "B"), unresolved("A"), unresolved("C.D")]), &["A", "C.D"]),65 Test.equals("nothing unresolved", &References.unresolved(&[]), &[]),66 Test.equals("pages become references", &References.ofPages(&[Docgen.Page{path: "g.html", source: "g.md", kind: "article", title: "Guide", uid: "guide", summary: "", body: "", headings: [], links: [], meta: []}]), &[Docgen.Reference{uid: "guide", name: "Guide", fullName: "Guide", href: "g.html", kind: "article"}])67 ])68 let ran = Test.run(&checks)69 for failure in Test.failuresOf(&ran) { let _printed = Io.writeErrorLine(failure) }70 Test.report(&ran)71}72