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.

ulist_test.gno

27.06 Kb · 1422 lines
   1package ulist
   2
   3import (
   4	"testing"
   5
   6	"gno.land/p/nym-moultest123/typeutil/v0"
   7	"gno.land/p/nt/uassert/v0"
   8	"gno.land/p/nt/ufmt/v0"
   9)
  10
  11func TestNew(t *testing.T) {
  12	l := New()
  13	uassert.Equal(t, 0, l.Size())
  14	uassert.Equal(t, 0, l.TotalSize())
  15}
  16
  17func TestListAppendAndGet(t *testing.T) {
  18	tests := []struct {
  19		name     string
  20		setup    func() *List
  21		index    int
  22		expected any
  23	}{
  24		{
  25			name: "empty list",
  26			setup: func() *List {
  27				return New()
  28			},
  29			index:    0,
  30			expected: nil,
  31		},
  32		{
  33			name: "single append and get",
  34			setup: func() *List {
  35				l := New()
  36				l.Append(42)
  37				return l
  38			},
  39			index:    0,
  40			expected: 42,
  41		},
  42		{
  43			name: "multiple appends and get first",
  44			setup: func() *List {
  45				l := New()
  46				l.Append(1)
  47				l.Append(2)
  48				l.Append(3)
  49				return l
  50			},
  51			index:    0,
  52			expected: 1,
  53		},
  54		{
  55			name: "multiple appends and get last",
  56			setup: func() *List {
  57				l := New()
  58				l.Append(1)
  59				l.Append(2)
  60				l.Append(3)
  61				return l
  62			},
  63			index:    2,
  64			expected: 3,
  65		},
  66		{
  67			name: "get with invalid index",
  68			setup: func() *List {
  69				l := New()
  70				l.Append(1)
  71				return l
  72			},
  73			index:    1,
  74			expected: nil,
  75		},
  76		{
  77			name: "31 items get first",
  78			setup: func() *List {
  79				l := New()
  80				for i := 0; i < 31; i++ {
  81					l.Append(i)
  82				}
  83				return l
  84			},
  85			index:    0,
  86			expected: 0,
  87		},
  88		{
  89			name: "31 items get last",
  90			setup: func() *List {
  91				l := New()
  92				for i := 0; i < 31; i++ {
  93					l.Append(i)
  94				}
  95				return l
  96			},
  97			index:    30,
  98			expected: 30,
  99		},
 100		{
 101			name: "31 items get middle",
 102			setup: func() *List {
 103				l := New()
 104				for i := 0; i < 31; i++ {
 105					l.Append(i)
 106				}
 107				return l
 108			},
 109			index:    15,
 110			expected: 15,
 111		},
 112		{
 113			name: "values around power of 2 boundary",
 114			setup: func() *List {
 115				l := New()
 116				for i := 0; i < 18; i++ {
 117					l.Append(i)
 118				}
 119				return l
 120			},
 121			index:    15,
 122			expected: 15,
 123		},
 124		{
 125			name: "values at power of 2",
 126			setup: func() *List {
 127				l := New()
 128				for i := 0; i < 18; i++ {
 129					l.Append(i)
 130				}
 131				return l
 132			},
 133			index:    16,
 134			expected: 16,
 135		},
 136		{
 137			name: "values after power of 2",
 138			setup: func() *List {
 139				l := New()
 140				for i := 0; i < 18; i++ {
 141					l.Append(i)
 142				}
 143				return l
 144			},
 145			index:    17,
 146			expected: 17,
 147		},
 148	}
 149
 150	for _, tt := range tests {
 151		t.Run(tt.name, func(t *testing.T) {
 152			l := tt.setup()
 153			got := l.Get(tt.index)
 154			if got != tt.expected {
 155				t.Errorf("List.Get() = %v, want %v", got, tt.expected)
 156			}
 157		})
 158	}
 159}
 160
 161// generateSequence creates a slice of integers from 0 to n-1
 162func generateSequence(n int) []any {
 163	result := make([]any, n)
 164	for i := 0; i < n; i++ {
 165		result[i] = i
 166	}
 167	return result
 168}
 169
 170func TestListDelete(t *testing.T) {
 171	tests := []struct {
 172		name          string
 173		setup         func() *List
 174		deleteIndices []int
 175		expectedErr   error
 176		expectedSize  int
 177	}{
 178		{
 179			name: "delete single element",
 180			setup: func() *List {
 181				l := New()
 182				l.Append(1, 2, 3)
 183				return l
 184			},
 185			deleteIndices: []int{1},
 186			expectedErr:   nil,
 187			expectedSize:  2,
 188		},
 189		{
 190			name: "delete multiple elements",
 191			setup: func() *List {
 192				l := New()
 193				l.Append(1, 2, 3, 4, 5)
 194				return l
 195			},
 196			deleteIndices: []int{0, 2, 4},
 197			expectedErr:   nil,
 198			expectedSize:  2,
 199		},
 200		{
 201			name: "delete with negative index",
 202			setup: func() *List {
 203				l := New()
 204				l.Append(1)
 205				return l
 206			},
 207			deleteIndices: []int{-1},
 208			expectedErr:   ErrOutOfBounds,
 209			expectedSize:  1,
 210		},
 211		{
 212			name: "delete beyond size",
 213			setup: func() *List {
 214				l := New()
 215				l.Append(1)
 216				return l
 217			},
 218			deleteIndices: []int{1},
 219			expectedErr:   ErrOutOfBounds,
 220			expectedSize:  1,
 221		},
 222		{
 223			name: "delete already deleted element",
 224			setup: func() *List {
 225				l := New()
 226				l.Append(1)
 227				l.Delete(0)
 228				return l
 229			},
 230			deleteIndices: []int{0},
 231			expectedErr:   ErrDeleted,
 232			expectedSize:  0,
 233		},
 234		{
 235			name: "delete multiple elements in reverse",
 236			setup: func() *List {
 237				l := New()
 238				l.Append(1, 2, 3, 4, 5)
 239				return l
 240			},
 241			deleteIndices: []int{4, 2, 0},
 242			expectedErr:   nil,
 243			expectedSize:  2,
 244		},
 245	}
 246
 247	for _, tt := range tests {
 248		t.Run(tt.name, func(t *testing.T) {
 249			l := tt.setup()
 250			initialSize := l.Size()
 251			err := l.Delete(tt.deleteIndices...)
 252			if err != nil && tt.expectedErr != nil {
 253				uassert.ErrorIs(t, err, tt.expectedErr)
 254			} else {
 255				uassert.Equal(t, tt.expectedErr, err)
 256			}
 257			uassert.Equal(t, tt.expectedSize, l.Size(),
 258				ufmt.Sprintf("Expected size %d after deleting %d elements from size %d, got %d",
 259					tt.expectedSize, len(tt.deleteIndices), initialSize, l.Size()))
 260		})
 261	}
 262}
 263
 264func TestListSizeAndTotalSize(t *testing.T) {
 265	t.Run("empty list", func(t *testing.T) {
 266		list := New()
 267		uassert.Equal(t, 0, list.Size())
 268		uassert.Equal(t, 0, list.TotalSize())
 269	})
 270
 271	t.Run("list with elements", func(t *testing.T) {
 272		list := New()
 273		list.Append(1)
 274		list.Append(2)
 275		list.Append(3)
 276		uassert.Equal(t, 3, list.Size())
 277		uassert.Equal(t, 3, list.TotalSize())
 278	})
 279
 280	t.Run("list with deleted elements", func(t *testing.T) {
 281		list := New()
 282		list.Append(1)
 283		list.Append(2)
 284		list.Append(3)
 285		list.Delete(1)
 286		uassert.Equal(t, 2, list.Size())
 287		uassert.Equal(t, 3, list.TotalSize())
 288	})
 289}
 290
 291func TestIterator(t *testing.T) {
 292	tests := []struct {
 293		name      string
 294		values    []any
 295		start     int
 296		end       int
 297		expected  []Entry
 298		wantStop  bool
 299		stopAfter int // stop after N elements, -1 for no stop
 300	}{
 301		{
 302			name:      "empty list",
 303			values:    []any{},
 304			start:     0,
 305			end:       10,
 306			expected:  []Entry{},
 307			stopAfter: -1,
 308		},
 309		{
 310			name:      "nil list",
 311			values:    nil,
 312			start:     0,
 313			end:       0,
 314			expected:  []Entry{},
 315			stopAfter: -1,
 316		},
 317		{
 318			name:   "single element forward",
 319			values: []any{42},
 320			start:  0,
 321			end:    0,
 322			expected: []Entry{
 323				{Index: 0, Value: 42},
 324			},
 325			stopAfter: -1,
 326		},
 327		{
 328			name:   "multiple elements forward",
 329			values: []any{1, 2, 3, 4, 5},
 330			start:  0,
 331			end:    4,
 332			expected: []Entry{
 333				{Index: 0, Value: 1},
 334				{Index: 1, Value: 2},
 335				{Index: 2, Value: 3},
 336				{Index: 3, Value: 4},
 337				{Index: 4, Value: 5},
 338			},
 339			stopAfter: -1,
 340		},
 341		{
 342			name:   "multiple elements reverse",
 343			values: []any{1, 2, 3, 4, 5},
 344			start:  4,
 345			end:    0,
 346			expected: []Entry{
 347				{Index: 4, Value: 5},
 348				{Index: 3, Value: 4},
 349				{Index: 2, Value: 3},
 350				{Index: 1, Value: 2},
 351				{Index: 0, Value: 1},
 352			},
 353			stopAfter: -1,
 354		},
 355		{
 356			name:   "partial range forward",
 357			values: []any{1, 2, 3, 4, 5},
 358			start:  1,
 359			end:    3,
 360			expected: []Entry{
 361				{Index: 1, Value: 2},
 362				{Index: 2, Value: 3},
 363				{Index: 3, Value: 4},
 364			},
 365			stopAfter: -1,
 366		},
 367		{
 368			name:   "partial range reverse",
 369			values: []any{1, 2, 3, 4, 5},
 370			start:  3,
 371			end:    1,
 372			expected: []Entry{
 373				{Index: 3, Value: 4},
 374				{Index: 2, Value: 3},
 375				{Index: 1, Value: 2},
 376			},
 377			stopAfter: -1,
 378		},
 379		{
 380			name:      "stop iteration early",
 381			values:    []any{1, 2, 3, 4, 5},
 382			start:     0,
 383			end:       4,
 384			wantStop:  true,
 385			stopAfter: 2,
 386			expected: []Entry{
 387				{Index: 0, Value: 1},
 388				{Index: 1, Value: 2},
 389			},
 390		},
 391		{
 392			name:   "negative start",
 393			values: []any{1, 2, 3},
 394			start:  -1,
 395			end:    2,
 396			expected: []Entry{
 397				{Index: 0, Value: 1},
 398				{Index: 1, Value: 2},
 399				{Index: 2, Value: 3},
 400			},
 401			stopAfter: -1,
 402		},
 403		{
 404			name:   "negative end",
 405			values: []any{1, 2, 3},
 406			start:  0,
 407			end:    -2,
 408			expected: []Entry{
 409				{Index: 0, Value: 1},
 410			},
 411			stopAfter: -1,
 412		},
 413		{
 414			name:      "start beyond size",
 415			values:    []any{1, 2, 3},
 416			start:     5,
 417			end:       6,
 418			expected:  []Entry{},
 419			stopAfter: -1,
 420		},
 421		{
 422			name:   "end beyond size",
 423			values: []any{1, 2, 3},
 424			start:  0,
 425			end:    5,
 426			expected: []Entry{
 427				{Index: 0, Value: 1},
 428				{Index: 1, Value: 2},
 429				{Index: 2, Value: 3},
 430			},
 431			stopAfter: -1,
 432		},
 433		{
 434			name:   "with deleted elements",
 435			values: []any{1, 2, nil, 4, 5},
 436			start:  0,
 437			end:    4,
 438			expected: []Entry{
 439				{Index: 0, Value: 1},
 440				{Index: 1, Value: 2},
 441				{Index: 3, Value: 4},
 442				{Index: 4, Value: 5},
 443			},
 444			stopAfter: -1,
 445		},
 446		{
 447			name:   "with deleted elements reverse",
 448			values: []any{1, nil, 3, nil, 5},
 449			start:  4,
 450			end:    0,
 451			expected: []Entry{
 452				{Index: 4, Value: 5},
 453				{Index: 2, Value: 3},
 454				{Index: 0, Value: 1},
 455			},
 456			stopAfter: -1,
 457		},
 458		{
 459			name:      "start equals end",
 460			values:    []any{1, 2, 3},
 461			start:     1,
 462			end:       1,
 463			expected:  []Entry{{Index: 1, Value: 2}},
 464			stopAfter: -1,
 465		},
 466	}
 467
 468	for _, tt := range tests {
 469		t.Run(tt.name, func(t *testing.T) {
 470			list := New()
 471			list.Append(tt.values...)
 472
 473			var result []Entry
 474			stopped := list.Iterator(tt.start, tt.end, func(index int, value any) bool {
 475				result = append(result, Entry{Index: index, Value: value})
 476				return tt.stopAfter >= 0 && len(result) >= tt.stopAfter
 477			})
 478
 479			uassert.Equal(t, len(result), len(tt.expected), "comparing length")
 480
 481			for i := range result {
 482				uassert.Equal(t, result[i].Index, tt.expected[i].Index, "comparing index")
 483				uassert.Equal(t, typeutil.ToString(result[i].Value), typeutil.ToString(tt.expected[i].Value), "comparing value")
 484			}
 485
 486			uassert.Equal(t, stopped, tt.wantStop, "comparing stopped")
 487		})
 488	}
 489}
 490
 491func TestLargeListAppendGetAndDelete(t *testing.T) {
 492	l := New()
 493	size := 100
 494
 495	// Append values from 0 to 99
 496	for i := 0; i < size; i++ {
 497		l.Append(i)
 498		val := l.Get(i)
 499		uassert.Equal(t, i, val)
 500	}
 501
 502	// Verify size
 503	uassert.Equal(t, size, l.Size())
 504	uassert.Equal(t, size, l.TotalSize())
 505
 506	// Get and verify each value
 507	for i := 0; i < size; i++ {
 508		val := l.Get(i)
 509		uassert.Equal(t, i, val)
 510	}
 511
 512	// Get and verify each value
 513	for i := 0; i < size; i++ {
 514		err := l.Delete(i)
 515		uassert.Equal(t, nil, err)
 516	}
 517
 518	// Verify size
 519	uassert.Equal(t, 0, l.Size())
 520	uassert.Equal(t, size, l.TotalSize())
 521
 522	// Get and verify each value
 523	for i := 0; i < size; i++ {
 524		val := l.Get(i)
 525		uassert.Equal(t, nil, val)
 526	}
 527}
 528
 529func TestEdgeCases(t *testing.T) {
 530	tests := []struct {
 531		name string
 532		test func(t *testing.T)
 533	}{
 534		{
 535			name: "nil list operations",
 536			test: func(t *testing.T) {
 537				var l *List
 538				uassert.Equal(t, 0, l.Size())
 539				uassert.Equal(t, 0, l.TotalSize())
 540				uassert.Equal(t, nil, l.Get(0))
 541				err := l.Delete(0)
 542				uassert.ErrorIs(t, err, ErrOutOfBounds)
 543			},
 544		},
 545		{
 546			name: "delete empty indices slice",
 547			test: func(t *testing.T) {
 548				l := New()
 549				l.Append(1)
 550				err := l.Delete()
 551				uassert.Equal(t, nil, err)
 552				uassert.Equal(t, 1, l.Size())
 553			},
 554		},
 555		{
 556			name: "append nil values",
 557			test: func(t *testing.T) {
 558				l := New()
 559				l.Append(nil, nil)
 560				uassert.Equal(t, 2, l.Size())
 561				uassert.Equal(t, nil, l.Get(0))
 562				uassert.Equal(t, nil, l.Get(1))
 563			},
 564		},
 565		{
 566			name: "delete same index multiple times",
 567			test: func(t *testing.T) {
 568				l := New()
 569				l.Append(1, 2, 3)
 570				err := l.Delete(1)
 571				uassert.Equal(t, nil, err)
 572				err = l.Delete(1)
 573				uassert.ErrorIs(t, err, ErrDeleted)
 574			},
 575		},
 576		{
 577			name: "iterator with all deleted elements",
 578			test: func(t *testing.T) {
 579				l := New()
 580				l.Append(1, 2, 3)
 581				l.Delete(0, 1, 2)
 582				var count int
 583				l.Iterator(0, 2, func(index int, value any) bool {
 584					count++
 585					return false
 586				})
 587				uassert.Equal(t, 0, count)
 588			},
 589		},
 590		{
 591			name: "append after delete",
 592			test: func(t *testing.T) {
 593				l := New()
 594				l.Append(1, 2)
 595				l.Delete(1)
 596				l.Append(3)
 597				uassert.Equal(t, 2, l.Size())
 598				uassert.Equal(t, 3, l.TotalSize())
 599				uassert.Equal(t, 1, l.Get(0))
 600				uassert.Equal(t, nil, l.Get(1))
 601				uassert.Equal(t, 3, l.Get(2))
 602			},
 603		},
 604	}
 605
 606	for _, tt := range tests {
 607		t.Run(tt.name, func(t *testing.T) {
 608			tt.test(t)
 609		})
 610	}
 611}
 612
 613func TestIteratorByOffset(t *testing.T) {
 614	tests := []struct {
 615		name     string
 616		values   []any
 617		offset   int
 618		count    int
 619		expected []Entry
 620		wantStop bool
 621	}{
 622		{
 623			name:     "empty list",
 624			values:   []any{},
 625			offset:   0,
 626			count:    5,
 627			expected: []Entry{},
 628			wantStop: false,
 629		},
 630		{
 631			name:   "positive count forward iteration",
 632			values: []any{1, 2, 3, 4, 5},
 633			offset: 1,
 634			count:  2,
 635			expected: []Entry{
 636				{Index: 1, Value: 2},
 637				{Index: 2, Value: 3},
 638			},
 639			wantStop: false,
 640		},
 641		{
 642			name:   "negative count backward iteration",
 643			values: []any{1, 2, 3, 4, 5},
 644			offset: 3,
 645			count:  -2,
 646			expected: []Entry{
 647				{Index: 3, Value: 4},
 648				{Index: 2, Value: 3},
 649			},
 650			wantStop: false,
 651		},
 652		{
 653			name:   "count exceeds available elements forward",
 654			values: []any{1, 2, 3},
 655			offset: 1,
 656			count:  5,
 657			expected: []Entry{
 658				{Index: 1, Value: 2},
 659				{Index: 2, Value: 3},
 660			},
 661			wantStop: false,
 662		},
 663		{
 664			name:   "count exceeds available elements backward",
 665			values: []any{1, 2, 3},
 666			offset: 1,
 667			count:  -5,
 668			expected: []Entry{
 669				{Index: 1, Value: 2},
 670				{Index: 0, Value: 1},
 671			},
 672			wantStop: false,
 673		},
 674		{
 675			name:     "zero count",
 676			values:   []any{1, 2, 3},
 677			offset:   0,
 678			count:    0,
 679			expected: []Entry{},
 680			wantStop: false,
 681		},
 682		{
 683			name:   "negative offset",
 684			values: []any{1, 2, 3},
 685			offset: -1,
 686			count:  2,
 687			expected: []Entry{
 688				{Index: 0, Value: 1},
 689				{Index: 1, Value: 2},
 690			},
 691			wantStop: false,
 692		},
 693		{
 694			name:   "offset beyond size",
 695			values: []any{1, 2, 3},
 696			offset: 5,
 697			count:  -2,
 698			expected: []Entry{
 699				{Index: 2, Value: 3},
 700				{Index: 1, Value: 2},
 701			},
 702			wantStop: false,
 703		},
 704		{
 705			name:   "with deleted elements",
 706			values: []any{1, nil, 3, nil, 5},
 707			offset: 0,
 708			count:  3,
 709			expected: []Entry{
 710				{Index: 0, Value: 1},
 711				{Index: 2, Value: 3},
 712				{Index: 4, Value: 5},
 713			},
 714			wantStop: false,
 715		},
 716		{
 717			name:   "early stop in forward iteration",
 718			values: []any{1, 2, 3, 4, 5},
 719			offset: 0,
 720			count:  5,
 721			expected: []Entry{
 722				{Index: 0, Value: 1},
 723				{Index: 1, Value: 2},
 724			},
 725			wantStop: true, // The callback will return true after 2 elements
 726		},
 727		{
 728			name:   "early stop in backward iteration",
 729			values: []any{1, 2, 3, 4, 5},
 730			offset: 4,
 731			count:  -5,
 732			expected: []Entry{
 733				{Index: 4, Value: 5},
 734				{Index: 3, Value: 4},
 735			},
 736			wantStop: true, // The callback will return true after 2 elements
 737		},
 738		{
 739			name:     "nil list",
 740			values:   nil,
 741			offset:   0,
 742			count:    5,
 743			expected: []Entry{},
 744			wantStop: false,
 745		},
 746		{
 747			name:   "single element forward",
 748			values: []any{1},
 749			offset: 0,
 750			count:  5,
 751			expected: []Entry{
 752				{Index: 0, Value: 1},
 753			},
 754			wantStop: false,
 755		},
 756		{
 757			name:   "single element backward",
 758			values: []any{1},
 759			offset: 0,
 760			count:  -5,
 761			expected: []Entry{
 762				{Index: 0, Value: 1},
 763			},
 764			wantStop: false,
 765		},
 766		{
 767			name:     "all deleted elements",
 768			values:   []any{nil, nil, nil},
 769			offset:   0,
 770			count:    3,
 771			expected: []Entry{},
 772			wantStop: false,
 773		},
 774	}
 775
 776	for _, tt := range tests {
 777		t.Run(tt.name, func(t *testing.T) {
 778			list := New()
 779			list.Append(tt.values...)
 780
 781			var result []Entry
 782			var cb IterCbFn
 783			if tt.wantStop {
 784				cb = func(index int, value any) bool {
 785					result = append(result, Entry{Index: index, Value: value})
 786					return len(result) >= 2 // Stop after 2 elements for early stop tests
 787				}
 788			} else {
 789				cb = func(index int, value any) bool {
 790					result = append(result, Entry{Index: index, Value: value})
 791					return false
 792				}
 793			}
 794
 795			stopped := list.IteratorByOffset(tt.offset, tt.count, cb)
 796
 797			uassert.Equal(t, len(tt.expected), len(result), "comparing length")
 798			for i := range result {
 799				uassert.Equal(t, tt.expected[i].Index, result[i].Index, "comparing index")
 800				uassert.Equal(t, typeutil.ToString(tt.expected[i].Value), typeutil.ToString(result[i].Value), "comparing value")
 801			}
 802			uassert.Equal(t, tt.wantStop, stopped, "comparing stopped")
 803		})
 804	}
 805}
 806
 807func TestMustDelete(t *testing.T) {
 808	tests := []struct {
 809		name        string
 810		setup       func() *List
 811		indices     []int
 812		shouldPanic bool
 813		panicMsg    string
 814	}{
 815		{
 816			name: "successful delete",
 817			setup: func() *List {
 818				l := New()
 819				l.Append(1, 2, 3)
 820				return l
 821			},
 822			indices:     []int{1},
 823			shouldPanic: false,
 824		},
 825		{
 826			name: "out of bounds",
 827			setup: func() *List {
 828				l := New()
 829				l.Append(1)
 830				return l
 831			},
 832			indices:     []int{1},
 833			shouldPanic: true,
 834			panicMsg:    ErrOutOfBounds.Error(),
 835		},
 836		{
 837			name: "already deleted",
 838			setup: func() *List {
 839				l := New()
 840				l.Append(1)
 841				l.Delete(0)
 842				return l
 843			},
 844			indices:     []int{0},
 845			shouldPanic: true,
 846			panicMsg:    ErrDeleted.Error(),
 847		},
 848	}
 849
 850	for _, tt := range tests {
 851		t.Run(tt.name, func(t *testing.T) {
 852			l := tt.setup()
 853			if tt.shouldPanic {
 854				defer func() {
 855					r := recover()
 856					if r == nil {
 857						t.Error("Expected panic but got none")
 858					}
 859					err, ok := r.(error)
 860					if !ok {
 861						t.Errorf("Expected error but got %v", r)
 862					}
 863					uassert.Equal(t, tt.panicMsg, err.Error())
 864				}()
 865			}
 866			l.MustDelete(tt.indices...)
 867			if tt.shouldPanic {
 868				t.Error("Expected panic")
 869			}
 870		})
 871	}
 872}
 873
 874func TestMustGet(t *testing.T) {
 875	tests := []struct {
 876		name        string
 877		setup       func() *List
 878		index       int
 879		expected    any
 880		shouldPanic bool
 881		panicMsg    string
 882	}{
 883		{
 884			name: "successful get",
 885			setup: func() *List {
 886				l := New()
 887				l.Append(42)
 888				return l
 889			},
 890			index:       0,
 891			expected:    42,
 892			shouldPanic: false,
 893		},
 894		{
 895			name: "out of bounds negative",
 896			setup: func() *List {
 897				l := New()
 898				l.Append(1)
 899				return l
 900			},
 901			index:       -1,
 902			shouldPanic: true,
 903			panicMsg:    ErrOutOfBounds.Error(),
 904		},
 905		{
 906			name: "out of bounds positive",
 907			setup: func() *List {
 908				l := New()
 909				l.Append(1)
 910				return l
 911			},
 912			index:       1,
 913			shouldPanic: true,
 914			panicMsg:    ErrOutOfBounds.Error(),
 915		},
 916		{
 917			name: "deleted element",
 918			setup: func() *List {
 919				l := New()
 920				l.Append(1)
 921				l.Delete(0)
 922				return l
 923			},
 924			index:       0,
 925			shouldPanic: true,
 926			panicMsg:    ErrDeleted.Error(),
 927		},
 928		{
 929			name: "nil list",
 930			setup: func() *List {
 931				return nil
 932			},
 933			index:       0,
 934			shouldPanic: true,
 935			panicMsg:    ErrOutOfBounds.Error(),
 936		},
 937	}
 938
 939	for _, tt := range tests {
 940		t.Run(tt.name, func(t *testing.T) {
 941			l := tt.setup()
 942			if tt.shouldPanic {
 943				defer func() {
 944					r := recover()
 945					if r == nil {
 946						t.Error("Expected panic but got none")
 947					}
 948					err, ok := r.(error)
 949					if !ok {
 950						t.Errorf("Expected error but got %v", r)
 951					}
 952					uassert.Equal(t, tt.panicMsg, err.Error())
 953				}()
 954			}
 955			result := l.MustGet(tt.index)
 956			if tt.shouldPanic {
 957				t.Error("Expected panic")
 958			}
 959			uassert.Equal(t, typeutil.ToString(tt.expected), typeutil.ToString(result))
 960		})
 961	}
 962}
 963
 964func TestGetRange(t *testing.T) {
 965	tests := []struct {
 966		name     string
 967		values   []any
 968		start    int
 969		end      int
 970		expected []Entry
 971	}{
 972		{
 973			name:     "empty list",
 974			values:   []any{},
 975			start:    0,
 976			end:      10,
 977			expected: []Entry{},
 978		},
 979		{
 980			name:   "single element",
 981			values: []any{42},
 982			start:  0,
 983			end:    0,
 984			expected: []Entry{
 985				{Index: 0, Value: 42},
 986			},
 987		},
 988		{
 989			name:   "multiple elements forward",
 990			values: []any{1, 2, 3, 4, 5},
 991			start:  1,
 992			end:    3,
 993			expected: []Entry{
 994				{Index: 1, Value: 2},
 995				{Index: 2, Value: 3},
 996				{Index: 3, Value: 4},
 997			},
 998		},
 999		{
1000			name:   "multiple elements reverse",
1001			values: []any{1, 2, 3, 4, 5},
1002			start:  3,
1003			end:    1,
1004			expected: []Entry{
1005				{Index: 3, Value: 4},
1006				{Index: 2, Value: 3},
1007				{Index: 1, Value: 2},
1008			},
1009		},
1010		{
1011			name:   "with deleted elements",
1012			values: []any{1, nil, 3, nil, 5},
1013			start:  0,
1014			end:    4,
1015			expected: []Entry{
1016				{Index: 0, Value: 1},
1017				{Index: 2, Value: 3},
1018				{Index: 4, Value: 5},
1019			},
1020		},
1021		{
1022			name:     "nil list",
1023			values:   nil,
1024			start:    0,
1025			end:      5,
1026			expected: []Entry{},
1027		},
1028		{
1029			name:     "negative indices",
1030			values:   []any{1, 2, 3},
1031			start:    -1,
1032			end:      -2,
1033			expected: []Entry{},
1034		},
1035		{
1036			name:   "indices beyond size",
1037			values: []any{1, 2, 3},
1038			start:  1,
1039			end:    5,
1040			expected: []Entry{
1041				{Index: 1, Value: 2},
1042				{Index: 2, Value: 3},
1043			},
1044		},
1045	}
1046
1047	for _, tt := range tests {
1048		t.Run(tt.name, func(t *testing.T) {
1049			list := New()
1050			list.Append(tt.values...)
1051
1052			result := list.GetRange(tt.start, tt.end)
1053
1054			uassert.Equal(t, len(tt.expected), len(result), "comparing length")
1055			for i := range result {
1056				uassert.Equal(t, tt.expected[i].Index, result[i].Index, "comparing index")
1057				uassert.Equal(t, typeutil.ToString(tt.expected[i].Value), typeutil.ToString(result[i].Value), "comparing value")
1058			}
1059		})
1060	}
1061}
1062
1063func TestGetByOffset(t *testing.T) {
1064	tests := []struct {
1065		name     string
1066		values   []any
1067		offset   int
1068		count    int
1069		expected []Entry
1070	}{
1071		{
1072			name:     "empty list",
1073			values:   []any{},
1074			offset:   0,
1075			count:    5,
1076			expected: []Entry{},
1077		},
1078		{
1079			name:   "positive count forward",
1080			values: []any{1, 2, 3, 4, 5},
1081			offset: 1,
1082			count:  2,
1083			expected: []Entry{
1084				{Index: 1, Value: 2},
1085				{Index: 2, Value: 3},
1086			},
1087		},
1088		{
1089			name:   "negative count backward",
1090			values: []any{1, 2, 3, 4, 5},
1091			offset: 3,
1092			count:  -2,
1093			expected: []Entry{
1094				{Index: 3, Value: 4},
1095				{Index: 2, Value: 3},
1096			},
1097		},
1098		{
1099			name:   "count exceeds available elements",
1100			values: []any{1, 2, 3},
1101			offset: 1,
1102			count:  5,
1103			expected: []Entry{
1104				{Index: 1, Value: 2},
1105				{Index: 2, Value: 3},
1106			},
1107		},
1108		{
1109			name:     "zero count",
1110			values:   []any{1, 2, 3},
1111			offset:   0,
1112			count:    0,
1113			expected: []Entry{},
1114		},
1115		{
1116			name:   "with deleted elements",
1117			values: []any{1, nil, 3, nil, 5},
1118			offset: 0,
1119			count:  3,
1120			expected: []Entry{
1121				{Index: 0, Value: 1},
1122				{Index: 2, Value: 3},
1123				{Index: 4, Value: 5},
1124			},
1125		},
1126		{
1127			name:   "negative offset",
1128			values: []any{1, 2, 3},
1129			offset: -1,
1130			count:  2,
1131			expected: []Entry{
1132				{Index: 0, Value: 1},
1133				{Index: 1, Value: 2},
1134			},
1135		},
1136		{
1137			name:   "offset beyond size",
1138			values: []any{1, 2, 3},
1139			offset: 5,
1140			count:  -2,
1141			expected: []Entry{
1142				{Index: 2, Value: 3},
1143				{Index: 1, Value: 2},
1144			},
1145		},
1146		{
1147			name:     "nil list",
1148			values:   nil,
1149			offset:   0,
1150			count:    5,
1151			expected: []Entry{},
1152		},
1153	}
1154
1155	for _, tt := range tests {
1156		t.Run(tt.name, func(t *testing.T) {
1157			list := New()
1158			list.Append(tt.values...)
1159
1160			result := list.GetByOffset(tt.offset, tt.count)
1161
1162			uassert.Equal(t, len(tt.expected), len(result), "comparing length")
1163			for i := range result {
1164				uassert.Equal(t, tt.expected[i].Index, result[i].Index, "comparing index")
1165				uassert.Equal(t, typeutil.ToString(tt.expected[i].Value), typeutil.ToString(result[i].Value), "comparing value")
1166			}
1167		})
1168	}
1169}
1170
1171func TestMustSet(t *testing.T) {
1172	tests := []struct {
1173		name        string
1174		setup       func() *List
1175		index       int
1176		value       any
1177		shouldPanic bool
1178		panicMsg    string
1179	}{
1180		{
1181			name: "successful set",
1182			setup: func() *List {
1183				l := New()
1184				l.Append(42)
1185				return l
1186			},
1187			index:       0,
1188			value:       99,
1189			shouldPanic: false,
1190		},
1191		{
1192			name: "restore deleted element",
1193			setup: func() *List {
1194				l := New()
1195				l.Append(42)
1196				l.Delete(0)
1197				return l
1198			},
1199			index:       0,
1200			value:       99,
1201			shouldPanic: false,
1202		},
1203		{
1204			name: "out of bounds negative",
1205			setup: func() *List {
1206				l := New()
1207				l.Append(1)
1208				return l
1209			},
1210			index:       -1,
1211			value:       99,
1212			shouldPanic: true,
1213			panicMsg:    ErrOutOfBounds.Error(),
1214		},
1215		{
1216			name: "out of bounds positive",
1217			setup: func() *List {
1218				l := New()
1219				l.Append(1)
1220				return l
1221			},
1222			index:       1,
1223			value:       99,
1224			shouldPanic: true,
1225			panicMsg:    ErrOutOfBounds.Error(),
1226		},
1227		{
1228			name: "nil list",
1229			setup: func() *List {
1230				return nil
1231			},
1232			index:       0,
1233			value:       99,
1234			shouldPanic: true,
1235			panicMsg:    ErrOutOfBounds.Error(),
1236		},
1237	}
1238
1239	for _, tt := range tests {
1240		t.Run(tt.name, func(t *testing.T) {
1241			l := tt.setup()
1242			if tt.shouldPanic {
1243				defer func() {
1244					r := recover()
1245					if r == nil {
1246						t.Error("Expected panic but got none")
1247					}
1248					err, ok := r.(error)
1249					if !ok {
1250						t.Errorf("Expected error but got %v", r)
1251					}
1252					uassert.Equal(t, tt.panicMsg, err.Error())
1253				}()
1254			}
1255			l.MustSet(tt.index, tt.value)
1256			if tt.shouldPanic {
1257				t.Error("Expected panic")
1258			}
1259			// Verify the value was set correctly for non-panic cases
1260			if !tt.shouldPanic {
1261				result := l.Get(tt.index)
1262				uassert.Equal(t, typeutil.ToString(tt.value), typeutil.ToString(result))
1263			}
1264		})
1265	}
1266}
1267
1268func TestSet(t *testing.T) {
1269	tests := []struct {
1270		name        string
1271		setup       func() *List
1272		index       int
1273		value       any
1274		expectedErr error
1275		verify      func(t *testing.T, l *List)
1276	}{
1277		{
1278			name: "set value in empty list",
1279			setup: func() *List {
1280				return New()
1281			},
1282			index:       0,
1283			value:       42,
1284			expectedErr: ErrOutOfBounds,
1285			verify: func(t *testing.T, l *List) {
1286				uassert.Equal(t, 0, l.Size())
1287			},
1288		},
1289		{
1290			name: "set value at valid index",
1291			setup: func() *List {
1292				l := New()
1293				l.Append(1)
1294				return l
1295			},
1296			index: 0,
1297			value: 42,
1298			verify: func(t *testing.T, l *List) {
1299				uassert.Equal(t, 42, l.Get(0))
1300				uassert.Equal(t, 1, l.Size())
1301				uassert.Equal(t, 1, l.TotalSize())
1302			},
1303		},
1304		{
1305			name: "set value at negative index",
1306			setup: func() *List {
1307				l := New()
1308				l.Append(1)
1309				return l
1310			},
1311			index:       -1,
1312			value:       42,
1313			expectedErr: ErrOutOfBounds,
1314			verify: func(t *testing.T, l *List) {
1315				uassert.Equal(t, 1, l.Get(0))
1316			},
1317		},
1318		{
1319			name: "set value beyond size",
1320			setup: func() *List {
1321				l := New()
1322				l.Append(1)
1323				return l
1324			},
1325			index:       1,
1326			value:       42,
1327			expectedErr: ErrOutOfBounds,
1328			verify: func(t *testing.T, l *List) {
1329				uassert.Equal(t, 1, l.Get(0))
1330				uassert.Equal(t, 1, l.Size())
1331			},
1332		},
1333		{
1334			name: "set nil value",
1335			setup: func() *List {
1336				l := New()
1337				l.Append(1)
1338				return l
1339			},
1340			index: 0,
1341			value: nil,
1342			verify: func(t *testing.T, l *List) {
1343				uassert.Equal(t, nil, l.Get(0))
1344				uassert.Equal(t, 0, l.Size())
1345			},
1346		},
1347		{
1348			name: "set value at deleted index",
1349			setup: func() *List {
1350				l := New()
1351				l.Append(1, 2, 3)
1352				l.Delete(1)
1353				return l
1354			},
1355			index: 1,
1356			value: 42,
1357			verify: func(t *testing.T, l *List) {
1358				uassert.Equal(t, 42, l.Get(1))
1359				uassert.Equal(t, 3, l.Size())
1360				uassert.Equal(t, 3, l.TotalSize())
1361			},
1362		},
1363		{
1364			name: "set value in nil list",
1365			setup: func() *List {
1366				return nil
1367			},
1368			index:       0,
1369			value:       42,
1370			expectedErr: ErrOutOfBounds,
1371			verify: func(t *testing.T, l *List) {
1372				uassert.Equal(t, 0, l.Size())
1373			},
1374		},
1375		{
1376			name: "set multiple values at same index",
1377			setup: func() *List {
1378				l := New()
1379				l.Append(1)
1380				return l
1381			},
1382			index: 0,
1383			value: 42,
1384			verify: func(t *testing.T, l *List) {
1385				uassert.Equal(t, 42, l.Get(0))
1386				err := l.Set(0, 99)
1387				uassert.Equal(t, nil, err)
1388				uassert.Equal(t, 99, l.Get(0))
1389				uassert.Equal(t, 1, l.Size())
1390			},
1391		},
1392		{
1393			name: "set value at last index",
1394			setup: func() *List {
1395				l := New()
1396				l.Append(1, 2, 3)
1397				return l
1398			},
1399			index: 2,
1400			value: 42,
1401			verify: func(t *testing.T, l *List) {
1402				uassert.Equal(t, 42, l.Get(2))
1403				uassert.Equal(t, 3, l.Size())
1404			},
1405		},
1406	}
1407
1408	for _, tt := range tests {
1409		t.Run(tt.name, func(t *testing.T) {
1410			l := tt.setup()
1411			err := l.Set(tt.index, tt.value)
1412
1413			if tt.expectedErr != nil {
1414				uassert.ErrorIs(t, err, tt.expectedErr)
1415			} else {
1416				uassert.Equal(t, nil, err)
1417			}
1418
1419			tt.verify(t, l)
1420		})
1421	}
1422}