numeric_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright 2014 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. "reflect"
  7. "strings"
  8. "testing"
  9. "golang.org/x/text/internal/testtext"
  10. )
  11. const (
  12. digSec = defaultSecondary
  13. digTert = defaultTertiary
  14. )
  15. var tPlus3 = e(0, 50, digTert+3)
  16. // numWeighter is a testWeighter used for testing numericWeighter.
  17. var numWeighter = testWeighter{
  18. "0": p(100),
  19. "0": []Elem{e(100, digSec, digTert+1)}, // U+FF10 FULLWIDTH DIGIT ZERO
  20. "₀": []Elem{e(100, digSec, digTert+5)}, // U+2080 SUBSCRIPT ZERO
  21. "1": p(101),
  22. // Allow non-primary collation elements to be inserted.
  23. "١": append(p(101), tPlus3), // U+0661 ARABIC-INDIC DIGIT ONE
  24. // Allow varying tertiary weight if the number is Nd.
  25. "1": []Elem{e(101, digSec, digTert+1)}, // U+FF11 FULLWIDTH DIGIT ONE
  26. "2": p(102),
  27. // Allow non-primary collation elements to be inserted.
  28. "٢": append(p(102), tPlus3), // U+0662 ARABIC-INDIC DIGIT TWO
  29. // Varying tertiary weights should be ignored.
  30. "2": []Elem{e(102, digSec, digTert+3)}, // U+FF12 FULLWIDTH DIGIT TWO
  31. "3": p(103),
  32. "4": p(104),
  33. "5": p(105),
  34. "6": p(106),
  35. "7": p(107),
  36. // Weights must be strictly monotonically increasing, but do not need to be
  37. // consecutive.
  38. "8": p(118),
  39. "9": p(119),
  40. // Allow non-primary collation elements to be inserted.
  41. "٩": append(p(119), tPlus3), // U+0669 ARABIC-INDIC DIGIT NINE
  42. // Varying tertiary weights should be ignored.
  43. "9": []Elem{e(119, digSec, digTert+1)}, // U+FF19 FULLWIDTH DIGIT NINE
  44. "₉": []Elem{e(119, digSec, digTert+5)}, // U+2089 SUBSCRIPT NINE
  45. "a": p(5),
  46. "b": p(6),
  47. "c": p(8, 2),
  48. "klm": p(99),
  49. "nop": p(121),
  50. "x": p(200),
  51. "y": p(201),
  52. }
  53. func p(w ...int) (elems []Elem) {
  54. for _, x := range w {
  55. e, _ := MakeElem(x, digSec, digTert, 0)
  56. elems = append(elems, e)
  57. }
  58. return elems
  59. }
  60. func TestNumericAppendNext(t *testing.T) {
  61. for _, tt := range []struct {
  62. in string
  63. w []Elem
  64. }{
  65. {"a", p(5)},
  66. {"klm", p(99)},
  67. {"aa", p(5, 5)},
  68. {"1", p(120, 1, 101)},
  69. {"0", p(120, 0)},
  70. {"01", p(120, 1, 101)},
  71. {"0001", p(120, 1, 101)},
  72. {"10", p(120, 2, 101, 100)},
  73. {"99", p(120, 2, 119, 119)},
  74. {"9999", p(120, 4, 119, 119, 119, 119)},
  75. {"1a", p(120, 1, 101, 5)},
  76. {"0b", p(120, 0, 6)},
  77. {"01c", p(120, 1, 101, 8, 2)},
  78. {"10x", p(120, 2, 101, 100, 200)},
  79. {"99y", p(120, 2, 119, 119, 201)},
  80. {"9999nop", p(120, 4, 119, 119, 119, 119, 121)},
  81. // Allow follow-up collation elements if they have a zero non-primary.
  82. {"١٢٩", []Elem{e(120), e(3), e(101), tPlus3, e(102), tPlus3, e(119), tPlus3}},
  83. {
  84. "129",
  85. []Elem{
  86. e(120), e(3),
  87. e(101, digSec, digTert+1),
  88. e(102, digSec, digTert+3),
  89. e(119, digSec, digTert+1),
  90. },
  91. },
  92. // Ensure AppendNext* adds to the given buffer.
  93. {"a10", p(5, 120, 2, 101, 100)},
  94. } {
  95. nw := NewNumericWeighter(numWeighter)
  96. b := []byte(tt.in)
  97. got := []Elem(nil)
  98. for n, sz := 0, 0; n < len(b); {
  99. got, sz = nw.AppendNext(got, b[n:])
  100. n += sz
  101. }
  102. if !reflect.DeepEqual(got, tt.w) {
  103. t.Errorf("AppendNext(%q) =\n%v; want\n%v", tt.in, got, tt.w)
  104. }
  105. got = nil
  106. for n, sz := 0, 0; n < len(tt.in); {
  107. got, sz = nw.AppendNextString(got, tt.in[n:])
  108. n += sz
  109. }
  110. if !reflect.DeepEqual(got, tt.w) {
  111. t.Errorf("AppendNextString(%q) =\n%v; want\n%v", tt.in, got, tt.w)
  112. }
  113. }
  114. }
  115. func TestNumericOverflow(t *testing.T) {
  116. manyDigits := strings.Repeat("9", maxDigits+1) + "a"
  117. nw := NewNumericWeighter(numWeighter)
  118. got, n := nw.AppendNextString(nil, manyDigits)
  119. if n != maxDigits {
  120. t.Errorf("n: got %d; want %d", n, maxDigits)
  121. }
  122. if got[1].Primary() != maxDigits {
  123. t.Errorf("primary(e[1]): got %d; want %d", n, maxDigits)
  124. }
  125. }
  126. func TestNumericWeighterAlloc(t *testing.T) {
  127. buf := make([]Elem, 100)
  128. w := NewNumericWeighter(numWeighter)
  129. s := "1234567890a"
  130. nNormal := testtext.AllocsPerRun(3, func() { numWeighter.AppendNextString(buf, s) })
  131. nNumeric := testtext.AllocsPerRun(3, func() { w.AppendNextString(buf, s) })
  132. if n := nNumeric - nNormal; n > 0 {
  133. t.Errorf("got %f; want 0", n)
  134. }
  135. }