golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/utf8string/string_test.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package utf8string
     6  
     7  import (
     8  	"math/rand"
     9  	"testing"
    10  	"unicode/utf8"
    11  )
    12  
    13  var testStrings = []string{
    14  	"",
    15  	"abcd",
    16  	"☺☻☹",
    17  	"日a本b語ç日ð本Ê語þ日¥本¼語i日©",
    18  	"日a本b語ç日ð本Ê語þ日¥本¼語i日©日a本b語ç日ð本Ê語þ日¥本¼語i日©日a本b語ç日ð本Ê語þ日¥本¼語i日©",
    19  	"\x80\x80\x80\x80",
    20  }
    21  
    22  func TestScanForwards(t *testing.T) {
    23  	for _, s := range testStrings {
    24  		runes := []rune(s)
    25  		str := NewString(s)
    26  		if str.RuneCount() != len(runes) {
    27  			t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
    28  			break
    29  		}
    30  		for i, expect := range runes {
    31  			got := str.At(i)
    32  			if got != expect {
    33  				t.Errorf("%s[%d]: expected %c (%U); got %c (%U)", s, i, expect, expect, got, got)
    34  			}
    35  		}
    36  	}
    37  }
    38  
    39  func TestScanBackwards(t *testing.T) {
    40  	for _, s := range testStrings {
    41  		runes := []rune(s)
    42  		str := NewString(s)
    43  		if str.RuneCount() != len(runes) {
    44  			t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
    45  			break
    46  		}
    47  		for i := len(runes) - 1; i >= 0; i-- {
    48  			expect := runes[i]
    49  			got := str.At(i)
    50  			if got != expect {
    51  				t.Errorf("%s[%d]: expected %c (%U); got %c (%U)", s, i, expect, expect, got, got)
    52  			}
    53  		}
    54  	}
    55  }
    56  
    57  func randCount() int {
    58  	if testing.Short() {
    59  		return 100
    60  	}
    61  	return 100000
    62  }
    63  
    64  func TestRandomAccess(t *testing.T) {
    65  	for _, s := range testStrings {
    66  		if len(s) == 0 {
    67  			continue
    68  		}
    69  		runes := []rune(s)
    70  		str := NewString(s)
    71  		if str.RuneCount() != len(runes) {
    72  			t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
    73  			break
    74  		}
    75  		for j := 0; j < randCount(); j++ {
    76  			i := rand.Intn(len(runes))
    77  			expect := runes[i]
    78  			got := str.At(i)
    79  			if got != expect {
    80  				t.Errorf("%s[%d]: expected %c (%U); got %c (%U)", s, i, expect, expect, got, got)
    81  			}
    82  		}
    83  	}
    84  }
    85  
    86  func TestRandomSliceAccess(t *testing.T) {
    87  	for _, s := range testStrings {
    88  		if len(s) == 0 || s[0] == '\x80' { // the bad-UTF-8 string fools this simple test
    89  			continue
    90  		}
    91  		runes := []rune(s)
    92  		str := NewString(s)
    93  		if str.RuneCount() != len(runes) {
    94  			t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
    95  			break
    96  		}
    97  		for k := 0; k < randCount(); k++ {
    98  			i := rand.Intn(len(runes))
    99  			j := rand.Intn(len(runes) + 1)
   100  			if i > j { // include empty strings
   101  				continue
   102  			}
   103  			expect := string(runes[i:j])
   104  			got := str.Slice(i, j)
   105  			if got != expect {
   106  				t.Errorf("%s[%d:%d]: expected %q got %q", s, i, j, expect, got)
   107  			}
   108  		}
   109  	}
   110  }
   111  
   112  func TestLimitSliceAccess(t *testing.T) {
   113  	for _, s := range testStrings {
   114  		str := NewString(s)
   115  		if str.Slice(0, 0) != "" {
   116  			t.Error("failure with empty slice at beginning")
   117  		}
   118  		nr := utf8.RuneCountInString(s)
   119  		if str.Slice(nr, nr) != "" {
   120  			t.Error("failure with empty slice at end")
   121  		}
   122  	}
   123  }