
ValueTest.pudu
Pudu53 lines3.7 KB
1/** @Test.Value.Suite — value builders, failures, and clocks */2module PuduLangLog.ValueTest34import Std.Bytes as Bytes5import Std.Io as Io6import Std.Test as Test7import PuduLangLog.Clock as Clock8import PuduLangLog.Failure as Failure9import PuduLangLog as Log10import PuduLangLog.Value as Value1112/** @Test.Value.Point — a program type that captures itself */13type Point = { x: Int, y: Int }1415impl Value.Capturable for Point {16 17 fn capture(self: &Self) -> Log.Value { Value.structure("Point", [("X", Value.int(self.x)), ("Y", Value.int(self.y))]) }18}192021fn main() -> Int {22 let moment = Log.Timestamp{millis: 5, offset: 60}23 let none: Option[Int] = None24 let stepping = Clock.stepping(moment, 10)25 let firstStep = stepping()26 let secondStep = stepping()27 let failure = Failure.causedBy(&Failure.withTrace(&Failure.of("ParseError", "bad digit"), ["Reader.next", "Main.main"]), Failure.from("IoError", "closed"))28 let checks = Test.suite("Value", &[29 Test.equals("built-in types capture as scalars", &[Value.of(3), Value.of("x"), Value.of(true), Value.of(1.5), Value.of('c')], &[Value.int(3), Value.text("x"), Value.bool(true), Value.float(1.5), Value.text("c")]),30 Test.equals("moments and bytes capture as scalars", &(Value.of(moment), Value.of(Bytes.fromText("a"))), &(Log.Scalar(Log.Moment(moment)), Log.Scalar(Log.Binary(Bytes.fromText("a"))))),31 Test.equals("arrays capture as sequences", &Value.of([1, 2]), &Value.list([Value.int(1), Value.int(2)])),32 Test.equals("options capture their value or null", &(Value.of(Some(4)), Value.of(none), Value.of([Some("a"), None])), &(Value.int(4), Value.nothing(), Value.list([Value.text("a"), Value.nothing()]))),33 Test.equals("values capture as themselves", &Value.of(Value.int(1)), &Value.int(1)),34 Test.equals("program types capture as they choose", &Value.of(Point{x: 1, y: 2}), &Value.structure("Point", [("X", Value.int(1)), ("Y", Value.int(2))])),35 Test.equals("durations and decimals", &(Value.duration(1500), Value.decimal(2.50d)), &(Log.Scalar(Log.Span(1500)), Log.Scalar(Log.Exact(2.50d)))),36 Test.equals("objects are untagged structures", &Value.object([("A", Value.int(1))]), &Log.Structure(Log.Structure{tag: None, properties: [Value.property("A", Value.int(1))]})),37 Test.equals("dictionaries by text and by any scalar", &(Value.dictionary([("a", Value.int(1))]), Value.keyed([(Log.Integer(2), Value.int(2))])), &(Log.Dictionary([Log.Entry{key: Log.Text("a"), value: Value.int(1)}]), Log.Dictionary([Log.Entry{key: Log.Integer(2), value: Value.int(2)}]))),38 Test.equals("render shows a value as a message would", &Value.render(&Value.of(Point{x: 1, y: 2})), &"Point \{ X: 1, Y: 2 \}"),39 Test.equals("json shows a value as a JSON formatter would", &Value.json(&Value.of(Point{x: 1, y: 2})), &"\{\"X\":1,\"Y\":2,\"$type\":\"Point\"\}"),40 Test.equals("failures describe their trace and causes", &Failure.describe(&failure), &"ParseError: bad digit\n at Reader.next\n at Main.main\n ---> IoError: closed"),41 Test.equals("a failure from an error value", &(Failure.from("Code", 42), Failure.from("Text", "quoted")), &(Failure.of("Code", "42"), Failure.of("Text", "quoted"))),42 Test.equals("a fixed clock", &Clock.fixed(moment)(), &moment),43 Test.equals("a stepping clock advances per reading", &(firstStep, secondStep), &(moment, Log.Timestamp{millis: 15, offset: 60})),44 Test.that("the system clock reads the present", Clock.system()().millis > 1700000000000),45 Test.equals("the UTC clock has no offset", &Clock.utc()().offset, &0)46 ])47 let ran = Test.run(&checks)48 for problem in Test.failuresOf(&ran) {49 let _reported = Io.writeErrorLine(problem)50 }51 Test.report(&ran)52}53