github.com/go-xe2/third@v1.0.3/golang.org/x/text/internal/number/pattern_test.go (about) 1 // Copyright 2015 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 number 6 7 import ( 8 "reflect" 9 "testing" 10 "unsafe" 11 ) 12 13 var testCases = []struct { 14 pat string 15 want *Pattern 16 }{{ 17 "#", 18 &Pattern{ 19 FormatWidth: 1, 20 // TODO: Should MinIntegerDigits be 1? 21 }, 22 }, { 23 "0", 24 &Pattern{ 25 FormatWidth: 1, 26 RoundingContext: RoundingContext{ 27 MinIntegerDigits: 1, 28 }, 29 }, 30 }, { 31 "+0", 32 &Pattern{ 33 Affix: "\x01+\x00", 34 FormatWidth: 2, 35 RoundingContext: RoundingContext{ 36 MinIntegerDigits: 1, 37 }, 38 }, 39 }, { 40 "0+", 41 &Pattern{ 42 Affix: "\x00\x01+", 43 FormatWidth: 2, 44 RoundingContext: RoundingContext{ 45 MinIntegerDigits: 1, 46 }, 47 }, 48 }, { 49 "0000", 50 &Pattern{ 51 FormatWidth: 4, 52 RoundingContext: RoundingContext{ 53 MinIntegerDigits: 4, 54 }, 55 }, 56 }, { 57 ".#", 58 &Pattern{ 59 FormatWidth: 2, 60 RoundingContext: RoundingContext{ 61 MaxFractionDigits: 1, 62 }, 63 }, 64 }, { 65 "#0.###", 66 &Pattern{ 67 FormatWidth: 6, 68 RoundingContext: RoundingContext{ 69 MinIntegerDigits: 1, 70 MaxFractionDigits: 3, 71 }, 72 }, 73 }, { 74 "#0.######", 75 &Pattern{ 76 FormatWidth: 9, 77 RoundingContext: RoundingContext{ 78 MinIntegerDigits: 1, 79 MaxFractionDigits: 6, 80 }, 81 }, 82 }, { 83 "#,0", 84 &Pattern{ 85 FormatWidth: 3, 86 GroupingSize: [2]uint8{1, 0}, 87 RoundingContext: RoundingContext{ 88 MinIntegerDigits: 1, 89 }, 90 }, 91 }, { 92 "#,0.00", 93 &Pattern{ 94 FormatWidth: 6, 95 GroupingSize: [2]uint8{1, 0}, 96 RoundingContext: RoundingContext{ 97 MinIntegerDigits: 1, 98 MinFractionDigits: 2, 99 MaxFractionDigits: 2, 100 }, 101 }, 102 }, { 103 "#,##0.###", 104 &Pattern{ 105 FormatWidth: 9, 106 GroupingSize: [2]uint8{3, 0}, 107 RoundingContext: RoundingContext{ 108 MinIntegerDigits: 1, 109 MaxFractionDigits: 3, 110 }, 111 }, 112 }, { 113 "#,##,##0.###", 114 &Pattern{ 115 FormatWidth: 12, 116 GroupingSize: [2]uint8{3, 2}, 117 RoundingContext: RoundingContext{ 118 MinIntegerDigits: 1, 119 MaxFractionDigits: 3, 120 }, 121 }, 122 }, { 123 // Ignore additional separators. 124 "#,####,##,##0.###", 125 &Pattern{ 126 FormatWidth: 17, 127 GroupingSize: [2]uint8{3, 2}, 128 RoundingContext: RoundingContext{ 129 MinIntegerDigits: 1, 130 MaxFractionDigits: 3, 131 }, 132 }, 133 }, { 134 "#E0", 135 &Pattern{ 136 FormatWidth: 3, 137 RoundingContext: RoundingContext{ 138 MaxIntegerDigits: 1, 139 MinExponentDigits: 1, 140 }, 141 }, 142 }, { 143 // At least one exponent digit is required. As long as this is true, one can 144 // determine that scientific rendering is needed if MinExponentDigits > 0. 145 "#E#", 146 nil, 147 }, { 148 "0E0", 149 &Pattern{ 150 FormatWidth: 3, 151 RoundingContext: RoundingContext{ 152 MinIntegerDigits: 1, 153 MinExponentDigits: 1, 154 }, 155 }, 156 }, { 157 "##0.###E00", 158 &Pattern{ 159 FormatWidth: 10, 160 RoundingContext: RoundingContext{ 161 MinIntegerDigits: 1, 162 MaxIntegerDigits: 3, 163 MaxFractionDigits: 3, 164 MinExponentDigits: 2, 165 }, 166 }, 167 }, { 168 "##00.0#E0", 169 &Pattern{ 170 FormatWidth: 9, 171 RoundingContext: RoundingContext{ 172 MinIntegerDigits: 2, 173 MaxIntegerDigits: 4, 174 MinFractionDigits: 1, 175 MaxFractionDigits: 2, 176 MinExponentDigits: 1, 177 }, 178 }, 179 }, { 180 "#00.0E+0", 181 &Pattern{ 182 FormatWidth: 8, 183 Flags: AlwaysExpSign, 184 RoundingContext: RoundingContext{ 185 MinIntegerDigits: 2, 186 MaxIntegerDigits: 3, 187 MinFractionDigits: 1, 188 MaxFractionDigits: 1, 189 MinExponentDigits: 1, 190 }, 191 }, 192 }, { 193 "0.0E++0", 194 nil, 195 }, { 196 "#0E+", 197 nil, 198 }, { 199 // significant digits 200 "@", 201 &Pattern{ 202 FormatWidth: 1, 203 RoundingContext: RoundingContext{ 204 MinSignificantDigits: 1, 205 MaxSignificantDigits: 1, 206 MaxFractionDigits: -1, 207 }, 208 }, 209 }, { 210 // significant digits 211 "@@@@", 212 &Pattern{ 213 FormatWidth: 4, 214 RoundingContext: RoundingContext{ 215 MinSignificantDigits: 4, 216 MaxSignificantDigits: 4, 217 MaxFractionDigits: -1, 218 }, 219 }, 220 }, { 221 "@###", 222 &Pattern{ 223 FormatWidth: 4, 224 RoundingContext: RoundingContext{ 225 MinSignificantDigits: 1, 226 MaxSignificantDigits: 4, 227 MaxFractionDigits: -1, 228 }, 229 }, 230 }, { 231 // Exponents in significant digits mode gets normalized. 232 "@@E0", 233 &Pattern{ 234 FormatWidth: 4, 235 RoundingContext: RoundingContext{ 236 MinIntegerDigits: 1, 237 MaxIntegerDigits: 1, 238 MinFractionDigits: 1, 239 MaxFractionDigits: 1, 240 MinExponentDigits: 1, 241 }, 242 }, 243 }, { 244 "@###E00", 245 &Pattern{ 246 FormatWidth: 7, 247 RoundingContext: RoundingContext{ 248 MinIntegerDigits: 1, 249 MaxIntegerDigits: 1, 250 MinFractionDigits: 0, 251 MaxFractionDigits: 3, 252 MinExponentDigits: 2, 253 }, 254 }, 255 }, { 256 // The significant digits mode does not allow fractions. 257 "@###.#E0", 258 nil, 259 }, { 260 //alternative negative pattern 261 "#0.###;(#0.###)", 262 &Pattern{ 263 Affix: "\x00\x00\x01(\x01)", 264 NegOffset: 2, 265 FormatWidth: 6, 266 RoundingContext: RoundingContext{ 267 MinIntegerDigits: 1, 268 MaxFractionDigits: 3, 269 }, 270 }, 271 }, { 272 // Rounding increment 273 "1.05", 274 &Pattern{ 275 FormatWidth: 4, 276 RoundingContext: RoundingContext{ 277 Increment: 105, 278 IncrementScale: 2, 279 MinIntegerDigits: 1, 280 MinFractionDigits: 2, 281 MaxFractionDigits: 2, 282 }, 283 }, 284 }, { 285 // Rounding increment with grouping 286 "1,05", 287 &Pattern{ 288 FormatWidth: 4, 289 GroupingSize: [2]uint8{2, 0}, 290 RoundingContext: RoundingContext{ 291 Increment: 105, 292 IncrementScale: 0, 293 MinIntegerDigits: 3, 294 MinFractionDigits: 0, 295 MaxFractionDigits: 0, 296 }, 297 }, 298 }, { 299 "0.0%", 300 &Pattern{ 301 Affix: "\x00\x01%", 302 FormatWidth: 4, 303 RoundingContext: RoundingContext{ 304 DigitShift: 2, 305 MinIntegerDigits: 1, 306 MinFractionDigits: 1, 307 MaxFractionDigits: 1, 308 }, 309 }, 310 }, { 311 "0.0‰", 312 &Pattern{ 313 Affix: "\x00\x03‰", 314 FormatWidth: 4, 315 RoundingContext: RoundingContext{ 316 DigitShift: 3, 317 MinIntegerDigits: 1, 318 MinFractionDigits: 1, 319 MaxFractionDigits: 1, 320 }, 321 }, 322 }, { 323 "#,##0.00¤", 324 &Pattern{ 325 Affix: "\x00\x02¤", 326 FormatWidth: 9, 327 GroupingSize: [2]uint8{3, 0}, 328 RoundingContext: RoundingContext{ 329 MinIntegerDigits: 1, 330 MinFractionDigits: 2, 331 MaxFractionDigits: 2, 332 }, 333 }, 334 }, { 335 "#,##0.00 ¤;(#,##0.00 ¤)", 336 &Pattern{Affix: "\x00\x04\u00a0¤\x01(\x05\u00a0¤)", 337 NegOffset: 6, 338 FormatWidth: 10, 339 GroupingSize: [2]uint8{3, 0}, 340 RoundingContext: RoundingContext{ 341 DigitShift: 0, 342 MinIntegerDigits: 1, 343 MinFractionDigits: 2, 344 MaxFractionDigits: 2, 345 }, 346 }, 347 }, { 348 // padding 349 "*x#", 350 &Pattern{ 351 PadRune: 'x', 352 FormatWidth: 1, 353 }, 354 }, { 355 // padding 356 "#*x", 357 &Pattern{ 358 PadRune: 'x', 359 FormatWidth: 1, 360 Flags: PadBeforeSuffix, 361 }, 362 }, { 363 "*xpre#suf", 364 &Pattern{ 365 Affix: "\x03pre\x03suf", 366 PadRune: 'x', 367 FormatWidth: 7, 368 }, 369 }, { 370 "pre*x#suf", 371 &Pattern{ 372 Affix: "\x03pre\x03suf", 373 PadRune: 'x', 374 FormatWidth: 7, 375 Flags: PadAfterPrefix, 376 }, 377 }, { 378 "pre#*xsuf", 379 &Pattern{ 380 Affix: "\x03pre\x03suf", 381 PadRune: 'x', 382 FormatWidth: 7, 383 Flags: PadBeforeSuffix, 384 }, 385 }, { 386 "pre#suf*x", 387 &Pattern{ 388 Affix: "\x03pre\x03suf", 389 PadRune: 'x', 390 FormatWidth: 7, 391 Flags: PadAfterSuffix, 392 }, 393 }, { 394 `* #0 o''clock`, 395 &Pattern{Affix: "\x00\x09 o\\'clock", 396 FormatWidth: 10, 397 PadRune: 32, 398 RoundingContext: RoundingContext{ 399 MinIntegerDigits: 0x1, 400 }, 401 }, 402 }, { 403 `'123'* #0'456'`, 404 &Pattern{Affix: "\x05'123'\x05'456'", 405 FormatWidth: 8, 406 PadRune: 32, 407 RoundingContext: RoundingContext{ 408 MinIntegerDigits: 0x1, 409 }, 410 Flags: PadAfterPrefix}, 411 }, { 412 // no duplicate padding 413 "*xpre#suf*x", nil, 414 }, { 415 // no duplicate padding 416 "*xpre#suf*x", nil, 417 }} 418 419 func TestParsePattern(t *testing.T) { 420 for i, tc := range testCases { 421 t.Run(tc.pat, func(t *testing.T) { 422 f, err := ParsePattern(tc.pat) 423 if !reflect.DeepEqual(f, tc.want) { 424 t.Errorf("%d:%s:\ngot %#v;\nwant %#v", i, tc.pat, f, tc.want) 425 } 426 if got, want := err != nil, tc.want == nil; got != want { 427 t.Errorf("%d:%s:error: got %v; want %v", i, tc.pat, err, want) 428 } 429 }) 430 } 431 } 432 433 func TestPatternSize(t *testing.T) { 434 if sz := unsafe.Sizeof(Pattern{}); sz > 56 { 435 t.Errorf("got %d; want <= 56", sz) 436 } 437 438 }