typeutil_test.gno

22.05 Kb ยท 1071 lines
   1package typeutil
   2
   3import (
   4	"std"
   5	"strings"
   6	"testing"
   7	"time"
   8)
   9
  10type testStringer struct {
  11	value string
  12}
  13
  14func (t testStringer) String() string {
  15	return "test:" + t.value
  16}
  17
  18func TestToString(t *testing.T) {
  19	// setup test data
  20	str := "hello"
  21	num := 42
  22	b := true
  23	now := time.Now()
  24	addr := std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
  25	stringer := testStringer{value: "hello"}
  26
  27	type testCase struct {
  28		name     string
  29		input    any
  30		expected string
  31	}
  32
  33	tests := []testCase{
  34		// basic types
  35		{"string", "hello", "hello"},
  36		{"empty_string", "", ""},
  37		{"nil", nil, ""},
  38
  39		// integer types
  40		{"int", 42, "42"},
  41		{"int8", int8(8), "8"},
  42		{"int16", int16(16), "16"},
  43		{"int32", int32(32), "32"},
  44		{"int64", int64(64), "64"},
  45		{"uint", uint(42), "42"},
  46		{"uint8", uint8(8), "8"},
  47		{"uint16", uint16(16), "16"},
  48		{"uint32", uint32(32), "32"},
  49		{"uint64", uint64(64), "64"},
  50
  51		// float types
  52		{"float32", float32(3.14), "3.14"},
  53		{"float64", 3.14159, "3.14159"},
  54
  55		// boolean
  56		{"bool_true", true, "true"},
  57		{"bool_false", false, "false"},
  58
  59		// special types
  60		{"time", now, now.String()},
  61		{"address", addr, string(addr)},
  62		{"bytes", []byte("hello"), "hello"},
  63		{"stringer", stringer, "test:hello"},
  64
  65		// slices
  66		{"empty_slice", []string{}, "[]"},
  67		{"string_slice", []string{"a", "b"}, "[a b]"},
  68		{"int_slice", []int{1, 2}, "[1 2]"},
  69		{"int32_slice", []int32{1, 2}, "[1 2]"},
  70		{"int64_slice", []int64{1, 2}, "[1 2]"},
  71		{"float32_slice", []float32{1.1, 2.2}, "[1.1 2.2]"},
  72		{"float64_slice", []float64{1.1, 2.2}, "[1.1 2.2]"},
  73		{"bytes_slice", [][]byte{[]byte("a"), []byte("b")}, "[a b]"},
  74		{"time_slice", []time.Time{now, now}, "[" + now.String() + " " + now.String() + "]"},
  75		{"address_slice", []std.Address{addr, addr}, "[" + string(addr) + " " + string(addr) + "]"},
  76		{"interface_slice", []any{1, "a", true}, "[1 a true]"},
  77
  78		// empty slices
  79		{"empty_string_slice", []string{}, "[]"},
  80		{"empty_int_slice", []int{}, "[]"},
  81		{"empty_int32_slice", []int32{}, "[]"},
  82		{"empty_int64_slice", []int64{}, "[]"},
  83		{"empty_float32_slice", []float32{}, "[]"},
  84		{"empty_float64_slice", []float64{}, "[]"},
  85		{"empty_bytes_slice", [][]byte{}, "[]"},
  86		{"empty_time_slice", []time.Time{}, "[]"},
  87		{"empty_address_slice", []std.Address{}, "[]"},
  88		{"empty_interface_slice", []any{}, "[]"},
  89
  90		// maps
  91		{"empty_string_map", map[string]string{}, "map[]"},
  92		{"string_map", map[string]string{"a": "1", "b": "2"}, "map[a:1 b:2]"},
  93		{"empty_interface_map", map[string]any{}, "map[]"},
  94		{"interface_map", map[string]any{"a": 1, "b": "2"}, "map[a:1 b:2]"},
  95
  96		// edge cases
  97		{"empty_bytes", []byte{}, ""},
  98		{"nil_interface", any(nil), ""},
  99		{"empty_struct", struct{}{}, "{}"},
 100		{"unknown_type", struct{ foo string }{}, "<unknown>"},
 101
 102		// pointer types
 103		{"nil_string_ptr", (*string)(nil), ""},
 104		{"string_ptr", &str, "hello"},
 105		{"nil_int_ptr", (*int)(nil), ""},
 106		{"int_ptr", &num, "42"},
 107		{"nil_bool_ptr", (*bool)(nil), ""},
 108		{"bool_ptr", &b, "true"},
 109		// {"nil_time_ptr", (*time.Time)(nil), ""}, // TODO: fix this
 110		{"time_ptr", &now, now.String()},
 111		// {"nil_address_ptr", (*std.Address)(nil), ""}, // TODO: fix this
 112		{"address_ptr", &addr, string(addr)},
 113	}
 114
 115	for _, tt := range tests {
 116		t.Run(tt.name, func(t *testing.T) {
 117			got := ToString(tt.input)
 118			if got != tt.expected {
 119				t.Errorf("%s: ToString(%v) = %q, want %q", tt.name, tt.input, got, tt.expected)
 120			}
 121		})
 122	}
 123}
 124
 125func TestToBool(t *testing.T) {
 126	str := "true"
 127	num := 42
 128	b := true
 129	now := time.Now()
 130	addr := std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
 131	zero := 0
 132	empty := ""
 133	falseVal := false
 134
 135	type testCase struct {
 136		name     string
 137		input    any
 138		expected bool
 139	}
 140
 141	tests := []testCase{
 142		// basic types
 143		{"true", true, true},
 144		{"false", false, false},
 145		{"nil", nil, false},
 146
 147		// strings
 148		{"empty_string", "", false},
 149		{"zero_string", "0", false},
 150		{"false_string", "false", false},
 151		{"f_string", "f", false},
 152		{"no_string", "no", false},
 153		{"n_string", "n", false},
 154		{"off_string", "off", false},
 155		{"space_string", " ", false},
 156		{"true_string", "true", true},
 157		{"yes_string", "yes", true},
 158		{"random_string", "hello", true},
 159
 160		// numbers
 161		{"zero_int", 0, false},
 162		{"positive_int", 1, true},
 163		{"negative_int", -1, true},
 164		{"zero_float", 0.0, false},
 165		{"positive_float", 0.1, true},
 166		{"negative_float", -0.1, true},
 167
 168		// special types
 169		{"empty_bytes", []byte{}, false},
 170		{"non_empty_bytes", []byte{1}, true},
 171		/*{"zero_time", time.Time{}, false},*/ // TODO: fix this
 172		{"empty_address", std.Address(""), false},
 173
 174		// slices
 175		{"empty_slice", []string{}, false},
 176		{"non_empty_slice", []string{"a"}, true},
 177
 178		// maps
 179		{"empty_map", map[string]string{}, false},
 180		{"non_empty_map", map[string]string{"a": "b"}, true},
 181
 182		// pointer types
 183		{"nil_bool_ptr", (*bool)(nil), false},
 184		{"true_ptr", &b, true},
 185		{"false_ptr", &falseVal, false},
 186		{"nil_string_ptr", (*string)(nil), false},
 187		{"string_ptr", &str, true},
 188		{"empty_string_ptr", &empty, false},
 189		{"nil_int_ptr", (*int)(nil), false},
 190		{"int_ptr", &num, true},
 191		{"zero_int_ptr", &zero, false},
 192		// {"nil_time_ptr", (*time.Time)(nil), false}, // TODO: fix this
 193		{"time_ptr", &now, true},
 194		// {"nil_address_ptr", (*std.Address)(nil), false}, // TODO: fix this
 195		{"address_ptr", &addr, true},
 196	}
 197
 198	for _, tt := range tests {
 199		t.Run(tt.name, func(t *testing.T) {
 200			got := ToBool(tt.input)
 201			if got != tt.expected {
 202				t.Errorf("%s: ToBool(%v) = %v, want %v", tt.name, tt.input, got, tt.expected)
 203			}
 204		})
 205	}
 206}
 207
 208func TestIsZero(t *testing.T) {
 209	str := "hello"
 210	num := 42
 211	b := true
 212	now := time.Now()
 213	addr := std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
 214	zero := 0
 215	empty := ""
 216	falseVal := false
 217
 218	type testCase struct {
 219		name     string
 220		input    any
 221		expected bool
 222	}
 223
 224	tests := []testCase{
 225		// basic types
 226		{"true", true, false},
 227		{"false", false, true},
 228		{"nil", nil, true},
 229
 230		// strings
 231		{"empty_string", "", true},
 232		{"non_empty_string", "hello", false},
 233
 234		// numbers
 235		{"zero_int", 0, true},
 236		{"non_zero_int", 1, false},
 237		{"zero_float", 0.0, true},
 238		{"non_zero_float", 0.1, false},
 239
 240		// special types
 241		{"empty_bytes", []byte{}, true},
 242		{"non_empty_bytes", []byte{1}, false},
 243		/*{"zero_time", time.Time{}, true},*/ // TODO: fix this
 244		{"empty_address", std.Address(""), true},
 245
 246		// slices
 247		{"empty_slice", []string{}, true},
 248		{"non_empty_slice", []string{"a"}, false},
 249
 250		// maps
 251		{"empty_map", map[string]string{}, true},
 252		{"non_empty_map", map[string]string{"a": "b"}, false},
 253
 254		// pointer types
 255		{"nil_bool_ptr", (*bool)(nil), true},
 256		{"false_ptr", &falseVal, true},
 257		{"true_ptr", &b, false},
 258		{"nil_string_ptr", (*string)(nil), true},
 259		{"empty_string_ptr", &empty, true},
 260		{"string_ptr", &str, false},
 261		{"nil_int_ptr", (*int)(nil), true},
 262		{"zero_int_ptr", &zero, true},
 263		{"int_ptr", &num, false},
 264		// {"nil_time_ptr", (*time.Time)(nil), true}, // TODO: fix this
 265		{"time_ptr", &now, false},
 266		// {"nil_address_ptr", (*std.Address)(nil), true}, // TODO: fix this
 267		{"address_ptr", &addr, false},
 268	}
 269
 270	for _, tt := range tests {
 271		t.Run(tt.name, func(t *testing.T) {
 272			got := IsZero(tt.input)
 273			if got != tt.expected {
 274				t.Errorf("%s: IsZero(%v) = %v, want %v", tt.name, tt.input, got, tt.expected)
 275			}
 276		})
 277	}
 278}
 279
 280func TestToInterfaceSlice(t *testing.T) {
 281	tests := []struct {
 282		name     string
 283		input    any
 284		expected []any
 285		compare  func([]any, []any) bool
 286	}{
 287		{
 288			name:     "nil",
 289			input:    nil,
 290			expected: nil,
 291			compare:  compareNil,
 292		},
 293		{
 294			name:     "empty_interface_slice",
 295			input:    []any{},
 296			expected: []any{},
 297			compare:  compareEmpty,
 298		},
 299		{
 300			name:     "interface_slice",
 301			input:    []any{1, "two", true},
 302			expected: []any{1, "two", true},
 303			compare:  compareInterfaces,
 304		},
 305		{
 306			name:     "string_slice",
 307			input:    []string{"a", "b", "c"},
 308			expected: []any{"a", "b", "c"},
 309			compare:  compareStrings,
 310		},
 311		{
 312			name:     "int_slice",
 313			input:    []int{1, 2, 3},
 314			expected: []any{1, 2, 3},
 315			compare:  compareInts,
 316		},
 317		{
 318			name:     "int32_slice",
 319			input:    []int32{1, 2, 3},
 320			expected: []any{int32(1), int32(2), int32(3)},
 321			compare:  compareInt32s,
 322		},
 323		{
 324			name:     "int64_slice",
 325			input:    []int64{1, 2, 3},
 326			expected: []any{int64(1), int64(2), int64(3)},
 327			compare:  compareInt64s,
 328		},
 329		{
 330			name:     "float32_slice",
 331			input:    []float32{1.1, 2.2, 3.3},
 332			expected: []any{float32(1.1), float32(2.2), float32(3.3)},
 333			compare:  compareFloat32s,
 334		},
 335		{
 336			name:     "float64_slice",
 337			input:    []float64{1.1, 2.2, 3.3},
 338			expected: []any{1.1, 2.2, 3.3},
 339			compare:  compareFloat64s,
 340		},
 341		{
 342			name:     "bool_slice",
 343			input:    []bool{true, false, true},
 344			expected: []any{true, false, true},
 345			compare:  compareBools,
 346		},
 347		/* {
 348			name:     "time_slice",
 349			input:    []time.Time{now},
 350			expected: []any{now},
 351			compare:  compareTimes,
 352		}, */ // TODO: fix this
 353		/* {
 354			name:     "address_slice",
 355			input:    []std.Address{addr},
 356			expected: []any{addr},
 357			compare:  compareAddresses,
 358		},*/ // TODO: fix this
 359		/* {
 360			name:     "bytes_slice",
 361			input:    [][]byte{[]byte("hello"), []byte("world")},
 362			expected: []any{[]byte("hello"), []byte("world")},
 363			compare:  compareBytes,
 364		},*/ // TODO: fix this
 365	}
 366
 367	for _, tt := range tests {
 368		t.Run(tt.name, func(t *testing.T) {
 369			got := ToInterfaceSlice(tt.input)
 370			if !tt.compare(got, tt.expected) {
 371				t.Errorf("ToInterfaceSlice() = %v, want %v", got, tt.expected)
 372			}
 373		})
 374	}
 375}
 376
 377func compareNil(a, b []any) bool {
 378	return a == nil && b == nil
 379}
 380
 381func compareEmpty(a, b []any) bool {
 382	return len(a) == 0 && len(b) == 0
 383}
 384
 385func compareInterfaces(a, b []any) bool {
 386	if len(a) != len(b) {
 387		return false
 388	}
 389	for i := range a {
 390		if a[i] != b[i] {
 391			return false
 392		}
 393	}
 394	return true
 395}
 396
 397func compareStrings(a, b []any) bool {
 398	if len(a) != len(b) {
 399		return false
 400	}
 401	for i := range a {
 402		as, ok1 := a[i].(string)
 403		bs, ok2 := b[i].(string)
 404		if !ok1 || !ok2 || as != bs {
 405			return false
 406		}
 407	}
 408	return true
 409}
 410
 411func compareInts(a, b []any) bool {
 412	if len(a) != len(b) {
 413		return false
 414	}
 415	for i := range a {
 416		ai, ok1 := a[i].(int)
 417		bi, ok2 := b[i].(int)
 418		if !ok1 || !ok2 || ai != bi {
 419			return false
 420		}
 421	}
 422	return true
 423}
 424
 425func compareInt32s(a, b []any) bool {
 426	if len(a) != len(b) {
 427		return false
 428	}
 429	for i := range a {
 430		ai, ok1 := a[i].(int32)
 431		bi, ok2 := b[i].(int32)
 432		if !ok1 || !ok2 || ai != bi {
 433			return false
 434		}
 435	}
 436	return true
 437}
 438
 439func compareInt64s(a, b []any) bool {
 440	if len(a) != len(b) {
 441		return false
 442	}
 443	for i := range a {
 444		ai, ok1 := a[i].(int64)
 445		bi, ok2 := b[i].(int64)
 446		if !ok1 || !ok2 || ai != bi {
 447			return false
 448		}
 449	}
 450	return true
 451}
 452
 453func compareFloat32s(a, b []any) bool {
 454	if len(a) != len(b) {
 455		return false
 456	}
 457	for i := range a {
 458		ai, ok1 := a[i].(float32)
 459		bi, ok2 := b[i].(float32)
 460		if !ok1 || !ok2 || ai != bi {
 461			return false
 462		}
 463	}
 464	return true
 465}
 466
 467func compareFloat64s(a, b []any) bool {
 468	if len(a) != len(b) {
 469		return false
 470	}
 471	for i := range a {
 472		ai, ok1 := a[i].(float64)
 473		bi, ok2 := b[i].(float64)
 474		if !ok1 || !ok2 || ai != bi {
 475			return false
 476		}
 477	}
 478	return true
 479}
 480
 481func compareBools(a, b []any) bool {
 482	if len(a) != len(b) {
 483		return false
 484	}
 485	for i := range a {
 486		ab, ok1 := a[i].(bool)
 487		bb, ok2 := b[i].(bool)
 488		if !ok1 || !ok2 || ab != bb {
 489			return false
 490		}
 491	}
 492	return true
 493}
 494
 495func compareTimes(a, b []any) bool {
 496	if len(a) != len(b) {
 497		return false
 498	}
 499	for i := range a {
 500		at, ok1 := a[i].(time.Time)
 501		bt, ok2 := b[i].(time.Time)
 502		if !ok1 || !ok2 || !at.Equal(bt) {
 503			return false
 504		}
 505	}
 506	return true
 507}
 508
 509func compareAddresses(a, b []any) bool {
 510	if len(a) != len(b) {
 511		return false
 512	}
 513	for i := range a {
 514		aa, ok1 := a[i].(std.Address)
 515		ba, ok2 := b[i].(std.Address)
 516		if !ok1 || !ok2 || aa != ba {
 517			return false
 518		}
 519	}
 520	return true
 521}
 522
 523func compareBytes(a, b []any) bool {
 524	if len(a) != len(b) {
 525		return false
 526	}
 527	for i := range a {
 528		ab, ok1 := a[i].([]byte)
 529		bb, ok2 := b[i].([]byte)
 530		if !ok1 || !ok2 || string(ab) != string(bb) {
 531			return false
 532		}
 533	}
 534	return true
 535}
 536
 537// compareStringInterfaceMaps compares two map[string]any for equality
 538func compareStringInterfaceMaps(a, b map[string]any) bool {
 539	if len(a) != len(b) {
 540		return false
 541	}
 542	for k, v1 := range a {
 543		v2, ok := b[k]
 544		if !ok {
 545			return false
 546		}
 547		// Compare values based on their type
 548		switch val1 := v1.(type) {
 549		case string:
 550			val2, ok := v2.(string)
 551			if !ok || val1 != val2 {
 552				return false
 553			}
 554		case int:
 555			val2, ok := v2.(int)
 556			if !ok || val1 != val2 {
 557				return false
 558			}
 559		case float64:
 560			val2, ok := v2.(float64)
 561			if !ok || val1 != val2 {
 562				return false
 563			}
 564		case bool:
 565			val2, ok := v2.(bool)
 566			if !ok || val1 != val2 {
 567				return false
 568			}
 569		case []any:
 570			val2, ok := v2.([]any)
 571			if !ok || len(val1) != len(val2) {
 572				return false
 573			}
 574			for i := range val1 {
 575				if val1[i] != val2[i] {
 576					return false
 577				}
 578			}
 579		case map[string]any:
 580			val2, ok := v2.(map[string]any)
 581			if !ok || !compareStringInterfaceMaps(val1, val2) {
 582				return false
 583			}
 584		default:
 585			return false
 586		}
 587	}
 588	return true
 589}
 590
 591func TestToMapStringInterface(t *testing.T) {
 592	tests := []struct {
 593		name     string
 594		input    any
 595		expected map[string]any
 596		wantErr  bool
 597	}{
 598		{
 599			name: "map[string]any",
 600			input: map[string]any{
 601				"key1": "value1",
 602				"key2": 42,
 603			},
 604			expected: map[string]any{
 605				"key1": "value1",
 606				"key2": 42,
 607			},
 608			wantErr: false,
 609		},
 610		{
 611			name: "map[string]string",
 612			input: map[string]string{
 613				"key1": "value1",
 614				"key2": "value2",
 615			},
 616			expected: map[string]any{
 617				"key1": "value1",
 618				"key2": "value2",
 619			},
 620			wantErr: false,
 621		},
 622		{
 623			name: "map[string]int",
 624			input: map[string]int{
 625				"key1": 1,
 626				"key2": 2,
 627			},
 628			expected: map[string]any{
 629				"key1": 1,
 630				"key2": 2,
 631			},
 632			wantErr: false,
 633		},
 634		{
 635			name: "map[string]float64",
 636			input: map[string]float64{
 637				"key1": 1.1,
 638				"key2": 2.2,
 639			},
 640			expected: map[string]any{
 641				"key1": 1.1,
 642				"key2": 2.2,
 643			},
 644			wantErr: false,
 645		},
 646		{
 647			name: "map[string]bool",
 648			input: map[string]bool{
 649				"key1": true,
 650				"key2": false,
 651			},
 652			expected: map[string]any{
 653				"key1": true,
 654				"key2": false,
 655			},
 656			wantErr: false,
 657		},
 658		{
 659			name: "map[string][]string",
 660			input: map[string][]string{
 661				"key1": {"a", "b"},
 662				"key2": {"c", "d"},
 663			},
 664			expected: map[string]any{
 665				"key1": []any{"a", "b"},
 666				"key2": []any{"c", "d"},
 667			},
 668			wantErr: false,
 669		},
 670		{
 671			name: "nested map[string]map[string]string",
 672			input: map[string]map[string]string{
 673				"key1": {"nested1": "value1"},
 674				"key2": {"nested2": "value2"},
 675			},
 676			expected: map[string]any{
 677				"key1": map[string]any{"nested1": "value1"},
 678				"key2": map[string]any{"nested2": "value2"},
 679			},
 680			wantErr: false,
 681		},
 682		{
 683			name:     "unsupported type",
 684			input:    42, // not a map
 685			expected: nil,
 686			wantErr:  true,
 687		},
 688	}
 689
 690	for _, tt := range tests {
 691		t.Run(tt.name, func(t *testing.T) {
 692			got, err := ToMapStringInterface(tt.input)
 693			if (err != nil) != tt.wantErr {
 694				t.Errorf("ToMapStringInterface() error = %v, wantErr %v", err, tt.wantErr)
 695				return
 696			}
 697			if !tt.wantErr {
 698				if !compareStringInterfaceMaps(got, tt.expected) {
 699					t.Errorf("ToMapStringInterface() = %v, expected %v", got, tt.expected)
 700				}
 701			}
 702		})
 703	}
 704}
 705
 706// Test error messages
 707func TestToMapStringInterfaceErrors(t *testing.T) {
 708	_, err := ToMapStringInterface(42)
 709	if err == nil || !strings.Contains(err.Error(), "unsupported map type") {
 710		t.Errorf("Expected error containing 'unsupported map type', got %v", err)
 711	}
 712}
 713
 714// compareIntInterfaceMaps compares two map[int]any for equality
 715func compareIntInterfaceMaps(a, b map[int]any) bool {
 716	if len(a) != len(b) {
 717		return false
 718	}
 719	for k, v1 := range a {
 720		v2, ok := b[k]
 721		if !ok {
 722			return false
 723		}
 724		// Compare values based on their type
 725		switch val1 := v1.(type) {
 726		case string:
 727			val2, ok := v2.(string)
 728			if !ok || val1 != val2 {
 729				return false
 730			}
 731		case int:
 732			val2, ok := v2.(int)
 733			if !ok || val1 != val2 {
 734				return false
 735			}
 736		case float64:
 737			val2, ok := v2.(float64)
 738			if !ok || val1 != val2 {
 739				return false
 740			}
 741		case bool:
 742			val2, ok := v2.(bool)
 743			if !ok || val1 != val2 {
 744				return false
 745			}
 746		case []any:
 747			val2, ok := v2.([]any)
 748			if !ok || len(val1) != len(val2) {
 749				return false
 750			}
 751			for i := range val1 {
 752				if val1[i] != val2[i] {
 753					return false
 754				}
 755			}
 756		case map[string]any:
 757			val2, ok := v2.(map[string]any)
 758			if !ok || !compareStringInterfaceMaps(val1, val2) {
 759				return false
 760			}
 761		default:
 762			return false
 763		}
 764	}
 765	return true
 766}
 767
 768func TestToMapIntInterface(t *testing.T) {
 769	tests := []struct {
 770		name     string
 771		input    any
 772		expected map[int]any
 773		wantErr  bool
 774	}{
 775		{
 776			name: "map[int]any",
 777			input: map[int]any{
 778				1: "value1",
 779				2: 42,
 780			},
 781			expected: map[int]any{
 782				1: "value1",
 783				2: 42,
 784			},
 785			wantErr: false,
 786		},
 787		{
 788			name: "map[int]string",
 789			input: map[int]string{
 790				1: "value1",
 791				2: "value2",
 792			},
 793			expected: map[int]any{
 794				1: "value1",
 795				2: "value2",
 796			},
 797			wantErr: false,
 798		},
 799		{
 800			name: "map[int]int",
 801			input: map[int]int{
 802				1: 10,
 803				2: 20,
 804			},
 805			expected: map[int]any{
 806				1: 10,
 807				2: 20,
 808			},
 809			wantErr: false,
 810		},
 811		{
 812			name: "map[int]float64",
 813			input: map[int]float64{
 814				1: 1.1,
 815				2: 2.2,
 816			},
 817			expected: map[int]any{
 818				1: 1.1,
 819				2: 2.2,
 820			},
 821			wantErr: false,
 822		},
 823		{
 824			name: "map[int]bool",
 825			input: map[int]bool{
 826				1: true,
 827				2: false,
 828			},
 829			expected: map[int]any{
 830				1: true,
 831				2: false,
 832			},
 833			wantErr: false,
 834		},
 835		{
 836			name: "map[int][]string",
 837			input: map[int][]string{
 838				1: {"a", "b"},
 839				2: {"c", "d"},
 840			},
 841			expected: map[int]any{
 842				1: []any{"a", "b"},
 843				2: []any{"c", "d"},
 844			},
 845			wantErr: false,
 846		},
 847		{
 848			name: "map[int]map[string]any",
 849			input: map[int]map[string]any{
 850				1: {"nested1": "value1"},
 851				2: {"nested2": "value2"},
 852			},
 853			expected: map[int]any{
 854				1: map[string]any{"nested1": "value1"},
 855				2: map[string]any{"nested2": "value2"},
 856			},
 857			wantErr: false,
 858		},
 859		{
 860			name:     "unsupported type",
 861			input:    42, // not a map
 862			expected: nil,
 863			wantErr:  true,
 864		},
 865	}
 866
 867	for _, tt := range tests {
 868		t.Run(tt.name, func(t *testing.T) {
 869			got, err := ToMapIntInterface(tt.input)
 870			if (err != nil) != tt.wantErr {
 871				t.Errorf("ToMapIntInterface() error = %v, wantErr %v", err, tt.wantErr)
 872				return
 873			}
 874			if !tt.wantErr {
 875				if !compareIntInterfaceMaps(got, tt.expected) {
 876					t.Errorf("ToMapIntInterface() = %v, expected %v", got, tt.expected)
 877				}
 878			}
 879		})
 880	}
 881}
 882
 883func TestToStringSlice(t *testing.T) {
 884	tests := []struct {
 885		name     string
 886		input    any
 887		expected []string
 888	}{
 889		{
 890			name:     "nil input",
 891			input:    nil,
 892			expected: nil,
 893		},
 894		{
 895			name:     "empty slice",
 896			input:    []string{},
 897			expected: []string{},
 898		},
 899		{
 900			name:     "string slice",
 901			input:    []string{"a", "b", "c"},
 902			expected: []string{"a", "b", "c"},
 903		},
 904		{
 905			name:     "int slice",
 906			input:    []int{1, 2, 3},
 907			expected: []string{"1", "2", "3"},
 908		},
 909		{
 910			name:     "int32 slice",
 911			input:    []int32{1, 2, 3},
 912			expected: []string{"1", "2", "3"},
 913		},
 914		{
 915			name:     "int64 slice",
 916			input:    []int64{1, 2, 3},
 917			expected: []string{"1", "2", "3"},
 918		},
 919		{
 920			name:     "uint slice",
 921			input:    []uint{1, 2, 3},
 922			expected: []string{"1", "2", "3"},
 923		},
 924		{
 925			name:     "uint8 slice",
 926			input:    []uint8{1, 2, 3},
 927			expected: []string{"1", "2", "3"},
 928		},
 929		{
 930			name:     "uint16 slice",
 931			input:    []uint16{1, 2, 3},
 932			expected: []string{"1", "2", "3"},
 933		},
 934		{
 935			name:     "uint32 slice",
 936			input:    []uint32{1, 2, 3},
 937			expected: []string{"1", "2", "3"},
 938		},
 939		{
 940			name:     "uint64 slice",
 941			input:    []uint64{1, 2, 3},
 942			expected: []string{"1", "2", "3"},
 943		},
 944		{
 945			name:     "float32 slice",
 946			input:    []float32{1.1, 2.2, 3.3},
 947			expected: []string{"1.1", "2.2", "3.3"},
 948		},
 949		{
 950			name:     "float64 slice",
 951			input:    []float64{1.1, 2.2, 3.3},
 952			expected: []string{"1.1", "2.2", "3.3"},
 953		},
 954		{
 955			name:     "bool slice",
 956			input:    []bool{true, false, true},
 957			expected: []string{"true", "false", "true"},
 958		},
 959		{
 960			name:     "[]byte slice",
 961			input:    [][]byte{[]byte("hello"), []byte("world")},
 962			expected: []string{"hello", "world"},
 963		},
 964		{
 965			name:     "interface slice",
 966			input:    []any{1, "hello", true},
 967			expected: []string{"1", "hello", "true"},
 968		},
 969		{
 970			name:     "time slice",
 971			input:    []time.Time{{}, {}},
 972			expected: []string{"0001-01-01 00:00:00 +0000 UTC", "0001-01-01 00:00:00 +0000 UTC"},
 973		},
 974		{
 975			name:     "address slice",
 976			input:    []std.Address{"addr1", "addr2"},
 977			expected: []string{"addr1", "addr2"},
 978		},
 979		{
 980			name:     "non-slice input",
 981			input:    42,
 982			expected: nil,
 983		},
 984	}
 985
 986	for _, tt := range tests {
 987		t.Run(tt.name, func(t *testing.T) {
 988			result := ToStringSlice(tt.input)
 989			if !slicesEqual(result, tt.expected) {
 990				t.Errorf("ToStringSlice(%v) = %v, want %v", tt.input, result, tt.expected)
 991			}
 992		})
 993	}
 994}
 995
 996// Helper function to compare string slices
 997func slicesEqual(a, b []string) bool {
 998	if len(a) != len(b) {
 999		return false
1000	}
1001	for i := range a {
1002		if a[i] != b[i] {
1003			return false
1004		}
1005	}
1006	return true
1007}
1008
1009func TestToStringAdvanced(t *testing.T) {
1010	tests := []struct {
1011		name     string
1012		input    any
1013		expected string
1014	}{
1015		{
1016			name: "slice with mixed basic types",
1017			input: []any{
1018				42,
1019				"hello",
1020				true,
1021				3.14,
1022			},
1023			expected: "[42 hello true 3.14]",
1024		},
1025		{
1026			name: "map with basic types",
1027			input: map[string]any{
1028				"int":   42,
1029				"str":   "hello",
1030				"bool":  true,
1031				"float": 3.14,
1032			},
1033			expected: "map[bool:true float:3.14 int:42 str:hello]",
1034		},
1035		{
1036			name: "mixed types map",
1037			input: map[any]any{
1038				42:         "number",
1039				"string":   123,
1040				true:       []int{1, 2, 3},
1041				struct{}{}: "empty",
1042			},
1043			expected: "map[42:number string:123 true:[1 2 3] {}:empty]",
1044		},
1045		{
1046			name: "nested maps",
1047			input: map[string]any{
1048				"a": map[string]int{
1049					"x": 1,
1050					"y": 2,
1051				},
1052				"b": []any{1, "two", true},
1053			},
1054			expected: "map[a:map[x:1 y:2] b:[1 two true]]",
1055		},
1056		{
1057			name:     "empty struct",
1058			input:    struct{}{},
1059			expected: "{}",
1060		},
1061	}
1062
1063	for _, tt := range tests {
1064		t.Run(tt.name, func(t *testing.T) {
1065			result := ToString(tt.input)
1066			if result != tt.expected {
1067				t.Errorf("\nToString(%v) =\n%v\nwant:\n%v", tt.input, result, tt.expected)
1068			}
1069		})
1070	}
1071}