1package asciiart23import (4 "strings"5 "testing"67 "gno.land/p/moul/kit/store/v0"8 "gno.land/p/nt/testutils/v0"9)1011func resetState() {12 gallery = store.Named("piece")13}1415func TestRenderDiamond(t *testing.T) {16 got := RenderDiamond(3)17 want := " *\n ***\n*****\n ***\n *"18 if got != want {19 t.Fatalf("RenderDiamond(3) =\n%s\nwant\n%s", got, want)20 }21}2223func TestRenderPyramid(t *testing.T) {24 got := RenderPyramid(3)25 want := " *\n ***\n*****"26 if got != want {27 t.Fatalf("RenderPyramid(3) =\n%s\nwant\n%s", got, want)28 }29}3031func TestRenderSierpinski(t *testing.T) {32 got := RenderSierpinski(4)33 want := "####\n# # \n## \n# "34 if got != want {35 t.Fatalf("RenderSierpinski(4) =\n%s\nwant\n%s", got, want)36 }37}3839func TestRenderSierpinskiRejectsNonPowerOfTwo(t *testing.T) {40 defer func() {41 if r := recover(); r == nil {42 t.Fatal("expected panic for a non-power-of-two size")43 }44 }()45 RenderSierpinski(5)46}4748func TestRenderChecker(t *testing.T) {49 got := RenderChecker(3)50 want := "#.#\n.#.\n#.#"51 if got != want {52 t.Fatalf("RenderChecker(3) =\n%s\nwant\n%s", got, want)53 }54}5556func TestRenderPatternUnknown(t *testing.T) {57 defer func() {58 if r := recover(); r == nil {59 t.Fatal("expected panic for an unknown pattern")60 }61 }()62 renderPattern("spiral", 3)63}6465// v1 asserted that its own padID() padded to width 6. That is the narrowest66// ceiling in this repo: padID(10^6) is 7 characters and sorts before67// padID(10^6-1), so from the millionth piece on the gallery would have68// rendered out of order. The store key is 8 bytes for every id.69func TestPadID(t *testing.T) {70 if a, b := store.ID(2).Key(), store.ID(10).Key(); !(a < b) {71 t.Error("id 2 should sort before id 10")72 }73 if a, b := store.ID(999999).Key(), store.ID(1000000).Key(); !(a < b) {74 t.Error("ordering should survive one past v1's width-6 ceiling")75 }76}7778// Crossing: Generate mutates realm state, so the test needs `cur realm`.79func TestGenerateAddsToGallery(cur realm, t *testing.T) {80 resetState()81 alice := testutils.TestAddress("alice")82 testing.SetRealm(testing.NewUserRealm(alice))8384 art := Generate(cross(cur), "checker", 3)85 if art != RenderChecker(3) {86 t.Fatal("Generate should return the rendered art")87 }88 if gallery.LastID() != 1 {89 t.Fatalf("LastID = %s, want 1", gallery.LastID())90 }9192 // The store's Get returns (value, ok), so a stored nil is distinguishable93 // from an absent id, which avl/v0's single-value Get cannot express.94 v, ok := gallery.Get(1)95 if !ok {96 t.Fatal("expected piece #1 to exist in the gallery")97 }98 p := v.(*piece)99 if p.Pattern != "checker" || p.Size != 3 || p.Author != alice {100 t.Fatalf("unexpected piece: %+v", p)101 }102}103104func TestGenerateRejectsOutOfRangeSize(cur realm, t *testing.T) {105 resetState()106 alice := testutils.TestAddress("alice")107 testing.SetRealm(testing.NewUserRealm(alice))108109 rec := revive(func() { Generate(cross(cur), "diamond", 0) })110 if rec == nil {111 t.Fatal("expected panic for size < 1")112 }113 rec = revive(func() { Generate(cross(cur), "diamond", maxSize+1) })114 if rec == nil {115 t.Fatal("expected panic for size > maxSize")116 }117}118119// Non-crossing: Render is a plain read.120func TestRenderHomeEmptyGallery(t *testing.T) {121 resetState()122 out := Render("")123 if !strings.Contains(out, "nothing generated yet") {124 t.Fatal(`Render("") on an empty gallery should say so`)125 }126}127128func TestRenderPieceNotFound(t *testing.T) {129 resetState()130 out := Render("99")131 if !strings.Contains(out, "No such piece") {132 t.Fatal(`Render("99") on a missing piece should say so`)133 }134}135Generate(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, pattern string, size int) string
Render(path string) string
RenderChecker(n int) string
RenderDiamond(n int) string
RenderPyramid(n int) string
RenderSierpinski(n int) string
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.