...

Source file src/golang.org/x/text/secure/precis/profile_test.go

Documentation: golang.org/x/text/secure/precis

     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 precis
     6  
     7  import (
     8  	"fmt"
     9  	"math/rand"
    10  	"testing"
    11  	"unicode"
    12  
    13  	"golang.org/x/text/internal/testtext"
    14  	"golang.org/x/text/transform"
    15  )
    16  
    17  // copyOrbit is a Transformer for the sole purpose of testing the apply method,
    18  // testing that apply will always call Span for the prefix of the input that
    19  // remains identical and then call Transform for the remainder. It will produce
    20  // inconsistent output for other usage patterns.
    21  // Provided that copyOrbit is used this way, the first t bytes of the output
    22  // will be identical to the input and the remaining output will be the result
    23  // of calling caseOrbit on the remaining input bytes.
    24  type copyOrbit int
    25  
    26  func (t copyOrbit) Reset() {}
    27  func (t copyOrbit) Span(src []byte, atEOF bool) (n int, err error) {
    28  	if int(t) == len(src) {
    29  		return int(t), nil
    30  	}
    31  	return int(t), transform.ErrEndOfSpan
    32  }
    33  
    34  // Transform implements transform.Transformer specifically for testing the apply method.
    35  // See documentation of copyOrbit before using this method.
    36  func (t copyOrbit) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
    37  	n := copy(dst, src)
    38  	for i, c := range dst[:n] {
    39  		dst[i] = orbitCase(c)
    40  	}
    41  	return n, n, nil
    42  }
    43  
    44  func orbitCase(c byte) byte {
    45  	if unicode.IsLower(rune(c)) {
    46  		return byte(unicode.ToUpper(rune(c)))
    47  	} else {
    48  		return byte(unicode.ToLower(rune(c)))
    49  	}
    50  }
    51  
    52  func TestBuffers(t *testing.T) {
    53  	want := "Those who cannot remember the past are condemned to compute it."
    54  
    55  	spans := rand.Perm(len(want) + 1)
    56  
    57  	// Compute the result of applying copyOrbit(span) transforms in reverse.
    58  	input := []byte(want)
    59  	for i := len(spans) - 1; i >= 0; i-- {
    60  		for j := spans[i]; j < len(input); j++ {
    61  			input[j] = orbitCase(input[j])
    62  		}
    63  	}
    64  
    65  	// Apply the copyOrbit(span) transforms.
    66  	b := buffers{src: input}
    67  	for _, n := range spans {
    68  		b.apply(copyOrbit(n))
    69  		if n%11 == 0 {
    70  			b.apply(transform.Nop)
    71  		}
    72  	}
    73  	if got := string(b.src); got != want {
    74  		t.Errorf("got %q; want %q", got, want)
    75  	}
    76  }
    77  
    78  type compareTestCase struct {
    79  	a      string
    80  	b      string
    81  	result bool
    82  }
    83  
    84  var compareTestCases = []struct {
    85  	name  string
    86  	p     *Profile
    87  	cases []compareTestCase
    88  }{
    89  	{"Nickname", Nickname, []compareTestCase{
    90  		{"a", "b", false},
    91  		{"  Swan  of   Avon   ", "swan of avon", true},
    92  		{"Foo", "foo", true},
    93  		{"foo", "foo", true},
    94  		{"Foo Bar", "foo bar", true},
    95  		{"foo bar", "foo bar", true},
    96  		{"\u03A3", "\u03C3", true},
    97  		{"\u03A3", "\u03C2", false},
    98  		{"\u03C3", "\u03C2", false},
    99  		{"Richard \u2163", "richard iv", true},
   100  		{"Å", "å", true},
   101  		{"ff", "ff", true}, // because of NFKC
   102  		{"ß", "sS", false},
   103  
   104  		// After applying the Nickname profile, \u00a8  becomes \u0020\u0308,
   105  		// however because the nickname profile is not idempotent, applying it again
   106  		// to \u0020\u0308 results in \u0308.
   107  		{"\u00a8", "\u0020\u0308", true},
   108  		{"\u00a8", "\u0308", true},
   109  		{"\u0020\u0308", "\u0308", true},
   110  	}},
   111  }
   112  
   113  func doCompareTests(t *testing.T, fn func(t *testing.T, p *Profile, tc compareTestCase)) {
   114  	for _, g := range compareTestCases {
   115  		for i, tc := range g.cases {
   116  			name := fmt.Sprintf("%s:%d:%+q", g.name, i, tc.a)
   117  			testtext.Run(t, name, func(t *testing.T) {
   118  				fn(t, g.p, tc)
   119  			})
   120  		}
   121  	}
   122  }
   123  
   124  func TestCompare(t *testing.T) {
   125  	doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
   126  		if result := p.Compare(tc.a, tc.b); result != tc.result {
   127  			t.Errorf("got %v; want %v", result, tc.result)
   128  		}
   129  	})
   130  }
   131  
   132  func TestCompareString(t *testing.T) {
   133  	doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
   134  		a, err := p.CompareKey(tc.a)
   135  		if err != nil {
   136  			t.Errorf("Unexpected error when creating key: %v", err)
   137  			return
   138  		}
   139  		b, err := p.CompareKey(tc.b)
   140  		if err != nil {
   141  			t.Errorf("Unexpected error when creating key: %v", err)
   142  			return
   143  		}
   144  
   145  		if result := (a == b); result != tc.result {
   146  			t.Errorf("got %v; want %v", result, tc.result)
   147  		}
   148  	})
   149  }
   150  

View as plain text