mirror of
https://github.com/miniflux/v2.git
synced 2024-09-13 22:49:48 +02:00
150 lines
3.9 KiB
Go
150 lines
3.9 KiB
Go
|
// 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 precis
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math/rand"
|
||
|
"testing"
|
||
|
"unicode"
|
||
|
|
||
|
"golang.org/x/text/internal/testtext"
|
||
|
"golang.org/x/text/transform"
|
||
|
)
|
||
|
|
||
|
// copyOrbit is a Transformer for the sole purpose of testing the apply method,
|
||
|
// testing that apply will always call Span for the prefix of the input that
|
||
|
// remains identical and then call Transform for the remainder. It will produce
|
||
|
// inconsistent output for other usage patterns.
|
||
|
// Provided that copyOrbit is used this way, the first t bytes of the output
|
||
|
// will be identical to the input and the remaining output will be the result
|
||
|
// of calling caseOrbit on the remaining input bytes.
|
||
|
type copyOrbit int
|
||
|
|
||
|
func (t copyOrbit) Reset() {}
|
||
|
func (t copyOrbit) Span(src []byte, atEOF bool) (n int, err error) {
|
||
|
if int(t) == len(src) {
|
||
|
return int(t), nil
|
||
|
}
|
||
|
return int(t), transform.ErrEndOfSpan
|
||
|
}
|
||
|
|
||
|
// Transform implements transform.Transformer specifically for testing the apply method.
|
||
|
// See documentation of copyOrbit before using this method.
|
||
|
func (t copyOrbit) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||
|
n := copy(dst, src)
|
||
|
for i, c := range dst[:n] {
|
||
|
dst[i] = orbitCase(c)
|
||
|
}
|
||
|
return n, n, nil
|
||
|
}
|
||
|
|
||
|
func orbitCase(c byte) byte {
|
||
|
if unicode.IsLower(rune(c)) {
|
||
|
return byte(unicode.ToUpper(rune(c)))
|
||
|
} else {
|
||
|
return byte(unicode.ToLower(rune(c)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestBuffers(t *testing.T) {
|
||
|
want := "Those who cannot remember the past are condemned to compute it."
|
||
|
|
||
|
spans := rand.Perm(len(want) + 1)
|
||
|
|
||
|
// Compute the result of applying copyOrbit(span) transforms in reverse.
|
||
|
input := []byte(want)
|
||
|
for i := len(spans) - 1; i >= 0; i-- {
|
||
|
for j := spans[i]; j < len(input); j++ {
|
||
|
input[j] = orbitCase(input[j])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Apply the copyOrbit(span) transforms.
|
||
|
b := buffers{src: input}
|
||
|
for _, n := range spans {
|
||
|
b.apply(copyOrbit(n))
|
||
|
if n%11 == 0 {
|
||
|
b.apply(transform.Nop)
|
||
|
}
|
||
|
}
|
||
|
if got := string(b.src); got != want {
|
||
|
t.Errorf("got %q; want %q", got, want)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type compareTestCase struct {
|
||
|
a string
|
||
|
b string
|
||
|
result bool
|
||
|
}
|
||
|
|
||
|
var compareTestCases = []struct {
|
||
|
name string
|
||
|
p *Profile
|
||
|
cases []compareTestCase
|
||
|
}{
|
||
|
{"Nickname", Nickname, []compareTestCase{
|
||
|
{"a", "b", false},
|
||
|
{" Swan of Avon ", "swan of avon", true},
|
||
|
{"Foo", "foo", true},
|
||
|
{"foo", "foo", true},
|
||
|
{"Foo Bar", "foo bar", true},
|
||
|
{"foo bar", "foo bar", true},
|
||
|
{"\u03A3", "\u03C3", true},
|
||
|
{"\u03A3", "\u03C2", false},
|
||
|
{"\u03C3", "\u03C2", false},
|
||
|
{"Richard \u2163", "richard iv", true},
|
||
|
{"Å", "å", true},
|
||
|
{"ff", "ff", true}, // because of NFKC
|
||
|
{"ß", "sS", false},
|
||
|
|
||
|
// After applying the Nickname profile, \u00a8 becomes \u0020\u0308,
|
||
|
// however because the nickname profile is not idempotent, applying it again
|
||
|
// to \u0020\u0308 results in \u0308.
|
||
|
{"\u00a8", "\u0020\u0308", true},
|
||
|
{"\u00a8", "\u0308", true},
|
||
|
{"\u0020\u0308", "\u0308", true},
|
||
|
}},
|
||
|
}
|
||
|
|
||
|
func doCompareTests(t *testing.T, fn func(t *testing.T, p *Profile, tc compareTestCase)) {
|
||
|
for _, g := range compareTestCases {
|
||
|
for i, tc := range g.cases {
|
||
|
name := fmt.Sprintf("%s:%d:%+q", g.name, i, tc.a)
|
||
|
testtext.Run(t, name, func(t *testing.T) {
|
||
|
fn(t, g.p, tc)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestCompare(t *testing.T) {
|
||
|
doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
|
||
|
if result := p.Compare(tc.a, tc.b); result != tc.result {
|
||
|
t.Errorf("got %v; want %v", result, tc.result)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestCompareString(t *testing.T) {
|
||
|
doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
|
||
|
a, err := p.CompareKey(tc.a)
|
||
|
if err != nil {
|
||
|
t.Errorf("Unexpected error when creating key: %v", err)
|
||
|
return
|
||
|
}
|
||
|
b, err := p.CompareKey(tc.b)
|
||
|
if err != nil {
|
||
|
t.Errorf("Unexpected error when creating key: %v", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if result := (a == b); result != tc.result {
|
||
|
t.Errorf("got %v; want %v", result, tc.result)
|
||
|
}
|
||
|
})
|
||
|
}
|