Search Apps Documentation Source Content File Folder Download Copy Actions Download

typeutil_test.gno

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