123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- // Copyright 2016 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package bidirule
- import (
- "fmt"
- "testing"
- "golang.org/x/text/internal/testtext"
- "golang.org/x/text/unicode/bidi"
- )
- const (
- strL = "ABC" // Left to right - most letters in LTR scripts
- strR = "עברית" // Right to left - most letters in non-Arabic RTL scripts
- strAL = "دبي" // Arabic letters - most letters in the Arabic script
- strEN = "123" // European Number (0-9, and Extended Arabic-Indic numbers)
- strES = "+-" // European Number Separator (+ and -)
- strET = "$" // European Number Terminator (currency symbols, the hash sign, the percent sign and so on)
- strAN = "\u0660" // Arabic Number; this encompasses the Arabic-Indic numbers, but not the Extended Arabic-Indic numbers
- strCS = "," // Common Number Separator (. , / : et al)
- strNSM = "\u0300" // Nonspacing Mark - most combining accents
- strBN = "\u200d" // Boundary Neutral - control characters (ZWNJ, ZWJ, and others)
- strB = "\u2029" // Paragraph Separator
- strS = "\u0009" // Segment Separator
- strWS = " " // Whitespace, including the SPACE character
- strON = "@" // Other Neutrals, including @, &, parentheses, MIDDLE DOT
- )
- type ruleTest struct {
- in string
- dir bidi.Direction
- n int // position at which the rule fails
- err error
- // For tests that split the string in two.
- pSrc int // number of source bytes to consume first
- szDst int // size of destination buffer
- nSrc int // source bytes consumed and bytes written
- err0 error // error after first run
- }
- func init() {
- for rule, cases := range testCases {
- for i, tc := range cases {
- if tc.err == nil {
- testCases[rule][i].n = len(tc.in)
- }
- }
- }
- }
- func doTests(t *testing.T, fn func(t *testing.T, tc ruleTest)) {
- for rule, cases := range testCases {
- for i, tc := range cases {
- name := fmt.Sprintf("%d/%d:%+q:%s", rule, i, tc.in, tc.in)
- testtext.Run(t, name, func(t *testing.T) {
- fn(t, tc)
- })
- }
- }
- }
- func TestDirection(t *testing.T) {
- doTests(t, func(t *testing.T, tc ruleTest) {
- dir := Direction([]byte(tc.in))
- if dir != tc.dir {
- t.Errorf("dir was %v; want %v", dir, tc.dir)
- }
- })
- }
- func TestDirectionString(t *testing.T) {
- doTests(t, func(t *testing.T, tc ruleTest) {
- dir := DirectionString(tc.in)
- if dir != tc.dir {
- t.Errorf("dir was %v; want %v", dir, tc.dir)
- }
- })
- }
- func TestValid(t *testing.T) {
- doTests(t, func(t *testing.T, tc ruleTest) {
- got := Valid([]byte(tc.in))
- want := tc.err == nil
- if got != want {
- t.Fatalf("Valid: got %v; want %v", got, want)
- }
- got = ValidString(tc.in)
- want = tc.err == nil
- if got != want {
- t.Fatalf("Valid: got %v; want %v", got, want)
- }
- })
- }
- func TestSpan(t *testing.T) {
- doTests(t, func(t *testing.T, tc ruleTest) {
- // Skip tests that test for limited destination buffer size.
- if tc.szDst > 0 {
- return
- }
- r := New()
- src := []byte(tc.in)
- n, err := r.Span(src[:tc.pSrc], tc.pSrc == len(tc.in))
- if err != tc.err0 {
- t.Errorf("err0 was %v; want %v", err, tc.err0)
- }
- if n != tc.nSrc {
- t.Fatalf("nSrc was %d; want %d", n, tc.nSrc)
- }
- n, err = r.Span(src[n:], true)
- if err != tc.err {
- t.Errorf("error was %v; want %v", err, tc.err)
- }
- if got := n + tc.nSrc; got != tc.n {
- t.Errorf("n was %d; want %d", got, tc.n)
- }
- })
- }
- func TestTransform(t *testing.T) {
- doTests(t, func(t *testing.T, tc ruleTest) {
- r := New()
- src := []byte(tc.in)
- dst := make([]byte, len(tc.in))
- if tc.szDst > 0 {
- dst = make([]byte, tc.szDst)
- }
- // First transform operates on a zero-length string for most tests.
- nDst, nSrc, err := r.Transform(dst, src[:tc.pSrc], tc.pSrc == len(tc.in))
- if err != tc.err0 {
- t.Errorf("err0 was %v; want %v", err, tc.err0)
- }
- if nDst != nSrc {
- t.Fatalf("nDst (%d) and nSrc (%d) should match", nDst, nSrc)
- }
- if nSrc != tc.nSrc {
- t.Fatalf("nSrc was %d; want %d", nSrc, tc.nSrc)
- }
- dst1 := make([]byte, len(tc.in))
- copy(dst1, dst[:nDst])
- nDst, nSrc, err = r.Transform(dst1[nDst:], src[nSrc:], true)
- if err != tc.err {
- t.Errorf("error was %v; want %v", err, tc.err)
- }
- if nDst != nSrc {
- t.Fatalf("nDst (%d) and nSrc (%d) should match", nDst, nSrc)
- }
- n := nSrc + tc.nSrc
- if n != tc.n {
- t.Fatalf("n was %d; want %d", n, tc.n)
- }
- if got, want := string(dst1[:n]), tc.in[:tc.n]; got != want {
- t.Errorf("got %+q; want %+q", got, want)
- }
- })
- }
|