golang.org/x/text@v0.14.0/unicode/cldr/collate_test.go (about) 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 5 package cldr 6 7 import ( 8 "fmt" 9 "strings" 10 "testing" 11 ) 12 13 // A recorder implements the RuleProcessor interface, whereby its methods 14 // simply record the invocations. 15 type recorder struct { 16 calls []string 17 } 18 19 func (r *recorder) Reset(anchor string, before int) error { 20 if before > 5 { 21 return fmt.Errorf("before %d > 5", before) 22 } 23 r.calls = append(r.calls, fmt.Sprintf("R:%s-%d", anchor, before)) 24 return nil 25 } 26 27 func (r *recorder) Insert(level int, str, context, extend string) error { 28 s := fmt.Sprintf("O:%d:%s", level, str) 29 if context != "" { 30 s += "|" + context 31 } 32 if extend != "" { 33 s += "/" + extend 34 } 35 r.calls = append(r.calls, s) 36 return nil 37 } 38 39 func (r *recorder) Index(id string) { 40 r.calls = append(r.calls, fmt.Sprintf("I:%s", id)) 41 } 42 43 func (r *recorder) Error(err error) { 44 r.calls = append(r.calls, fmt.Sprintf("E:%v", err)) 45 } 46 47 func TestRuleProcessor(t *testing.T) { 48 for _, tt := range []struct { 49 desc string 50 in string 51 out string 52 }{ 53 {desc: "empty"}, 54 {desc: "whitespace and comments only", 55 in: ` 56 57 58 # adsfads 59 # adfadf 60 `, 61 }, 62 { 63 desc: "reset anchor", 64 in: ` 65 & a 66 &b # 67 & [ before 3 ] c 68 & [before 4] d & ee 69 & [first tertiary ignorable] 70 &'g' 71 & 'h''h'h'h' 72 &'\u0069' # LATIN SMALL LETTER I 73 `, 74 out: ` 75 R:a-0 76 R:b-0 77 R:c-3 78 R:d-4 79 R:ee-0 80 R:<first tertiary ignorable/>-0 81 R:g-0 82 R:hhhh-0 83 R:i-0 84 `, 85 }, 86 { 87 desc: "ordering", 88 in: ` 89 & 0 90 < 1 <<''2# 91 <<< 3'3''33'3# 92 <<<<4 93 = 5 << 6 | s 94 <<<< 7 / z 95 << 8'' | s / ch 96 `, 97 out: ` 98 R:0-0 99 O:1:1 100 O:2:'2 101 O:3:33333 102 O:4:4 103 O:5:5 104 O:2:6|s 105 O:4:7/z 106 O:2:8'|s/ch 107 `, 108 }, 109 { 110 desc: "index", 111 in: "< '\ufdd0'A", 112 out: "I:A", 113 }, 114 { 115 desc: "sequence", 116 in: ` 117 & 0 118 <<* 1234 119 <* a-cde-f 120 =* q-q 121 `, 122 out: ` 123 R:0-0 124 O:2:1 125 O:2:2 126 O:2:3 127 O:2:4 128 O:1:a 129 O:1:b 130 O:1:c 131 O:1:d 132 O:1:e 133 O:1:f 134 O:5:q 135 `, 136 }, 137 { 138 desc: "compact", 139 in: "&B<t<<<T<s<<<S<e<<<E", 140 out: ` 141 R:B-0 142 O:1:t 143 O:3:T 144 O:1:s 145 O:3:S 146 O:1:e 147 O:3:E 148 `, 149 }, 150 { 151 desc: "err operator", 152 in: "a", 153 out: "E:1: illegal operator 'a'", 154 }, 155 { 156 desc: "err line number", 157 in: `& a 158 << b 159 a`, 160 out: ` 161 R:a-0 162 O:2:b 163 E:3: illegal operator 'a'`, 164 }, 165 { 166 desc: "err empty anchor", 167 in: " & ", 168 out: "E:1: missing string", 169 }, 170 { 171 desc: "err anchor invalid special 1", 172 in: " & [ foo ", 173 out: "E:1: unmatched bracket", 174 }, 175 { 176 desc: "err anchor invalid special 2", 177 in: "&[", 178 out: "E:1: unmatched bracket", 179 }, 180 { 181 desc: "err anchor invalid before 1", 182 in: "&[before a]", 183 out: `E:1: strconv.ParseUint: parsing "a": invalid syntax`, 184 }, 185 { 186 desc: "err anchor invalid before 2", 187 in: "&[before 12]", 188 out: `E:1: strconv.ParseUint: parsing "12": value out of range`, 189 }, 190 { 191 desc: "err anchor invalid before 3", 192 in: "&[before 2]", 193 out: "E:1: missing string", 194 }, 195 { 196 desc: "err anchor invalid before 4", 197 in: "&[before 6] a", 198 out: "E:1: before 6 > 5", 199 }, 200 { 201 desc: "err empty order", 202 in: " < ", 203 out: "E:1: missing string", 204 }, 205 { 206 desc: "err empty identity", 207 in: " = ", 208 out: "E:1: missing string", 209 }, 210 { 211 desc: "err empty context", 212 in: " < a | ", 213 out: "E:1: missing string after context", 214 }, 215 { 216 desc: "err empty extend", 217 in: " < a / ", 218 out: "E:1: missing string after extension", 219 }, 220 { 221 desc: "err empty sequence", 222 in: " <* ", 223 out: "E:1: empty sequence", 224 }, 225 { 226 desc: "err sequence 1", 227 in: " <* -a", 228 out: "E:1: range without starter value", 229 }, 230 { 231 desc: "err sequence 3", 232 in: " <* a-a-b", 233 out: `O:1:a 234 E:1: range without starter value 235 `, 236 }, 237 { 238 desc: "err sequence 3", 239 in: " <* b-a", 240 out: `O:1:b 241 E:1: invalid range 'b'-'a' 242 `, 243 }, 244 { 245 desc: "err unmatched quote", 246 in: " < 'b", 247 out: ` E:1: unmatched single quote 248 `, 249 }, 250 } { 251 rec := &recorder{} 252 err := Collation{ 253 Cr: []*Common{ 254 {hidden: hidden{CharData: tt.in}}, 255 }, 256 }.Process(rec) 257 if err != nil { 258 rec.Error(err) 259 } 260 got := rec.calls 261 want := strings.Split(strings.TrimSpace(tt.out), "\n") 262 if tt.out == "" { 263 want = nil 264 } 265 if len(got) != len(want) { 266 t.Errorf("%s: nResults: got %d; want %d", tt.desc, len(got), len(want)) 267 continue 268 } 269 for i, g := range got { 270 if want := strings.TrimSpace(want[i]); g != want { 271 t.Errorf("%s:%d: got %q; want %q", tt.desc, i, g, want) 272 } 273 } 274 } 275 }