github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/tpl/strings/strings_test.go (about)

     1  // Copyright 2017 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package strings
    15  
    16  import (
    17  	"html/template"
    18  	"testing"
    19  
    20  	"github.com/gohugoio/hugo/config"
    21  	"github.com/gohugoio/hugo/deps"
    22  
    23  	qt "github.com/frankban/quicktest"
    24  	"github.com/spf13/cast"
    25  )
    26  
    27  var ns = New(&deps.Deps{Cfg: config.New()})
    28  
    29  type tstNoStringer struct{}
    30  
    31  func TestChomp(t *testing.T) {
    32  	t.Parallel()
    33  	c := qt.New(t)
    34  
    35  	for _, test := range []struct {
    36  		s      interface{}
    37  		expect interface{}
    38  	}{
    39  		{"\n a\n", "\n a"},
    40  		{"\n a\n\n", "\n a"},
    41  		{"\n a\r\n", "\n a"},
    42  		{"\n a\n\r\n", "\n a"},
    43  		{"\n a\r\r", "\n a"},
    44  		{"\n a\r", "\n a"},
    45  		// errors
    46  		{tstNoStringer{}, false},
    47  	} {
    48  
    49  		result, err := ns.Chomp(test.s)
    50  
    51  		if b, ok := test.expect.(bool); ok && !b {
    52  			c.Assert(err, qt.Not(qt.IsNil))
    53  			continue
    54  		}
    55  
    56  		c.Assert(err, qt.IsNil)
    57  		c.Assert(result, qt.Equals, test.expect)
    58  
    59  		// repeat the check with template.HTML input
    60  		result, err = ns.Chomp(template.HTML(cast.ToString(test.s)))
    61  		c.Assert(err, qt.IsNil)
    62  		c.Assert(result, qt.Equals, template.HTML(cast.ToString(test.expect)))
    63  	}
    64  }
    65  
    66  func TestContains(t *testing.T) {
    67  	t.Parallel()
    68  	c := qt.New(t)
    69  
    70  	for _, test := range []struct {
    71  		s      interface{}
    72  		substr interface{}
    73  		expect bool
    74  		isErr  bool
    75  	}{
    76  		{"", "", true, false},
    77  		{"123", "23", true, false},
    78  		{"123", "234", false, false},
    79  		{"123", "", true, false},
    80  		{"", "a", false, false},
    81  		{123, "23", true, false},
    82  		{123, "234", false, false},
    83  		{123, "", true, false},
    84  		{template.HTML("123"), []byte("23"), true, false},
    85  		{template.HTML("123"), []byte("234"), false, false},
    86  		{template.HTML("123"), []byte(""), true, false},
    87  		// errors
    88  		{"", tstNoStringer{}, false, true},
    89  		{tstNoStringer{}, "", false, true},
    90  	} {
    91  
    92  		result, err := ns.Contains(test.s, test.substr)
    93  
    94  		if test.isErr {
    95  			c.Assert(err, qt.Not(qt.IsNil))
    96  			continue
    97  		}
    98  
    99  		c.Assert(err, qt.IsNil)
   100  		c.Assert(result, qt.Equals, test.expect)
   101  	}
   102  }
   103  
   104  func TestContainsAny(t *testing.T) {
   105  	t.Parallel()
   106  	c := qt.New(t)
   107  
   108  	for _, test := range []struct {
   109  		s      interface{}
   110  		substr interface{}
   111  		expect bool
   112  		isErr  bool
   113  	}{
   114  		{"", "", false, false},
   115  		{"", "1", false, false},
   116  		{"", "123", false, false},
   117  		{"1", "", false, false},
   118  		{"1", "1", true, false},
   119  		{"111", "1", true, false},
   120  		{"123", "789", false, false},
   121  		{"123", "729", true, false},
   122  		{"a☺b☻c☹d", "uvw☻xyz", true, false},
   123  		{1, "", false, false},
   124  		{1, "1", true, false},
   125  		{111, "1", true, false},
   126  		{123, "789", false, false},
   127  		{123, "729", true, false},
   128  		{[]byte("123"), template.HTML("789"), false, false},
   129  		{[]byte("123"), template.HTML("729"), true, false},
   130  		{[]byte("a☺b☻c☹d"), template.HTML("uvw☻xyz"), true, false},
   131  		// errors
   132  		{"", tstNoStringer{}, false, true},
   133  		{tstNoStringer{}, "", false, true},
   134  	} {
   135  
   136  		result, err := ns.ContainsAny(test.s, test.substr)
   137  
   138  		if test.isErr {
   139  			c.Assert(err, qt.Not(qt.IsNil))
   140  			continue
   141  		}
   142  
   143  		c.Assert(err, qt.IsNil)
   144  		c.Assert(result, qt.Equals, test.expect)
   145  	}
   146  }
   147  
   148  func TestCountRunes(t *testing.T) {
   149  	t.Parallel()
   150  	c := qt.New(t)
   151  
   152  	for _, test := range []struct {
   153  		s      interface{}
   154  		expect interface{}
   155  	}{
   156  		{"foo bar", 6},
   157  		{"旁边", 2},
   158  		{`<div class="test">旁边</div>`, 2},
   159  		// errors
   160  		{tstNoStringer{}, false},
   161  	} {
   162  
   163  		result, err := ns.CountRunes(test.s)
   164  
   165  		if b, ok := test.expect.(bool); ok && !b {
   166  			c.Assert(err, qt.Not(qt.IsNil))
   167  			continue
   168  		}
   169  
   170  		c.Assert(err, qt.IsNil)
   171  		c.Assert(result, qt.Equals, test.expect)
   172  	}
   173  }
   174  
   175  func TestRuneCount(t *testing.T) {
   176  	t.Parallel()
   177  	c := qt.New(t)
   178  
   179  	for _, test := range []struct {
   180  		s      interface{}
   181  		expect interface{}
   182  	}{
   183  		{"foo bar", 7},
   184  		{"旁边", 2},
   185  		{`<div class="test">旁边</div>`, 26},
   186  		// errors
   187  		{tstNoStringer{}, false},
   188  	} {
   189  
   190  		result, err := ns.RuneCount(test.s)
   191  
   192  		if b, ok := test.expect.(bool); ok && !b {
   193  			c.Assert(err, qt.Not(qt.IsNil))
   194  			continue
   195  		}
   196  
   197  		c.Assert(err, qt.IsNil)
   198  		c.Assert(result, qt.Equals, test.expect)
   199  	}
   200  }
   201  
   202  func TestCountWords(t *testing.T) {
   203  	t.Parallel()
   204  	c := qt.New(t)
   205  
   206  	for _, test := range []struct {
   207  		s      interface{}
   208  		expect interface{}
   209  	}{
   210  		{"Do Be Do Be Do", 5},
   211  		{"旁边", 2},
   212  		{`<div class="test">旁边</div>`, 2},
   213  		{"Here's to you...", 3},
   214  		{"Here’s to you...", 3},
   215  		{"Here’s to you…", 3},
   216  		// errors
   217  		{tstNoStringer{}, false},
   218  	} {
   219  
   220  		result, err := ns.CountWords(test.s)
   221  
   222  		if b, ok := test.expect.(bool); ok && !b {
   223  			c.Assert(err, qt.Not(qt.IsNil))
   224  			continue
   225  		}
   226  
   227  		c.Assert(err, qt.IsNil)
   228  		c.Assert(result, qt.Equals, test.expect)
   229  	}
   230  }
   231  
   232  func TestHasPrefix(t *testing.T) {
   233  	t.Parallel()
   234  	c := qt.New(t)
   235  
   236  	for _, test := range []struct {
   237  		s      interface{}
   238  		prefix interface{}
   239  		expect interface{}
   240  		isErr  bool
   241  	}{
   242  		{"abcd", "ab", true, false},
   243  		{"abcd", "cd", false, false},
   244  		{template.HTML("abcd"), "ab", true, false},
   245  		{template.HTML("abcd"), "cd", false, false},
   246  		{template.HTML("1234"), 12, true, false},
   247  		{template.HTML("1234"), 34, false, false},
   248  		{[]byte("abcd"), "ab", true, false},
   249  		// errors
   250  		{"", tstNoStringer{}, false, true},
   251  		{tstNoStringer{}, "", false, true},
   252  	} {
   253  
   254  		result, err := ns.HasPrefix(test.s, test.prefix)
   255  
   256  		if test.isErr {
   257  			c.Assert(err, qt.Not(qt.IsNil))
   258  			continue
   259  		}
   260  
   261  		c.Assert(err, qt.IsNil)
   262  		c.Assert(result, qt.Equals, test.expect)
   263  	}
   264  }
   265  
   266  func TestHasSuffix(t *testing.T) {
   267  	t.Parallel()
   268  	c := qt.New(t)
   269  
   270  	for _, test := range []struct {
   271  		s      interface{}
   272  		suffix interface{}
   273  		expect interface{}
   274  		isErr  bool
   275  	}{
   276  		{"abcd", "cd", true, false},
   277  		{"abcd", "ab", false, false},
   278  		{template.HTML("abcd"), "cd", true, false},
   279  		{template.HTML("abcd"), "ab", false, false},
   280  		{template.HTML("1234"), 34, true, false},
   281  		{template.HTML("1234"), 12, false, false},
   282  		{[]byte("abcd"), "cd", true, false},
   283  		// errors
   284  		{"", tstNoStringer{}, false, true},
   285  		{tstNoStringer{}, "", false, true},
   286  	} {
   287  
   288  		result, err := ns.HasSuffix(test.s, test.suffix)
   289  
   290  		if test.isErr {
   291  			c.Assert(err, qt.Not(qt.IsNil))
   292  			continue
   293  		}
   294  
   295  		c.Assert(err, qt.IsNil)
   296  		c.Assert(result, qt.Equals, test.expect)
   297  	}
   298  }
   299  
   300  func TestReplace(t *testing.T) {
   301  	t.Parallel()
   302  	c := qt.New(t)
   303  
   304  	for _, test := range []struct {
   305  		s      interface{}
   306  		old    interface{}
   307  		new    interface{}
   308  		limit  interface{}
   309  		expect interface{}
   310  	}{
   311  		{"aab", "a", "b", nil, "bbb"},
   312  		{"11a11", 1, 2, nil, "22a22"},
   313  		{12345, 1, 2, nil, "22345"},
   314  		{"aab", "a", "b", 1, "bab"},
   315  		{"11a11", 1, 2, 2, "22a11"},
   316  		// errors
   317  		{tstNoStringer{}, "a", "b", nil, false},
   318  		{"a", tstNoStringer{}, "b", nil, false},
   319  		{"a", "b", tstNoStringer{}, nil, false},
   320  	} {
   321  
   322  		var (
   323  			result string
   324  			err    error
   325  		)
   326  
   327  		if test.limit != nil {
   328  			result, err = ns.Replace(test.s, test.old, test.new, test.limit)
   329  		} else {
   330  			result, err = ns.Replace(test.s, test.old, test.new)
   331  		}
   332  
   333  		if b, ok := test.expect.(bool); ok && !b {
   334  			c.Assert(err, qt.Not(qt.IsNil))
   335  			continue
   336  		}
   337  
   338  		c.Assert(err, qt.IsNil)
   339  		c.Assert(result, qt.Equals, test.expect)
   340  	}
   341  }
   342  
   343  func TestSliceString(t *testing.T) {
   344  	t.Parallel()
   345  	c := qt.New(t)
   346  
   347  	var err error
   348  	for _, test := range []struct {
   349  		v1     interface{}
   350  		v2     interface{}
   351  		v3     interface{}
   352  		expect interface{}
   353  	}{
   354  		{"abc", 1, 2, "b"},
   355  		{"abc", 1, 3, "bc"},
   356  		{"abcdef", 1, int8(3), "bc"},
   357  		{"abcdef", 1, int16(3), "bc"},
   358  		{"abcdef", 1, int32(3), "bc"},
   359  		{"abcdef", 1, int64(3), "bc"},
   360  		{"abc", 0, 1, "a"},
   361  		{"abcdef", nil, nil, "abcdef"},
   362  		{"abcdef", 0, 6, "abcdef"},
   363  		{"abcdef", 0, 2, "ab"},
   364  		{"abcdef", 2, nil, "cdef"},
   365  		{"abcdef", int8(2), nil, "cdef"},
   366  		{"abcdef", int16(2), nil, "cdef"},
   367  		{"abcdef", int32(2), nil, "cdef"},
   368  		{"abcdef", int64(2), nil, "cdef"},
   369  		{123, 1, 3, "23"},
   370  		{"abcdef", 6, nil, false},
   371  		{"abcdef", 4, 7, false},
   372  		{"abcdef", -1, nil, false},
   373  		{"abcdef", -1, 7, false},
   374  		{"abcdef", 1, -1, false},
   375  		{tstNoStringer{}, 0, 1, false},
   376  		{"ĀĀĀ", 0, 1, "Ā"}, // issue #1333
   377  		{"a", t, nil, false},
   378  		{"a", 1, t, false},
   379  	} {
   380  
   381  		var result string
   382  		if test.v2 == nil {
   383  			result, err = ns.SliceString(test.v1)
   384  		} else if test.v3 == nil {
   385  			result, err = ns.SliceString(test.v1, test.v2)
   386  		} else {
   387  			result, err = ns.SliceString(test.v1, test.v2, test.v3)
   388  		}
   389  
   390  		if b, ok := test.expect.(bool); ok && !b {
   391  			c.Assert(err, qt.Not(qt.IsNil))
   392  			continue
   393  		}
   394  
   395  		c.Assert(err, qt.IsNil)
   396  		c.Assert(result, qt.Equals, test.expect)
   397  	}
   398  
   399  	// Too many arguments
   400  	_, err = ns.SliceString("a", 1, 2, 3)
   401  	if err == nil {
   402  		t.Errorf("Should have errored")
   403  	}
   404  }
   405  
   406  func TestSplit(t *testing.T) {
   407  	t.Parallel()
   408  	c := qt.New(t)
   409  
   410  	for _, test := range []struct {
   411  		v1     interface{}
   412  		v2     string
   413  		expect interface{}
   414  	}{
   415  		{"a, b", ", ", []string{"a", "b"}},
   416  		{"a & b & c", " & ", []string{"a", "b", "c"}},
   417  		{"http://example.com", "http://", []string{"", "example.com"}},
   418  		{123, "2", []string{"1", "3"}},
   419  		{tstNoStringer{}, ",", false},
   420  	} {
   421  
   422  		result, err := ns.Split(test.v1, test.v2)
   423  
   424  		if b, ok := test.expect.(bool); ok && !b {
   425  			c.Assert(err, qt.Not(qt.IsNil))
   426  			continue
   427  		}
   428  
   429  		c.Assert(err, qt.IsNil)
   430  		c.Assert(result, qt.DeepEquals, test.expect)
   431  	}
   432  }
   433  
   434  func TestSubstr(t *testing.T) {
   435  	t.Parallel()
   436  	c := qt.New(t)
   437  
   438  	var err error
   439  	for _, test := range []struct {
   440  		v1     interface{}
   441  		v2     interface{}
   442  		v3     interface{}
   443  		expect interface{}
   444  	}{
   445  		{"abc", 1, 2, "bc"},
   446  		{"abc", 0, 1, "a"},
   447  		{"abcdef", 0, 0, ""},
   448  		{"abcdef", 1, 0, ""},
   449  		{"abcdef", -1, 0, ""},
   450  		{"abcdef", -1, 2, "f"},
   451  		{"abcdef", -3, 3, "def"},
   452  		{"abcdef", -1, nil, "f"},
   453  		{"abcdef", -2, nil, "ef"},
   454  		{"abcdef", -3, 1, "d"},
   455  		{"abcdef", 0, -1, "abcde"},
   456  		{"abcdef", 2, -1, "cde"},
   457  		{"abcdef", 4, -4, ""},
   458  		{"abcdef", 7, 1, ""},
   459  		{"abcdef", 6, nil, ""},
   460  		{"abcdef", 1, 100, "bcdef"},
   461  		{"abcdef", -100, 3, "abc"},
   462  		{"abcdef", -3, -1, "de"},
   463  		{"abcdef", 2, nil, "cdef"},
   464  		{"abcdef", int8(2), nil, "cdef"},
   465  		{"abcdef", int16(2), nil, "cdef"},
   466  		{"abcdef", int32(2), nil, "cdef"},
   467  		{"abcdef", int64(2), nil, "cdef"},
   468  		{"abcdef", 2, int8(3), "cde"},
   469  		{"abcdef", 2, int16(3), "cde"},
   470  		{"abcdef", 2, int32(3), "cde"},
   471  		{"abcdef", 2, int64(3), "cde"},
   472  		{123, 1, 3, "23"},
   473  		{1.2e3, 0, 4, "1200"},
   474  		{tstNoStringer{}, 0, 1, false},
   475  		{"abcdef", 2.0, nil, "cdef"},
   476  		{"abcdef", 2.0, 2, "cd"},
   477  		{"abcdef", 2, 2.0, "cd"},
   478  		{"ĀĀĀ", 1, 2, "ĀĀ"}, // # issue 1333
   479  		{"abcdef", "doo", nil, false},
   480  		{"abcdef", "doo", "doo", false},
   481  		{"abcdef", 1, "doo", false},
   482  		{"", 0, nil, ""},
   483  	} {
   484  
   485  		var result string
   486  
   487  		if test.v3 == nil {
   488  			result, err = ns.Substr(test.v1, test.v2)
   489  		} else {
   490  			result, err = ns.Substr(test.v1, test.v2, test.v3)
   491  		}
   492  
   493  		if b, ok := test.expect.(bool); ok && !b {
   494  			c.Check(err, qt.Not(qt.IsNil), qt.Commentf("%v", test))
   495  			continue
   496  		}
   497  
   498  		c.Assert(err, qt.IsNil, qt.Commentf("%v", test))
   499  		c.Check(result, qt.Equals, test.expect, qt.Commentf("%v", test))
   500  	}
   501  
   502  	_, err = ns.Substr("abcdef")
   503  	c.Assert(err, qt.Not(qt.IsNil))
   504  
   505  	_, err = ns.Substr("abcdef", 1, 2, 3)
   506  	c.Assert(err, qt.Not(qt.IsNil))
   507  }
   508  
   509  func TestTitle(t *testing.T) {
   510  	t.Parallel()
   511  	c := qt.New(t)
   512  
   513  	for _, test := range []struct {
   514  		s      interface{}
   515  		expect interface{}
   516  	}{
   517  		{"test", "Test"},
   518  		{template.HTML("hypertext"), "Hypertext"},
   519  		{[]byte("bytes"), "Bytes"},
   520  		// errors
   521  		{tstNoStringer{}, false},
   522  	} {
   523  
   524  		result, err := ns.Title(test.s)
   525  
   526  		if b, ok := test.expect.(bool); ok && !b {
   527  			c.Assert(err, qt.Not(qt.IsNil))
   528  			continue
   529  		}
   530  
   531  		c.Assert(err, qt.IsNil)
   532  		c.Assert(result, qt.Equals, test.expect)
   533  	}
   534  }
   535  
   536  func TestToLower(t *testing.T) {
   537  	t.Parallel()
   538  	c := qt.New(t)
   539  
   540  	for _, test := range []struct {
   541  		s      interface{}
   542  		expect interface{}
   543  	}{
   544  		{"TEST", "test"},
   545  		{template.HTML("LoWeR"), "lower"},
   546  		{[]byte("BYTES"), "bytes"},
   547  		// errors
   548  		{tstNoStringer{}, false},
   549  	} {
   550  
   551  		result, err := ns.ToLower(test.s)
   552  
   553  		if b, ok := test.expect.(bool); ok && !b {
   554  			c.Assert(err, qt.Not(qt.IsNil))
   555  			continue
   556  		}
   557  
   558  		c.Assert(err, qt.IsNil)
   559  		c.Assert(result, qt.Equals, test.expect)
   560  	}
   561  }
   562  
   563  func TestToUpper(t *testing.T) {
   564  	t.Parallel()
   565  	c := qt.New(t)
   566  
   567  	for _, test := range []struct {
   568  		s      interface{}
   569  		expect interface{}
   570  	}{
   571  		{"test", "TEST"},
   572  		{template.HTML("UpPeR"), "UPPER"},
   573  		{[]byte("bytes"), "BYTES"},
   574  		// errors
   575  		{tstNoStringer{}, false},
   576  	} {
   577  
   578  		result, err := ns.ToUpper(test.s)
   579  
   580  		if b, ok := test.expect.(bool); ok && !b {
   581  			c.Assert(err, qt.Not(qt.IsNil))
   582  			continue
   583  		}
   584  
   585  		c.Assert(err, qt.IsNil)
   586  		c.Assert(result, qt.Equals, test.expect)
   587  	}
   588  }
   589  
   590  func TestTrim(t *testing.T) {
   591  	t.Parallel()
   592  	c := qt.New(t)
   593  
   594  	for _, test := range []struct {
   595  		s      interface{}
   596  		cutset interface{}
   597  		expect interface{}
   598  	}{
   599  		{"abba", "a", "bb"},
   600  		{"abba", "ab", ""},
   601  		{"<tag>", "<>", "tag"},
   602  		{`"quote"`, `"`, "quote"},
   603  		{1221, "1", "22"},
   604  		{1221, "12", ""},
   605  		{template.HTML("<tag>"), "<>", "tag"},
   606  		{[]byte("<tag>"), "<>", "tag"},
   607  		// errors
   608  		{"", tstNoStringer{}, false},
   609  		{tstNoStringer{}, "", false},
   610  	} {
   611  
   612  		result, err := ns.Trim(test.s, test.cutset)
   613  
   614  		if b, ok := test.expect.(bool); ok && !b {
   615  			c.Assert(err, qt.Not(qt.IsNil))
   616  			continue
   617  		}
   618  
   619  		c.Assert(err, qt.IsNil)
   620  		c.Assert(result, qt.Equals, test.expect)
   621  	}
   622  }
   623  
   624  func TestTrimLeft(t *testing.T) {
   625  	t.Parallel()
   626  	c := qt.New(t)
   627  
   628  	for _, test := range []struct {
   629  		s      interface{}
   630  		cutset interface{}
   631  		expect interface{}
   632  	}{
   633  		{"abba", "a", "bba"},
   634  		{"abba", "ab", ""},
   635  		{"<tag>", "<>", "tag>"},
   636  		{`"quote"`, `"`, `quote"`},
   637  		{1221, "1", "221"},
   638  		{1221, "12", ""},
   639  		{"007", "0", "7"},
   640  		{template.HTML("<tag>"), "<>", "tag>"},
   641  		{[]byte("<tag>"), "<>", "tag>"},
   642  		// errors
   643  		{"", tstNoStringer{}, false},
   644  		{tstNoStringer{}, "", false},
   645  	} {
   646  
   647  		result, err := ns.TrimLeft(test.cutset, test.s)
   648  
   649  		if b, ok := test.expect.(bool); ok && !b {
   650  			c.Assert(err, qt.Not(qt.IsNil))
   651  			continue
   652  		}
   653  
   654  		c.Assert(err, qt.IsNil)
   655  		c.Assert(result, qt.Equals, test.expect)
   656  	}
   657  }
   658  
   659  func TestTrimPrefix(t *testing.T) {
   660  	t.Parallel()
   661  	c := qt.New(t)
   662  
   663  	for _, test := range []struct {
   664  		s      interface{}
   665  		prefix interface{}
   666  		expect interface{}
   667  	}{
   668  		{"aabbaa", "a", "abbaa"},
   669  		{"aabb", "b", "aabb"},
   670  		{1234, "12", "34"},
   671  		{1234, "34", "1234"},
   672  		// errors
   673  		{"", tstNoStringer{}, false},
   674  		{tstNoStringer{}, "", false},
   675  	} {
   676  
   677  		result, err := ns.TrimPrefix(test.prefix, test.s)
   678  
   679  		if b, ok := test.expect.(bool); ok && !b {
   680  			c.Assert(err, qt.Not(qt.IsNil))
   681  			continue
   682  		}
   683  
   684  		c.Assert(err, qt.IsNil)
   685  		c.Assert(result, qt.Equals, test.expect)
   686  	}
   687  }
   688  
   689  func TestTrimRight(t *testing.T) {
   690  	t.Parallel()
   691  	c := qt.New(t)
   692  
   693  	for _, test := range []struct {
   694  		s      interface{}
   695  		cutset interface{}
   696  		expect interface{}
   697  	}{
   698  		{"abba", "a", "abb"},
   699  		{"abba", "ab", ""},
   700  		{"<tag>", "<>", "<tag"},
   701  		{`"quote"`, `"`, `"quote`},
   702  		{1221, "1", "122"},
   703  		{1221, "12", ""},
   704  		{"007", "0", "007"},
   705  		{template.HTML("<tag>"), "<>", "<tag"},
   706  		{[]byte("<tag>"), "<>", "<tag"},
   707  		// errors
   708  		{"", tstNoStringer{}, false},
   709  		{tstNoStringer{}, "", false},
   710  	} {
   711  
   712  		result, err := ns.TrimRight(test.cutset, test.s)
   713  
   714  		if b, ok := test.expect.(bool); ok && !b {
   715  			c.Assert(err, qt.Not(qt.IsNil))
   716  			continue
   717  		}
   718  
   719  		c.Assert(err, qt.IsNil)
   720  		c.Assert(result, qt.Equals, test.expect)
   721  	}
   722  }
   723  
   724  func TestTrimSuffix(t *testing.T) {
   725  	t.Parallel()
   726  	c := qt.New(t)
   727  
   728  	for _, test := range []struct {
   729  		s      interface{}
   730  		suffix interface{}
   731  		expect interface{}
   732  	}{
   733  		{"aabbaa", "a", "aabba"},
   734  		{"aabb", "b", "aab"},
   735  		{1234, "12", "1234"},
   736  		{1234, "34", "12"},
   737  		// errors
   738  		{"", tstNoStringer{}, false},
   739  		{tstNoStringer{}, "", false},
   740  	} {
   741  
   742  		result, err := ns.TrimSuffix(test.suffix, test.s)
   743  
   744  		if b, ok := test.expect.(bool); ok && !b {
   745  			c.Assert(err, qt.Not(qt.IsNil))
   746  			continue
   747  		}
   748  
   749  		c.Assert(err, qt.IsNil)
   750  		c.Assert(result, qt.Equals, test.expect)
   751  	}
   752  }
   753  
   754  func TestRepeat(t *testing.T) {
   755  	t.Parallel()
   756  	c := qt.New(t)
   757  
   758  	for _, test := range []struct {
   759  		s      interface{}
   760  		n      interface{}
   761  		expect interface{}
   762  	}{
   763  		{"yo", "2", "yoyo"},
   764  		{"~", "16", "~~~~~~~~~~~~~~~~"},
   765  		{"<tag>", "0", ""},
   766  		{"yay", "1", "yay"},
   767  		{1221, "1", "1221"},
   768  		{1221, 2, "12211221"},
   769  		{template.HTML("<tag>"), "2", "<tag><tag>"},
   770  		{[]byte("<tag>"), 2, "<tag><tag>"},
   771  		// errors
   772  		{"", tstNoStringer{}, false},
   773  		{tstNoStringer{}, "", false},
   774  		{"ab", -1, false},
   775  	} {
   776  
   777  		result, err := ns.Repeat(test.n, test.s)
   778  
   779  		if b, ok := test.expect.(bool); ok && !b {
   780  			c.Assert(err, qt.Not(qt.IsNil))
   781  			continue
   782  		}
   783  
   784  		c.Assert(err, qt.IsNil)
   785  		c.Assert(result, qt.Equals, test.expect)
   786  	}
   787  }