You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

184 lines
4.2 KiB

  1. // Copyright 2012 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. package colltab
  5. import (
  6. "fmt"
  7. "testing"
  8. "unicode"
  9. )
  10. func (e Elem) String() string {
  11. q := ""
  12. if v := e.Quaternary(); v == MaxQuaternary {
  13. q = "max"
  14. } else {
  15. q = fmt.Sprint(v)
  16. }
  17. return fmt.Sprintf("[%d, %d, %d, %s]",
  18. e.Primary(),
  19. e.Secondary(),
  20. e.Tertiary(),
  21. q)
  22. }
  23. type ceTest struct {
  24. f func(inout []int) (Elem, ceType)
  25. arg []int
  26. }
  27. func makeCE(weights []int) Elem {
  28. ce, _ := MakeElem(weights[0], weights[1], weights[2], uint8(weights[3]))
  29. return ce
  30. }
  31. var defaultValues = []int{0, defaultSecondary, defaultTertiary, 0}
  32. func e(w ...int) Elem {
  33. return makeCE(append(w, defaultValues[len(w):]...))
  34. }
  35. func makeContractIndex(index, n, offset int) Elem {
  36. const (
  37. contractID = 0xC0000000
  38. maxNBits = 4
  39. maxTrieIndexBits = 12
  40. maxContractOffsetBits = 13
  41. )
  42. ce := Elem(contractID)
  43. ce += Elem(offset << (maxNBits + maxTrieIndexBits))
  44. ce += Elem(index << maxNBits)
  45. ce += Elem(n)
  46. return ce
  47. }
  48. func makeExpandIndex(index int) Elem {
  49. const expandID = 0xE0000000
  50. return expandID + Elem(index)
  51. }
  52. func makeDecompose(t1, t2 int) Elem {
  53. const decompID = 0xF0000000
  54. return Elem(t2<<8+t1) + decompID
  55. }
  56. func normalCE(inout []int) (ce Elem, t ceType) {
  57. ce = makeCE(inout)
  58. inout[0] = ce.Primary()
  59. inout[1] = ce.Secondary()
  60. inout[2] = int(ce.Tertiary())
  61. inout[3] = int(ce.CCC())
  62. return ce, ceNormal
  63. }
  64. func expandCE(inout []int) (ce Elem, t ceType) {
  65. ce = makeExpandIndex(inout[0])
  66. inout[0] = splitExpandIndex(ce)
  67. return ce, ceExpansionIndex
  68. }
  69. func contractCE(inout []int) (ce Elem, t ceType) {
  70. ce = makeContractIndex(inout[0], inout[1], inout[2])
  71. i, n, o := splitContractIndex(ce)
  72. inout[0], inout[1], inout[2] = i, n, o
  73. return ce, ceContractionIndex
  74. }
  75. func decompCE(inout []int) (ce Elem, t ceType) {
  76. ce = makeDecompose(inout[0], inout[1])
  77. t1, t2 := splitDecompose(ce)
  78. inout[0], inout[1] = int(t1), int(t2)
  79. return ce, ceDecompose
  80. }
  81. var ceTests = []ceTest{
  82. {normalCE, []int{0, 0, 0, 0}},
  83. {normalCE, []int{0, 30, 3, 0}},
  84. {normalCE, []int{0, 30, 3, 0xFF}},
  85. {normalCE, []int{100, defaultSecondary, defaultTertiary, 0}},
  86. {normalCE, []int{100, defaultSecondary, defaultTertiary, 0xFF}},
  87. {normalCE, []int{100, defaultSecondary, 3, 0}},
  88. {normalCE, []int{0x123, defaultSecondary, 8, 0xFF}},
  89. {contractCE, []int{0, 0, 0}},
  90. {contractCE, []int{1, 1, 1}},
  91. {contractCE, []int{1, (1 << maxNBits) - 1, 1}},
  92. {contractCE, []int{(1 << maxTrieIndexBits) - 1, 1, 1}},
  93. {contractCE, []int{1, 1, (1 << maxContractOffsetBits) - 1}},
  94. {expandCE, []int{0}},
  95. {expandCE, []int{5}},
  96. {expandCE, []int{(1 << maxExpandIndexBits) - 1}},
  97. {decompCE, []int{0, 0}},
  98. {decompCE, []int{1, 1}},
  99. {decompCE, []int{0x1F, 0x1F}},
  100. }
  101. func TestColElem(t *testing.T) {
  102. for i, tt := range ceTests {
  103. inout := make([]int, len(tt.arg))
  104. copy(inout, tt.arg)
  105. ce, typ := tt.f(inout)
  106. if ce.ctype() != typ {
  107. t.Errorf("%d: type is %d; want %d (ColElem: %X)", i, ce.ctype(), typ, ce)
  108. }
  109. for j, a := range tt.arg {
  110. if inout[j] != a {
  111. t.Errorf("%d: argument %d is %X; want %X (ColElem: %X)", i, j, inout[j], a, ce)
  112. }
  113. }
  114. }
  115. }
  116. type implicitTest struct {
  117. r rune
  118. p int
  119. }
  120. var implicitTests = []implicitTest{
  121. {0x33FF, 0x533FF},
  122. {0x3400, 0x23400},
  123. {0x4DC0, 0x54DC0},
  124. {0x4DFF, 0x54DFF},
  125. {0x4E00, 0x14E00},
  126. {0x9FCB, 0x19FCB},
  127. {0xA000, 0x5A000},
  128. {0xF8FF, 0x5F8FF},
  129. {0xF900, 0x1F900},
  130. {0xFA23, 0x1FA23},
  131. {0xFAD9, 0x1FAD9},
  132. {0xFB00, 0x5FB00},
  133. {0x20000, 0x40000},
  134. {0x2B81C, 0x4B81C},
  135. {unicode.MaxRune, 0x15FFFF}, // maximum primary value
  136. }
  137. func TestImplicit(t *testing.T) {
  138. for _, tt := range implicitTests {
  139. if p := implicitPrimary(tt.r); p != tt.p {
  140. t.Errorf("%U: was %X; want %X", tt.r, p, tt.p)
  141. }
  142. }
  143. }
  144. func TestUpdateTertiary(t *testing.T) {
  145. tests := []struct {
  146. in, out Elem
  147. t uint8
  148. }{
  149. {0x4000FE20, 0x0000FE8A, 0x0A},
  150. {0x4000FE21, 0x0000FEAA, 0x0A},
  151. {0x0000FE8B, 0x0000FE83, 0x03},
  152. {0x82FF0188, 0x9BFF0188, 0x1B},
  153. {0xAFF0CC02, 0xAFF0CC1B, 0x1B},
  154. }
  155. for i, tt := range tests {
  156. if out := tt.in.updateTertiary(tt.t); out != tt.out {
  157. t.Errorf("%d: was %X; want %X", i, out, tt.out)
  158. }
  159. }
  160. }