
ContextTest.pudu
Pudu62 lines3.3 KB
1/** @Test.Context.Suite — typed items, shared tokens, expiry, and cancellation */2module PuduLangMediator.ContextTest34import Std.Concurrent.Cancel as Cancel5import Std.Io as Io6import Std.Test as Test7import PuduLangMediator.Context as Context8import PuduLangMediator as Messaging910/** @Test.Context.Tenant — a record stored as an item */11type Tenant = { id: Int, region: Str }121314fn main() -> Int {15 let context = Context.create()16 let tenant: Context.Key[Tenant] = Context.key("tenant")17 let attempts: Context.Key[Int] = Context.key("attempts")18 let lookalike: Context.Key[Int] = Context.key("attempts")19 Context.set(&context, &tenant, Tenant{id: 7, region: "eu"})20 Context.set(&context, &attempts, 1)21 Context.set(&context, &attempts, 2)22 let shared = Context.withToken(&context, Cancel.token())23 Context.set(&shared, &Context.key("flag"), true)24 let removable: Context.Key[Str] = Context.key("note")25 Context.set(&context, &removable, "temporary")26 Context.remove(&context, &removable)27 let stopping = Context.create()28 let before: Result[(), Messaging.Failure[Str]] = Context.check(&stopping)29 Context.cancel(&stopping, "done")30 Context.cancel(&stopping, "later")31 let after: Result[(), Messaging.Failure[Str]] = Context.check(&stopping)32 let paused: Result[(), Messaging.Failure[Str]] = Context.pause(&stopping, 1000)33 let quick: Result[(), Messaging.Failure[Str]] = Context.pause(&Context.create(), 1)34 let expired = Context.expiring(&Context.create(), 0)35 let parent = Context.create()36 let child = Context.expiring(&parent, 60000)37 Context.cancel(&parent, "parent")38 let checks = Test.suite("Context", &[39 Test.equals("a record item reads back", &Context.get(&context, &tenant), &Some(Tenant{id: 7, region: "eu"})),40 Test.equals("a later item replaces an earlier one", &Context.get(&context, &attempts), &Some(2)),41 Test.equals("a key made separately under the same name does not read it", &Context.get(&context, &lookalike), &None),42 Test.that("but the name is present", Context.has(&context, &lookalike)),43 Test.equals("getOr falls back for an absent item", &Context.getOr(&context, &Context.key("missing"), 9), &9),44 Test.equals("getOr answers a present item", &Context.getOr(&context, &attempts, 9), &2),45 Test.equals("a context with another token shares items", &Context.names(&context), &["tenant", "attempts", "flag"]),46 Test.not("a removed item is gone", Context.has(&context, &removable)),47 Test.equals("a live context checks out", &before, &Ok(())),48 Test.equals("the first cancellation reason is kept", &after, &Err(Messaging.Cancelled("cancelled: done"))),49 Test.that("a cancelled context is stopped", Context.stopped(&stopping)),50 Test.equals("a pause on a cancelled context ends at once", &paused, &Err(Messaging.Cancelled("cancelled: done"))),51 Test.equals("a short pause completes", &quick, &Ok(())),52 Test.that("an expiring context stops when its time is up", Context.stopped(&expired)),53 Test.that("an expiring context stops with its parent", Context.stopped(&child)),54 Test.that("a cancellable context observes its token", Context.stopped(&Context.cancellable(Cancel.expiring(0))))55 ])56 let ran = Test.run(&checks)57 for failure in Test.failuresOf(&ran) {58 let _reported = Io.writeErrorLine(failure)59 }60 Test.report(&ran)61}62