// 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) } } }