
TemplateTest.pudu
Pudu63 lines3.8 KB
1/** @Test.Expressions.Template.Suite — expression templates and their directives */2module PuduLangLog.Expressions.TemplateTest34import Std.Io as Io5import Std.Test as Test6import PuduLangLog.Event as Event7import PuduLangLog.Expressions as Expressions8import PuduLangLog.Failure as Failure9import PuduLangLog as Log10import PuduLangLog.Value as Value111213fn sample() -> Log.Event {14 Event.withFailure(&Event.create(Log.Timestamp{millis: 1790604309123, offset: 0}, Log.Warning, "Cart \{Cart\} for \{User\}", [15 Value.property("User", Value.text("Ada")),16 Value.property("Cart", Value.list([Value.text("tea"), Value.text("cup")])),17 Value.property("Total", Value.decimal(12.5d)),18 Value.property("Meta", Value.object([("region", Value.text("eu")), ("tier", Value.int(2))])),19 Value.property("Empty", Value.list([]))20 ]), Failure.of("IoError", "full"))21}222324fn rendered(template: Str) -> Str {25 match Expressions.template(template) {26 case Ok(formatter) => formatter(&sample())27 case Err(reason) => "? " + reason28 }29}303132fn main() -> Int {33 let checks = Test.suite("Expressions.Template", &[34 Test.equals("literal text and doubled braces", &rendered("plain \{\{x\}\} text"), &"plain \{x\} text"),35 Test.equals("holes with formats", &rendered("[\{@t:HH:mm:ss\} \{@l:u3\}] \{Total:0.00\} \{User\}"), &"[14:05:09 WRN] 12.50 Ada"),36 Test.equals("the message and the template", &rendered("\{@m\} | \{@mt\}"), &"Cart [\"tea\",\"cup\"] for Ada | Cart \{Cart\} for \{User\}"),37 Test.equals("collections render as JSON and undefined holes as nothing", &rendered("\{Meta\}|\{Missing\}|\{@x\}"), &"\{\"region\":\"eu\",\"tier\":2\}||IoError: full"),38 Test.equals("an if block", &rendered("\{#if Total > 10\}big\{#end\}"), &"big"),39 Test.equals("else if and else", &[rendered("\{#if Total > 100\}a\{#else if Total > 10\}b\{#else\}c\{#end\}"), rendered("\{#if Total > 100\}a\{#else if Total > 50\}b\{#else\}c\{#end\}"), rendered("\{#if Missing\}a\{#end\}")], &["b", "c", ""]),40 Test.equals("each over a sequence with a delimiter", &rendered("\{#each item, i in Cart\}\{i\}:\{item\}\{#delimit\}, \{#end\}"), &"0:tea, 1:cup"),41 Test.equals("each over members", &rendered("\{#each name, held in Meta\}\{name\}=\{held\}\{#delimit\};\{#end\}"), &"region=eu;tier=2"),42 Test.equals("each with an else for nothing", &[rendered("\{#each x in Empty\}\{x\}\{#else\}none\{#end\}"), rendered("\{#each x in Missing\}\{x\}\{#else\}none\{#end\}")], &["none", "none"]),43 Test.equals("nested blocks", &rendered("\{#each x in Cart\}\{#if x = 'cup'\}[\{x\}]\{#end\}\{#end\}"), &"[cup]"),44 Test.equals("rest leaves out names the template reads", &rendered("\{User\} \{Rest()\}"), &"Ada \{\"Cart\":[\"tea\",\"cup\"],\"Total\":12.5,\"Meta\":\{\"region\":\"eu\",\"tier\":2\},\"Empty\":[]\}"),45 Test.equals("deep rest also leaves out names the message uses", &rendered("\{Rest(true)\}"), &"\{\"Total\":12.5,\"Meta\":\{\"region\":\"eu\",\"tier\":2\},\"Empty\":[]\}"),46 Test.equals("refusals", &[rendered("\{User"), rendered("\{#if User\}x"), rendered("\{#end\}"), rendered("\{#frob\}"), rendered("\{#each x Cart\}\{#end\}"), rendered("\{#if a\}\{#else\}b\{#delimit\}"), rendered("\{User User\}"), rendered("\{Frob(User)\}")], &[47 "? a hole opened at 0 is not closed",48 "? `\{#if\}` is not closed",49 "? unexpected `\{#end\}`",50 "? unknown directive `\{#frob\}`",51 "? `\{#each\}` needs `in`",52 "? `\{#else\}` must be followed by `\{#end\}`",53 "? unexpected `User` in hole `User User`",54 "? unknown function `frob`"55 ])56 ])57 let ran = Test.run(&checks)58 for failure in Test.failuresOf(&ran) {59 let _reported = Io.writeErrorLine(failure)60 }61 Test.report(&ran)62}63