Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-log

Structured event logging for Pudu: message templates, enrichment, filtering, formatting, and sinks

0.1.0Apache-2.01

InstallClose

ReaderTest.pudu

Pudu49 lines3.1 KB

GitHub ↗
1/** @Test.Formatting.Reader.Suite — compact JSON written and read back */2module PuduLangLog.Formatting.ReaderTest34import Std.Env as Env5import Std.Io as Io6import Std.Result as Result7import Std.Test as Test8import PuduLangLog.Event as Event9import PuduLangLog.Failure as Failure10import PuduLangLog.Formatting.Compact as Compact11import PuduLangLog.Formatting.Reader as Reader12import PuduLangLog as Log13import PuduLangLog.Value as Value1415/// The compact text of events written, read back, and written again.16fn rewritten(formatter: Log.Formatter, events: &Array[Log.Event]) -> Result[Str, Str] {17  let text = events.map(|event: Log.Event| formatter(&event)).join("")18  let read = Reader.readAll(text) ?19  Ok(read.map(|event: Log.Event| formatter(&event)).join(""))20}2122/// Runs the suite.23fn main() -> Int {24  let moment = Log.Timestamp{millis: 1790604309123, offset: 0}25  let first = Event.create(moment, Log.Warning, "Disk \{Disk\} is \{Percent:0.0\}% full", [Value.property("Disk", Value.text("C")), Value.property("Percent", Value.decimal(93.25d))])26  let second = Event.withTrace(&Event.withFailure(&Event.create(moment, Log.Information, "User \{@User\}", [Value.property("User", Value.structure("User", [("Name", Value.text("a\"b")), ("Tags", Value.list([Value.text("x")]))])), Value.property("@odd", Value.bool(false))]), Failure.causedBy(&Failure.withTrace(&Failure.of("IoError", "full"), ["write"]), Failure.of("Os", "denied"))), "t1", "s1")27  let events = [first, second]28  let compactText = events.map(|event: Log.Event| Compact.compact()(&event)).join("")29  let path = Env.temporaryDirectory() + "/pudu-lang-log-reader-test.clef"30  let _written = Io.write(path, compactText + "\n\n")31  let fromFile = Reader.readFile(path)32  let _removed = Io.remove(path)33  let checks = Test.suite("Formatting.Reader", &[34      Test.equals("compact JSON reads back to the same text", &rewritten(Compact.compact(), &events), &Ok(compactText)),35      Test.equals("rendered compact JSON reads back to the same messages", &Result.map(Reader.readAll(events.map(|event: Log.Event| Compact.rendered()(&event)).join("")), |read: Array[Log.Event]| read.map(|event: Log.Event| Event.message(&event))), &Ok(events.map(|event: Log.Event| Event.message(&event)))),36      Test.equals("a read event renders the same message", &Result.map(Reader.readLine(Compact.compact()(&second)), |event: Log.Event| Event.message(&event)), &Ok(Event.message(&second))),37      Test.equals("the failure survives the round trip", &Result.map(Reader.readLine(Compact.compact()(&second)), |event: Log.Event| event.failure), &Ok(second.failure)),38      Test.equals("a file with blank lines", &Result.map(fromFile, |read: Array[Log.Event]| read.length()), &Ok(2)),39      Test.equals("a missing file is refused", &Result.isErr(&Reader.readFile(path)), &true),40      Test.equals("the first bad line is named", &Reader.readAll(compactText + "oops\n"), &Err("Line 3: The line is not JSON: expected a value at 0")),41      Test.equals("empty text holds no events", &Result.map(Reader.readAll(""), |read: Array[Log.Event]| read.length()), &Ok(0))42    ])43  let ran = Test.run(&checks)44  for failure in Test.failuresOf(&ran) {45    let _reported = Io.writeErrorLine(failure)46  }47  Test.report(&ran)48}49