github.com/enetx/g@v1.0.80/tests/string_test.go (about)

     1  package g_test
     2  
     3  import (
     4  	"io"
     5  	"reflect"
     6  	"testing"
     7  	"unicode"
     8  
     9  	"github.com/enetx/g"
    10  )
    11  
    12  func TestStringBuilder(t *testing.T) {
    13  	// Create a String
    14  	str := g.NewString("hello")
    15  
    16  	// Call the Builder method
    17  	builder := str.Builder()
    18  
    19  	// Check if the Builder has been properly initialized
    20  	expected := "hello"
    21  	if result := builder.String().Std(); result != expected {
    22  		t.Errorf("Builder() = %s; want %s", result, expected)
    23  	}
    24  }
    25  
    26  func TestStringMinMax(t *testing.T) {
    27  	// Test cases for Min method
    28  	minTestCases := []struct {
    29  		inputs   []g.String
    30  		expected g.String
    31  	}{
    32  		{[]g.String{"apple", "banana", "orange"}, "apple"},
    33  		{[]g.String{"cat", "dog", "elephant"}, "cat"},
    34  		{[]g.String{"123", "456", "789"}, "123"},
    35  	}
    36  
    37  	for _, testCase := range minTestCases {
    38  		result := g.NewString(testCase.inputs[0]).Min(testCase.inputs[1:]...)
    39  		if result != testCase.expected {
    40  			t.Errorf("Min test failed. Expected: %s, Got: %s", testCase.expected, result)
    41  		}
    42  	}
    43  
    44  	// Test cases for Max method
    45  	maxTestCases := []struct {
    46  		inputs   []g.String
    47  		expected g.String
    48  	}{
    49  		{[]g.String{"apple", "banana", "orange"}, "orange"},
    50  		{[]g.String{"cat", "dog", "elephant"}, "elephant"},
    51  		{[]g.String{"123", "456", "789"}, "789"},
    52  	}
    53  
    54  	for _, testCase := range maxTestCases {
    55  		result := g.NewString(testCase.inputs[0]).Max(testCase.inputs[1:]...)
    56  		if result != testCase.expected {
    57  			t.Errorf("Max test failed. Expected: %s, Got: %s", testCase.expected, result)
    58  		}
    59  	}
    60  }
    61  
    62  func TestChars(t *testing.T) {
    63  	// Testing on a regular string with ASCII characters
    64  	asciiStr := g.String("Hello")
    65  	asciiExpected := g.Slice[g.String]{"H", "e", "l", "l", "o"}
    66  	asciiResult := asciiStr.Chars().Collect()
    67  	if !reflect.DeepEqual(asciiExpected, asciiResult) {
    68  		t.Errorf("Expected %v, but got %v", asciiExpected, asciiResult)
    69  	}
    70  
    71  	// Testing on a string with Unicode characters (Russian)
    72  	unicodeStr := g.String("Привет")
    73  	unicodeExpected := g.Slice[g.String]{"П", "р", "и", "в", "е", "т"}
    74  	unicodeResult := unicodeStr.Chars().Collect()
    75  	if !reflect.DeepEqual(unicodeExpected, unicodeResult) {
    76  		t.Errorf("Expected %v, but got %v", unicodeExpected, unicodeResult)
    77  	}
    78  
    79  	// Testing on a string with Unicode characters (Chinese)
    80  	chineseStr := g.String("你好")
    81  	chineseExpected := g.Slice[g.String]{"你", "好"}
    82  	chineseResult := chineseStr.Chars().Collect()
    83  	if !reflect.DeepEqual(chineseExpected, chineseResult) {
    84  		t.Errorf("Expected %v, but got %v", chineseExpected, chineseResult)
    85  	}
    86  
    87  	// Additional test with a mix of ASCII and Unicode characters
    88  	mixedStr := g.String("Hello 你好")
    89  	mixedExpected := g.Slice[g.String]{"H", "e", "l", "l", "o", " ", "你", "好"}
    90  	mixedResult := mixedStr.Chars().Collect()
    91  	if !reflect.DeepEqual(mixedExpected, mixedResult) {
    92  		t.Errorf("Expected %v, but got %v", mixedExpected, mixedResult)
    93  	}
    94  
    95  	// Testing on a string with special characters and symbols
    96  	specialStr := g.String("Hello, 你好! How are you today? こんにちは")
    97  	specialExpected := g.Slice[g.String]{
    98  		"H",
    99  		"e",
   100  		"l",
   101  		"l",
   102  		"o",
   103  		",",
   104  		" ",
   105  		"你",
   106  		"好",
   107  		"!",
   108  		" ",
   109  		"H",
   110  		"o",
   111  		"w",
   112  		" ",
   113  		"a",
   114  		"r",
   115  		"e",
   116  		" ",
   117  		"y",
   118  		"o",
   119  		"u",
   120  		" ",
   121  		"t",
   122  		"o",
   123  		"d",
   124  		"a",
   125  		"y",
   126  		"?",
   127  		" ",
   128  		"こ",
   129  		"ん",
   130  		"に",
   131  		"ち",
   132  		"は",
   133  	}
   134  	specialResult := specialStr.Chars().Collect()
   135  	if !reflect.DeepEqual(specialExpected, specialResult) {
   136  		t.Errorf("Expected %v, but got %v", specialExpected, specialResult)
   137  	}
   138  
   139  	// Testing on a string with emojis
   140  	emojiStr := g.String("Hello, 😊🌍🚀")
   141  	emojiExpected := g.Slice[g.String]{"H", "e", "l", "l", "o", ",", " ", "😊", "🌍", "🚀"}
   142  	emojiResult := emojiStr.Chars().Collect()
   143  	if !reflect.DeepEqual(emojiExpected, emojiResult) {
   144  		t.Errorf("Expected %v, but got %v", emojiExpected, emojiResult)
   145  	}
   146  
   147  	// Testing on an empty string
   148  	emptyStr := g.String("")
   149  	emptyExpected := g.Slice[g.String]{}
   150  	emptyResult := emptyStr.Chars().Collect()
   151  	if !reflect.DeepEqual(emptyExpected, emptyResult) {
   152  		t.Errorf("Expected %v, but got %v", emptyExpected, emptyResult)
   153  	}
   154  }
   155  
   156  func TestStringIsDigit(t *testing.T) {
   157  	tests := []struct {
   158  		name string
   159  		str  g.String
   160  		want bool
   161  	}{
   162  		{"empty", g.String(""), false},
   163  		{"one", g.String("1"), true},
   164  		{"nine", g.String("99999"), true},
   165  		{"non-digit", g.String("1111a"), false},
   166  	}
   167  
   168  	for _, tt := range tests {
   169  		t.Run(tt.name, func(t *testing.T) {
   170  			if got := tt.str.IsDigit(); got != tt.want {
   171  				t.Errorf("String.IsDigit() = %v, want %v", got, tt.want)
   172  			}
   173  		})
   174  	}
   175  }
   176  
   177  func TestStringToInt(t *testing.T) {
   178  	tests := []struct {
   179  		name string
   180  		str  g.String
   181  		want g.Int
   182  	}{
   183  		{
   184  			name: "empty",
   185  			str:  g.String(""),
   186  			want: 0,
   187  		},
   188  		{
   189  			name: "one digit",
   190  			str:  g.String("1"),
   191  			want: 1,
   192  		},
   193  		{
   194  			name: "two digits",
   195  			str:  g.String("12"),
   196  			want: 12,
   197  		},
   198  		{
   199  			name: "one letter",
   200  			str:  g.String("a"),
   201  			want: 0,
   202  		},
   203  		{
   204  			name: "one digit and one letter",
   205  			str:  g.String("1a"),
   206  			want: 0,
   207  		},
   208  	}
   209  	for _, tt := range tests {
   210  		t.Run(tt.name, func(t *testing.T) {
   211  			if got := tt.str.ToInt().UnwrapOrDefault(); got != tt.want {
   212  				t.Errorf("String.ToInt() = %v, want %v", got, tt.want)
   213  			}
   214  		})
   215  	}
   216  }
   217  
   218  func TestStringToTitle(t *testing.T) {
   219  	tests := []struct {
   220  		name string
   221  		str  g.String
   222  		want g.String
   223  	}{
   224  		{"empty", "", ""},
   225  		{"one word", "hello", "Hello"},
   226  		{"two words", "hello world", "Hello World"},
   227  		{"three words", "hello world, how are you?", "Hello World, How Are You?"},
   228  		{"multiple hyphens", "foo-bar-baz", "Foo-Bar-Baz"},
   229  		{"non-ascii letters", "こんにちは, 世界!", "こんにちは, 世界!"},
   230  		{"all whitespace", "   \t\n   ", "   \t\n   "},
   231  		{"numbers", "12345 67890", "12345 67890"},
   232  		{"arabic", "مرحبا بالعالم", "مرحبا بالعالم"},
   233  		{"chinese", "你好世界", "你好世界"},
   234  		{"czech", "ahoj světe", "Ahoj Světe"},
   235  		{"danish", "hej verden", "Hej Verden"},
   236  		{"dutch", "hallo wereld", "Hallo Wereld"},
   237  		{"french", "bonjour tout le monde", "Bonjour Tout Le Monde"},
   238  		{"german", "hallo welt", "Hallo Welt"},
   239  		{"hebrew", "שלום עולם", "שלום עולם"},
   240  		{"hindi", "नमस्ते दुनिया", "नमस्ते दुनिया"},
   241  		{"hungarian", "szia világ", "Szia Világ"},
   242  		{"italian", "ciao mondo", "Ciao Mondo"},
   243  		{"japanese", "こんにちは世界", "こんにちは世界"},
   244  		{"korean", "안녕하세요 세상", "안녕하세요 세상"},
   245  		{"norwegian", "hei verden", "Hei Verden"},
   246  		{"polish", "witaj świecie", "Witaj Świecie"},
   247  		{"portuguese", "olá mundo", "Olá Mundo"},
   248  		{"russian", "привет мир", "Привет Мир"},
   249  		{"spanish", "hola mundo", "Hola Mundo"},
   250  		{"swedish", "hej världen", "Hej Världen"},
   251  		{"turkish", "merhaba dünya", "Merhaba Dünya"},
   252  	}
   253  
   254  	for _, tt := range tests {
   255  		t.Run(tt.name, func(t *testing.T) {
   256  			if got := tt.str.Title(); got.Ne(tt.want) {
   257  				t.Errorf("String.ToTitle() = %v, want %v", got, tt.want)
   258  			}
   259  		})
   260  	}
   261  }
   262  
   263  func TestStringAdd(t *testing.T) {
   264  	tests := []struct {
   265  		name string
   266  		str  g.String
   267  		s    g.String
   268  		want g.String
   269  	}{
   270  		{
   271  			name: "empty",
   272  			str:  g.String(""),
   273  			s:    g.String(""),
   274  			want: g.String(""),
   275  		},
   276  		{
   277  			name: "empty_hs",
   278  			str:  g.String(""),
   279  			s:    g.String("test"),
   280  			want: g.String("test"),
   281  		},
   282  		{
   283  			name: "empty_s",
   284  			str:  g.String("test"),
   285  			s:    g.String(""),
   286  			want: g.String("test"),
   287  		},
   288  		{
   289  			name: "not_empty",
   290  			str:  g.String("test"),
   291  			s:    g.String("test"),
   292  			want: g.String("testtest"),
   293  		},
   294  	}
   295  
   296  	for _, tt := range tests {
   297  		t.Run(tt.name, func(t *testing.T) {
   298  			if got := tt.str.Append(tt.s); got != tt.want {
   299  				t.Errorf("String.Add() = %v, want %v", got, tt.want)
   300  			}
   301  		})
   302  	}
   303  }
   304  
   305  func TestStringAddPrefix(t *testing.T) {
   306  	tests := []struct {
   307  		name string
   308  		str  g.String
   309  		s    g.String
   310  		want g.String
   311  	}{
   312  		{
   313  			name: "empty",
   314  			str:  g.String(""),
   315  			s:    g.String(""),
   316  			want: g.String(""),
   317  		},
   318  		{
   319  			name: "empty_hs",
   320  			str:  g.String(""),
   321  			s:    g.String("test"),
   322  			want: g.String("test"),
   323  		},
   324  		{
   325  			name: "empty_s",
   326  			str:  g.String("test"),
   327  			s:    g.String(""),
   328  			want: g.String("test"),
   329  		},
   330  		{
   331  			name: "not_empty",
   332  			str:  g.String("rest"),
   333  			s:    g.String("test"),
   334  			want: g.String("testrest"),
   335  		},
   336  	}
   337  
   338  	for _, tt := range tests {
   339  		t.Run(tt.name, func(t *testing.T) {
   340  			if got := tt.str.Prepend(tt.s); got != tt.want {
   341  				t.Errorf("String.AddPrefix() = %v, want %v", got, tt.want)
   342  			}
   343  		})
   344  	}
   345  }
   346  
   347  func TestStringRandom(t *testing.T) {
   348  	for i := range 100 {
   349  		random := g.NewString("").Random(g.Int(i))
   350  
   351  		if random.Len().Std() != i {
   352  			t.Errorf("Random string length %d is not equal to %d", random.Len(), i)
   353  		}
   354  	}
   355  }
   356  
   357  func TestStringChunks(t *testing.T) {
   358  	str := g.String("")
   359  	chunks := str.Chunks(3)
   360  
   361  	if chunks.Len() != 0 {
   362  		t.Errorf("Expected empty slice, but got %v", chunks)
   363  	}
   364  
   365  	str = g.String("hello")
   366  	chunks = str.Chunks(10)
   367  
   368  	if chunks.Len() != 1 {
   369  		t.Errorf("Expected 1 chunk, but got %v", chunks.Len())
   370  	}
   371  
   372  	if chunks[0] != str {
   373  		t.Errorf("Expected chunk to be %v, but got %v", str, chunks.Get(0))
   374  	}
   375  
   376  	str = g.String("hello")
   377  	chunks = str.Chunks(2)
   378  
   379  	if chunks.Len() != 3 {
   380  		t.Errorf("Expected 3 chunks, but got %v", chunks.Len())
   381  	}
   382  
   383  	expectedChunks := g.Slice[g.String]{"he", "ll", "o"}
   384  
   385  	for i, c := range chunks {
   386  		if c != expectedChunks[i] {
   387  			t.Errorf("Expected chunk %v to be %v, but got %v", i, expectedChunks[i], c)
   388  		}
   389  	}
   390  
   391  	str = g.String("hello world")
   392  	chunks = str.Chunks(3)
   393  
   394  	if chunks.Len() != 4 {
   395  		t.Errorf("Expected 4 chunks, but got %v", chunks.Len())
   396  	}
   397  
   398  	expectedChunks = g.Slice[g.String]{"hel", "lo ", "wor", "ld"}
   399  
   400  	for i, c := range chunks {
   401  		if c != expectedChunks[i] {
   402  			t.Errorf("Expected chunk %v to be %v, but got %v", i, expectedChunks[i], c)
   403  		}
   404  	}
   405  
   406  	str = g.String("hello")
   407  	chunks = str.Chunks(5)
   408  
   409  	if chunks.Len() != 1 {
   410  		t.Errorf("Expected 1 chunk, but got %v", chunks.Len())
   411  	}
   412  
   413  	if chunks.Get(0) != str {
   414  		t.Errorf("Expected chunk to be %v, but got %v", str, chunks.Get(0))
   415  	}
   416  
   417  	str = g.String("hello")
   418  	chunks = str.Chunks(-1)
   419  
   420  	if chunks.Len() != 0 {
   421  		t.Errorf("Expected empty slice, but got %v", chunks)
   422  	}
   423  }
   424  
   425  func TestStringCut(t *testing.T) {
   426  	tests := []struct {
   427  		name   string
   428  		input  g.String
   429  		start  g.String
   430  		end    g.String
   431  		output g.String
   432  	}{
   433  		{"Basic", "Hello [start]world[end]!", "[start]", "[end]", "world"},
   434  		{"No start", "Hello world!", "[start]", "[end]", ""},
   435  		{"No end", "Hello [start]world!", "[start]", "[end]", ""},
   436  		{"Start equals end", "Hello [tag]world[tag]!", "[tag]", "[tag]", "world"},
   437  		{
   438  			"Multiple instances",
   439  			"A [start]first[end] B [start]second[end] C",
   440  			"[start]",
   441  			"[end]",
   442  			"first",
   443  		},
   444  		{"Empty input", "", "[start]", "[end]", ""},
   445  		{"Empty start and end", "Hello world!", "", "", ""},
   446  		{
   447  			"Nested tags",
   448  			"A [start]first [start]nested[end] value[end] B",
   449  			"[start]",
   450  			"[end]",
   451  			"first [start]nested",
   452  		},
   453  		{
   454  			"Overlapping tags",
   455  			"A [start]first[end][start]second[end] B",
   456  			"[start]",
   457  			"[end]",
   458  			"first",
   459  		},
   460  		{"Unicode characters", "Привет [начало]мир[конец]!", "[начало]", "[конец]", "мир"},
   461  	}
   462  
   463  	for _, test := range tests {
   464  		t.Run(test.name, func(t *testing.T) {
   465  			_, result := test.input.Cut(test.start, test.end)
   466  			if result != test.output {
   467  				t.Errorf("Expected '%s', got '%s'", test.output, result)
   468  			}
   469  		})
   470  	}
   471  }
   472  
   473  func TestStringCompare(t *testing.T) {
   474  	testCases := []struct {
   475  		str1     g.String
   476  		str2     g.String
   477  		expected int
   478  	}{
   479  		{"apple", "banana", -1},
   480  		{"banana", "apple", 1},
   481  		{"banana", "banana", 0},
   482  		{"apple", "Apple", 1},
   483  		{"", "", 0},
   484  	}
   485  
   486  	for _, tc := range testCases {
   487  		result := tc.str1.Cmp(tc.str2)
   488  		if int(result) != tc.expected {
   489  			t.Errorf("Compare(%q, %q): expected %d, got %d", tc.str1, tc.str2, tc.expected, result)
   490  		}
   491  	}
   492  }
   493  
   494  func TestStringEq(t *testing.T) {
   495  	testCases := []struct {
   496  		str1     g.String
   497  		str2     g.String
   498  		expected bool
   499  	}{
   500  		{"apple", "banana", false},
   501  		{"banana", "banana", true},
   502  		{"Apple", "apple", false},
   503  		{"", "", true},
   504  	}
   505  
   506  	for _, tc := range testCases {
   507  		result := tc.str1.Eq(tc.str2)
   508  		if result != tc.expected {
   509  			t.Errorf("Eq(%q, %q): expected %t, got %t", tc.str1, tc.str2, tc.expected, result)
   510  		}
   511  	}
   512  }
   513  
   514  func TestStringNe(t *testing.T) {
   515  	testCases := []struct {
   516  		str1     g.String
   517  		str2     g.String
   518  		expected bool
   519  	}{
   520  		{"apple", "banana", true},
   521  		{"banana", "banana", false},
   522  		{"Apple", "apple", true},
   523  		{"", "", false},
   524  	}
   525  
   526  	for _, tc := range testCases {
   527  		result := tc.str1.Ne(tc.str2)
   528  		if result != tc.expected {
   529  			t.Errorf("Ne(%q, %q): expected %t, got %t", tc.str1, tc.str2, tc.expected, result)
   530  		}
   531  	}
   532  }
   533  
   534  func TestStringGt(t *testing.T) {
   535  	testCases := []struct {
   536  		str1     g.String
   537  		str2     g.String
   538  		expected bool
   539  	}{
   540  		{"apple", "banana", false},
   541  		{"banana", "apple", true},
   542  		{"Apple", "apple", false},
   543  		{"banana", "banana", false},
   544  		{"", "", false},
   545  	}
   546  
   547  	for _, tc := range testCases {
   548  		result := tc.str1.Gt(tc.str2)
   549  		if result != tc.expected {
   550  			t.Errorf("Gt(%q, %q): expected %t, got %t", tc.str1, tc.str2, tc.expected, result)
   551  		}
   552  	}
   553  }
   554  
   555  func TestStringLt(t *testing.T) {
   556  	testCases := []struct {
   557  		str1     g.String
   558  		str2     g.String
   559  		expected bool
   560  	}{
   561  		{"apple", "banana", true},
   562  		{"banana", "apple", false},
   563  		{"Apple", "apple", true},
   564  		{"banana", "banana", false},
   565  		{"", "", false},
   566  	}
   567  
   568  	for _, tc := range testCases {
   569  		result := tc.str1.Lt(tc.str2)
   570  		if result != tc.expected {
   571  			t.Errorf("Lt(%q, %q): expected %t, got %t", tc.str1, tc.str2, tc.expected, result)
   572  		}
   573  	}
   574  }
   575  
   576  func TestStringLte(t *testing.T) {
   577  	testCases := []struct {
   578  		str1     g.String
   579  		str2     g.String
   580  		expected bool
   581  	}{
   582  		{"apple", "banana", true},
   583  		{"banana", "apple", false},
   584  		{"Apple", "apple", true},
   585  		{"banana", "banana", true}, // Equal strings should return true
   586  		{"", "", true},             // Empty strings should return true
   587  	}
   588  
   589  	for _, tc := range testCases {
   590  		result := tc.str1.Lte(tc.str2)
   591  		if result != tc.expected {
   592  			t.Errorf("Lte(%q, %q): expected %t, got %t", tc.str1, tc.str2, tc.expected, result)
   593  		}
   594  	}
   595  }
   596  
   597  func TestStringGte(t *testing.T) {
   598  	testCases := []struct {
   599  		str1     g.String
   600  		str2     g.String
   601  		expected bool
   602  	}{
   603  		{"apple", "banana", false},
   604  		{"banana", "apple", true},
   605  		{"Apple", "apple", false},
   606  		{"banana", "banana", true}, // Equal strings should return true
   607  		{"", "", true},             // Empty strings should return true
   608  	}
   609  
   610  	for _, tc := range testCases {
   611  		result := tc.str1.Gte(tc.str2)
   612  		if result != tc.expected {
   613  			t.Errorf("Gte(%q, %q): expected %t, got %t", tc.str1, tc.str2, tc.expected, result)
   614  		}
   615  	}
   616  }
   617  
   618  func TestStringReverse(t *testing.T) {
   619  	testCases := []struct {
   620  		in      g.String
   621  		wantOut g.String
   622  	}{
   623  		{in: "", wantOut: ""},
   624  		{in: " ", wantOut: " "},
   625  		{in: "a", wantOut: "a"},
   626  		{in: "ab", wantOut: "ba"},
   627  		{in: "abc", wantOut: "cba"},
   628  		{in: "abcdefg", wantOut: "gfedcba"},
   629  		{in: "ab丂d", wantOut: "d丂ba"},
   630  		{in: "abåd", wantOut: "dåba"},
   631  
   632  		{in: "世界", wantOut: "界世"},
   633  		{in: "🙂🙃", wantOut: "🙃🙂"},
   634  		{in: "こんにちは", wantOut: "はちにんこ"},
   635  
   636  		// Punctuation and whitespace
   637  		{in: "Hello, world!", wantOut: "!dlrow ,olleH"},
   638  		{in: "Hello\tworld!", wantOut: "!dlrow\tolleH"},
   639  		{in: "Hello\nworld!", wantOut: "!dlrow\nolleH"},
   640  
   641  		// Mixed languages and scripts
   642  		{in: "Hello, 世界!", wantOut: "!界世 ,olleH"},
   643  		{in: "Привет, мир!", wantOut: "!рим ,тевирП"},
   644  		{in: "안녕하세요, 세계!", wantOut: "!계세 ,요세하녕안"},
   645  
   646  		// Palindromes
   647  		{in: "racecar", wantOut: "racecar"},
   648  		{in: "A man, a plan, a canal: Panama", wantOut: "amanaP :lanac a ,nalp a ,nam A"},
   649  
   650  		{
   651  			in:      "The quick brown fox jumps over the lazy dog.",
   652  			wantOut: ".god yzal eht revo spmuj xof nworb kciuq ehT",
   653  		},
   654  		{in: "A man a plan a canal panama", wantOut: "amanap lanac a nalp a nam A"},
   655  		{in: "Was it a car or a cat I saw?", wantOut: "?was I tac a ro rac a ti saW"},
   656  		{in: "Never odd or even", wantOut: "neve ro ddo reveN"},
   657  		{in: "Do geese see God?", wantOut: "?doG ees eseeg oD"},
   658  		{in: "A Santa at NASA", wantOut: "ASAN ta atnaS A"},
   659  		{in: "Yo, Banana Boy!", wantOut: "!yoB ananaB ,oY"},
   660  		{in: "Madam, in Eden I'm Adam", wantOut: "madA m'I nedE ni ,madaM"},
   661  		{in: "Never odd or even", wantOut: "neve ro ddo reveN"},
   662  		{in: "Was it a car or a cat I saw?", wantOut: "?was I tac a ro rac a ti saW"},
   663  		{in: "Do geese see God?", wantOut: "?doG ees eseeg oD"},
   664  		{in: "No 'x' in Nixon", wantOut: "noxiN ni 'x' oN"},
   665  		{in: "A Santa at NASA", wantOut: "ASAN ta atnaS A"},
   666  		{in: "Yo, Banana Boy!", wantOut: "!yoB ananaB ,oY"},
   667  	}
   668  
   669  	for _, tc := range testCases {
   670  		result := tc.in.Reverse()
   671  		if result.Ne(tc.wantOut) {
   672  			t.Errorf("Reverse(%s): expected %s, got %s", tc.in, result, tc.wantOut)
   673  		}
   674  	}
   675  }
   676  
   677  func TestStringNormalizeNFC(t *testing.T) {
   678  	testCases := []struct {
   679  		input    g.String
   680  		expected g.String
   681  	}{
   682  		{input: "Mëtàl Hëàd", expected: "Mëtàl Hëàd"},
   683  		{input: "Café", expected: "Café"},
   684  		{input: "Ĵūņě", expected: "Ĵūņě"},
   685  		{input: "𝓽𝓮𝓼𝓽 𝓬𝓪𝓼𝓮", expected: "𝓽𝓮𝓼𝓽 𝓬𝓪𝓼𝓮"},
   686  		{input: "ḀϊṍẀṙṧ", expected: "ḀϊṍẀṙṧ"},
   687  		{input: "えもじ れんしゅう", expected: "えもじ れんしゅう"},
   688  		{input: "Научные исследования", expected: "Научные исследования"},
   689  		{input: "🌟Unicode✨", expected: "🌟Unicode✨"},
   690  		{input: "A\u0308", expected: "Ä"},
   691  		{input: "o\u0308", expected: "ö"},
   692  		{input: "u\u0308", expected: "ü"},
   693  		{input: "O\u0308", expected: "Ö"},
   694  		{input: "U\u0308", expected: "Ü"},
   695  	}
   696  
   697  	for _, tc := range testCases {
   698  		t.Run("", func(t *testing.T) {
   699  			output := tc.input.NormalizeNFC()
   700  			if output != tc.expected {
   701  				t.Errorf("Normalize(%q) = %q; want %q", tc.input, output, tc.expected)
   702  			}
   703  		})
   704  	}
   705  }
   706  
   707  func TestStringSimilarity(t *testing.T) {
   708  	testCases := []struct {
   709  		str1     g.String
   710  		str2     g.String
   711  		expected g.Float
   712  	}{
   713  		{"hello", "hello", 100},
   714  		{"hello", "world", 20},
   715  		{"hello", "", 0},
   716  		{"", "", 100},
   717  		{"cat", "cats", 75},
   718  		{"kitten", "sitting", 57.14},
   719  		{"good", "bad", 25},
   720  		{"book", "back", 50},
   721  		{"abcdef", "azced", 50},
   722  		{"tree", "three", 80},
   723  		{"house", "horse", 80},
   724  		{"language", "languish", 62.50},
   725  		{"programming", "programmer", 72.73},
   726  		{"algorithm", "logarithm", 77.78},
   727  		{"software", "hardware", 50},
   728  		{"tea", "ate", 33.33},
   729  		{"pencil", "pen", 50},
   730  		{"information", "informant", 63.64},
   731  		{"coffee", "toffee", 83.33},
   732  		{"developer", "develop", 77.78},
   733  		{"distance", "difference", 50},
   734  		{"similar", "similarity", 70},
   735  		{"apple", "apples", 83.33},
   736  		{"internet", "internets", 88.89},
   737  		{"education", "dedication", 80},
   738  	}
   739  
   740  	for _, tc := range testCases {
   741  		t.Run("", func(t *testing.T) {
   742  			output := tc.str1.Similarity(tc.str2)
   743  			if output.RoundDecimal(2).Ne(tc.expected) {
   744  				t.Errorf(
   745  					"g.String(\"%s\").SimilarText(\"%s\") = %.2f%% but want %.2f%%\n",
   746  					tc.str1,
   747  					tc.str2,
   748  					output,
   749  					tc.expected,
   750  				)
   751  			}
   752  		})
   753  	}
   754  }
   755  
   756  func TestStringReader(t *testing.T) {
   757  	tests := []struct {
   758  		name     string
   759  		str      g.String
   760  		expected string
   761  	}{
   762  		{"Empty String", "", ""},
   763  		{"Single character String", "a", "a"},
   764  		{"Multiple characters String", "hello world", "hello world"},
   765  		{"String with special characters", "こんにちは、世界!", "こんにちは、世界!"},
   766  	}
   767  
   768  	for _, test := range tests {
   769  		t.Run(test.name, func(t *testing.T) {
   770  			reader := test.str.Reader()
   771  			resultBytes, err := io.ReadAll(reader)
   772  			if err != nil {
   773  				t.Fatalf("Error reading from *strings.Reader: %v", err)
   774  			}
   775  
   776  			result := string(resultBytes)
   777  
   778  			if result != test.expected {
   779  				t.Errorf("Reader() content = %s, expected %s", result, test.expected)
   780  			}
   781  		})
   782  	}
   783  }
   784  
   785  func TestStringContainsAny(t *testing.T) {
   786  	testCases := []struct {
   787  		name    string
   788  		input   g.String
   789  		substrs g.Slice[g.String]
   790  		want    bool
   791  	}{
   792  		{
   793  			name:    "ContainsAny_OneSubstringMatch",
   794  			input:   "This is an example",
   795  			substrs: []g.String{"This", "missing"},
   796  			want:    true,
   797  		},
   798  		{
   799  			name:    "ContainsAny_NoSubstringMatch",
   800  			input:   "This is an example",
   801  			substrs: []g.String{"notfound", "missing"},
   802  			want:    false,
   803  		},
   804  		{
   805  			name:    "ContainsAny_EmptySubstrings",
   806  			input:   "This is an example",
   807  			substrs: []g.String{},
   808  			want:    false,
   809  		},
   810  		{
   811  			name:    "ContainsAny_EmptyInput",
   812  			input:   "",
   813  			substrs: []g.String{"notfound", "missing"},
   814  			want:    false,
   815  		},
   816  	}
   817  
   818  	for _, tc := range testCases {
   819  		t.Run(tc.name, func(t *testing.T) {
   820  			got := tc.input.ContainsAny(tc.substrs...)
   821  			if got != tc.want {
   822  				t.Errorf("ContainsAny() = %v; want %v", got, tc.want)
   823  			}
   824  		})
   825  	}
   826  }
   827  
   828  func TestStringContainsAll(t *testing.T) {
   829  	testCases := []struct {
   830  		name    string
   831  		input   g.String
   832  		substrs g.Slice[g.String]
   833  		want    bool
   834  	}{
   835  		{
   836  			name:    "ContainsAll_AllSubstringsMatch",
   837  			input:   "This is an example",
   838  			substrs: []g.String{"This", "example"},
   839  			want:    true,
   840  		},
   841  		{
   842  			name:    "ContainsAll_NotAllSubstringsMatch",
   843  			input:   "This is an example",
   844  			substrs: []g.String{"This", "missing"},
   845  			want:    false,
   846  		},
   847  		{
   848  			name:    "ContainsAll_EmptySubstrings",
   849  			input:   "This is an example",
   850  			substrs: []g.String{},
   851  			want:    true,
   852  		},
   853  		{
   854  			name:    "ContainsAll_EmptyInput",
   855  			input:   "",
   856  			substrs: []g.String{"notfound", "missing"},
   857  			want:    false,
   858  		},
   859  	}
   860  
   861  	for _, tc := range testCases {
   862  		t.Run(tc.name, func(t *testing.T) {
   863  			got := tc.input.ContainsAll(tc.substrs...)
   864  			if got != tc.want {
   865  				t.Errorf("ContainsAll() = %v; want %v", got, tc.want)
   866  			}
   867  		})
   868  	}
   869  }
   870  
   871  func TestStringReplaceNth(t *testing.T) {
   872  	tests := []struct {
   873  		name     string
   874  		str      g.String
   875  		oldS     g.String
   876  		newS     g.String
   877  		n        g.Int
   878  		expected g.String
   879  	}{
   880  		{
   881  			"First occurrence",
   882  			"The quick brown dog jumped over the lazy dog.",
   883  			"dog",
   884  			"fox",
   885  			1,
   886  			"The quick brown fox jumped over the lazy dog.",
   887  		},
   888  		{
   889  			"Second occurrence",
   890  			"The quick brown dog jumped over the lazy dog.",
   891  			"dog",
   892  			"fox",
   893  			2,
   894  			"The quick brown dog jumped over the lazy fox.",
   895  		},
   896  		{
   897  			"Last occurrence",
   898  			"The quick brown dog jumped over the lazy dog.",
   899  			"dog",
   900  			"fox",
   901  			-1,
   902  			"The quick brown dog jumped over the lazy fox.",
   903  		},
   904  		{
   905  			"Negative n (except -1)",
   906  			"The quick brown dog jumped over the lazy dog.",
   907  			"dog",
   908  			"fox",
   909  			-2,
   910  			"The quick brown dog jumped over the lazy dog.",
   911  		},
   912  		{
   913  			"Zero n",
   914  			"The quick brown dog jumped over the lazy dog.",
   915  			"dog",
   916  			"fox",
   917  			0,
   918  			"The quick brown dog jumped over the lazy dog.",
   919  		},
   920  		{
   921  			"Longer replacement",
   922  			"Hello, world!",
   923  			"world",
   924  			"beautiful world",
   925  			1,
   926  			"Hello, beautiful world!",
   927  		},
   928  		{
   929  			"Shorter replacement",
   930  			"A wonderful day, isn't it?",
   931  			"wonderful",
   932  			"nice",
   933  			1,
   934  			"A nice day, isn't it?",
   935  		},
   936  		{
   937  			"Replace entire string",
   938  			"Hello, world!",
   939  			"Hello, world!",
   940  			"Greetings, world!",
   941  			1,
   942  			"Greetings, world!",
   943  		},
   944  		{"No replacement", "Hello, world!", "x", "y", 1, "Hello, world!"},
   945  		{"Nonexistent substring", "Hello, world!", "foobar", "test", 1, "Hello, world!"},
   946  		{"Replace empty string", "Hello, world!", "", "x", 1, "Hello, world!"},
   947  		{"Multiple identical substrings", "banana", "na", "xy", 1, "baxyna"},
   948  		{"Multiple identical substrings, last", "banana", "na", "xy", -1, "banaxy"},
   949  		{"Replace with empty string", "Hello, world!", "world", "", 1, "Hello, !"},
   950  		{"Empty input string", "", "world", "test", 1, ""},
   951  		{"Empty input, empty oldS, empty newS", "", "", "", 1, ""},
   952  		{"Replace multiple spaces", "Hello    world!", "    ", " ", 1, "Hello world!"},
   953  		{"Unicode characters", "こんにちは世界!", "世界", "World", 1, "こんにちはWorld!"},
   954  	}
   955  
   956  	for _, test := range tests {
   957  		t.Run(test.name, func(t *testing.T) {
   958  			result := test.str.ReplaceNth(test.oldS, test.newS, test.n)
   959  			if result != test.expected {
   960  				t.Errorf("ReplaceNth() got %q, want %q", result, test.expected)
   961  			}
   962  		})
   963  	}
   964  }
   965  
   966  func TestStringIsASCII(t *testing.T) {
   967  	testCases := []struct {
   968  		input    g.String
   969  		expected bool
   970  	}{
   971  		{"Hello, world!", true},
   972  		{"こんにちは", false},
   973  		{"", true},
   974  		{"1234567890", true},
   975  		{"ABCabc", true},
   976  		{"~`!@#$%^&*()-_+={[}]|\\:;\"'<,>.?/", true},
   977  		{"áéíóú", false},
   978  		{"Привет", false},
   979  	}
   980  
   981  	for _, tc := range testCases {
   982  		result := tc.input.IsASCII()
   983  		if result != tc.expected {
   984  			t.Errorf("IsASCII(%q) returned %v, expected %v", tc.input, result, tc.expected)
   985  		}
   986  	}
   987  }
   988  
   989  func TestStringReplaceMulti(t *testing.T) {
   990  	// Test case 1: Basic replacements
   991  	input1 := g.String("Hello, world! This is a test.")
   992  	replaced1 := input1.ReplaceMulti("Hello", "Greetings", "world", "universe", "test", "example")
   993  	expected1 := g.String("Greetings, universe! This is a example.")
   994  	if replaced1 != expected1 {
   995  		t.Errorf("Test case 1 failed: Expected '%s', got '%s'", expected1, replaced1)
   996  	}
   997  
   998  	// Test case 2: Replacements with special characters
   999  	input2 := g.String("The price is $100.00, not $200.00!")
  1000  	replaced2 := input2.ReplaceMulti("$100.00", "$50.00", "$200.00", "$80.00")
  1001  	expected2 := g.String("The price is $50.00, not $80.00!")
  1002  	if replaced2 != expected2 {
  1003  		t.Errorf("Test case 2 failed: Expected '%s', got '%s'", expected2, replaced2)
  1004  	}
  1005  
  1006  	// Test case 3: No replacements
  1007  	input3 := g.String("No replacements here.")
  1008  	replaced3 := input3.ReplaceMulti("Hello", "Greetings", "world", "universe")
  1009  	if replaced3 != input3 {
  1010  		t.Errorf("Test case 3 failed: Expected '%s', got '%s'", input3, replaced3)
  1011  	}
  1012  
  1013  	// Test case 4: Empty string
  1014  	input4 := g.String("")
  1015  	replaced4 := input4.ReplaceMulti("Hello", "Greetings")
  1016  	if replaced4 != input4 {
  1017  		t.Errorf("Test case 4 failed: Expected '%s', got '%s'", input4, replaced4)
  1018  	}
  1019  }
  1020  
  1021  func TestStringToFloat(t *testing.T) {
  1022  	// Test cases for valid float strings
  1023  	validFloatCases := []struct {
  1024  		input    g.String
  1025  		expected g.Float
  1026  	}{
  1027  		{"3.14", g.Float(3.14)},
  1028  		{"-123.456", g.Float(-123.456)},
  1029  		{"0.0", g.Float(0.0)},
  1030  	}
  1031  
  1032  	for _, testCase := range validFloatCases {
  1033  		result := testCase.input.ToFloat()
  1034  		if result.IsErr() {
  1035  			t.Errorf("ToFloat test failed for %s. Unexpected error: %v", testCase.input, result.Err())
  1036  		}
  1037  
  1038  		if result.Ok().Ne(testCase.expected) {
  1039  			t.Errorf("ToFloat test failed for %s. Expected: %v, Got: %v",
  1040  				testCase.input,
  1041  				testCase.expected,
  1042  				result.Ok(),
  1043  			)
  1044  		}
  1045  	}
  1046  
  1047  	// Test cases for invalid float strings
  1048  	invalidFloatCases := []g.String{"abc", "123abc", "12.34.56", "", " "}
  1049  
  1050  	for _, input := range invalidFloatCases {
  1051  		result := input.ToFloat()
  1052  		if result.IsOk() {
  1053  			t.Errorf("ToFloat test failed for %s. Expected error, got result: %v", input, result.Ok())
  1054  		}
  1055  	}
  1056  }
  1057  
  1058  func TestStringLower(t *testing.T) {
  1059  	// Test cases for lowercase conversion
  1060  	lowerCases := []struct {
  1061  		input    g.String
  1062  		expected g.String
  1063  	}{
  1064  		{"HELLO", "hello"},
  1065  		{"Hello World", "hello world"},
  1066  		{"123", "123"},
  1067  		{"", ""},
  1068  		{"AbCdEfG", "abcdefg"},
  1069  	}
  1070  
  1071  	for _, testCase := range lowerCases {
  1072  		result := testCase.input.Lower()
  1073  		if !result.Eq(testCase.expected) {
  1074  			t.Errorf("Lower test failed for %s. Expected: %s, Got: %s", testCase.input, testCase.expected, result)
  1075  		}
  1076  	}
  1077  }
  1078  
  1079  func TestStringTrim(t *testing.T) {
  1080  	// Test cases for Trim
  1081  	trimCases := []struct {
  1082  		input    g.String
  1083  		cutset   g.String
  1084  		expected g.String
  1085  	}{
  1086  		{"   Hello, World!   ", " ", "Hello, World!"},
  1087  		{"Hello, World!", ",! ", "Hello, World"},
  1088  		{"  Golang  ", " Go", "lang"},
  1089  		{"", "", ""},
  1090  	}
  1091  
  1092  	for _, testCase := range trimCases {
  1093  		result := testCase.input.Trim(testCase.cutset)
  1094  		if !result.Eq(testCase.expected) {
  1095  			t.Errorf(
  1096  				"Trim test failed for %s with cutset %s. Expected: %s, Got: %s",
  1097  				testCase.input,
  1098  				testCase.cutset,
  1099  				testCase.expected,
  1100  				result,
  1101  			)
  1102  		}
  1103  	}
  1104  }
  1105  
  1106  func TestStringTrimLeft(t *testing.T) {
  1107  	// Test cases for TrimLeft
  1108  	trimLeftCases := []struct {
  1109  		input    g.String
  1110  		cutset   g.String
  1111  		expected g.String
  1112  	}{
  1113  		{"   Hello, World!   ", " ", "Hello, World!   "},
  1114  		{"Hello, World!", ",! ", "Hello, World!"},
  1115  		{"  Golang  ", " Go", "lang  "},
  1116  		{"", "", ""},
  1117  	}
  1118  
  1119  	for _, testCase := range trimLeftCases {
  1120  		result := testCase.input.TrimLeft(testCase.cutset)
  1121  		if !result.Eq(testCase.expected) {
  1122  			t.Errorf(
  1123  				"TrimLeft test failed for %s with cutset %s. Expected: %s, Got: %s",
  1124  				testCase.input,
  1125  				testCase.cutset,
  1126  				testCase.expected,
  1127  				result,
  1128  			)
  1129  		}
  1130  	}
  1131  }
  1132  
  1133  func TestStringTrimPrefix(t *testing.T) {
  1134  	// Test cases for TrimPrefix
  1135  	trimPrefixCases := []struct {
  1136  		input    g.String
  1137  		prefix   g.String
  1138  		expected g.String
  1139  	}{
  1140  		{"Hello, World!", "Hello, ", "World!"},
  1141  		{"prefix-prefix-suffix", "prefix-", "prefix-suffix"},
  1142  		{"no prefix", "prefix-", "no prefix"},
  1143  		{"", "prefix-", ""},
  1144  	}
  1145  
  1146  	for _, testCase := range trimPrefixCases {
  1147  		result := testCase.input.TrimPrefix(testCase.prefix)
  1148  		if !result.Eq(testCase.expected) {
  1149  			t.Errorf(
  1150  				"TrimPrefix test failed for %s with prefix %s. Expected: %s, Got: %s",
  1151  				testCase.input,
  1152  				testCase.prefix,
  1153  				testCase.expected,
  1154  				result,
  1155  			)
  1156  		}
  1157  	}
  1158  }
  1159  
  1160  func TestStringTrimSuffix(t *testing.T) {
  1161  	// Test cases for TrimSuffix
  1162  	trimSuffixCases := []struct {
  1163  		input    g.String
  1164  		suffix   g.String
  1165  		expected g.String
  1166  	}{
  1167  		{"Hello, World!", ", World!", "Hello"},
  1168  		{"prefix-prefix-suffix", "-suffix", "prefix-prefix"},
  1169  		{"no suffix", "-suffix", "no suffix"},
  1170  		{"", "-suffix", ""},
  1171  	}
  1172  
  1173  	for _, testCase := range trimSuffixCases {
  1174  		result := testCase.input.TrimSuffix(testCase.suffix)
  1175  		if !result.Eq(testCase.expected) {
  1176  			t.Errorf(
  1177  				"TrimSuffix test failed for %s with suffix %s. Expected: %s, Got: %s",
  1178  				testCase.input,
  1179  				testCase.suffix,
  1180  				testCase.expected,
  1181  				result,
  1182  			)
  1183  		}
  1184  	}
  1185  }
  1186  
  1187  func TestStringReplace(t *testing.T) {
  1188  	// Test cases for Replace
  1189  	replaceCases := []struct {
  1190  		input    g.String
  1191  		oldS     g.String
  1192  		newS     g.String
  1193  		n        g.Int
  1194  		expected g.String
  1195  	}{
  1196  		{"Hello, World!", "Hello", "Hi", 1, "Hi, World!"},
  1197  		{"Hello, Hello, Hello!", "Hello", "Hi", -1, "Hi, Hi, Hi!"},
  1198  		{"prefix-prefix-suffix", "prefix", "pre", 1, "pre-prefix-suffix"},
  1199  		{"no match", "match", "replacement", 1, "no replacement"},
  1200  		{"", "", "", 0, ""},
  1201  	}
  1202  
  1203  	for _, testCase := range replaceCases {
  1204  		result := testCase.input.Replace(testCase.oldS, testCase.newS, testCase.n)
  1205  		if !result.Eq(testCase.expected) {
  1206  			t.Errorf(
  1207  				"Replace test failed for %s with oldS %s and newS %s. Expected: %s, Got: %s",
  1208  				testCase.input,
  1209  				testCase.oldS,
  1210  				testCase.newS,
  1211  				testCase.expected,
  1212  				result,
  1213  			)
  1214  		}
  1215  	}
  1216  }
  1217  
  1218  func TestStringContainsAnyChars(t *testing.T) {
  1219  	// Test cases for ContainsAnyChars
  1220  	containsAnyCharsCases := []struct {
  1221  		input    g.String
  1222  		chars    g.String
  1223  		expected bool
  1224  	}{
  1225  		{"Hello, World!", "aeiou", true}, // Contains vowels
  1226  		{"1234567890", "aeiou", false},   // Does not contain vowels
  1227  		{"Hello, World!", "abc", false},  // Contains a, b, or c
  1228  		{"Hello, World!", "123", false},  // Does not contain 1, 2, or 3
  1229  		{"", "aeiou", false},             // Empty string
  1230  	}
  1231  
  1232  	for _, testCase := range containsAnyCharsCases {
  1233  		result := testCase.input.ContainsAnyChars(testCase.chars)
  1234  		if result != testCase.expected {
  1235  			t.Errorf(
  1236  				"ContainsAnyChars test failed for %s with chars %s. Expected: %t, Got: %t",
  1237  				testCase.input,
  1238  				testCase.chars,
  1239  				testCase.expected,
  1240  				result,
  1241  			)
  1242  		}
  1243  	}
  1244  }
  1245  
  1246  func TestStringSplitLines(t *testing.T) {
  1247  	// Test case 1: String with multiple lines.
  1248  	str1 := g.NewString("hello\nworld\nhow\nare\nyou\n")
  1249  	expected1 := g.Slice[g.String]{"hello", "world", "how", "are", "you"}
  1250  	result1 := str1.Lines().Collect()
  1251  	if !reflect.DeepEqual(result1, expected1) {
  1252  		t.Errorf("Test case 1 failed: Expected %v, got %v", expected1, result1)
  1253  	}
  1254  
  1255  	// Test case 2: String with single line.
  1256  	str2 := g.NewString("hello")
  1257  	expected2 := g.Slice[g.String]{"hello"}
  1258  	result2 := str2.Lines().Collect()
  1259  	if !reflect.DeepEqual(result2, expected2) {
  1260  		t.Errorf("Test case 2 failed: Expected %v, got %v", expected2, result2)
  1261  	}
  1262  }
  1263  
  1264  func TestStringSplitN(t *testing.T) {
  1265  	// Test case 1: String with multiple segments, n > 0.
  1266  	str1 := g.NewString("hello,world,how,are,you")
  1267  	sep1 := g.NewString(",")
  1268  	n1 := g.Int(3)
  1269  	expected1 := g.Slice[g.String]{"hello", "world", "how,are,you"}
  1270  	result1 := str1.SplitN(sep1, n1)
  1271  	if !reflect.DeepEqual(result1, expected1) {
  1272  		t.Errorf("Test case 1 failed: Expected %v, got %v", expected1, result1)
  1273  	}
  1274  
  1275  	// Test case 2: String with multiple segments, n < 0.
  1276  	str2 := g.NewString("hello,world,how,are,you")
  1277  	sep2 := g.NewString(",")
  1278  	n2 := g.Int(-1)
  1279  	expected2 := g.Slice[g.String]{"hello", "world", "how", "are", "you"}
  1280  	result2 := str2.SplitN(sep2, n2)
  1281  	if !reflect.DeepEqual(result2, expected2) {
  1282  		t.Errorf("Test case 2 failed: Expected %v, got %v", expected2, result2)
  1283  	}
  1284  
  1285  	// Test case 3: String with single segment, n > 0.
  1286  	str3 := g.NewString("hello")
  1287  	sep3 := g.NewString(",")
  1288  	n3 := g.Int(1)
  1289  	expected3 := g.Slice[g.String]{"hello"}
  1290  	result3 := str3.SplitN(sep3, n3)
  1291  	if !reflect.DeepEqual(result3, expected3) {
  1292  		t.Errorf("Test case 3 failed: Expected %v, got %v", expected3, result3)
  1293  	}
  1294  }
  1295  
  1296  func TestStringFields(t *testing.T) {
  1297  	// Test case 1: String with multiple words separated by whitespace.
  1298  	str1 := g.NewString("hello world how are you")
  1299  	expected1 := g.Slice[g.String]{"hello", "world", "how", "are", "you"}
  1300  	result1 := str1.Fields().Collect()
  1301  	if !reflect.DeepEqual(result1, expected1) {
  1302  		t.Errorf("Test case 1 failed: Expected %v, got %v", expected1, result1)
  1303  	}
  1304  
  1305  	// Test case 2: String with single word.
  1306  	str2 := g.NewString("hello")
  1307  	expected2 := g.Slice[g.String]{"hello"}
  1308  	result2 := str2.Fields().Collect()
  1309  	if !reflect.DeepEqual(result2, expected2) {
  1310  		t.Errorf("Test case 2 failed: Expected %v, got %v", expected2, result2)
  1311  	}
  1312  
  1313  	// Test case 3: Empty string.
  1314  	str3 := g.NewString("")
  1315  	expected3 := g.Slice[g.String]{}
  1316  	result3 := str3.Fields().Collect()
  1317  	if !reflect.DeepEqual(result3, expected3) {
  1318  		t.Errorf("Test case 3 failed: Expected %v, got %v", expected3, result3)
  1319  	}
  1320  
  1321  	// Test case 4: String with leading and trailing whitespace.
  1322  	str4 := g.NewString("   hello   world   ")
  1323  	expected4 := g.Slice[g.String]{"hello", "world"}
  1324  	result4 := str4.Fields().Collect()
  1325  	if !reflect.DeepEqual(result4, expected4) {
  1326  		t.Errorf("Test case 4 failed: Expected %v, got %v", expected4, result4)
  1327  	}
  1328  }
  1329  
  1330  func TestStringCount(t *testing.T) {
  1331  	// Test case 1: Count occurrences of substring in a string with multiple occurrences.
  1332  	str1 := g.NewString("hello world hello hello")
  1333  	substr1 := g.NewString("hello")
  1334  	expected1 := g.Int(3)
  1335  	result1 := str1.Count(substr1)
  1336  	if result1 != expected1 {
  1337  		t.Errorf("Test case 1 failed: Expected %d, got %d", expected1, result1)
  1338  	}
  1339  
  1340  	// Test case 2: Count occurrences of substring in a string with no occurrences.
  1341  	str2 := g.NewString("abcdefg")
  1342  	substr2 := g.NewString("xyz")
  1343  	expected2 := g.Int(0)
  1344  	result2 := str2.Count(substr2)
  1345  	if result2 != expected2 {
  1346  		t.Errorf("Test case 2 failed: Expected %d, got %d", expected2, result2)
  1347  	}
  1348  
  1349  	// Test case 3: Count occurrences of substring in an empty string.
  1350  	str3 := g.NewString("")
  1351  	substr3 := g.NewString("hello")
  1352  	expected3 := g.Int(0)
  1353  	result3 := str3.Count(substr3)
  1354  	if result3 != expected3 {
  1355  		t.Errorf("Test case 3 failed: Expected %d, got %d", expected3, result3)
  1356  	}
  1357  }
  1358  
  1359  func TestStringEqFold(t *testing.T) {
  1360  	// Test case 1: Strings are equal case-insensitively.
  1361  	str1 := g.NewString("Hello")
  1362  	str2 := g.NewString("hello")
  1363  	expected1 := true
  1364  	result1 := str1.EqFold(str2)
  1365  	if result1 != expected1 {
  1366  		t.Errorf("Test case 1 failed: Expected %t, got %t", expected1, result1)
  1367  	}
  1368  
  1369  	// Test case 2: Strings are not equal case-insensitively.
  1370  	str3 := g.NewString("world")
  1371  	expected2 := false
  1372  	result2 := str1.EqFold(str3)
  1373  	if result2 != expected2 {
  1374  		t.Errorf("Test case 2 failed: Expected %t, got %t", expected2, result2)
  1375  	}
  1376  
  1377  	// Test case 3: Empty strings.
  1378  	str4 := g.NewString("")
  1379  	str5 := g.NewString("")
  1380  	expected3 := true
  1381  	result3 := str4.EqFold(str5)
  1382  	if result3 != expected3 {
  1383  		t.Errorf("Test case 3 failed: Expected %t, got %t", expected3, result3)
  1384  	}
  1385  }
  1386  
  1387  func TestStringLastIndex(t *testing.T) {
  1388  	// Test case 1: Substring is present in the string.
  1389  	str1 := g.NewString("hello world hello")
  1390  	substr1 := g.NewString("hello")
  1391  	expected1 := g.Int(12)
  1392  	result1 := str1.LastIndex(substr1)
  1393  	if result1 != expected1 {
  1394  		t.Errorf("Test case 1 failed: Expected %d, got %d", expected1, result1)
  1395  	}
  1396  
  1397  	// Test case 2: Substring is not present in the string.
  1398  	substr2 := g.NewString("foo")
  1399  	expected2 := g.Int(-1)
  1400  	result2 := str1.LastIndex(substr2)
  1401  	if result2 != expected2 {
  1402  		t.Errorf("Test case 2 failed: Expected %d, got %d", expected2, result2)
  1403  	}
  1404  
  1405  	// Test case 3: Empty string.
  1406  	str3 := g.NewString("")
  1407  	substr3 := g.NewString("hello")
  1408  	expected3 := g.Int(-1)
  1409  	result3 := str3.LastIndex(substr3)
  1410  	if result3 != expected3 {
  1411  		t.Errorf("Test case 3 failed: Expected %d, got %d", expected3, result3)
  1412  	}
  1413  }
  1414  
  1415  func TestStringIndexRune(t *testing.T) {
  1416  	// Test case 1: Rune is present in the string.
  1417  	str1 := g.NewString("hello")
  1418  	rune1 := 'e'
  1419  	expected1 := g.Int(1)
  1420  	result1 := str1.IndexRune(rune1)
  1421  	if result1 != expected1 {
  1422  		t.Errorf("Test case 1 failed: Expected %d, got %d", expected1, result1)
  1423  	}
  1424  
  1425  	// Test case 2: Rune is not present in the string.
  1426  	rune2 := 'x'
  1427  	expected2 := g.Int(-1)
  1428  	result2 := str1.IndexRune(rune2)
  1429  	if result2 != expected2 {
  1430  		t.Errorf("Test case 2 failed: Expected %d, got %d", expected2, result2)
  1431  	}
  1432  
  1433  	// Test case 3: Empty string.
  1434  	str3 := g.NewString("")
  1435  	rune3 := 'h'
  1436  	expected3 := g.Int(-1)
  1437  	result3 := str3.IndexRune(rune3)
  1438  	if result3 != expected3 {
  1439  		t.Errorf("Test case 3 failed: Expected %d, got %d", expected3, result3)
  1440  	}
  1441  }
  1442  
  1443  func TestStringNotEmpty(t *testing.T) {
  1444  	// Test case 1: String is not empty.
  1445  	str1 := g.NewString("hello")
  1446  	expected1 := true
  1447  	result1 := str1.NotEmpty()
  1448  	if result1 != expected1 {
  1449  		t.Errorf("Test case 1 failed: Expected %t, got %t", expected1, result1)
  1450  	}
  1451  
  1452  	// Test case 2: String is empty.
  1453  	str2 := g.NewString("")
  1454  	expected2 := false
  1455  	result2 := str2.NotEmpty()
  1456  	if result2 != expected2 {
  1457  		t.Errorf("Test case 2 failed: Expected %t, got %t", expected2, result2)
  1458  	}
  1459  }
  1460  
  1461  func TestRepeat(t *testing.T) {
  1462  	// Test case 1: Repeat count is positive.
  1463  	str := g.NewString("abc")
  1464  	count := g.Int(3)
  1465  	expected1 := g.NewString("abcabcabc")
  1466  	result1 := str.Repeat(count)
  1467  	if !result1.Eq(expected1) {
  1468  		t.Errorf("Test case 1 failed: Expected %s, got %s", expected1, result1)
  1469  	}
  1470  
  1471  	// Test case 2: Repeat count is zero.
  1472  	count = 0
  1473  	expected2 := g.NewString("")
  1474  	result2 := str.Repeat(count)
  1475  	if !result2.Eq(expected2) {
  1476  		t.Errorf("Test case 2 failed: Expected %s, got %s", expected2, result2)
  1477  	}
  1478  }
  1479  
  1480  func TestStringLeftJustify(t *testing.T) {
  1481  	// Test case 1: Original string length is less than the specified length.
  1482  	str1 := g.NewString("Hello")
  1483  	length1 := g.Int(10)
  1484  	pad1 := g.NewString(".")
  1485  	expected1 := g.NewString("Hello.....")
  1486  	result1 := str1.LeftJustify(length1, pad1)
  1487  	if !result1.Eq(expected1) {
  1488  		t.Errorf("Test case 1 failed: Expected %s, got %s", expected1, result1)
  1489  	}
  1490  
  1491  	// Test case 2: Original string length is equal to the specified length.
  1492  	str2 := g.NewString("Hello")
  1493  	length2 := g.Int(5)
  1494  	pad2 := g.NewString(".")
  1495  	expected2 := g.NewString("Hello")
  1496  	result2 := str2.LeftJustify(length2, pad2)
  1497  	if !result2.Eq(expected2) {
  1498  		t.Errorf("Test case 2 failed: Expected %s, got %s", expected2, result2)
  1499  	}
  1500  
  1501  	// Test case 3: Original string length is greater than the specified length.
  1502  	str3 := g.NewString("Hello")
  1503  	length3 := g.Int(3)
  1504  	pad3 := g.NewString(".")
  1505  	expected3 := g.NewString("Hello")
  1506  	result3 := str3.LeftJustify(length3, pad3)
  1507  	if !result3.Eq(expected3) {
  1508  		t.Errorf("Test case 3 failed: Expected %s, got %s", expected3, result3)
  1509  	}
  1510  
  1511  	// Test case 4: Empty padding string.
  1512  	str4 := g.NewString("Hello")
  1513  	length4 := g.Int(10)
  1514  	pad4 := g.NewString("")
  1515  	expected4 := g.NewString("Hello")
  1516  	result4 := str4.LeftJustify(length4, pad4)
  1517  	if !result4.Eq(expected4) {
  1518  		t.Errorf("Test case 4 failed: Expected %s, got %s", expected4, result4)
  1519  	}
  1520  }
  1521  
  1522  func TestStringRightJustify(t *testing.T) {
  1523  	// Test case 1: Original string length is less than the specified length.
  1524  	str1 := g.NewString("Hello")
  1525  	length1 := g.Int(10)
  1526  	pad1 := g.NewString(".")
  1527  	expected1 := g.NewString(".....Hello")
  1528  	result1 := str1.RightJustify(length1, pad1)
  1529  	if !result1.Eq(expected1) {
  1530  		t.Errorf("Test case 1 failed: Expected %s, got %s", expected1, result1)
  1531  	}
  1532  
  1533  	// Test case 2: Original string length is equal to the specified length.
  1534  	str2 := g.NewString("Hello")
  1535  	length2 := g.Int(5)
  1536  	pad2 := g.NewString(".")
  1537  	expected2 := g.NewString("Hello")
  1538  	result2 := str2.RightJustify(length2, pad2)
  1539  	if !result2.Eq(expected2) {
  1540  		t.Errorf("Test case 2 failed: Expected %s, got %s", expected2, result2)
  1541  	}
  1542  
  1543  	// Test case 3: Original string length is greater than the specified length.
  1544  	str3 := g.NewString("Hello")
  1545  	length3 := g.Int(3)
  1546  	pad3 := g.NewString(".")
  1547  	expected3 := g.NewString("Hello")
  1548  	result3 := str3.RightJustify(length3, pad3)
  1549  	if !result3.Eq(expected3) {
  1550  		t.Errorf("Test case 3 failed: Expected %s, got %s", expected3, result3)
  1551  	}
  1552  
  1553  	// Test case 4: Empty padding string.
  1554  	str4 := g.NewString("Hello")
  1555  	length4 := g.Int(10)
  1556  	pad4 := g.NewString("")
  1557  	expected4 := g.NewString("Hello")
  1558  	result4 := str4.RightJustify(length4, pad4)
  1559  	if !result4.Eq(expected4) {
  1560  		t.Errorf("Test case 4 failed: Expected %s, got %s", expected4, result4)
  1561  	}
  1562  }
  1563  
  1564  func TestStringCenter(t *testing.T) {
  1565  	// Test case 1: Original string length is less than the specified length.
  1566  	str1 := g.NewString("Hello")
  1567  	length1 := g.Int(10)
  1568  	pad1 := g.NewString(".")
  1569  	expected1 := g.NewString("..Hello...")
  1570  	result1 := str1.Center(length1, pad1)
  1571  	if !result1.Eq(expected1) {
  1572  		t.Errorf("Test case 1 failed: Expected %s, got %s", expected1, result1)
  1573  	}
  1574  
  1575  	// Test case 2: Original string length is equal to the specified length.
  1576  	str2 := g.NewString("Hello")
  1577  	length2 := g.Int(5)
  1578  	pad2 := g.NewString(".")
  1579  	expected2 := g.NewString("Hello")
  1580  	result2 := str2.Center(length2, pad2)
  1581  	if !result2.Eq(expected2) {
  1582  		t.Errorf("Test case 2 failed: Expected %s, got %s", expected2, result2)
  1583  	}
  1584  
  1585  	// Test case 3: Original string length is greater than the specified length.
  1586  	str3 := g.NewString("Hello")
  1587  	length3 := g.Int(3)
  1588  	pad3 := g.NewString(".")
  1589  	expected3 := g.NewString("Hello")
  1590  	result3 := str3.Center(length3, pad3)
  1591  	if !result3.Eq(expected3) {
  1592  		t.Errorf("Test case 3 failed: Expected %s, got %s", expected3, result3)
  1593  	}
  1594  
  1595  	// Test case 4: Empty padding string.
  1596  	str4 := g.NewString("Hello")
  1597  	length4 := g.Int(10)
  1598  	pad4 := g.NewString("")
  1599  	expected4 := g.NewString("Hello")
  1600  	result4 := str4.Center(length4, pad4)
  1601  	if !result4.Eq(expected4) {
  1602  		t.Errorf("Test case 4 failed: Expected %s, got %s", expected4, result4)
  1603  	}
  1604  }
  1605  
  1606  func TestStringEndsWith(t *testing.T) {
  1607  	// Test case 1: String ends with one of the provided suffixes.
  1608  	str1 := g.NewString("example.com")
  1609  	suffixes1 := g.Slice[g.String]{g.NewString(".com"), g.NewString(".net")}
  1610  	expected1 := true
  1611  	result1 := str1.EndsWith(suffixes1...)
  1612  	if result1 != expected1 {
  1613  		t.Errorf("Test case 1 failed: Expected %t, got %t", expected1, result1)
  1614  	}
  1615  
  1616  	// Test case 2: String ends with multiple provided suffixes.
  1617  	str2 := g.NewString("example.net")
  1618  	suffixes2 := g.Slice[g.String]{g.NewString(".com"), g.NewString(".net")}
  1619  	expected2 := true
  1620  	result2 := str2.EndsWith(suffixes2...)
  1621  	if result2 != expected2 {
  1622  		t.Errorf("Test case 2 failed: Expected %t, got %t", expected2, result2)
  1623  	}
  1624  
  1625  	// Test case 3: String does not end with any of the provided suffixes.
  1626  	str3 := g.NewString("example.org")
  1627  	suffixes3 := g.Slice[g.String]{g.NewString(".com"), g.NewString(".net")}
  1628  	expected3 := false
  1629  	result3 := str3.EndsWith(suffixes3...)
  1630  	if result3 != expected3 {
  1631  		t.Errorf("Test case 3 failed: Expected %t, got %t", expected3, result3)
  1632  	}
  1633  }
  1634  
  1635  func TestStringStartsWith(t *testing.T) {
  1636  	// Test cases
  1637  	testCases := []struct {
  1638  		str      g.String
  1639  		prefixes []g.String
  1640  		expected bool
  1641  	}{
  1642  		{"http://example.com", []g.String{"http://", "https://"}, true},
  1643  		{"https://example.com", []g.String{"http://", "https://"}, true},
  1644  		{"ftp://example.com", []g.String{"http://", "https://"}, false},
  1645  		{"", []g.String{""}, true}, // Empty string should match empty prefix
  1646  		{"", []g.String{"non-empty"}, false},
  1647  	}
  1648  
  1649  	// Test each case
  1650  	for _, tc := range testCases {
  1651  		// Wrap the input string
  1652  		s := g.String(tc.str)
  1653  
  1654  		// Call the StartsWith method
  1655  		result := s.StartsWith(tc.prefixes...)
  1656  
  1657  		// Assert the result
  1658  		if result != tc.expected {
  1659  			t.Errorf("StartsWith() returned %v; expected %v", result, tc.expected)
  1660  		}
  1661  	}
  1662  }
  1663  
  1664  func TestStringSplitAfter(t *testing.T) {
  1665  	testCases := []struct {
  1666  		input     g.String
  1667  		separator g.String
  1668  		expected  g.Slice[g.String]
  1669  	}{
  1670  		{"hello,world,how,are,you", ",", g.Slice[g.String]{"hello,", "world,", "how,", "are,", "you"}},
  1671  		{"apple banana cherry", " ", g.Slice[g.String]{"apple ", "banana ", "cherry"}},
  1672  		{"a-b-c-d-e", "-", g.Slice[g.String]{"a-", "b-", "c-", "d-", "e"}},
  1673  		{"abcd", "a", g.Slice[g.String]{"a", "bcd"}},
  1674  		{"thisistest", "is", g.Slice[g.String]{"this", "is", "test"}},
  1675  		{"☺☻☹", "", g.Slice[g.String]{"☺", "☻", "☹"}},
  1676  		{"☺☻☹", "☹", g.Slice[g.String]{"☺☻☹", ""}},
  1677  		{"123", "", g.Slice[g.String]{"1", "2", "3"}},
  1678  	}
  1679  
  1680  	for _, tc := range testCases {
  1681  		actual := tc.input.SplitAfter(tc.separator).Collect()
  1682  
  1683  		if !reflect.DeepEqual(actual, tc.expected) {
  1684  			t.Errorf(
  1685  				"Unexpected result for input: %s, separator: %s\nExpected: %v\nGot: %v",
  1686  				tc.input,
  1687  				tc.separator,
  1688  				tc.expected,
  1689  				actual,
  1690  			)
  1691  		}
  1692  	}
  1693  }
  1694  
  1695  func TestStringFieldsBy(t *testing.T) {
  1696  	testCases := []struct {
  1697  		input    g.String
  1698  		fn       func(r rune) bool
  1699  		expected g.Slice[g.String]
  1700  	}{
  1701  		{"hello world", unicode.IsSpace, g.Slice[g.String]{"hello", "world"}},
  1702  		{"1,2,3,4,5", func(r rune) bool { return r == ',' }, g.Slice[g.String]{"1", "2", "3", "4", "5"}},
  1703  		{"camelCcase", unicode.IsUpper, g.Slice[g.String]{"camel", "case"}},
  1704  	}
  1705  
  1706  	for _, tc := range testCases {
  1707  		actual := tc.input.FieldsBy(tc.fn).Collect()
  1708  
  1709  		if !reflect.DeepEqual(actual, tc.expected) {
  1710  			t.Errorf("Unexpected result for input: %s\nExpected: %v\nGot: %v", tc.input, tc.expected, actual)
  1711  		}
  1712  	}
  1713  }
  1714  
  1715  func TestStringTrimSpace(t *testing.T) {
  1716  	testCases := []struct {
  1717  		input    g.String
  1718  		expected g.String
  1719  	}{
  1720  		{"   hello   ", "hello"},
  1721  		{"   world", "world"},
  1722  		{"foo   ", "foo"},
  1723  		{"\tbar\t", "bar"},
  1724  		{"", ""},
  1725  		{"  ", ""},
  1726  	}
  1727  
  1728  	for _, tc := range testCases {
  1729  		actual := tc.input.TrimSpace()
  1730  
  1731  		if actual != tc.expected {
  1732  			t.Errorf("Unexpected result for input: %s\nExpected: %s\nGot: %s", tc.input, tc.expected, actual)
  1733  		}
  1734  	}
  1735  }
  1736  
  1737  func TestStringRemove(t *testing.T) {
  1738  	tests := []struct {
  1739  		original g.String
  1740  		matches  g.Slice[g.String]
  1741  		expected g.String
  1742  	}{
  1743  		{
  1744  			original: "Hello, world! This is a test.",
  1745  			matches:  g.Slice[g.String]{"Hello", "test"},
  1746  			expected: ", world! This is a .",
  1747  		},
  1748  		{
  1749  			original: "This is a test string. This is a test string.",
  1750  			matches:  g.Slice[g.String]{"test", "string"},
  1751  			expected: "This is a  . This is a  .",
  1752  		},
  1753  		{
  1754  			original: "I love ice cream. Ice cream is delicious.",
  1755  			matches:  g.Slice[g.String]{"Ice", "cream"},
  1756  			expected: "I love ice .   is delicious.",
  1757  		},
  1758  	}
  1759  
  1760  	for _, test := range tests {
  1761  		original := test.original
  1762  		modified := original.Remove(test.matches...)
  1763  		if modified != test.expected {
  1764  			t.Errorf("Remove(%q, %q) = %q, expected %q", test.original, test.matches, modified.Std(), test.expected)
  1765  		}
  1766  	}
  1767  }