1
2
3
4
5 package number
6
7 import (
8 "fmt"
9 "log"
10 "testing"
11
12 "golang.org/x/text/language"
13 )
14
15 func TestAppendDecimal(t *testing.T) {
16 type pairs map[string]string
17
18 testCases := []struct {
19 pattern string
20
21
22 pat *Pattern
23
24 test pairs
25 }{{
26 pattern: "0",
27 test: pairs{
28 "0": "0",
29 "1": "1",
30 "-1": "-1",
31 ".00": "0",
32 "10.": "10",
33 "12": "12",
34 "1.2": "1",
35 "NaN": "NaN",
36 "-Inf": "-∞",
37 },
38 }, {
39 pattern: "+0;+0",
40 test: pairs{
41 "0": "+0",
42 "1": "+1",
43 "-1": "-1",
44 ".00": "+0",
45 "10.": "+10",
46 "12": "+12",
47 "1.2": "+1",
48 "NaN": "NaN",
49 "-Inf": "-∞",
50 "Inf": "+∞",
51 },
52 }, {
53 pattern: "0 +;0 +",
54 test: pairs{
55 "0": "0 +",
56 "1": "1 +",
57 "-1": "1 -",
58 ".00": "0 +",
59 },
60 }, {
61 pattern: "0;0-",
62 test: pairs{
63 "-1": "1-",
64 "NaN": "NaN",
65 "-Inf": "∞-",
66 "Inf": "∞",
67 },
68 }, {
69 pattern: "0000",
70 test: pairs{
71 "0": "0000",
72 "1": "0001",
73 "12": "0012",
74 "12345": "12345",
75 },
76 }, {
77 pattern: ".0",
78 test: pairs{
79 "0": ".0",
80 "1": "1.0",
81 "1.2": "1.2",
82 "1.2345": "1.2",
83 },
84 }, {
85 pattern: "#.0",
86 test: pairs{
87 "0": ".0",
88 },
89 }, {
90 pattern: "#.0#",
91 test: pairs{
92 "0": ".0",
93 "1": "1.0",
94 },
95 }, {
96 pattern: "0.0#",
97 test: pairs{
98 "0": "0.0",
99 },
100 }, {
101 pattern: "#0.###",
102 test: pairs{
103 "0": "0",
104 "1": "1",
105 "1.2": "1.2",
106 "1.2345": "1.234",
107 "1234.5": "1234.5",
108 "1234.567": "1234.567",
109 },
110 }, {
111 pattern: "#0.######",
112 test: pairs{
113 "0": "0",
114 "1234.5678": "1234.5678",
115 "0.123456789": "0.123457",
116 "NaN": "NaN",
117 "Inf": "∞",
118 },
119
120
121 }, {
122 pattern: "#,#.00",
123 test: pairs{
124 "100": "1,0,0.00",
125 },
126 }, {
127 pattern: "#,0.##",
128 test: pairs{
129 "10": "1,0",
130 },
131 }, {
132 pattern: "#,0",
133 test: pairs{
134 "10": "1,0",
135 },
136 }, {
137 pattern: "#,##,#.00",
138 test: pairs{
139 "1000": "1,00,0.00",
140 },
141 }, {
142 pattern: "#,##0.###",
143 test: pairs{
144 "0": "0",
145 "1234.5678": "1,234.568",
146 "0.123456789": "0.123",
147 },
148 }, {
149 pattern: "#,##,##0.###",
150 test: pairs{
151 "0": "0",
152 "123456789012": "1,23,45,67,89,012",
153 "0.123456789": "0.123",
154 },
155 }, {
156 pattern: "0,00,000.###",
157 test: pairs{
158 "0": "0,00,000",
159 "123456789012": "1,23,45,67,89,012",
160 "12.3456789": "0,00,012.346",
161 "0.123456789": "0,00,000.123",
162 },
163
164
165 }, {
166 pattern: "#",
167 test: pairs{
168 ".00": "",
169 "0": "",
170 "1": "1",
171 "10.": "10",
172 },
173 }, {
174 pattern: ".#",
175 test: pairs{
176 "0": "",
177 "1": "1",
178 "1.2": "1.2",
179 "1.2345": "1.2",
180 },
181 }, {
182 pattern: "#,#.##",
183 test: pairs{
184 "10": "1,0",
185 },
186 }, {
187 pattern: "#,#",
188 test: pairs{
189 "10": "1,0",
190 },
191
192
193 }, {
194 pattern: "#,max_int=2",
195 pat: &Pattern{
196 RoundingContext: RoundingContext{
197 MaxIntegerDigits: 2,
198 },
199 },
200 test: pairs{
201 "2017": "17",
202 },
203 }, {
204 pattern: "0,max_int=2",
205 pat: &Pattern{
206 RoundingContext: RoundingContext{
207 MaxIntegerDigits: 2,
208 MinIntegerDigits: 1,
209 },
210 },
211 test: pairs{
212 "2000": "0",
213 "2001": "1",
214 "2017": "17",
215 },
216 }, {
217 pattern: "00,max_int=2",
218 pat: &Pattern{
219 RoundingContext: RoundingContext{
220 MaxIntegerDigits: 2,
221 MinIntegerDigits: 2,
222 },
223 },
224 test: pairs{
225 "2000": "00",
226 "2001": "01",
227 "2017": "17",
228 },
229 }, {
230 pattern: "@@@@,max_int=2",
231 pat: &Pattern{
232 RoundingContext: RoundingContext{
233 MaxIntegerDigits: 2,
234 MinSignificantDigits: 4,
235 },
236 },
237 test: pairs{
238 "2017": "17.00",
239 "2000": "0.000",
240 "2001": "1.000",
241 },
242
243
244 }, {
245 pattern: "@@##",
246 test: pairs{
247 "1": "1.0",
248 "0.1": "0.10",
249 "123": "123",
250 "1234": "1234",
251 "12345": "12340",
252 },
253 }, {
254 pattern: "@@@@",
255 test: pairs{
256 "1": "1.000",
257 ".1": "0.1000",
258 ".001": "0.001000",
259 "123": "123.0",
260 "1234": "1234",
261 "12345": "12340",
262 "NaN": "NaN",
263 "-Inf": "-∞",
264 },
265
266
267
268
269
270
271 }, {
272 pattern: "#E0",
273 test: pairs{
274 "0": "0\u202f×\u202f10⁰",
275 "1": "1\u202f×\u202f10⁰",
276 "123.456": "1\u202f×\u202f10²",
277 },
278 }, {
279 pattern: "#E+0",
280 test: pairs{
281 "0": "0\u202f×\u202f10⁺⁰",
282 "1000": "1\u202f×\u202f10⁺³",
283 "1E100": "1\u202f×\u202f10⁺¹⁰⁰",
284 "1E-100": "1\u202f×\u202f10⁻¹⁰⁰",
285 "NaN": "NaN",
286 "-Inf": "-∞",
287 },
288 }, {
289 pattern: "##0E00",
290 test: pairs{
291 "100": "100\u202f×\u202f10⁰⁰",
292 "12345": "12\u202f×\u202f10⁰³",
293 "123.456": "123\u202f×\u202f10⁰⁰",
294 },
295 }, {
296 pattern: "##0.###E00",
297 test: pairs{
298 "100": "100\u202f×\u202f10⁰⁰",
299 "12345": "12.345\u202f×\u202f10⁰³",
300 "123456": "123.456\u202f×\u202f10⁰³",
301 "123.456": "123.456\u202f×\u202f10⁰⁰",
302 "123.4567": "123.457\u202f×\u202f10⁰⁰",
303 },
304 }, {
305 pattern: "##0.000E00",
306 test: pairs{
307 "100": "100.000\u202f×\u202f10⁰⁰",
308 "12345": "12.345\u202f×\u202f10⁰³",
309 "123.456": "123.456\u202f×\u202f10⁰⁰",
310 "12.3456": "12.346\u202f×\u202f10⁰⁰",
311 },
312 }, {
313 pattern: "@@E0",
314 test: pairs{
315 "0": "0.0\u202f×\u202f10⁰",
316 "99": "9.9\u202f×\u202f10¹",
317 "0.99": "9.9\u202f×\u202f10⁻¹",
318 },
319 }, {
320 pattern: "@###E00",
321 test: pairs{
322 "0": "0\u202f×\u202f10⁰⁰",
323 "1": "1\u202f×\u202f10⁰⁰",
324 "11": "1.1\u202f×\u202f10⁰¹",
325 "111": "1.11\u202f×\u202f10⁰²",
326 "1111": "1.111\u202f×\u202f10⁰³",
327 "11111": "1.111\u202f×\u202f10⁰⁴",
328 "0.1": "1\u202f×\u202f10⁻⁰¹",
329 "0.11": "1.1\u202f×\u202f10⁻⁰¹",
330 "0.001": "1\u202f×\u202f10⁻⁰³",
331 },
332 }, {
333 pattern: "*x##0",
334 test: pairs{
335 "0": "xx0",
336 "10": "x10",
337 "100": "100",
338 "1000": "1000",
339 },
340 }, {
341 pattern: "##0*x",
342 test: pairs{
343 "0": "0xx",
344 "10": "10x",
345 "100": "100",
346 "1000": "1000",
347 },
348 }, {
349 pattern: "* ###0.000",
350 test: pairs{
351 "0": " 0.000",
352 "123": " 123.000",
353 "123.456": " 123.456",
354 "1234.567": "1234.567",
355 },
356 }, {
357 pattern: "**0.0#######E00",
358 test: pairs{
359 "0": "***0.0\u202f×\u202f10⁰⁰",
360 "10": "***1.0\u202f×\u202f10⁰¹",
361 "11": "***1.1\u202f×\u202f10⁰¹",
362 "111": "**1.11\u202f×\u202f10⁰²",
363 "1111": "*1.111\u202f×\u202f10⁰³",
364 "11111": "1.1111\u202f×\u202f10⁰⁴",
365 "11110": "*1.111\u202f×\u202f10⁰⁴",
366 "11100": "**1.11\u202f×\u202f10⁰⁴",
367 "11000": "***1.1\u202f×\u202f10⁰⁴",
368 "10000": "***1.0\u202f×\u202f10⁰⁴",
369 },
370 }, {
371 pattern: "*xpre0suf",
372 test: pairs{
373 "0": "pre0suf",
374 "10": "pre10suf",
375 },
376 }, {
377 pattern: "*∞ pre ###0 suf",
378 test: pairs{
379 "0": "∞∞∞ pre 0 suf",
380 "10": "∞∞ pre 10 suf",
381 "100": "∞ pre 100 suf",
382 "1000": " pre 1000 suf",
383 },
384 }, {
385 pattern: "pre *∞###0 suf",
386 test: pairs{
387 "0": "pre ∞∞∞0 suf",
388 "10": "pre ∞∞10 suf",
389 "100": "pre ∞100 suf",
390 "1000": "pre 1000 suf",
391 },
392 }, {
393 pattern: "pre ###0*∞ suf",
394 test: pairs{
395 "0": "pre 0∞∞∞ suf",
396 "10": "pre 10∞∞ suf",
397 "100": "pre 100∞ suf",
398 "1000": "pre 1000 suf",
399 },
400 }, {
401 pattern: "pre ###0 suf *∞",
402 test: pairs{
403 "0": "pre 0 suf ∞∞∞",
404 "10": "pre 10 suf ∞∞",
405 "100": "pre 100 suf ∞",
406 "1000": "pre 1000 suf ",
407 },
408 }, {
409
410 pattern: "**###0;**-#####0x",
411 test: pairs{
412 "0": "***0",
413 "-1": "*-1x",
414 },
415 }, {
416 pattern: "0.00%",
417 test: pairs{
418 "0.1": "10.00%",
419 },
420 }, {
421 pattern: "0.##%",
422 test: pairs{
423 "0.1": "10%",
424 "0.11": "11%",
425 "0.111": "11.1%",
426 "0.1111": "11.11%",
427 "0.11111": "11.11%",
428 },
429 }, {
430 pattern: "‰ 0.0#",
431 test: pairs{
432 "0.1": "‰ 100.0",
433 "0.11": "‰ 110.0",
434 "0.111": "‰ 111.0",
435 "0.1111": "‰ 111.1",
436 "0.11111": "‰ 111.11",
437 "0.111111": "‰ 111.11",
438 },
439 }}
440
441
442
443
444
445 for _, tc := range testCases {
446 pat := tc.pat
447 if pat == nil {
448 var err error
449 if pat, err = ParsePattern(tc.pattern); err != nil {
450 log.Fatal(err)
451 }
452 }
453 var f Formatter
454 f.InitPattern(language.English, pat)
455 for num, want := range tc.test {
456 buf := make([]byte, 100)
457 t.Run(tc.pattern+"/"+num, func(t *testing.T) {
458 var d Decimal
459 d.Convert(f.RoundingContext, dec(num))
460 buf = f.Format(buf[:0], &d)
461 if got := string(buf); got != want {
462 t.Errorf("\n got %[1]q (%[1]s)\nwant %[2]q (%[2]s)", got, want)
463 }
464 })
465 }
466 }
467 }
468
469 func TestLocales(t *testing.T) {
470 testCases := []struct {
471 tag language.Tag
472 num string
473 want string
474 }{
475 {language.Make("en"), "123456.78", "123,456.78"},
476 {language.Make("de"), "123456.78", "123.456,78"},
477 {language.Make("de-CH"), "123456.78", "123’456.78"},
478 {language.Make("fr"), "123456.78", "123 456,78"},
479 {language.Make("bn"), "123456.78", "১,২৩,৪৫৬.৭৮"},
480 }
481 for _, tc := range testCases {
482 t.Run(fmt.Sprint(tc.tag, "/", tc.num), func(t *testing.T) {
483 var f Formatter
484 f.InitDecimal(tc.tag)
485 var d Decimal
486 d.Convert(f.RoundingContext, dec(tc.num))
487 b := f.Format(nil, &d)
488 if got := string(b); got != tc.want {
489 t.Errorf("got %[1]q (%[1]s); want %[2]q (%[2]s)", got, tc.want)
490 }
491 })
492 }
493 }
494
495 func TestFormatters(t *testing.T) {
496 var f Formatter
497 testCases := []struct {
498 init func(t language.Tag)
499 num string
500 want string
501 }{
502 {f.InitDecimal, "123456.78", "123,456.78"},
503 {f.InitScientific, "123456.78", "1.23\u202f×\u202f10⁵"},
504 {f.InitEngineering, "123456.78", "123.46\u202f×\u202f10³"},
505 {f.InitEngineering, "1234", "1.23\u202f×\u202f10³"},
506
507 {f.InitPercent, "0.1234", "12.34%"},
508 {f.InitPerMille, "0.1234", "123.40‰"},
509 }
510 for i, tc := range testCases {
511 t.Run(fmt.Sprint(i, "/", tc.num), func(t *testing.T) {
512 tc.init(language.English)
513 f.SetScale(2)
514 var d Decimal
515 d.Convert(f.RoundingContext, dec(tc.num))
516 b := f.Format(nil, &d)
517 if got := string(b); got != tc.want {
518 t.Errorf("got %[1]q (%[1]s); want %[2]q (%[2]s)", got, tc.want)
519 }
520 })
521 }
522 }
523
View as plain text