PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/kit/tally/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / kit / tally
Files
4 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/kit/tally/v0
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • tally.gnogno
  • tally_test.gnogno
tally_test.gnogno
1package tally23import (4	"testing"56	"gno.land/p/nt/uassert/v0"7)89func keys(entries []Entry) string {10	out := ""11	for i, e := range entries {12		if i > 0 {13			out += ","14		}15		out += e.Key16	}17	return out18}1920func TestSortOrdersByScoreThenKey(t *testing.T) {21	cases := []struct {22		name string23		in   []Entry24		want string25	}{26		{"already ordered", []Entry{{"a", 3}, {"b", 2}, {"c", 1}}, "a,b,c"},27		{"reversed", []Entry{{"c", 1}, {"b", 2}, {"a", 3}}, "a,b,c"},28		{"all tied, key decides", []Entry{{"c", 5}, {"a", 5}, {"b", 5}}, "a,b,c"},29		{"partial tie", []Entry{{"z", 1}, {"b", 9}, {"a", 9}}, "a,b,z"},30		{"negatives sort below", []Entry{{"a", -1}, {"b", 0}, {"c", 1}}, "c,b,a"},31		{"single", []Entry{{"only", 7}}, "only"},32		{"empty", nil, ""},33	}34	for _, tc := range cases {35		t.Run(tc.name, func(t *testing.T) {36			in := make([]Entry, len(tc.in))37			copy(in, tc.in)38			Sort(in)39			uassert.Equal(t, tc.want, keys(in))40		})41	}42}4344// TestSortIsATotalOrder is the defect this package exists to remove. A45// comparator whose last clause repeats the score (rpgroom's third clause) is46// not a total order: two equal rows compare false both ways and their order is47// decided by the algorithm. Sorting twice from different inputs must agree.48func TestSortIsATotalOrder(t *testing.T) {49	a := []Entry{{"x", 5}, {"y", 5}, {"z", 5}, {"w", 9}}50	b := []Entry{{"z", 5}, {"w", 9}, {"y", 5}, {"x", 5}}51	Sort(a)52	Sort(b)53	uassert.Equal(t, keys(a), keys(b))54	uassert.Equal(t, "w,x,y,z", keys(a))55}5657func TestTop(t *testing.T) {58	in := []Entry{{"c", 1}, {"a", 3}, {"b", 2}}59	uassert.Equal(t, "a,b", keys(Top(in, 2)))60	uassert.Equal(t, "a,b,c", keys(Top(in, 10)))61	uassert.Equal(t, "", keys(Top(in, 0)))62	uassert.Equal(t, "", keys(Top(in, -1)))63	uassert.Equal(t, "", keys(Top(nil, 3)))64}6566// TestTopDoesNotDisturbTheCaller pins that Top copies. A realm that renders a67// Top(3) and then iterates its own slice must not find it reordered.68func TestTopDoesNotDisturbTheCaller(t *testing.T) {69	in := []Entry{{"c", 1}, {"a", 3}, {"b", 2}}70	_ = Top(in, 2)71	uassert.Equal(t, "c,a,b", keys(in))72}7374func TestRank(t *testing.T) {75	in := []Entry{{"c", 1}, {"a", 3}, {"b", 2}}76	uassert.Equal(t, 1, Rank(in, "a"))77	uassert.Equal(t, 2, Rank(in, "b"))78	uassert.Equal(t, 3, Rank(in, "c"))79	uassert.Equal(t, 0, Rank(in, "absent"))80}8182// TestRankNeverTies is what makes a rendered "#3" mean something: two equal83// scores still get 2 and 3, never 2 and 2.84func TestRankNeverTies(t *testing.T) {85	in := []Entry{{"a", 5}, {"b", 5}, {"c", 5}}86	seen := map[int]bool{}87	for _, e := range in {88		r := Rank(in, e.Key)89		if seen[r] {90			t.Errorf("rank %d claimed twice", r)91		}92		seen[r] = true93	}94	uassert.Equal(t, 3, len(seen))95}9697func TestBoardAddAndScore(t *testing.T) {98	b := NewBoard()99	uassert.Equal(t, 0, b.Len())100	uassert.Equal(t, int64(5), b.Add("a", 5))101	uassert.Equal(t, int64(8), b.Add("a", 3))102	uassert.Equal(t, int64(6), b.Add("a", -2))103	uassert.Equal(t, int64(6), b.Score("a"))104	uassert.Equal(t, int64(0), b.Score("never"))105	uassert.Equal(t, 1, b.Len())106}107108func TestBoardHasDistinguishesAbsentFromZero(t *testing.T) {109	b := NewBoard()110	b.Set("zero", 0)111	uassert.True(t, b.Has("zero"))112	uassert.False(t, b.Has("absent"))113	uassert.Equal(t, int64(0), b.Score("zero"))114	uassert.Equal(t, int64(0), b.Score("absent"))115}116117func TestBoardRemove(t *testing.T) {118	b := NewBoard()119	b.Set("a", 1)120	uassert.True(t, b.Remove("a"))121	uassert.False(t, b.Remove("a"))122	uassert.Equal(t, 0, b.Len())123}124125func TestBoardEntriesAndTop(t *testing.T) {126	b := NewBoard()127	b.Set("c", 1)128	b.Set("a", 3)129	b.Set("b", 3)130	uassert.Equal(t, "a,b,c", keys(b.Entries()))131	uassert.Equal(t, "a,b", keys(b.Top(2)))132	uassert.Equal(t, 1, b.Rank("a"))133	uassert.Equal(t, 2, b.Rank("b"))134	uassert.Equal(t, 0, b.Rank("absent"))135}136137// TestBoardOrderDoesNotDependOnInsertion is the reason Board is backed by a138// tree and not a map: the same scores inserted in a different order must139// render identically.140func TestBoardOrderDoesNotDependOnInsertion(t *testing.T) {141	one := NewBoard()142	for _, e := range []Entry{{"a", 5}, {"b", 5}, {"c", 9}} {143		one.Set(e.Key, e.Score)144	}145	two := NewBoard()146	for _, e := range []Entry{{"c", 9}, {"b", 5}, {"a", 5}} {147		two.Set(e.Key, e.Score)148	}149	uassert.Equal(t, keys(one.Entries()), keys(two.Entries()))150	uassert.Equal(t, "c,a,b", keys(one.Entries()))151}152

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.