...

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

View as plain text