github.com/goravel/framework@v1.13.9/support/str/str_test.go (about)

     1  package str
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/suite"
     8  
     9  	"github.com/goravel/framework/support/env"
    10  )
    11  
    12  type StringTestSuite struct {
    13  	suite.Suite
    14  }
    15  
    16  func TestStringTestSuite(t *testing.T) {
    17  	suite.Run(t, &StringTestSuite{})
    18  }
    19  
    20  func (s *StringTestSuite) SetupTest() {
    21  }
    22  
    23  func (s *StringTestSuite) TestAfter() {
    24  	s.Equal("Framework", Of("GoravelFramework").After("Goravel").String())
    25  	s.Equal("lel", Of("parallel").After("l").String())
    26  	s.Equal("3def", Of("abc123def").After("2").String())
    27  	s.Equal("abc123def", Of("abc123def").After("4").String())
    28  	s.Equal("GoravelFramework", Of("GoravelFramework").After("").String())
    29  }
    30  
    31  func (s *StringTestSuite) TestAfterLast() {
    32  	s.Equal("Framework", Of("GoravelFramework").AfterLast("Goravel").String())
    33  	s.Equal("", Of("parallel").AfterLast("l").String())
    34  	s.Equal("3def", Of("abc123def").AfterLast("2").String())
    35  	s.Equal("abc123def", Of("abc123def").AfterLast("4").String())
    36  }
    37  
    38  func (s *StringTestSuite) TestAppend() {
    39  	s.Equal("foobar", Of("foo").Append("bar").String())
    40  	s.Equal("foobar", Of("foo").Append("bar").Append("").String())
    41  	s.Equal("foobar", Of("foo").Append("bar").Append().String())
    42  }
    43  
    44  func (s *StringTestSuite) TestBasename() {
    45  	s.Equal("str", Of("/framework/support/str").Basename().String())
    46  	s.Equal("str", Of("/framework/support/str/").Basename().String())
    47  	s.Equal("str", Of("str").Basename().String())
    48  	s.Equal("str", Of("/str").Basename().String())
    49  	s.Equal("str", Of("/str/").Basename().String())
    50  	s.Equal("str", Of("str/").Basename().String())
    51  
    52  	str := Of("/").Basename().String()
    53  	if env.IsWindows() {
    54  		s.Equal("\\", str)
    55  	} else {
    56  		s.Equal("/", str)
    57  	}
    58  
    59  	s.Equal(".", Of("").Basename().String())
    60  	s.Equal("str", Of("/framework/support/str/str.go").Basename(".go").String())
    61  }
    62  
    63  func (s *StringTestSuite) TestBefore() {
    64  	s.Equal("Goravel", Of("GoravelFramework").Before("Framework").String())
    65  	s.Equal("para", Of("parallel").Before("l").String())
    66  	s.Equal("abc123", Of("abc123def").Before("def").String())
    67  	s.Equal("abc", Of("abc123def").Before("123").String())
    68  }
    69  
    70  func (s *StringTestSuite) TestBeforeLast() {
    71  	s.Equal("Goravel", Of("GoravelFramework").BeforeLast("Framework").String())
    72  	s.Equal("paralle", Of("parallel").BeforeLast("l").String())
    73  	s.Equal("abc123", Of("abc123def").BeforeLast("def").String())
    74  	s.Equal("abc", Of("abc123def").BeforeLast("123").String())
    75  }
    76  
    77  func (s *StringTestSuite) TestBetween() {
    78  	s.Equal("foobarbaz", Of("foobarbaz").Between("", "b").String())
    79  	s.Equal("foobarbaz", Of("foobarbaz").Between("f", "").String())
    80  	s.Equal("foobarbaz", Of("foobarbaz").Between("", "").String())
    81  	s.Equal("obar", Of("foobarbaz").Between("o", "b").String())
    82  	s.Equal("bar", Of("foobarbaz").Between("foo", "baz").String())
    83  	s.Equal("foo][bar][baz", Of("[foo][bar][baz]").Between("[", "]").String())
    84  }
    85  
    86  func (s *StringTestSuite) TestBetweenFirst() {
    87  	s.Equal("foobarbaz", Of("foobarbaz").BetweenFirst("", "b").String())
    88  	s.Equal("foobarbaz", Of("foobarbaz").BetweenFirst("f", "").String())
    89  	s.Equal("foobarbaz", Of("foobarbaz").BetweenFirst("", "").String())
    90  	s.Equal("o", Of("foobarbaz").BetweenFirst("o", "b").String())
    91  	s.Equal("foo", Of("[foo][bar][baz]").BetweenFirst("[", "]").String())
    92  	s.Equal("foobar", Of("foofoobarbaz").BetweenFirst("foo", "baz").String())
    93  }
    94  
    95  func (s *StringTestSuite) TestCamel() {
    96  	s.Equal("goravelGOFramework", Of("Goravel_g_o_framework").Camel().String())
    97  	s.Equal("goravelGOFramework", Of("Goravel_gO_framework").Camel().String())
    98  	s.Equal("goravelGoFramework", Of("Goravel -_- go -_-  framework  ").Camel().String())
    99  
   100  	s.Equal("fooBar", Of("FooBar").Camel().String())
   101  	s.Equal("fooBar", Of("foo_bar").Camel().String())
   102  	s.Equal("fooBar", Of("foo-Bar").Camel().String())
   103  	s.Equal("fooBar", Of("foo bar").Camel().String())
   104  	s.Equal("fooBar", Of("foo.bar").Camel().String())
   105  }
   106  
   107  func (s *StringTestSuite) TestCharAt() {
   108  	s.Equal("好", Of("你好,世界!").CharAt(1))
   109  	s.Equal("त", Of("नमस्ते, दुनिया!").CharAt(4))
   110  	s.Equal("w", Of("Привет, world!").CharAt(8))
   111  	s.Equal("계", Of("안녕하세요, 세계!").CharAt(-2))
   112  	s.Equal("", Of("こんにちは、世界!").CharAt(-200))
   113  }
   114  
   115  func (s *StringTestSuite) TestContains() {
   116  	s.True(Of("kkumar").Contains("uma"))
   117  	s.True(Of("kkumar").Contains("kumar"))
   118  	s.True(Of("kkumar").Contains("uma", "xyz"))
   119  	s.False(Of("kkumar").Contains("xyz"))
   120  	s.False(Of("kkumar").Contains(""))
   121  }
   122  
   123  func (s *StringTestSuite) TestContainsAll() {
   124  	s.True(Of("krishan kumar").ContainsAll("krishan", "kumar"))
   125  	s.True(Of("krishan kumar").ContainsAll("kumar"))
   126  	s.False(Of("krishan kumar").ContainsAll("kumar", "xyz"))
   127  }
   128  
   129  func (s *StringTestSuite) TestDirname() {
   130  	str := Of("/framework/support/str").Dirname().String()
   131  	if env.IsWindows() {
   132  		s.Equal("\\framework\\support", str)
   133  	} else {
   134  		s.Equal("/framework/support", str)
   135  	}
   136  
   137  	str = Of("/framework/support/str").Dirname(2).String()
   138  	if env.IsWindows() {
   139  		s.Equal("\\framework", str)
   140  	} else {
   141  		s.Equal("/framework", str)
   142  	}
   143  
   144  	s.Equal(".", Of("framework").Dirname().String())
   145  	s.Equal(".", Of(".").Dirname().String())
   146  
   147  	str = Of("/").Dirname().String()
   148  	if env.IsWindows() {
   149  		s.Equal("\\", str)
   150  	} else {
   151  		s.Equal("/", str)
   152  	}
   153  
   154  	str = Of("/framework/").Dirname(2).String()
   155  	if env.IsWindows() {
   156  		s.Equal("\\", str)
   157  	} else {
   158  		s.Equal("/", str)
   159  	}
   160  }
   161  
   162  func (s *StringTestSuite) TestEndsWith() {
   163  	s.True(Of("bowen").EndsWith("wen"))
   164  	s.True(Of("bowen").EndsWith("bowen"))
   165  	s.True(Of("bowen").EndsWith("wen", "xyz"))
   166  	s.False(Of("bowen").EndsWith("xyz"))
   167  	s.False(Of("bowen").EndsWith(""))
   168  	s.False(Of("bowen").EndsWith())
   169  	s.False(Of("bowen").EndsWith("N"))
   170  	s.True(Of("a7.12").EndsWith("7.12"))
   171  	// Test for  muti-byte string
   172  	s.True(Of("你好").EndsWith("好"))
   173  	s.True(Of("你好").EndsWith("你好"))
   174  	s.True(Of("你好").EndsWith("好", "xyz"))
   175  	s.False(Of("你好").EndsWith("xyz"))
   176  	s.False(Of("你好").EndsWith(""))
   177  }
   178  
   179  func (s *StringTestSuite) TestExactly() {
   180  	s.True(Of("foo").Exactly("foo"))
   181  	s.False(Of("foo").Exactly("Foo"))
   182  }
   183  
   184  func (s *StringTestSuite) TestExcerpt() {
   185  	s.Equal("...is a beautiful morn...", Of("This is a beautiful morning").Excerpt("beautiful", ExcerptOption{
   186  		Radius: 5,
   187  	}).String())
   188  	s.Equal("This is a beautiful morning", Of("This is a beautiful morning").Excerpt("foo", ExcerptOption{
   189  		Radius: 5,
   190  	}).String())
   191  	s.Equal("(...)is a beautiful morn(...)", Of("This is a beautiful morning").Excerpt("beautiful", ExcerptOption{
   192  		Omission: "(...)",
   193  		Radius:   5,
   194  	}).String())
   195  }
   196  
   197  func (s *StringTestSuite) TestExplode() {
   198  	s.Equal([]string{"Foo", "Bar", "Baz"}, Of("Foo Bar Baz").Explode(" "))
   199  	// with limit
   200  	s.Equal([]string{"Foo", "Bar Baz"}, Of("Foo Bar Baz").Explode(" ", 2))
   201  	s.Equal([]string{"Foo", "Bar"}, Of("Foo Bar Baz").Explode(" ", -1))
   202  	s.Equal([]string{}, Of("Foo Bar Baz").Explode(" ", -10))
   203  }
   204  
   205  func (s *StringTestSuite) TestFinish() {
   206  	s.Equal("abbc", Of("ab").Finish("bc").String())
   207  	s.Equal("abbc", Of("abbcbc").Finish("bc").String())
   208  	s.Equal("abcbbc", Of("abcbbcbc").Finish("bc").String())
   209  }
   210  
   211  func (s *StringTestSuite) TestHeadline() {
   212  	s.Equal("Hello", Of("hello").Headline().String())
   213  	s.Equal("This Is A Headline", Of("this is a headline").Headline().String())
   214  	s.Equal("Camelcase Is A Headline", Of("CamelCase is a headline").Headline().String())
   215  	s.Equal("Kebab-Case Is A Headline", Of("kebab-case is a headline").Headline().String())
   216  }
   217  
   218  func (s *StringTestSuite) TestIs() {
   219  	s.True(Of("foo").Is("foo", "bar", "baz"))
   220  	s.True(Of("foo123").Is("bar*", "baz*", "foo*"))
   221  	s.False(Of("foo").Is("bar", "baz"))
   222  	s.True(Of("a.b").Is("a.b", "c.*"))
   223  	s.False(Of("abc*").Is("abc\\*", "xyz*"))
   224  	s.False(Of("").Is("foo"))
   225  	s.True(Of("foo/bar/baz").Is("foo/*", "bar/*", "baz*"))
   226  	// Is case-sensitive
   227  	s.False(Of("foo/bar/baz").Is("*BAZ*"))
   228  }
   229  
   230  func (s *StringTestSuite) TestIsEmpty() {
   231  	s.True(Of("").IsEmpty())
   232  	s.False(Of("F").IsEmpty())
   233  }
   234  
   235  func (s *StringTestSuite) TestIsNotEmpty() {
   236  	s.False(Of("").IsNotEmpty())
   237  	s.True(Of("F").IsNotEmpty())
   238  }
   239  
   240  func (s *StringTestSuite) TestIsAscii() {
   241  	s.True(Of("abc").IsAscii())
   242  	s.False(Of("你好").IsAscii())
   243  }
   244  
   245  func (s *StringTestSuite) TestIsSlice() {
   246  	// Test when the string represents a valid JSON array
   247  	s.True(Of(`["apple", "banana", "cherry"]`).IsSlice())
   248  
   249  	// Test when the string represents a valid JSON array with objects
   250  	s.True(Of(`[{"name": "John"}, {"name": "Alice"}]`).IsSlice())
   251  
   252  	// Test when the string represents an empty JSON array
   253  	s.True(Of(`[]`).IsSlice())
   254  
   255  	// Test when the string represents an invalid JSON object
   256  	s.False(Of(`{"name": "John"}`).IsSlice())
   257  
   258  	// Test when the string is not valid JSON
   259  	s.False(Of(`Not a JSON array`).IsSlice())
   260  
   261  	// Test when the string is empty
   262  	s.False(Of("").IsSlice())
   263  }
   264  
   265  func (s *StringTestSuite) TestIsMap() {
   266  	// Test when the string represents a valid JSON object
   267  	s.True(Of(`{"name": "John", "age": 30}`).IsMap())
   268  
   269  	// Test when the string represents a valid JSON object with nested objects
   270  	s.True(Of(`{"person": {"name": "Alice", "age": 25}}`).IsMap())
   271  
   272  	// Test when the string represents an empty JSON object
   273  	s.True(Of(`{}`).IsMap())
   274  
   275  	// Test when the string represents an invalid JSON array
   276  	s.False(Of(`["apple", "banana", "cherry"]`).IsMap())
   277  
   278  	// Test when the string is not valid JSON
   279  	s.False(Of(`Not a JSON object`).IsMap())
   280  
   281  	// Test when the string is empty
   282  	s.False(Of("").IsMap())
   283  }
   284  
   285  func (s *StringTestSuite) TestIsUlid() {
   286  	s.True(Of("01E65Z7XCHCR7X1P2MKF78ENRP").IsUlid())
   287  	// lowercase characters are not allowed
   288  	s.False(Of("01e65z7xchcr7x1p2mkf78enrp").IsUlid())
   289  	// too short (ULIDS must be 26 characters long)
   290  	s.False(Of("01E65Z7XCHCR7X1P2MKF78E").IsUlid())
   291  	// contains invalid characters
   292  	s.False(Of("01E65Z7XCHCR7X1P2MKF78ENR!").IsUlid())
   293  }
   294  
   295  func (s *StringTestSuite) TestIsUuid() {
   296  	s.True(Of("3f2504e0-4f89-41d3-9a0c-0305e82c3301").IsUuid())
   297  	s.False(Of("3f2504e0-4f89-41d3-9a0c-0305e82c3301-extra").IsUuid())
   298  }
   299  
   300  func (s *StringTestSuite) TestKebab() {
   301  	s.Equal("goravel-framework", Of("GoravelFramework").Kebab().String())
   302  }
   303  
   304  func (s *StringTestSuite) TestLcFirst() {
   305  	s.Equal("framework", Of("Framework").LcFirst().String())
   306  	s.Equal("framework", Of("framework").LcFirst().String())
   307  }
   308  
   309  func (s *StringTestSuite) TestLength() {
   310  	s.Equal(11, Of("foo bar baz").Length())
   311  	s.Equal(0, Of("").Length())
   312  }
   313  
   314  func (s *StringTestSuite) TestLimit() {
   315  	s.Equal("This is...", Of("This is a beautiful morning").Limit(7).String())
   316  	s.Equal("This is****", Of("This is a beautiful morning").Limit(7, "****").String())
   317  	s.Equal("这是一...", Of("这是一段中文").Limit(3).String())
   318  	s.Equal("这是一段中文", Of("这是一段中文").Limit(9).String())
   319  }
   320  
   321  func (s *StringTestSuite) TestLower() {
   322  	s.Equal("foo bar baz", Of("FOO BAR BAZ").Lower().String())
   323  	s.Equal("foo bar baz", Of("fOo Bar bAz").Lower().String())
   324  }
   325  
   326  func (s *StringTestSuite) TestLTrim() {
   327  	s.Equal("foo ", Of(" foo ").LTrim().String())
   328  }
   329  
   330  func (s *StringTestSuite) TestMask() {
   331  	s.Equal("kri**************", Of("krishan@email.com").Mask("*", 3).String())
   332  	s.Equal("*******@email.com", Of("krishan@email.com").Mask("*", 0, 7).String())
   333  	s.Equal("kris*************", Of("krishan@email.com").Mask("*", -13).String())
   334  	s.Equal("kris***@email.com", Of("krishan@email.com").Mask("*", -13, 3).String())
   335  
   336  	s.Equal("*****************", Of("krishan@email.com").Mask("*", -17).String())
   337  	s.Equal("*****an@email.com", Of("krishan@email.com").Mask("*", -99, 5).String())
   338  
   339  	s.Equal("krishan@email.com", Of("krishan@email.com").Mask("*", 17).String())
   340  	s.Equal("krishan@email.com", Of("krishan@email.com").Mask("*", 17, 99).String())
   341  
   342  	s.Equal("krishan@email.com", Of("krishan@email.com").Mask("", 3).String())
   343  
   344  	s.Equal("krissssssssssssss", Of("krishan@email.com").Mask("something", 3).String())
   345  
   346  	s.Equal("这是一***", Of("这是一段中文").Mask("*", 3).String())
   347  	s.Equal("**一段中文", Of("这是一段中文").Mask("*", 0, 2).String())
   348  }
   349  
   350  func (s *StringTestSuite) TestMatch() {
   351  	s.Equal("World", Of("Hello, World!").Match("World").String())
   352  	s.Equal("(test)", Of("This is a (test) string").Match(`\([^)]+\)`).String())
   353  	s.Equal("123", Of("abc123def456def").Match(`\d+`).String())
   354  	s.Equal("", Of("No match here").Match(`\d+`).String())
   355  	s.Equal("Hello, World!", Of("Hello, World!").Match("").String())
   356  	s.Equal("[456]", Of("123 [456]").Match(`\[456\]`).String())
   357  }
   358  
   359  func (s *StringTestSuite) TestMatchAll() {
   360  	s.Equal([]string{"World"}, Of("Hello, World!").MatchAll("World"))
   361  	s.Equal([]string{"(test)"}, Of("This is a (test) string").MatchAll(`\([^)]+\)`))
   362  	s.Equal([]string{"123", "456"}, Of("abc123def456def").MatchAll(`\d+`))
   363  	s.Equal([]string(nil), Of("No match here").MatchAll(`\d+`))
   364  	s.Equal([]string{"Hello, World!"}, Of("Hello, World!").MatchAll(""))
   365  	s.Equal([]string{"[456]"}, Of("123 [456]").MatchAll(`\[456\]`))
   366  }
   367  
   368  func (s *StringTestSuite) TestIsMatch() {
   369  	// Test matching with a single pattern
   370  	s.True(Of("Hello, Goravel!").IsMatch(`.*,.*!`))
   371  	s.True(Of("Hello, Goravel!").IsMatch(`^.*$(.*)`))
   372  	s.True(Of("Hello, Goravel!").IsMatch(`(?i)goravel`))
   373  	s.True(Of("Hello, GOravel!").IsMatch(`^(.*(.*(.*)))`))
   374  
   375  	// Test non-matching with a single pattern
   376  	s.False(Of("Hello, Goravel!").IsMatch(`H.o`))
   377  	s.False(Of("Hello, Goravel!").IsMatch(`^goravel!`))
   378  	s.False(Of("Hello, Goravel!").IsMatch(`goravel!(.*)`))
   379  	s.False(Of("Hello, Goravel!").IsMatch(`^[a-zA-Z,!]+$`))
   380  
   381  	// Test with multiple patterns
   382  	s.True(Of("Hello, Goravel!").IsMatch(`.*,.*!`, `H.o`))
   383  	s.True(Of("Hello, Goravel!").IsMatch(`(?i)goravel`, `^.*$(.*)`))
   384  	s.True(Of("Hello, Goravel!").IsMatch(`(?i)goravel`, `goravel!(.*)`))
   385  	s.True(Of("Hello, Goravel!").IsMatch(`^[a-zA-Z,!]+$`, `^(.*(.*(.*)))`))
   386  }
   387  
   388  func (s *StringTestSuite) TestNewLine() {
   389  	s.Equal("Goravel\n", Of("Goravel").NewLine().String())
   390  	s.Equal("Goravel\n\nbar", Of("Goravel").NewLine(2).Append("bar").String())
   391  }
   392  
   393  func (s *StringTestSuite) TestPadBoth() {
   394  	// Test padding with spaces
   395  	s.Equal("   Hello   ", Of("Hello").PadBoth(11, " ").String())
   396  	s.Equal("  World!  ", Of("World!").PadBoth(10, " ").String())
   397  	s.Equal("==Hello===", Of("Hello").PadBoth(10, "=").String())
   398  	s.Equal("Hello", Of("Hello").PadBoth(3, " ").String())
   399  	s.Equal("      ", Of("").PadBoth(6, " ").String())
   400  }
   401  
   402  func (s *StringTestSuite) TestPadLeft() {
   403  	s.Equal("   Goravel", Of("Goravel").PadLeft(10, " ").String())
   404  	s.Equal("==Goravel", Of("Goravel").PadLeft(9, "=").String())
   405  	s.Equal("Goravel", Of("Goravel").PadLeft(3, " ").String())
   406  }
   407  
   408  func (s *StringTestSuite) TestPadRight() {
   409  	s.Equal("Goravel   ", Of("Goravel").PadRight(10, " ").String())
   410  	s.Equal("Goravel==", Of("Goravel").PadRight(9, "=").String())
   411  	s.Equal("Goravel", Of("Goravel").PadRight(3, " ").String())
   412  }
   413  
   414  func (s *StringTestSuite) TestPipe() {
   415  	callback := func(str string) string {
   416  		return Of(str).Append("bar").String()
   417  	}
   418  	s.Equal("foobar", Of("foo").Pipe(callback).String())
   419  }
   420  
   421  func (s *StringTestSuite) TestPrepend() {
   422  	s.Equal("foobar", Of("bar").Prepend("foo").String())
   423  	s.Equal("foobar", Of("bar").Prepend("foo").Prepend("").String())
   424  	s.Equal("foobar", Of("bar").Prepend("foo").Prepend().String())
   425  }
   426  
   427  func (s *StringTestSuite) TestRemove() {
   428  	s.Equal("Fbar", Of("Foobar").Remove("o").String())
   429  	s.Equal("Foo", Of("Foobar").Remove("bar").String())
   430  	s.Equal("oobar", Of("Foobar").Remove("F").String())
   431  	s.Equal("Foobar", Of("Foobar").Remove("f").String())
   432  
   433  	s.Equal("Fbr", Of("Foobar").Remove("o", "a").String())
   434  	s.Equal("Fooar", Of("Foobar").Remove("f", "b").String())
   435  	s.Equal("Foobar", Of("Foo|bar").Remove("f", "|").String())
   436  }
   437  
   438  func (s *StringTestSuite) TestRepeat() {
   439  	s.Equal("aaaaa", Of("a").Repeat(5).String())
   440  	s.Equal("", Of("").Repeat(5).String())
   441  }
   442  
   443  func (s *StringTestSuite) TestReplace() {
   444  	s.Equal("foo/foo/foo", Of("?/?/?").Replace("?", "foo").String())
   445  	s.Equal("foo/foo/foo", Of("x/x/x").Replace("X", "foo", false).String())
   446  	s.Equal("bar/bar", Of("?/?").Replace("?", "bar").String())
   447  	s.Equal("?/?/?", Of("? ? ?").Replace(" ", "/").String())
   448  }
   449  
   450  func (s *StringTestSuite) TestReplaceEnd() {
   451  	s.Equal("Golang is great!", Of("Golang is good!").ReplaceEnd("good!", "great!").String())
   452  	s.Equal("Hello, World!", Of("Hello, Earth!").ReplaceEnd("Earth!", "World!").String())
   453  	s.Equal("München Berlin", Of("München Frankfurt").ReplaceEnd("Frankfurt", "Berlin").String())
   454  	s.Equal("Café Latte", Of("Café Americano").ReplaceEnd("Americano", "Latte").String())
   455  	s.Equal("Golang is good!", Of("Golang is good!").ReplaceEnd("", "great!").String())
   456  	s.Equal("Golang is good!", Of("Golang is good!").ReplaceEnd("excellent!", "great!").String())
   457  }
   458  
   459  func (s *StringTestSuite) TestReplaceFirst() {
   460  	s.Equal("fooqux foobar", Of("foobar foobar").ReplaceFirst("bar", "qux").String())
   461  	s.Equal("foo/qux? foo/bar?", Of("foo/bar? foo/bar?").ReplaceFirst("bar?", "qux?").String())
   462  	s.Equal("foo foobar", Of("foobar foobar").ReplaceFirst("bar", "").String())
   463  	s.Equal("foobar foobar", Of("foobar foobar").ReplaceFirst("xxx", "yyy").String())
   464  	s.Equal("foobar foobar", Of("foobar foobar").ReplaceFirst("", "yyy").String())
   465  	// Test for multibyte string support
   466  	s.Equal("Jxxxnköping Malmö", Of("Jönköping Malmö").ReplaceFirst("ö", "xxx").String())
   467  	s.Equal("Jönköping Malmö", Of("Jönköping Malmö").ReplaceFirst("", "yyy").String())
   468  }
   469  
   470  func (s *StringTestSuite) TestReplaceLast() {
   471  	s.Equal("foobar fooqux", Of("foobar foobar").ReplaceLast("bar", "qux").String())
   472  	s.Equal("foo/bar? foo/qux?", Of("foo/bar? foo/bar?").ReplaceLast("bar?", "qux?").String())
   473  	s.Equal("foobar foo", Of("foobar foobar").ReplaceLast("bar", "").String())
   474  	s.Equal("foobar foobar", Of("foobar foobar").ReplaceLast("xxx", "yyy").String())
   475  	s.Equal("foobar foobar", Of("foobar foobar").ReplaceLast("", "yyy").String())
   476  	// Test for multibyte string support
   477  	s.Equal("Malmö Jönkxxxping", Of("Malmö Jönköping").ReplaceLast("ö", "xxx").String())
   478  	s.Equal("Malmö Jönköping", Of("Malmö Jönköping").ReplaceLast("", "yyy").String())
   479  }
   480  
   481  func (s *StringTestSuite) TestReplaceMatches() {
   482  	s.Equal("Golang is great!", Of("Golang is good!").ReplaceMatches("good", "great").String())
   483  	s.Equal("Hello, World!", Of("Hello, Earth!").ReplaceMatches("Earth", "World").String())
   484  	s.Equal("Apples, Apples, Apples", Of("Oranges, Oranges, Oranges").ReplaceMatches("Oranges", "Apples").String())
   485  	s.Equal("1, 2, 3, 4, 5", Of("10, 20, 30, 40, 50").ReplaceMatches("0", "").String())
   486  	s.Equal("München Berlin", Of("München Frankfurt").ReplaceMatches("Frankfurt", "Berlin").String())
   487  	s.Equal("Café Latte", Of("Café Americano").ReplaceMatches("Americano", "Latte").String())
   488  	s.Equal("The quick brown fox", Of("The quick brown fox").ReplaceMatches(`\b([a-z])`, `$1`).String())
   489  	s.Equal("One, One, One", Of("1, 2, 3").ReplaceMatches(`\d`, "One").String())
   490  	s.Equal("Hello, World!", Of("Hello, World!").ReplaceMatches("Earth", "").String())
   491  	s.Equal("Hello, World!", Of("Hello, World!").ReplaceMatches("Golang", "Great").String())
   492  }
   493  
   494  func (s *StringTestSuite) TestReplaceStart() {
   495  	s.Equal("foobar foobar", Of("foobar foobar").ReplaceStart("bar", "qux").String())
   496  	s.Equal("foo/bar? foo/bar?", Of("foo/bar? foo/bar?").ReplaceStart("bar?", "qux?").String())
   497  	s.Equal("quxbar foobar", Of("foobar foobar").ReplaceStart("foo", "qux").String())
   498  	s.Equal("qux? foo/bar?", Of("foo/bar? foo/bar?").ReplaceStart("foo/bar?", "qux?").String())
   499  	s.Equal("bar foobar", Of("foobar foobar").ReplaceStart("foo", "").String())
   500  	s.Equal("1", Of("0").ReplaceStart("0", "1").String())
   501  	// Test for multibyte string support
   502  	s.Equal("xxxnköping Malmö", Of("Jönköping Malmö").ReplaceStart("Jö", "xxx").String())
   503  	s.Equal("Jönköping Malmö", Of("Jönköping Malmö").ReplaceStart("", "yyy").String())
   504  }
   505  
   506  func (s *StringTestSuite) TestRTrim() {
   507  	s.Equal(" foo", Of(" foo ").RTrim().String())
   508  	s.Equal(" foo", Of(" foo__").RTrim("_").String())
   509  }
   510  
   511  func (s *StringTestSuite) TestSnake() {
   512  	s.Equal("goravel_g_o_framework", Of("GoravelGOFramework").Snake().String())
   513  	s.Equal("goravel_go_framework", Of("GoravelGoFramework").Snake().String())
   514  	s.Equal("goravel go framework", Of("GoravelGoFramework").Snake(" ").String())
   515  	s.Equal("goravel_go_framework", Of("Goravel Go Framework").Snake().String())
   516  	s.Equal("goravel_go_framework", Of("Goravel    Go      Framework   ").Snake().String())
   517  	s.Equal("goravel__go__framework", Of("GoravelGoFramework").Snake("__").String())
   518  	s.Equal("żółta_łódka", Of("ŻółtaŁódka").Snake().String())
   519  }
   520  
   521  func (s *StringTestSuite) TestSplit() {
   522  	s.Equal([]string{"one", "two", "three", "four"}, Of("one-two-three-four").Split("-"))
   523  	s.Equal([]string{"", "", "D", "E", "", ""}, Of(",,D,E,,").Split(","))
   524  	s.Equal([]string{"one", "two", "three,four"}, Of("one,two,three,four").Split(",", 3))
   525  }
   526  
   527  func (s *StringTestSuite) TestSquish() {
   528  	s.Equal("Hello World", Of("  Hello   World  ").Squish().String())
   529  	s.Equal("A B C", Of("A  B  C").Squish().String())
   530  	s.Equal("Lorem ipsum dolor sit amet", Of(" Lorem   ipsum \n  dolor  sit \t amet ").Squish().String())
   531  	s.Equal("Leading and trailing spaces", Of("  Leading  "+
   532  		"and trailing "+
   533  		" spaces  ").Squish().String())
   534  	s.Equal("", Of("").Squish().String())
   535  }
   536  
   537  func (s *StringTestSuite) TestStart() {
   538  	s.Equal("/test/string", Of("test/string").Start("/").String())
   539  	s.Equal("/test/string", Of("/test/string").Start("/").String())
   540  	s.Equal("/test/string", Of("//test/string").Start("/").String())
   541  }
   542  
   543  func (s *StringTestSuite) TestStartsWith() {
   544  	s.True(Of("Wenbo Han").StartsWith("Wen"))
   545  	s.True(Of("Wenbo Han").StartsWith("Wenbo"))
   546  	s.True(Of("Wenbo Han").StartsWith("Han", "Wen"))
   547  	s.False(Of("Wenbo Han").StartsWith())
   548  	s.False(Of("Wenbo Han").StartsWith("we"))
   549  	s.True(Of("Jönköping").StartsWith("Jö"))
   550  	s.False(Of("Jönköping").StartsWith("Jonko"))
   551  }
   552  
   553  func (s *StringTestSuite) TestStudly() {
   554  	s.Equal("GoravelGOFramework", Of("Goravel_g_o_framework").Studly().String())
   555  	s.Equal("GoravelGOFramework", Of("Goravel_gO_framework").Studly().String())
   556  	s.Equal("GoravelGoFramework", Of("Goravel -_- go -_-  framework  ").Studly().String())
   557  
   558  	s.Equal("FooBar", Of("FooBar").Studly().String())
   559  	s.Equal("FooBar", Of("foo_bar").Studly().String())
   560  	s.Equal("FooBar", Of("foo-Bar").Studly().String())
   561  	s.Equal("FooBar", Of("foo bar").Studly().String())
   562  	s.Equal("FooBar", Of("foo.bar").Studly().String())
   563  }
   564  
   565  func (s *StringTestSuite) TestSubstr() {
   566  	s.Equal("Ё", Of("БГДЖИЛЁ").Substr(-1).String())
   567  	s.Equal("ЛЁ", Of("БГДЖИЛЁ").Substr(-2).String())
   568  	s.Equal("И", Of("БГДЖИЛЁ").Substr(-3, 1).String())
   569  	s.Equal("ДЖИЛ", Of("БГДЖИЛЁ").Substr(2, -1).String())
   570  	s.Equal("", Of("БГДЖИЛЁ").Substr(4, -4).String())
   571  	s.Equal("ИЛ", Of("БГДЖИЛЁ").Substr(-3, -1).String())
   572  	s.Equal("ГДЖИЛЁ", Of("БГДЖИЛЁ").Substr(1).String())
   573  	s.Equal("ГДЖ", Of("БГДЖИЛЁ").Substr(1, 3).String())
   574  	s.Equal("БГДЖ", Of("БГДЖИЛЁ").Substr(0, 4).String())
   575  	s.Equal("Ё", Of("БГДЖИЛЁ").Substr(-1, 1).String())
   576  	s.Equal("", Of("Б").Substr(2).String())
   577  }
   578  
   579  func (s *StringTestSuite) TestSwap() {
   580  	s.Equal("Go is excellent", Of("Golang is awesome").Swap(map[string]string{
   581  		"Golang":  "Go",
   582  		"awesome": "excellent",
   583  	}).String())
   584  	s.Equal("Golang is awesome", Of("Golang is awesome").Swap(map[string]string{}).String())
   585  	s.Equal("Golang is awesome", Of("Golang is awesome").Swap(map[string]string{
   586  		"":        "Go",
   587  		"awesome": "excellent",
   588  	}).String())
   589  }
   590  
   591  func (s *StringTestSuite) TestTap() {
   592  	tap := Of("foobarbaz")
   593  	fromTehTap := ""
   594  	tap = tap.Tap(func(s String) {
   595  		fromTehTap = s.Substr(0, 3).String()
   596  	})
   597  	s.Equal("foo", fromTehTap)
   598  	s.Equal("foobarbaz", tap.String())
   599  }
   600  
   601  func (s *StringTestSuite) TestTitle() {
   602  	s.Equal("Krishan Kumar", Of("krishan kumar").Title().String())
   603  	s.Equal("Krishan Kumar", Of("kriSHan kuMAr").Title().String())
   604  }
   605  
   606  func (s *StringTestSuite) TestTrim() {
   607  	s.Equal("foo", Of(" foo ").Trim().String())
   608  	s.Equal("foo", Of("_foo_").Trim("_").String())
   609  }
   610  
   611  func (s *StringTestSuite) TestUcFirst() {
   612  	s.Equal("", Of("").UcFirst().String())
   613  	s.Equal("Framework", Of("framework").UcFirst().String())
   614  	s.Equal("Framework", Of("Framework").UcFirst().String())
   615  	s.Equal(" framework", Of(" framework").UcFirst().String())
   616  	s.Equal("Goravel framework", Of("goravel framework").UcFirst().String())
   617  }
   618  
   619  func (s *StringTestSuite) TestUcSplit() {
   620  	s.Equal([]string{"Krishan", "Kumar"}, Of("KrishanKumar").UcSplit())
   621  	s.Equal([]string{"Hello", "From", "Goravel"}, Of("HelloFromGoravel").UcSplit())
   622  	s.Equal([]string{"He_llo_", "World"}, Of("He_llo_World").UcSplit())
   623  }
   624  
   625  func (s *StringTestSuite) TestUnless() {
   626  	str := Of("Hello, World!")
   627  
   628  	// Test case 1: The callback returns true, so the fallback should not be applied
   629  	s.Equal("Hello, World!", str.Unless(func(s *String) bool {
   630  		return true
   631  	}, func(s *String) *String {
   632  		return Of("This should not be applied")
   633  	}).String())
   634  
   635  	// Test case 2: The callback returns false, so the fallback should be applied
   636  	s.Equal("Fallback Applied", str.Unless(func(s *String) bool {
   637  		return false
   638  	}, func(s *String) *String {
   639  		return Of("Fallback Applied")
   640  	}).String())
   641  
   642  	// Test case 3: Testing with an empty string
   643  	s.Equal("Fallback Applied", Of("").Unless(func(s *String) bool {
   644  		return false
   645  	}, func(s *String) *String {
   646  		return Of("Fallback Applied")
   647  	}).String())
   648  }
   649  
   650  func (s *StringTestSuite) TestUpper() {
   651  	s.Equal("FOO BAR BAZ", Of("foo bar baz").Upper().String())
   652  	s.Equal("FOO BAR BAZ", Of("foO bAr BaZ").Upper().String())
   653  }
   654  
   655  func (s *StringTestSuite) TestWhen() {
   656  	// true
   657  	s.Equal("when true", Of("when ").When(true, func(s *String) *String {
   658  		return s.Append("true")
   659  	}).String())
   660  	s.Equal("gets a value from if", Of("gets a value ").When(true, func(s *String) *String {
   661  		return s.Append("from if")
   662  	}).String())
   663  
   664  	// false
   665  	s.Equal("when", Of("when").When(false, func(s *String) *String {
   666  		return s.Append("true")
   667  	}).String())
   668  
   669  	s.Equal("when false fallbacks to default", Of("when false ").When(false, func(s *String) *String {
   670  		return s.Append("true")
   671  	}, func(s *String) *String {
   672  		return s.Append("fallbacks to default")
   673  	}).String())
   674  }
   675  
   676  func (s *StringTestSuite) TestWhenContains() {
   677  	s.Equal("Tony Stark", Of("stark").WhenContains("tar", func(s *String) *String {
   678  		return s.Prepend("Tony ").Title()
   679  	}, func(s *String) *String {
   680  		return s.Prepend("Arno ").Title()
   681  	}).String())
   682  
   683  	s.Equal("stark", Of("stark").WhenContains("xxx", func(s *String) *String {
   684  		return s.Prepend("Tony ").Title()
   685  	}).String())
   686  
   687  	s.Equal("Arno Stark", Of("stark").WhenContains("xxx", func(s *String) *String {
   688  		return s.Prepend("Tony ").Title()
   689  	}, func(s *String) *String {
   690  		return s.Prepend("Arno ").Title()
   691  	}).String())
   692  }
   693  
   694  func (s *StringTestSuite) TestWhenContainsAll() {
   695  	// Test when all values are present
   696  	s.Equal("Tony Stark", Of("tony stark").WhenContainsAll([]string{"tony", "stark"},
   697  		func(s *String) *String {
   698  			return s.Title()
   699  		},
   700  		func(s *String) *String {
   701  			return s.Studly()
   702  		},
   703  	).String())
   704  
   705  	// Test when not all values are present
   706  	s.Equal("tony stark", Of("tony stark").WhenContainsAll([]string{"xxx"},
   707  		func(s *String) *String {
   708  			return s.Title()
   709  		},
   710  	).String())
   711  
   712  	// Test when some values are present and some are not
   713  	s.Equal("TonyStark", Of("tony stark").WhenContainsAll([]string{"tony", "xxx"},
   714  		func(s *String) *String {
   715  			return s.Title()
   716  		},
   717  		func(s *String) *String {
   718  			return s.Studly()
   719  		},
   720  	).String())
   721  }
   722  
   723  func (s *StringTestSuite) TestWhenEmpty() {
   724  	// Test when the string is empty
   725  	s.Equal("DEFAULT", Of("").WhenEmpty(
   726  		func(s *String) *String {
   727  			return s.Append("default").Upper()
   728  		}).String())
   729  
   730  	// Test when the string is not empty
   731  	s.Equal("non-empty", Of("non-empty").WhenEmpty(
   732  		func(s *String) *String {
   733  			return s.Append("default")
   734  		},
   735  	).String())
   736  }
   737  
   738  func (s *StringTestSuite) TestWhenIsAscii() {
   739  	s.Equal("Ascii: A", Of("A").WhenIsAscii(
   740  		func(s *String) *String {
   741  			return s.Prepend("Ascii: ")
   742  		}).String())
   743  	s.Equal("ù", Of("ù").WhenIsAscii(
   744  		func(s *String) *String {
   745  			return s.Prepend("Ascii: ")
   746  		}).String())
   747  	s.Equal("Not Ascii: ù", Of("ù").WhenIsAscii(
   748  		func(s *String) *String {
   749  			return s.Prepend("Ascii: ")
   750  		},
   751  		func(s *String) *String {
   752  			return s.Prepend("Not Ascii: ")
   753  		},
   754  	).String())
   755  }
   756  
   757  func (s *StringTestSuite) TestWhenNotEmpty() {
   758  	// Test when the string is not empty
   759  	s.Equal("UPPERCASE", Of("uppercase").WhenNotEmpty(
   760  		func(s *String) *String {
   761  			return s.Upper()
   762  		},
   763  	).String())
   764  
   765  	// Test when the string is empty
   766  	s.Equal("", Of("").WhenNotEmpty(
   767  		func(s *String) *String {
   768  			return s.Append("not empty")
   769  		},
   770  		func(s *String) *String {
   771  			return s.Upper()
   772  		},
   773  	).String())
   774  }
   775  
   776  func (s *StringTestSuite) TestWhenStartsWith() {
   777  	// Test when the string starts with a specific prefix
   778  	s.Equal("Tony Stark", Of("tony stark").WhenStartsWith([]string{"ton"},
   779  		func(s *String) *String {
   780  			return s.Title()
   781  		},
   782  		func(s *String) *String {
   783  			return s.Studly()
   784  		},
   785  	).String())
   786  
   787  	// Test when the string starts with any of the specified prefixes
   788  	s.Equal("Tony Stark", Of("tony stark").WhenStartsWith([]string{"ton", "not"},
   789  		func(s *String) *String {
   790  			return s.Title()
   791  		},
   792  		func(s *String) *String {
   793  			return s.Studly()
   794  		},
   795  	).String())
   796  
   797  	// Test when the string does not start with the specified prefix
   798  	s.Equal("tony stark", Of("tony stark").WhenStartsWith([]string{"xxx"},
   799  		func(s *String) *String {
   800  			return s.Title()
   801  		},
   802  	).String())
   803  
   804  	// Test when the string starts with one of the specified prefixes and not the other
   805  	s.Equal("Tony Stark", Of("tony stark").WhenStartsWith([]string{"tony", "xxx"},
   806  		func(s *String) *String {
   807  			return s.Title()
   808  		},
   809  		func(s *String) *String {
   810  			return s.Studly()
   811  		},
   812  	).String())
   813  }
   814  
   815  func (s *StringTestSuite) TestWhenEndsWith() {
   816  	// Test when the string ends with a specific suffix
   817  	s.Equal("Tony Stark", Of("tony stark").WhenEndsWith([]string{"ark"},
   818  		func(s *String) *String {
   819  			return s.Title()
   820  		},
   821  		func(s *String) *String {
   822  			return s.Studly()
   823  		},
   824  	).String())
   825  
   826  	// Test when the string ends with any of the specified suffixes
   827  	s.Equal("Tony Stark", Of("tony stark").WhenEndsWith([]string{"kra", "ark"},
   828  		func(s *String) *String {
   829  			return s.Title()
   830  		},
   831  		func(s *String) *String {
   832  			return s.Studly()
   833  		},
   834  	).String())
   835  
   836  	// Test when the string does not end with the specified suffix
   837  	s.Equal("tony stark", Of("tony stark").WhenEndsWith([]string{"xxx"},
   838  		func(s *String) *String {
   839  			return s.Title()
   840  		},
   841  	).String())
   842  
   843  	// Test when the string ends with one of the specified suffixes and not the other
   844  	s.Equal("TonyStark", Of("tony stark").WhenEndsWith([]string{"tony", "xxx"},
   845  		func(s *String) *String {
   846  			return s.Title()
   847  		},
   848  		func(s *String) *String {
   849  			return s.Studly()
   850  		},
   851  	).String())
   852  }
   853  
   854  func (s *StringTestSuite) TestWhenExactly() {
   855  	// Test when the string exactly matches the expected value
   856  	s.Equal("Nailed it...!", Of("Tony Stark").WhenExactly("Tony Stark",
   857  		func(s *String) *String {
   858  			return Of("Nailed it...!")
   859  		},
   860  		func(s *String) *String {
   861  			return Of("Swing and a miss...!")
   862  		},
   863  	).String())
   864  
   865  	// Test when the string does not exactly match the expected value
   866  	s.Equal("Swing and a miss...!", Of("Tony Stark").WhenExactly("Iron Man",
   867  		func(s *String) *String {
   868  			return Of("Nailed it...!")
   869  		},
   870  		func(s *String) *String {
   871  			return Of("Swing and a miss...!")
   872  		},
   873  	).String())
   874  
   875  	// Test when the string exactly matches the expected value with no "else" callback
   876  	s.Equal("Tony Stark", Of("Tony Stark").WhenExactly("Iron Man",
   877  		func(s *String) *String {
   878  			return Of("Nailed it...!")
   879  		},
   880  	).String())
   881  }
   882  
   883  func (s *StringTestSuite) TestWhenNotExactly() {
   884  	// Test when the string does not exactly match the expected value with an "else" callback
   885  	s.Equal("Iron Man", Of("Tony").WhenNotExactly("Tony Stark",
   886  		func(s *String) *String {
   887  			return Of("Iron Man")
   888  		},
   889  	).String())
   890  
   891  	// Test when the string does not exactly match the expected value with both "if" and "else" callbacks
   892  	s.Equal("Swing and a miss...!", Of("Tony Stark").WhenNotExactly("Tony Stark",
   893  		func(s *String) *String {
   894  			return Of("Iron Man")
   895  		},
   896  		func(s *String) *String {
   897  			return Of("Swing and a miss...!")
   898  		},
   899  	).String())
   900  }
   901  
   902  func (s *StringTestSuite) TestWhenIs() {
   903  	// Test when the string exactly matches the expected value with an "if" callback
   904  	s.Equal("Winner: /", Of("/").WhenIs("/",
   905  		func(s *String) *String {
   906  			return s.Prepend("Winner: ")
   907  		},
   908  		func(s *String) *String {
   909  			return Of("Try again")
   910  		},
   911  	).String())
   912  
   913  	// Test when the string does not exactly match the expected value with an "if" callback
   914  	s.Equal("/", Of("/").WhenIs(" /",
   915  		func(s *String) *String {
   916  			return s.Prepend("Winner: ")
   917  		},
   918  	).String())
   919  
   920  	// Test when the string does not exactly match the expected value with both "if" and "else" callbacks
   921  	s.Equal("Try again", Of("/").WhenIs(" /",
   922  		func(s *String) *String {
   923  			return s.Prepend("Winner: ")
   924  		},
   925  		func(s *String) *String {
   926  			return Of("Try again")
   927  		},
   928  	).String())
   929  
   930  	// Test when the string matches a pattern using wildcard and "if" callback
   931  	s.Equal("Winner: foo/bar/baz", Of("foo/bar/baz").WhenIs("foo/*",
   932  		func(s *String) *String {
   933  			return s.Prepend("Winner: ")
   934  		},
   935  	).String())
   936  }
   937  
   938  func (s *StringTestSuite) TestWhenIsUlid() {
   939  	// Test when the string is a valid ULID with an "if" callback
   940  	s.Equal("Ulid: 01GJSNW9MAF792C0XYY8RX6QFT", Of("01GJSNW9MAF792C0XYY8RX6QFT").WhenIsUlid(
   941  		func(s *String) *String {
   942  			return s.Prepend("Ulid: ")
   943  		},
   944  		func(s *String) *String {
   945  			return s.Prepend("Not Ulid: ")
   946  		},
   947  	).String())
   948  
   949  	// Test when the string is not a valid ULID with an "if" callback
   950  	s.Equal("2cdc7039-65a6-4ac7-8e5d-d554a98", Of("2cdc7039-65a6-4ac7-8e5d-d554a98").WhenIsUlid(
   951  		func(s *String) *String {
   952  			return s.Prepend("Ulid: ")
   953  		},
   954  	).String())
   955  
   956  	// Test when the string is not a valid ULID with both "if" and "else" callbacks
   957  	s.Equal("Not Ulid: ss-01GJSNW9MAF792C0XYY8RX6QFT", Of("ss-01GJSNW9MAF792C0XYY8RX6QFT").WhenIsUlid(
   958  		func(s *String) *String {
   959  			return s.Prepend("Ulid: ")
   960  		},
   961  		func(s *String) *String {
   962  			return s.Prepend("Not Ulid: ")
   963  		},
   964  	).String())
   965  }
   966  
   967  func (s *StringTestSuite) TestWhenIsUuid() {
   968  	// Test when the string is a valid UUID with an "if" callback
   969  	s.Equal("Uuid: 2cdc7039-65a6-4ac7-8e5d-d554a98e7b15", Of("2cdc7039-65a6-4ac7-8e5d-d554a98e7b15").WhenIsUuid(
   970  		func(s *String) *String {
   971  			return s.Prepend("Uuid: ")
   972  		},
   973  		func(s *String) *String {
   974  			return s.Prepend("Not Uuid: ")
   975  		},
   976  	).String())
   977  
   978  	s.Equal("2cdc7039-65a6-4ac7-8e5d-d554a98", Of("2cdc7039-65a6-4ac7-8e5d-d554a98").WhenIsUuid(
   979  		func(s *String) *String {
   980  			return s.Prepend("Uuid: ")
   981  		},
   982  	).String())
   983  
   984  	s.Equal("Not Uuid: 2cdc7039-65a6-4ac7-8e5d-d554a98", Of("2cdc7039-65a6-4ac7-8e5d-d554a98").WhenIsUuid(
   985  		func(s *String) *String {
   986  			return s.Prepend("Uuid: ")
   987  		},
   988  		func(s *String) *String {
   989  			return s.Prepend("Not Uuid: ")
   990  		},
   991  	).String())
   992  }
   993  
   994  func (s *StringTestSuite) TestWhenTest() {
   995  	// Test when the regular expression matches with an "if" callback
   996  	s.Equal("Winner: foo bar", Of("foo bar").WhenTest(`bar*`,
   997  		func(s *String) *String {
   998  			return s.Prepend("Winner: ")
   999  		},
  1000  		func(s *String) *String {
  1001  			return Of("Try again")
  1002  		},
  1003  	).String())
  1004  
  1005  	// Test when the regular expression does not match with an "if" callback
  1006  	s.Equal("Try again", Of("foo bar").WhenTest(`/link/`,
  1007  		func(s *String) *String {
  1008  			return s.Prepend("Winner: ")
  1009  		},
  1010  		func(s *String) *String {
  1011  			return Of("Try again")
  1012  		},
  1013  	).String())
  1014  
  1015  	// Test when the regular expression does not match with both "if" and "else" callbacks
  1016  	s.Equal("foo bar", Of("foo bar").WhenTest(`/link/`,
  1017  		func(s *String) *String {
  1018  			return s.Prepend("Winner: ")
  1019  		},
  1020  	).String())
  1021  }
  1022  
  1023  func (s *StringTestSuite) TestWordCount() {
  1024  	s.Equal(2, Of("Hello, world!").WordCount())
  1025  	s.Equal(10, Of("Hi, this is my first contribution to the Goravel framework.").WordCount())
  1026  }
  1027  
  1028  func (s *StringTestSuite) TestWords() {
  1029  	s.Equal("Perfectly balanced, as >>>", Of("Perfectly balanced, as all things should be.").Words(3, " >>>").String())
  1030  	s.Equal("Perfectly balanced, as all things should be.", Of("Perfectly balanced, as all things should be.").Words(100).String())
  1031  }
  1032  
  1033  func TestFieldsFunc(t *testing.T) {
  1034  	tests := []struct {
  1035  		input          string
  1036  		shouldPreserve []func(rune) bool
  1037  		expected       []string
  1038  	}{
  1039  		// Test case 1: Basic word splitting with space separator.
  1040  		{
  1041  			input:    "Hello World",
  1042  			expected: []string{"Hello", "World"},
  1043  		},
  1044  		// Test case 2: Splitting with space and preserving hyphen.
  1045  		{
  1046  			input:          "Hello-World",
  1047  			shouldPreserve: []func(rune) bool{func(r rune) bool { return r == '-' }},
  1048  			expected:       []string{"Hello", "-World"},
  1049  		},
  1050  		// Test case 3: Splitting with space and preserving multiple characters.
  1051  		{
  1052  			input: "Hello-World,This,Is,a,Test",
  1053  			shouldPreserve: []func(rune) bool{
  1054  				func(r rune) bool { return r == '-' },
  1055  				func(r rune) bool { return r == ',' },
  1056  			},
  1057  			expected: []string{"Hello", "-World", ",This", ",Is", ",a", ",Test"},
  1058  		},
  1059  		// Test case 4: No splitting when no separator is found.
  1060  		{
  1061  			input:    "HelloWorld",
  1062  			expected: []string{"HelloWorld"},
  1063  		},
  1064  	}
  1065  
  1066  	for _, test := range tests {
  1067  		t.Run(test.input, func(t *testing.T) {
  1068  			result := fieldsFunc(test.input, func(r rune) bool { return r == ' ' }, test.shouldPreserve...)
  1069  			assert.Equal(t, test.expected, result)
  1070  		})
  1071  	}
  1072  }
  1073  
  1074  func TestSubstr(t *testing.T) {
  1075  	assert.Equal(t, "world", Substr("Hello, world!", 7, 5))
  1076  	assert.Equal(t, "", Substr("Golang", 10))
  1077  	assert.Equal(t, "tine", Substr("Goroutines", -5, 4))
  1078  	assert.Equal(t, "ic", Substr("Unicode", 2, -3))
  1079  	assert.Equal(t, "esting", Substr("Testing", 1, 10))
  1080  	assert.Equal(t, "", Substr("", 0, 5))
  1081  	assert.Equal(t, "世界!", Substr("你好,世界!", 3, 3))
  1082  }
  1083  
  1084  func TestMaximum(t *testing.T) {
  1085  	assert.Equal(t, 10, maximum(5, 10))
  1086  	assert.Equal(t, 3.14, maximum(3.14, 2.71))
  1087  	assert.Equal(t, "banana", maximum("apple", "banana"))
  1088  	assert.Equal(t, -5, maximum(-5, -10))
  1089  	assert.Equal(t, 42, maximum(42, 42))
  1090  }
  1091  
  1092  func TestRandom(t *testing.T) {
  1093  	assert.Len(t, Random(10), 10)
  1094  	assert.Empty(t, Random(0))
  1095  	assert.Panics(t, func() {
  1096  		Random(-1)
  1097  	})
  1098  }
  1099  
  1100  func TestCase2Camel(t *testing.T) {
  1101  	assert.Equal(t, "GoravelFramework", Case2Camel("goravel_framework"))
  1102  	assert.Equal(t, "GoravelFramework1", Case2Camel("goravel_framework1"))
  1103  	assert.Equal(t, "GoravelFramework", Case2Camel("GoravelFramework"))
  1104  }
  1105  
  1106  func TestCamel2Case(t *testing.T) {
  1107  	assert.Equal(t, "goravel_framework", Camel2Case("GoravelFramework"))
  1108  	assert.Equal(t, "goravel_framework1", Camel2Case("GoravelFramework1"))
  1109  	assert.Equal(t, "goravel_framework", Camel2Case("goravel_framework"))
  1110  }