order_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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 build
  5. import (
  6. "strconv"
  7. "testing"
  8. "golang.org/x/text/internal/colltab"
  9. )
  10. type entryTest struct {
  11. f func(in []int) (uint32, error)
  12. arg []int
  13. val uint32
  14. }
  15. // makeList returns a list of entries of length n+2, with n normal
  16. // entries plus a leading and trailing anchor.
  17. func makeList(n int) []*entry {
  18. es := make([]*entry, n+2)
  19. weights := []rawCE{{w: []int{100, 20, 5, 0}}}
  20. for i := range es {
  21. runes := []rune{rune(i)}
  22. es[i] = &entry{
  23. runes: runes,
  24. elems: weights,
  25. }
  26. weights = nextWeight(colltab.Primary, weights)
  27. }
  28. for i := 1; i < len(es); i++ {
  29. es[i-1].next = es[i]
  30. es[i].prev = es[i-1]
  31. _, es[i-1].level = compareWeights(es[i-1].elems, es[i].elems)
  32. }
  33. es[0].exclude = true
  34. es[0].logical = firstAnchor
  35. es[len(es)-1].exclude = true
  36. es[len(es)-1].logical = lastAnchor
  37. return es
  38. }
  39. func TestNextIndexed(t *testing.T) {
  40. const n = 5
  41. es := makeList(n)
  42. for i := int64(0); i < 1<<n; i++ {
  43. mask := strconv.FormatInt(i+(1<<n), 2)
  44. for i, c := range mask {
  45. es[i].exclude = c == '1'
  46. }
  47. e := es[0]
  48. for i, c := range mask {
  49. if c == '0' {
  50. e, _ = e.nextIndexed()
  51. if e != es[i] {
  52. t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems)
  53. }
  54. }
  55. }
  56. if e, _ = e.nextIndexed(); e != nil {
  57. t.Errorf("%d: expected nil entry; found %d", i, e.elems)
  58. }
  59. }
  60. }
  61. func TestRemove(t *testing.T) {
  62. const n = 5
  63. for i := int64(0); i < 1<<n; i++ {
  64. es := makeList(n)
  65. mask := strconv.FormatInt(i+(1<<n), 2)
  66. for i, c := range mask {
  67. if c == '0' {
  68. es[i].remove()
  69. }
  70. }
  71. e := es[0]
  72. for i, c := range mask {
  73. if c == '1' {
  74. if e != es[i] {
  75. t.Errorf("%d: expected entry %d; found %d", i, es[i].elems, e.elems)
  76. }
  77. e, _ = e.nextIndexed()
  78. }
  79. }
  80. if e != nil {
  81. t.Errorf("%d: expected nil entry; found %d", i, e.elems)
  82. }
  83. }
  84. }
  85. // nextPerm generates the next permutation of the array. The starting
  86. // permutation is assumed to be a list of integers sorted in increasing order.
  87. // It returns false if there are no more permuations left.
  88. func nextPerm(a []int) bool {
  89. i := len(a) - 2
  90. for ; i >= 0; i-- {
  91. if a[i] < a[i+1] {
  92. break
  93. }
  94. }
  95. if i < 0 {
  96. return false
  97. }
  98. for j := len(a) - 1; j >= i; j-- {
  99. if a[j] > a[i] {
  100. a[i], a[j] = a[j], a[i]
  101. break
  102. }
  103. }
  104. for j := i + 1; j < (len(a)+i+1)/2; j++ {
  105. a[j], a[len(a)+i-j] = a[len(a)+i-j], a[j]
  106. }
  107. return true
  108. }
  109. func TestInsertAfter(t *testing.T) {
  110. const n = 5
  111. orig := makeList(n)
  112. perm := make([]int, n)
  113. for i := range perm {
  114. perm[i] = i + 1
  115. }
  116. for ok := true; ok; ok = nextPerm(perm) {
  117. es := makeList(n)
  118. last := es[0]
  119. for _, i := range perm {
  120. last.insertAfter(es[i])
  121. last = es[i]
  122. }
  123. for _, e := range es {
  124. e.elems = es[0].elems
  125. }
  126. e := es[0]
  127. for _, i := range perm {
  128. e, _ = e.nextIndexed()
  129. if e.runes[0] != orig[i].runes[0] {
  130. t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes, e.runes)
  131. break
  132. }
  133. }
  134. }
  135. }
  136. func TestInsertBefore(t *testing.T) {
  137. const n = 5
  138. orig := makeList(n)
  139. perm := make([]int, n)
  140. for i := range perm {
  141. perm[i] = i + 1
  142. }
  143. for ok := true; ok; ok = nextPerm(perm) {
  144. es := makeList(n)
  145. last := es[len(es)-1]
  146. for _, i := range perm {
  147. last.insertBefore(es[i])
  148. last = es[i]
  149. }
  150. for _, e := range es {
  151. e.elems = es[0].elems
  152. }
  153. e := es[0]
  154. for i := n - 1; i >= 0; i-- {
  155. e, _ = e.nextIndexed()
  156. if e.runes[0] != rune(perm[i]) {
  157. t.Errorf("%d:%d: expected entry %X; found %X", perm, i, orig[i].runes, e.runes)
  158. break
  159. }
  160. }
  161. }
  162. }
  163. type entryLessTest struct {
  164. a, b *entry
  165. res bool
  166. }
  167. var (
  168. w1 = []rawCE{{w: []int{100, 20, 5, 5}}}
  169. w2 = []rawCE{{w: []int{101, 20, 5, 5}}}
  170. )
  171. var entryLessTests = []entryLessTest{
  172. {&entry{str: "a", elems: w1},
  173. &entry{str: "a", elems: w1},
  174. false,
  175. },
  176. {&entry{str: "a", elems: w1},
  177. &entry{str: "a", elems: w2},
  178. true,
  179. },
  180. {&entry{str: "a", elems: w1},
  181. &entry{str: "b", elems: w1},
  182. true,
  183. },
  184. {&entry{str: "a", elems: w2},
  185. &entry{str: "a", elems: w1},
  186. false,
  187. },
  188. {&entry{str: "c", elems: w1},
  189. &entry{str: "b", elems: w1},
  190. false,
  191. },
  192. {&entry{str: "a", elems: w1, logical: firstAnchor},
  193. &entry{str: "a", elems: w1},
  194. true,
  195. },
  196. {&entry{str: "a", elems: w1},
  197. &entry{str: "b", elems: w1, logical: firstAnchor},
  198. false,
  199. },
  200. {&entry{str: "b", elems: w1},
  201. &entry{str: "a", elems: w1, logical: lastAnchor},
  202. true,
  203. },
  204. {&entry{str: "a", elems: w1, logical: lastAnchor},
  205. &entry{str: "c", elems: w1},
  206. false,
  207. },
  208. }
  209. func TestEntryLess(t *testing.T) {
  210. for i, tt := range entryLessTests {
  211. if res := entryLess(tt.a, tt.b); res != tt.res {
  212. t.Errorf("%d: was %v; want %v", i, res, tt.res)
  213. }
  214. }
  215. }