184 lines
4.2 KiB
Go
184 lines
4.2 KiB
Go
// Copyright 2012 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 colltab
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"unicode"
|
|
)
|
|
|
|
func (e Elem) String() string {
|
|
q := ""
|
|
if v := e.Quaternary(); v == MaxQuaternary {
|
|
q = "max"
|
|
} else {
|
|
q = fmt.Sprint(v)
|
|
}
|
|
return fmt.Sprintf("[%d, %d, %d, %s]",
|
|
e.Primary(),
|
|
e.Secondary(),
|
|
e.Tertiary(),
|
|
q)
|
|
}
|
|
|
|
type ceTest struct {
|
|
f func(inout []int) (Elem, ceType)
|
|
arg []int
|
|
}
|
|
|
|
func makeCE(weights []int) Elem {
|
|
ce, _ := MakeElem(weights[0], weights[1], weights[2], uint8(weights[3]))
|
|
return ce
|
|
}
|
|
|
|
var defaultValues = []int{0, defaultSecondary, defaultTertiary, 0}
|
|
|
|
func e(w ...int) Elem {
|
|
return makeCE(append(w, defaultValues[len(w):]...))
|
|
}
|
|
|
|
func makeContractIndex(index, n, offset int) Elem {
|
|
const (
|
|
contractID = 0xC0000000
|
|
maxNBits = 4
|
|
maxTrieIndexBits = 12
|
|
maxContractOffsetBits = 13
|
|
)
|
|
ce := Elem(contractID)
|
|
ce += Elem(offset << (maxNBits + maxTrieIndexBits))
|
|
ce += Elem(index << maxNBits)
|
|
ce += Elem(n)
|
|
return ce
|
|
}
|
|
|
|
func makeExpandIndex(index int) Elem {
|
|
const expandID = 0xE0000000
|
|
return expandID + Elem(index)
|
|
}
|
|
|
|
func makeDecompose(t1, t2 int) Elem {
|
|
const decompID = 0xF0000000
|
|
return Elem(t2<<8+t1) + decompID
|
|
}
|
|
|
|
func normalCE(inout []int) (ce Elem, t ceType) {
|
|
ce = makeCE(inout)
|
|
inout[0] = ce.Primary()
|
|
inout[1] = ce.Secondary()
|
|
inout[2] = int(ce.Tertiary())
|
|
inout[3] = int(ce.CCC())
|
|
return ce, ceNormal
|
|
}
|
|
|
|
func expandCE(inout []int) (ce Elem, t ceType) {
|
|
ce = makeExpandIndex(inout[0])
|
|
inout[0] = splitExpandIndex(ce)
|
|
return ce, ceExpansionIndex
|
|
}
|
|
|
|
func contractCE(inout []int) (ce Elem, t ceType) {
|
|
ce = makeContractIndex(inout[0], inout[1], inout[2])
|
|
i, n, o := splitContractIndex(ce)
|
|
inout[0], inout[1], inout[2] = i, n, o
|
|
return ce, ceContractionIndex
|
|
}
|
|
|
|
func decompCE(inout []int) (ce Elem, t ceType) {
|
|
ce = makeDecompose(inout[0], inout[1])
|
|
t1, t2 := splitDecompose(ce)
|
|
inout[0], inout[1] = int(t1), int(t2)
|
|
return ce, ceDecompose
|
|
}
|
|
|
|
var ceTests = []ceTest{
|
|
{normalCE, []int{0, 0, 0, 0}},
|
|
{normalCE, []int{0, 30, 3, 0}},
|
|
{normalCE, []int{0, 30, 3, 0xFF}},
|
|
{normalCE, []int{100, defaultSecondary, defaultTertiary, 0}},
|
|
{normalCE, []int{100, defaultSecondary, defaultTertiary, 0xFF}},
|
|
{normalCE, []int{100, defaultSecondary, 3, 0}},
|
|
{normalCE, []int{0x123, defaultSecondary, 8, 0xFF}},
|
|
|
|
{contractCE, []int{0, 0, 0}},
|
|
{contractCE, []int{1, 1, 1}},
|
|
{contractCE, []int{1, (1 << maxNBits) - 1, 1}},
|
|
{contractCE, []int{(1 << maxTrieIndexBits) - 1, 1, 1}},
|
|
{contractCE, []int{1, 1, (1 << maxContractOffsetBits) - 1}},
|
|
|
|
{expandCE, []int{0}},
|
|
{expandCE, []int{5}},
|
|
{expandCE, []int{(1 << maxExpandIndexBits) - 1}},
|
|
|
|
{decompCE, []int{0, 0}},
|
|
{decompCE, []int{1, 1}},
|
|
{decompCE, []int{0x1F, 0x1F}},
|
|
}
|
|
|
|
func TestColElem(t *testing.T) {
|
|
for i, tt := range ceTests {
|
|
inout := make([]int, len(tt.arg))
|
|
copy(inout, tt.arg)
|
|
ce, typ := tt.f(inout)
|
|
if ce.ctype() != typ {
|
|
t.Errorf("%d: type is %d; want %d (ColElem: %X)", i, ce.ctype(), typ, ce)
|
|
}
|
|
for j, a := range tt.arg {
|
|
if inout[j] != a {
|
|
t.Errorf("%d: argument %d is %X; want %X (ColElem: %X)", i, j, inout[j], a, ce)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
type implicitTest struct {
|
|
r rune
|
|
p int
|
|
}
|
|
|
|
var implicitTests = []implicitTest{
|
|
{0x33FF, 0x533FF},
|
|
{0x3400, 0x23400},
|
|
{0x4DC0, 0x54DC0},
|
|
{0x4DFF, 0x54DFF},
|
|
{0x4E00, 0x14E00},
|
|
{0x9FCB, 0x19FCB},
|
|
{0xA000, 0x5A000},
|
|
{0xF8FF, 0x5F8FF},
|
|
{0xF900, 0x1F900},
|
|
{0xFA23, 0x1FA23},
|
|
{0xFAD9, 0x1FAD9},
|
|
{0xFB00, 0x5FB00},
|
|
{0x20000, 0x40000},
|
|
{0x2B81C, 0x4B81C},
|
|
{unicode.MaxRune, 0x15FFFF}, // maximum primary value
|
|
}
|
|
|
|
func TestImplicit(t *testing.T) {
|
|
for _, tt := range implicitTests {
|
|
if p := implicitPrimary(tt.r); p != tt.p {
|
|
t.Errorf("%U: was %X; want %X", tt.r, p, tt.p)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUpdateTertiary(t *testing.T) {
|
|
tests := []struct {
|
|
in, out Elem
|
|
t uint8
|
|
}{
|
|
{0x4000FE20, 0x0000FE8A, 0x0A},
|
|
{0x4000FE21, 0x0000FEAA, 0x0A},
|
|
{0x0000FE8B, 0x0000FE83, 0x03},
|
|
{0x82FF0188, 0x9BFF0188, 0x1B},
|
|
{0xAFF0CC02, 0xAFF0CC1B, 0x1B},
|
|
}
|
|
for i, tt := range tests {
|
|
if out := tt.in.updateTertiary(tt.t); out != tt.out {
|
|
t.Errorf("%d: was %X; want %X", i, out, tt.out)
|
|
}
|
|
}
|
|
}
|