Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

lplist_test.gno

6.03 Kb · 242 lines
  1package lplist
  2
  3import (
  4	"testing"
  5
  6	"gno.land/p/nym-moultest123/ulist/v0"
  7)
  8
  9// TestLayeredProxyListBasicOperations tests the basic operations of LayeredProxyList
 10func TestLayeredProxyListBasicOperations(t *testing.T) {
 11	// Create source list with initial data
 12	source := ulist.New()
 13	source.Append(1, 2, 3)
 14
 15	// Create proxy list with a simple multiplier migrator
 16	migrator := func(v any) any {
 17		return v.(int) * 2
 18	}
 19	proxy := NewLayeredProxyList(source, migrator)
 20
 21	// Test initial state
 22	if got := proxy.Size(); got != 3 {
 23		t.Errorf("initial Size() = %v, want %v", got, 3)
 24	}
 25	if got := proxy.TotalSize(); got != 3 {
 26		t.Errorf("initial TotalSize() = %v, want %v", got, 3)
 27	}
 28
 29	// Test Get with migration
 30	tests := []struct {
 31		index int
 32		want  any
 33	}{
 34		{0, 2}, // 1 * 2
 35		{1, 4}, // 2 * 2
 36		{2, 6}, // 3 * 2
 37	}
 38
 39	for _, tt := range tests {
 40		if got := proxy.Get(tt.index); got != tt.want {
 41			t.Errorf("Get(%v) = %v, want %v", tt.index, got, tt.want)
 42		}
 43	}
 44
 45	// Test Append to target
 46	proxy.Append(7, 8)
 47	if got := proxy.Size(); got != 5 {
 48		t.Errorf("Size() after append = %v, want %v", got, 5)
 49	}
 50
 51	// Test Get from target (no migration)
 52	if got := proxy.Get(3); got != 7 {
 53		t.Errorf("Get(3) = %v, want %v", got, 7)
 54	}
 55}
 56
 57// TestLayeredProxyListDelete tests delete operations
 58func TestLayeredProxyListDelete(t *testing.T) {
 59	source := ulist.New()
 60	source.Append(1, 2, 3)
 61	proxy := NewLayeredProxyList(source, nil)
 62	proxy.Append(4, 5)
 63
 64	// Test deleting from source (should fail)
 65	if err := proxy.Delete(1); err == nil {
 66		t.Error("Delete from source should return error")
 67	}
 68
 69	// Test deleting from target (should succeed)
 70	if err := proxy.Delete(3); err != nil {
 71		t.Errorf("Delete from target failed: %s", err.Error())
 72	}
 73
 74	// After deletion, the value might be undefined rather than nil
 75	// Check that it's not equal to the original value
 76	if got := proxy.Get(3); got == 5 {
 77		t.Errorf("Get(3) after delete = %v, want it to be deleted", got)
 78	}
 79}
 80
 81// TestLayeredProxyListIteration tests iteration methods
 82func TestLayeredProxyListIteration(t *testing.T) {
 83	source := ulist.New()
 84	source.Append(1, 2, 3)
 85	proxy := NewLayeredProxyList(source, nil)
 86	proxy.Append(4, 5)
 87
 88	// Test GetRange
 89	entries := proxy.GetRange(0, 4)
 90	if len(entries) != 5 {
 91		t.Errorf("GetRange returned %v entries, want 5", len(entries))
 92	}
 93
 94	// Test reverse iteration
 95	entries = proxy.GetRange(4, 0)
 96	if len(entries) != 5 {
 97		t.Errorf("Reverse GetRange returned %v entries, want 5", len(entries))
 98	}
 99
100	// Test IteratorByOffset with positive count
101	var values []any
102	proxy.IteratorByOffset(1, 3, func(index int, value any) bool {
103		values = append(values, value)
104		return false
105	})
106	if len(values) != 3 {
107		t.Errorf("IteratorByOffset returned %v values, want 3", len(values))
108	}
109}
110
111// TestLayeredProxyListMustOperations tests must operations
112func TestLayeredProxyListMustOperations(t *testing.T) {
113	source := ulist.New()
114	source.Append(1, 2)
115	proxy := NewLayeredProxyList(source, nil)
116
117	// Test MustGet success
118	defer func() {
119		if r := recover(); r != nil {
120			t.Errorf("MustGet panicked unexpectedly: %v", r)
121		}
122	}()
123	if got := proxy.MustGet(1); got != 2 {
124		t.Errorf("MustGet(1) = %v, want 2", got)
125	}
126
127	// Test MustGet panic
128	defer func() {
129		if r := recover(); r == nil {
130			t.Error("MustGet should have panicked")
131		}
132	}()
133	proxy.MustGet(99) // Should panic
134}
135
136// TestLayeredProxyListWithNilMigrator tests behavior without a migrator
137func TestLayeredProxyListWithNilMigrator(t *testing.T) {
138	source := ulist.New()
139	source.Append(1, 2)
140	proxy := NewLayeredProxyList(source, nil)
141
142	if got := proxy.Get(0); got != 1 {
143		t.Errorf("Get(0) with nil migrator = %v, want 1", got)
144	}
145}
146
147// TestLayeredProxyListEmpty tests operations on empty lists
148func TestLayeredProxyListEmpty(t *testing.T) {
149	source := ulist.New()
150	proxy := NewLayeredProxyList(source, nil)
151
152	if got := proxy.Size(); got != 0 {
153		t.Errorf("Size() of empty list = %v, want 0", got)
154	}
155
156	if got := proxy.Get(0); got != nil {
157		t.Errorf("Get(0) of empty list = %v, want nil", got)
158	}
159
160	entries := proxy.GetRange(0, 10)
161	if len(entries) != 0 {
162		t.Errorf("GetRange on empty list returned %v entries, want 0", len(entries))
163	}
164}
165
166// TestLayeredProxyListChaining tests chaining of layered proxies with struct migrations
167func TestLayeredProxyListChaining(t *testing.T) {
168	// Define struct types for different versions
169	type v1 struct {
170		namev1 string
171	}
172	type v2 struct {
173		namev2 string
174	}
175	type v3 struct {
176		namev3 string
177	}
178
179	// Create source list with v1 objects
180	source := ulist.New()
181	source.Append(v1{namev1: "object1"}, v1{namev1: "object2"})
182
183	// Migration function from v1 to v2
184	v1Tov2 := func(v any) any {
185		obj := v.(v1)
186		return v2{namev2: obj.namev1 + "_v2"}
187	}
188
189	// Create first proxy with v1->v2 migration
190	proxyV2 := NewLayeredProxyList(source, v1Tov2)
191	proxyV2.Append(v2{namev2: "direct_v2"})
192
193	// Migration function from v2 to v3
194	v2Tov3 := func(v any) any {
195		obj := v.(v2)
196		return v3{namev3: obj.namev2 + "_v3"}
197	}
198
199	// Create second proxy with v2->v3 migration, using the first proxy as source
200	proxyV3 := NewLayeredProxyList(proxyV2, v2Tov3)
201	proxyV3.Append(v3{namev3: "direct_v3"})
202
203	// Verify sizes
204	if got := proxyV3.Size(); got != 4 {
205		t.Errorf("proxyV3.Size() = %v, want 4", got)
206	}
207
208	// Test that all objects are correctly migrated when accessed through proxyV3
209	expected := []struct {
210		index int
211		name  string
212	}{
213		{0, "object1_v2_v3"}, // v1 -> v2 -> v3
214		{1, "object2_v2_v3"}, // v1 -> v2 -> v3
215		{2, "direct_v2_v3"},  // v2 -> v3
216		{3, "direct_v3"},     // v3 (no migration)
217	}
218
219	for _, tt := range expected {
220		obj := proxyV3.Get(tt.index).(v3)
221		if obj.namev3 != tt.name {
222			t.Errorf("proxyV3.Get(%d).namev3 = %v, want %v", tt.index, obj.namev3, tt.name)
223		}
224	}
225
226	// Verify getting items from middle layer (proxyV2)
227	middleExpected := []struct {
228		index int
229		name  string
230	}{
231		{0, "object1_v2"}, // v1 -> v2
232		{1, "object2_v2"}, // v1 -> v2
233		{2, "direct_v2"},  // v2 (no migration)
234	}
235
236	for _, tt := range middleExpected {
237		obj := proxyV2.Get(tt.index).(v2)
238		if obj.namev2 != tt.name {
239			t.Errorf("proxyV2.Get(%d).namev2 = %v, want %v", tt.index, obj.namev2, tt.name)
240		}
241	}
242}