panictoerr_test.gno
3.14 Kb · 102 lines
1package panictoerr_test
2
3import (
4 "errors"
5 "testing"
6
7 pte "gno.land/p/aeddi/panictoerr"
8 "gno.land/p/nt/uassert/v0"
9 grc20 "gno.land/r/demo/defi/grc20factory"
10)
11
12// cur is a zero-value realm used as a placeholder when forwarding to
13// uassert/urequire dispatch helpers that gained an `rlm realm` param.
14// These tests pass `func()` callbacks (no crossing inside the callback),
15// so rlm is ignored — a nil realm here is safe.
16var cur realm
17
18// Test PanicToError with different types as panic value.
19func TestSimplePanicToError(t *testing.T) {
20 err := pte.PanicToError(func() {
21 panic("string")
22 })
23 uassert.Equal(t, err.Error(), "string")
24
25 err = pte.PanicToError(func() {
26 panic(errors.New("error"))
27 })
28 uassert.Equal(t, err.Error(), "error")
29
30 err = pte.PanicToError(func() {
31 panic(42)
32 })
33 uassert.Equal(t, err.Error(), "42")
34}
35
36func TestRealmPanicToError(cur realm, t *testing.T) {
37 // Set a test realm to be able to call a realm.
38 testRealm := testing.NewCodeRealm("gno.land/r/aeddi/panictoerr/test")
39 testing.SetRealm(testRealm)
40
41 const message = "token instance does not exist"
42 var err error
43
44 // Define a panicking function (local panic; does not cross any
45 // realm boundary). Under the unified declaring-realm borrow,
46 // calling grc20.Bank() would borrow into /r/demo/defi/grc20factory
47 // and any panic there would cross a realm boundary, becoming an
48 // abort catchable only by revive() — see the `aborting` case
49 // below. To exercise the pure recover() path, panic locally.
50 panicking := func() {
51 panic(message)
52 }
53
54 // panicking function should panic.
55 uassert.PanicsWithMessage(t, cur, message, panicking)
56
57 // panicking function should panic when wrapped in AbortToError.
58 uassert.PanicsWithMessage(t, cur, message, func() { pte.AbortToError(panicking) })
59
60 // panicking function should not panic when wrapped in PanicToError.
61 uassert.NotPanics(
62 t, cur,
63 func() { err = pte.PanicToError(panicking) },
64 "panicking function should not panic when wrapped in PanicToError",
65 )
66 uassert.Equal(t, err.Error(), message)
67
68 // panicking function should not panic when wrapped in PanicAbortToError.
69 uassert.NotPanics(
70 t, cur,
71 func() { err = pte.PanicAbortToError(panicking) },
72 "panicking function should not panic when wrapped in PanicAbortToError",
73 )
74 uassert.Equal(t, err.Error(), message)
75
76 // Define an aborting function (crossing).
77 aborting := func() {
78 grc20.Faucet(cross(cur), "unknown")
79 }
80
81 // aborting function should abort.
82 uassert.AbortsWithMessage(t, cur, message, aborting)
83
84 // aborting function should abort when wrapped in PanicToError.
85 uassert.AbortsWithMessage(t, cur, message, func() { pte.PanicToError(aborting) })
86
87 // aborting function should not abort when wrapped in AbortToError.
88 uassert.NotAborts(
89 t, cur,
90 func() { err = pte.AbortToError(aborting) },
91 "aborting function should not abort when wrapped in AbortToError",
92 )
93 uassert.Equal(t, err.Error(), message)
94
95 // aborting function should not abort when wrapped in PanicAbortToError.
96 uassert.NotAborts(
97 t, cur,
98 func() { err = pte.PanicAbortToError(aborting) },
99 "aborting function should not abort when wrapped in PanicAbortToError",
100 )
101 uassert.Equal(t, err.Error(), message)
102}