
ContextTest.pudu
Pudu66 lines3.8 KB
1/** @Test.Context.Suite — keys, typed properties, forks, and cancellation */2module PuduLangResilience.ContextTest34import Std.Concurrent.Cancel as Cancel5import Std.Io as Io6import Std.Test as Test7import PuduLangResilience.Context as Context8import PuduLangResilience as Resilience91011fn main() -> Int {12 let context = Context.keyed("orders")13 let attempts = Context.intKey("attempts")14 let region = Context.textKey("region")15 let cached = Context.boolKey("cached")16 let point = Context.key("point", fn(value: (Int, Int)) -> Str { show(value[0]) + "," + show(value[1]) }, fn(_text: Str) -> Option[(Int, Int)] { None })17 Context.set(&context, &attempts, -3)18 Context.set(&context, ®ion, "eu")19 Context.set(&context, &cached, false)20 Context.set(&context, &point, (1, 2))21 let shared = Context.withToken(&context, Cancel.token())22 Context.set(&shared, ®ion, "us")23 let seenThroughOriginal = Context.get(&context, ®ion)24 let forked = Context.fork(&context, Cancel.token())25 Context.set(&forked, ®ion, "ap")26 Context.set(&forked, &Context.textKey("forked-only"), "yes")27 let beforeAdopt = Context.get(&context, &Context.textKey("forked-only"))28 Context.adopt(&context, &forked)29 Context.remove(&context, &cached)30 let flagged = Context.create()31 Context.set(&flagged, &Context.textKey("cached"), "maybe")32 let stopping = Context.create()33 let beforeCancel: Result[(), Resilience.Failure[Str]] = Context.check(&stopping)34 Context.cancel(&stopping, "done")35 Context.cancel(&stopping, "later")36 let afterCancel: Result[(), Resilience.Failure[Str]] = Context.check(&stopping)37 let paused: Result[(), Resilience.Failure[Str]] = Context.pause(&stopping, 1000)38 let quick: Result[(), Resilience.Failure[Str]] = Context.pause(&Context.create(), 1)39 let checks = Test.suite("Context", &[40 Test.equals("a keyed context names its operation", &context.operationKey, &Some("orders")),41 Test.equals("a fresh context names no operation", &Context.create().operationKey, &None),42 Test.equals("a whole number reads back", &Context.get(&context, &attempts), &Some(-3)),43 Test.equals("a false flag reads back before removal", &Context.get(&flagged, &cached), &None),44 Test.equals("a value that does not decode reads as absent", &Context.get(&context, &point), &None),45 Test.that("an undecodable value is still stored", Context.has(&context, &point)),46 Test.equals("getOr falls back for an absent key", &Context.getOr(&context, &Context.intKey("missing"), 7), &7),47 Test.equals("a context with another token shares properties", &seenThroughOriginal, &Some("us")),48 Test.equals("a fork starts from a copy", &Context.get(&forked, &attempts), &Some(-3)),49 Test.equals("a fork's changes stay in the fork", &beforeAdopt, &None),50 Test.equals("adopting copies the fork's properties", &(Context.get(&context, ®ion), Context.get(&context, &Context.textKey("forked-only"))), &(Some("ap"), Some("yes"))),51 Test.not("a removed property is gone", Context.has(&context, &cached)),52 Test.equals("every stored name is listed", &Context.names(&context), &["attempts", "forked-only", "point", "region"]),53 Test.equals("a context whose token has not fired checks out", &beforeCancel, &Ok(())),54 Test.that("a cancelled context is stopped", Context.stopped(&stopping)),55 Test.equals("the first cancellation reason is kept", &afterCancel, &Err(Resilience.Cancelled("cancelled: done"))),56 Test.equals("a pause on a cancelled context ends at once", &paused, &Err(Resilience.Cancelled("cancelled: done"))),57 Test.equals("a short pause completes", &quick, &Ok(())),58 Test.equals("a cancellable context observes its token", &Context.stopped(&Context.cancellable(Cancel.expiring(0))), &true)59 ])60 let ran = Test.run(&checks)61 for failure in Test.failuresOf(&ran) {62 let _reported = Io.writeErrorLine(failure)63 }64 Test.report(&ran)65}66