
TemplateTest.pudu
Pudu55 lines3.1 KB
1/** @Docgen.Template.Tests — templates fill metadata exactly and refuse malformed tags */2module PuduLangDocgen.TemplateTest34import Std.Io as Io5import Std.Test as Test6import PuduLangDocgen as Docgen7import PuduLangDocgen.Template as Template8910fn context() -> Docgen.Meta {11 Docgen.Fields([12 ("title", Docgen.Text("A & B")), ("html", Docgen.Text("<b>x</b>")), ("count", Docgen.Whole(2)), ("on", Docgen.Flag(true)),13 ("off", Docgen.Flag(false)), ("empty", Docgen.Items([])), ("items", Docgen.Items([Docgen.Fields([("name", Docgen.Text("one"))]), Docgen.Fields([("name", Docgen.Text("two"))])])),14 ("words", Docgen.Items([Docgen.Text("a"), Docgen.Text("b")])), ("site", Docgen.Fields([("name", Docgen.Text("Docs")), ("owner", Docgen.Fields([("name", Docgen.Text("Team"))]))]))15 ])16}171819fn rendered(text: Str) -> Str {20 let partial = match Template.parse("[\{\{name\}\}]") {21 case Ok(nodes) => nodes22 case Err(_) => []23 }24 match Template.parse(text) {25 case Ok(nodes) => Template.render(&nodes, &context(), &mapOf([("item", partial)]))26 case Err(reason) => "error: " + reason27 }28}293031fn main() -> Int {32 let checks = Test.suite("Template", &[33 Test.equals("escaped value", &rendered("\{\{title\}\}"), &"A & B"),34 Test.equals("raw values", &rendered("\{\{\{html\}\}\} \{\{& html\}\}"), &"<b>x</b> <b>x</b>"),35 Test.equals("numbers and flags", &rendered("\{\{count\}\} \{\{on\}\}"), &"2 true"),36 Test.equals("missing value empty", &rendered("[\{\{nope\}\}]"), &"[]"),37 Test.equals("list section", &rendered("\{\{#items\}\}<\{\{name\}\}>\{\{/items\}\}"), &"<one><two>"),38 Test.equals("scalar list with dot", &rendered("\{\{#words\}\}\{\{.\}\},\{\{/words\}\}"), &"a,b,"),39 Test.equals("truthy and falsy sections", &rendered("\{\{#on\}\}yes\{\{/on\}\}\{\{#off\}\}no\{\{/off\}\}\{\{#empty\}\}no\{\{/empty\}\}"), &"yes"),40 Test.equals("inverted sections", &rendered("\{\{^off\}\}a\{\{/off\}\}\{\{^empty\}\}b\{\{/empty\}\}\{\{^on\}\}c\{\{/on\}\}"), &"ab"),41 Test.equals("object section scopes", &rendered("\{\{#site\}\}\{\{name\}\}/\{\{title\}\}\{\{/site\}\}"), &"Docs/A & B"),42 Test.equals("dotted names", &rendered("\{\{site.owner.name\}\}"), &"Team"),43 Test.equals("partials see the context", &rendered("\{\{#items\}\}\{\{>item\}\}\{\{/items\}\}"), &"[one][two]"),44 Test.equals("unknown partial empty", &rendered("a\{\{>none\}\}b"), &"ab"),45 Test.equals("comments dropped", &rendered("a\{\{! note \}\}b"), &"ab"),46 Test.equals("unclosed section", &rendered("\{\{#on\}\}x"), &"error: section on is not closed"),47 Test.equals("mismatched section", &rendered("\{\{#on\}\}x\{\{/off\}\}"), &"error: section on is closed by off"),48 Test.equals("stray close", &rendered("x\{\{/on\}\}"), &"error: section on is closed without being opened"),49 Test.equals("unclosed tag", &rendered("\{\{title"), &"error: tag is not closed")50 ])51 let ran = Test.run(&checks)52 for failure in Test.failuresOf(&ran) { let _printed = Io.writeErrorLine(failure) }53 Test.report(&ran)54}55