102 lines
3.2 KiB
Go
102 lines
3.2 KiB
Go
// Copyright 2011 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 norm
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"golang.org/x/text/transform"
|
|
)
|
|
|
|
func TestTransform(t *testing.T) {
|
|
tests := []struct {
|
|
f Form
|
|
in, out string
|
|
eof bool
|
|
dstSize int
|
|
err error
|
|
}{
|
|
{NFC, "ab", "ab", true, 2, nil},
|
|
{NFC, "qx", "qx", true, 2, nil},
|
|
{NFD, "qx", "qx", true, 2, nil},
|
|
{NFC, "", "", true, 1, nil},
|
|
{NFD, "", "", true, 1, nil},
|
|
{NFC, "", "", false, 1, nil},
|
|
{NFD, "", "", false, 1, nil},
|
|
|
|
// Normalized segment does not fit in destination.
|
|
{NFD, "ö", "", true, 1, transform.ErrShortDst},
|
|
{NFD, "ö", "", true, 2, transform.ErrShortDst},
|
|
|
|
// As an artifact of the algorithm, only full segments are written.
|
|
// This is not strictly required, and some bytes could be written.
|
|
// In practice, for Transform to not block, the destination buffer
|
|
// should be at least MaxSegmentSize to work anyway and these edge
|
|
// conditions will be relatively rare.
|
|
{NFC, "ab", "", true, 1, transform.ErrShortDst},
|
|
// This is even true for inert runes.
|
|
{NFC, "qx", "", true, 1, transform.ErrShortDst},
|
|
{NFC, "a\u0300abc", "\u00e0a", true, 4, transform.ErrShortDst},
|
|
|
|
// We cannot write a segment if successive runes could still change the result.
|
|
{NFD, "ö", "", false, 3, transform.ErrShortSrc},
|
|
{NFC, "a\u0300", "", false, 4, transform.ErrShortSrc},
|
|
{NFD, "a\u0300", "", false, 4, transform.ErrShortSrc},
|
|
{NFC, "ö", "", false, 3, transform.ErrShortSrc},
|
|
|
|
{NFC, "a\u0300", "", true, 1, transform.ErrShortDst},
|
|
// Theoretically could fit, but won't due to simplified checks.
|
|
{NFC, "a\u0300", "", true, 2, transform.ErrShortDst},
|
|
{NFC, "a\u0300", "", true, 3, transform.ErrShortDst},
|
|
{NFC, "a\u0300", "\u00e0", true, 4, nil},
|
|
|
|
{NFD, "öa\u0300", "o\u0308", false, 8, transform.ErrShortSrc},
|
|
{NFD, "öa\u0300ö", "o\u0308a\u0300", true, 8, transform.ErrShortDst},
|
|
{NFD, "öa\u0300ö", "o\u0308a\u0300", false, 12, transform.ErrShortSrc},
|
|
|
|
// Illegal input is copied verbatim.
|
|
{NFD, "\xbd\xb2=\xbc ", "\xbd\xb2=\xbc ", true, 8, nil},
|
|
}
|
|
b := make([]byte, 100)
|
|
for i, tt := range tests {
|
|
nDst, _, err := tt.f.Transform(b[:tt.dstSize], []byte(tt.in), tt.eof)
|
|
out := string(b[:nDst])
|
|
if out != tt.out || err != tt.err {
|
|
t.Errorf("%d: was %+q (%v); want %+q (%v)", i, out, err, tt.out, tt.err)
|
|
}
|
|
if want := tt.f.String(tt.in)[:nDst]; want != out {
|
|
t.Errorf("%d: incorrect normalization: was %+q; want %+q", i, out, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
var transBufSizes = []int{
|
|
MaxTransformChunkSize,
|
|
3 * MaxTransformChunkSize / 2,
|
|
2 * MaxTransformChunkSize,
|
|
3 * MaxTransformChunkSize,
|
|
100 * MaxTransformChunkSize,
|
|
}
|
|
|
|
func doTransNorm(f Form, buf []byte, b []byte) []byte {
|
|
acc := []byte{}
|
|
for p := 0; p < len(b); {
|
|
nd, ns, _ := f.Transform(buf[:], b[p:], true)
|
|
p += ns
|
|
acc = append(acc, buf[:nd]...)
|
|
}
|
|
return acc
|
|
}
|
|
|
|
func TestTransformNorm(t *testing.T) {
|
|
for _, sz := range transBufSizes {
|
|
buf := make([]byte, sz)
|
|
runNormTests(t, fmt.Sprintf("Transform:%d", sz), func(f Form, out []byte, s string) []byte {
|
|
return doTransNorm(f, buf, append(out, s...))
|
|
})
|
|
}
|
|
}
|