golang.org/x/text@v0.14.0/secure/bidirule/bidirule_test.go (about) 1 // Copyright 2016 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 bidirule 6 7 import ( 8 "fmt" 9 "testing" 10 11 "golang.org/x/text/internal/testtext" 12 "golang.org/x/text/unicode/bidi" 13 ) 14 15 const ( 16 strL = "ABC" // Left to right - most letters in LTR scripts 17 strR = "עברית" // Right to left - most letters in non-Arabic RTL scripts 18 strAL = "دبي" // Arabic letters - most letters in the Arabic script 19 strEN = "123" // European Number (0-9, and Extended Arabic-Indic numbers) 20 strES = "+-" // European Number Separator (+ and -) 21 strET = "$" // European Number Terminator (currency symbols, the hash sign, the percent sign and so on) 22 strAN = "\u0660" // Arabic Number; this encompasses the Arabic-Indic numbers, but not the Extended Arabic-Indic numbers 23 strCS = "," // Common Number Separator (. , / : et al) 24 strNSM = "\u0300" // Nonspacing Mark - most combining accents 25 strBN = "\u200d" // Boundary Neutral - control characters (ZWNJ, ZWJ, and others) 26 strB = "\u2029" // Paragraph Separator 27 strS = "\u0009" // Segment Separator 28 strWS = " " // Whitespace, including the SPACE character 29 strON = "@" // Other Neutrals, including @, &, parentheses, MIDDLE DOT 30 ) 31 32 type ruleTest struct { 33 in string 34 dir bidi.Direction 35 n int // position at which the rule fails 36 err error 37 38 // For tests that split the string in two. 39 pSrc int // number of source bytes to consume first 40 szDst int // size of destination buffer 41 nSrc int // source bytes consumed and bytes written 42 err0 error // error after first run 43 } 44 45 func init() { 46 for rule, cases := range testCases { 47 for i, tc := range cases { 48 if tc.err == nil { 49 testCases[rule][i].n = len(tc.in) 50 } 51 } 52 } 53 } 54 55 func doTests(t *testing.T, fn func(t *testing.T, tc ruleTest)) { 56 for rule, cases := range testCases { 57 for i, tc := range cases { 58 name := fmt.Sprintf("%d/%d:%+q:%s", rule, i, tc.in, tc.in) 59 testtext.Run(t, name, func(t *testing.T) { 60 fn(t, tc) 61 }) 62 } 63 } 64 } 65 66 func TestDirection(t *testing.T) { 67 doTests(t, func(t *testing.T, tc ruleTest) { 68 dir := Direction([]byte(tc.in)) 69 if dir != tc.dir { 70 t.Errorf("dir was %v; want %v", dir, tc.dir) 71 } 72 }) 73 } 74 75 func TestDirectionString(t *testing.T) { 76 doTests(t, func(t *testing.T, tc ruleTest) { 77 dir := DirectionString(tc.in) 78 if dir != tc.dir { 79 t.Errorf("dir was %v; want %v", dir, tc.dir) 80 } 81 }) 82 } 83 84 func TestValid(t *testing.T) { 85 doTests(t, func(t *testing.T, tc ruleTest) { 86 got := Valid([]byte(tc.in)) 87 want := tc.err == nil 88 if got != want { 89 t.Fatalf("Valid: got %v; want %v", got, want) 90 } 91 92 got = ValidString(tc.in) 93 want = tc.err == nil 94 if got != want { 95 t.Fatalf("Valid: got %v; want %v", got, want) 96 } 97 }) 98 } 99 100 func TestSpan(t *testing.T) { 101 doTests(t, func(t *testing.T, tc ruleTest) { 102 // Skip tests that test for limited destination buffer size. 103 if tc.szDst > 0 { 104 return 105 } 106 107 r := New() 108 src := []byte(tc.in) 109 110 n, err := r.Span(src[:tc.pSrc], tc.pSrc == len(tc.in)) 111 if err != tc.err0 { 112 t.Errorf("err0 was %v; want %v", err, tc.err0) 113 } 114 if n != tc.nSrc { 115 t.Fatalf("nSrc was %d; want %d", n, tc.nSrc) 116 } 117 118 n, err = r.Span(src[n:], true) 119 if err != tc.err { 120 t.Errorf("error was %v; want %v", err, tc.err) 121 } 122 if got := n + tc.nSrc; got != tc.n { 123 t.Errorf("n was %d; want %d", got, tc.n) 124 } 125 }) 126 } 127 128 func TestTransform(t *testing.T) { 129 doTests(t, func(t *testing.T, tc ruleTest) { 130 r := New() 131 132 src := []byte(tc.in) 133 dst := make([]byte, len(tc.in)) 134 if tc.szDst > 0 { 135 dst = make([]byte, tc.szDst) 136 } 137 138 // First transform operates on a zero-length string for most tests. 139 nDst, nSrc, err := r.Transform(dst, src[:tc.pSrc], tc.pSrc == len(tc.in)) 140 if err != tc.err0 { 141 t.Errorf("err0 was %v; want %v", err, tc.err0) 142 } 143 if nDst != nSrc { 144 t.Fatalf("nDst (%d) and nSrc (%d) should match", nDst, nSrc) 145 } 146 if nSrc != tc.nSrc { 147 t.Fatalf("nSrc was %d; want %d", nSrc, tc.nSrc) 148 } 149 150 dst1 := make([]byte, len(tc.in)) 151 copy(dst1, dst[:nDst]) 152 153 nDst, nSrc, err = r.Transform(dst1[nDst:], src[nSrc:], true) 154 if err != tc.err { 155 t.Errorf("error was %v; want %v", err, tc.err) 156 } 157 if nDst != nSrc { 158 t.Fatalf("nDst (%d) and nSrc (%d) should match", nDst, nSrc) 159 } 160 n := nSrc + tc.nSrc 161 if n != tc.n { 162 t.Fatalf("n was %d; want %d", n, tc.n) 163 } 164 if got, want := string(dst1[:n]), tc.in[:tc.n]; got != want { 165 t.Errorf("got %+q; want %+q", got, want) 166 } 167 }) 168 }