github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/text/runes/cond_test.go (about)

     1  // Copyright 2015 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 runes
     6  
     7  import (
     8  	"strings"
     9  	"testing"
    10  	"unicode"
    11  
    12  	"golang.org/x/text/cases"
    13  	"golang.org/x/text/language"
    14  	"golang.org/x/text/transform"
    15  )
    16  
    17  var (
    18  	toUpper = cases.Upper(language.Und)
    19  	toLower = cases.Lower(language.Und)
    20  )
    21  
    22  func TestPredicate(t *testing.T) {
    23  	testConditional(t, func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer {
    24  		return If(Predicate(func(r rune) bool {
    25  			return unicode.Is(rt, r)
    26  		}), t, f)
    27  	})
    28  }
    29  
    30  func TestIn(t *testing.T) {
    31  	testConditional(t, func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer {
    32  		return If(In(rt), t, f)
    33  	})
    34  }
    35  
    36  func TestNotIn(t *testing.T) {
    37  	testConditional(t, func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer {
    38  		return If(NotIn(rt), f, t)
    39  	})
    40  }
    41  
    42  func testConditional(t *testing.T, f func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer) {
    43  	lower := f(unicode.Latin, toLower, toLower)
    44  
    45  	for i, tt := range []transformTest{{
    46  		desc:    "empty",
    47  		szDst:   large,
    48  		atEOF:   true,
    49  		in:      "",
    50  		out:     "",
    51  		outFull: "",
    52  		t:       lower,
    53  	}, {
    54  		desc:    "small",
    55  		szDst:   1,
    56  		atEOF:   true,
    57  		in:      "B",
    58  		out:     "b",
    59  		outFull: "b",
    60  		t:       lower,
    61  	}, {
    62  		desc:    "short dst",
    63  		szDst:   2,
    64  		atEOF:   true,
    65  		in:      "AAA",
    66  		out:     "aa",
    67  		outFull: "aaa",
    68  		err:     transform.ErrShortDst,
    69  		t:       lower,
    70  	}, {
    71  		desc:    "short dst writing error",
    72  		szDst:   1,
    73  		atEOF:   false,
    74  		in:      "A\x80",
    75  		out:     "a",
    76  		outFull: "a\x80",
    77  		err:     transform.ErrShortDst,
    78  		t:       lower,
    79  	}, {
    80  		desc:    "short dst writing incomplete rune",
    81  		szDst:   2,
    82  		atEOF:   true,
    83  		in:      "Σ\xc2",
    84  		out:     "Σ",
    85  		outFull: "Σ\xc2",
    86  		err:     transform.ErrShortDst,
    87  		t:       f(unicode.Latin, toLower, nil),
    88  	}, {
    89  		desc:    "short dst, longer",
    90  		szDst:   5,
    91  		atEOF:   true,
    92  		in:      "Hellø",
    93  		out:     "Hell",
    94  		outFull: "Hellø",
    95  		err:     transform.ErrShortDst,
    96  		// idem is used to test short buffers by forcing processing of full-rune increments.
    97  		t: f(unicode.Latin, Map(idem), nil),
    98  	}, {
    99  		desc:    "short dst, longer, writing error",
   100  		szDst:   6,
   101  		atEOF:   false,
   102  		in:      "\x80Hello\x80",
   103  		out:     "\x80Hello",
   104  		outFull: "\x80Hello\x80",
   105  		err:     transform.ErrShortDst,
   106  		t:       f(unicode.Latin, Map(idem), nil),
   107  	}, {
   108  		desc:    "short src",
   109  		szDst:   2,
   110  		atEOF:   false,
   111  		in:      "A\xc2",
   112  		out:     "a",
   113  		outFull: "a\xc2",
   114  		err:     transform.ErrShortSrc,
   115  		t:       lower,
   116  	}, {
   117  		desc:    "invalid input, atEOF",
   118  		szDst:   large,
   119  		atEOF:   true,
   120  		in:      "\x80",
   121  		out:     "\x80",
   122  		outFull: "\x80",
   123  		t:       lower,
   124  	}, {
   125  		desc:    "invalid input, !atEOF",
   126  		szDst:   large,
   127  		atEOF:   false,
   128  		in:      "\x80",
   129  		out:     "\x80",
   130  		outFull: "\x80",
   131  		t:       lower,
   132  	}, {
   133  		desc:    "invalid input, incomplete rune atEOF",
   134  		szDst:   large,
   135  		atEOF:   true,
   136  		in:      "\xc2",
   137  		out:     "\xc2",
   138  		outFull: "\xc2",
   139  		t:       lower,
   140  	}, {
   141  		desc:    "nop",
   142  		szDst:   large,
   143  		atEOF:   true,
   144  		in:      "Hello World!",
   145  		out:     "Hello World!",
   146  		outFull: "Hello World!",
   147  		t:       f(unicode.Latin, nil, nil),
   148  	}, {
   149  		desc:    "nop in",
   150  		szDst:   large,
   151  		atEOF:   true,
   152  		in:      "THIS IS α ΤΕΣΤ",
   153  		out:     "this is α ΤΕΣΤ",
   154  		outFull: "this is α ΤΕΣΤ",
   155  		t:       f(unicode.Greek, nil, toLower),
   156  	}, {
   157  		desc:    "nop not in",
   158  		szDst:   large,
   159  		atEOF:   true,
   160  		in:      "THIS IS α ΤΕΣΤ",
   161  		out:     "this is α ΤΕΣΤ",
   162  		outFull: "this is α ΤΕΣΤ",
   163  		t:       f(unicode.Latin, toLower, nil),
   164  	}, {
   165  		desc:    "pass atEOF is true when at end",
   166  		szDst:   large,
   167  		atEOF:   true,
   168  		in:      "hello",
   169  		out:     "HELLO",
   170  		outFull: "HELLO",
   171  		t:       f(unicode.Latin, upperAtEOF{}, nil),
   172  	}, {
   173  		desc:    "pass atEOF is true when at end of segment",
   174  		szDst:   large,
   175  		atEOF:   true,
   176  		in:      "hello ",
   177  		out:     "HELLO ",
   178  		outFull: "HELLO ",
   179  		t:       f(unicode.Latin, upperAtEOF{}, nil),
   180  	}, {
   181  		desc:    "don't pass atEOF is true when atEOF is false",
   182  		szDst:   large,
   183  		atEOF:   false,
   184  		in:      "hello",
   185  		out:     "",
   186  		outFull: "HELLO",
   187  		t:       f(unicode.Latin, upperAtEOF{}, nil),
   188  		err:     transform.ErrShortSrc,
   189  	}, {
   190  		desc:    "large input ASCII",
   191  		szDst:   12000,
   192  		atEOF:   false,
   193  		in:      strings.Repeat("HELLO", 2000),
   194  		out:     strings.Repeat("hello", 2000),
   195  		outFull: strings.Repeat("hello", 2000),
   196  		t:       lower,
   197  		err:     nil,
   198  	}, {
   199  		desc:    "large input non-ASCII",
   200  		szDst:   12000,
   201  		atEOF:   false,
   202  		in:      strings.Repeat("\u3333", 2000),
   203  		out:     strings.Repeat("\u3333", 2000),
   204  		outFull: strings.Repeat("\u3333", 2000),
   205  		t:       lower,
   206  		err:     nil,
   207  	}} {
   208  		tt.check(t, i)
   209  	}
   210  }
   211  
   212  // upperAtEOF is a strange Transformer that converts text to uppercase, but only
   213  // if atEOF is true.
   214  type upperAtEOF struct{ transform.NopResetter }
   215  
   216  func (upperAtEOF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
   217  	if !atEOF {
   218  		return 0, 0, transform.ErrShortSrc
   219  	}
   220  	return toUpper.Transform(dst, src, atEOF)
   221  }
   222  
   223  func BenchmarkConditional(b *testing.B) {
   224  	dst := make([]byte, len(input))
   225  	src := []byte(input)
   226  
   227  	r := If(In(unicode.Hangul), transform.Nop, transform.Nop)
   228  	b.ResetTimer()
   229  
   230  	for i := 0; i < b.N; i++ {
   231  		r.Transform(dst, src, true)
   232  	}
   233  }