format-string.js (5594B)
1 // |reftest| skip-if(!this.hasOwnProperty("Intl")) 2 3 function groupByThree(s) { 4 return String(s).split("").reduceRight((acc, x) => x + (acc.match(/^\d{3}/) ? "," : "") + acc, ""); 5 } 6 7 const tests = [ 8 {value: "", expected: "0"}, 9 {value: "0", expected: "0"}, 10 {value: "+0", expected: "0"}, 11 {value: "-0", expected: "-0"}, 12 13 {value: "Infinity", expected: "∞"}, 14 {value: "+Infinity", expected: "∞"}, 15 {value: "-Infinity", expected: "-∞"}, 16 17 {value: "NaN", expected: "NaN"}, 18 {value: "invalid", expected: "NaN"}, 19 20 // Integer 1 with and without fractional/exponent part. 21 {value: "1", expected: "1"}, 22 {value: "1.", expected: "1"}, 23 {value: "1.0", expected: "1"}, 24 {value: "1.00", expected: "1"}, 25 {value: "1e0", expected: "1"}, 26 {value: "1e+0", expected: "1"}, 27 {value: "1e-0", expected: "1"}, 28 29 // Leading zeros. 30 {value: "01", expected: "1"}, 31 {value: "01.", expected: "1"}, 32 {value: "01.0", expected: "1"}, 33 {value: "01.00", expected: "1"}, 34 {value: "01e0", expected: "1"}, 35 {value: "01e+0", expected: "1"}, 36 {value: "01e-0", expected: "1"}, 37 38 // Large values. 39 {value: "1e300", expected: "1" + ",000".repeat(100)}, 40 {value: "1e308", expected: "100" + ",000".repeat(102)}, 41 {value: "1e309", expected: "∞"}, 42 {value: "1e3000", expected: "∞"}, 43 {value: "1e+9999999", expected: "∞"}, 44 {value: "1e+99999999", expected: "∞"}, 45 {value: ".1e+9999999", expected: "∞"}, 46 {value: ".1e+99999999", expected: "∞"}, 47 {value: ".1e+999999999", expected: "∞"}, 48 {value: ".1e+9999999999", expected: "∞"}, 49 {value: "9007199254740991", expected: "9,007,199,254,740,991"}, 50 {value: "9007199254740992", expected: "9,007,199,254,740,992"}, 51 {value: "9007199254740993", expected: "9,007,199,254,740,993"}, 52 53 {value: "-1e300", expected: "-1" + ",000".repeat(100)}, 54 {value: "-1e308", expected: "-100" + ",000".repeat(102)}, 55 {value: "-1e309", expected: "-∞"}, 56 {value: "-1e3000", expected: "-∞"}, 57 {value: "-1e+9999999", expected: "-∞"}, 58 {value: "-1e+99999999", expected: "-∞"}, 59 {value: "-.1e+9999999", expected: "-∞"}, 60 {value: "-.1e+99999999", expected: "-∞"}, 61 {value: "-.1e+999999999", expected: "-∞"}, 62 {value: "-.1e+9999999999", expected: "-∞"}, 63 {value: "-9007199254740991", expected: "-9,007,199,254,740,991"}, 64 {value: "-9007199254740992", expected: "-9,007,199,254,740,992"}, 65 {value: "-9007199254740993", expected: "-9,007,199,254,740,993"}, 66 67 // Small values. 68 {value: "0.10000000000000000001", expected: "0.10000000000000000001"}, 69 {value: "0.00000000000000000001", expected: "0.00000000000000000001"}, 70 {value: "1e-20", expected: "0.00000000000000000001"}, 71 {value: "1e-30", expected: "0"}, 72 {value: ".1e-9999999", expected: "0"}, 73 {value: ".1e-99999999", expected: "0"}, 74 {value: ".1e-999999999", expected: "0"}, 75 {value: ".1e-9999999999", expected: "0"}, 76 77 {value: "-0.10000000000000000001", expected: "-0.10000000000000000001"}, 78 {value: "-0.00000000000000000001", expected: "-0.00000000000000000001"}, 79 {value: "-1e-20", expected: "-0.00000000000000000001"}, 80 {value: "-1e-30", expected: "-0"}, 81 {value: "-.1e-9999999", expected: "-0"}, 82 {value: "-.1e-99999999", expected: "-0"}, 83 {value: "-.1e-999999999", expected: "-0"}, 84 {value: "-.1e-9999999999", expected: "-0"}, 85 86 // Non-standard exponent notation. 87 {value: ".001e-2", expected: "0.00001"}, 88 {value: "123.001e-2", expected: "1.23001"}, 89 {value: "1000e-2", expected: "10"}, 90 {value: "1000e+2", expected: "100,000"}, 91 {value: "1000e-0", expected: "1,000"}, 92 93 // Non-decimal strings. 94 {value: "0b101", expected: "5"}, 95 {value: "0o377", expected: "255"}, 96 {value: "0xdeadBEEF", expected: "3,735,928,559"}, 97 {value: "0B0011", expected: "3"}, 98 {value: "0O0777", expected: "511"}, 99 {value: "0X0ABC", expected: "2,748"}, 100 {value: "0b" + "1".repeat(1000), expected: groupByThree((2n ** 1000n) - 1n)}, 101 {value: "0o1" + "7".repeat(333), expected: groupByThree((2n ** 1000n) - 1n)}, 102 {value: "0x" + "f".repeat(250), expected: groupByThree((2n ** 1000n) - 1n)}, 103 104 {value: "0b" + "1".repeat(1023), expected: groupByThree(0b10n ** 1023n - 1n)}, 105 {value: "0b" + "1".repeat(1024), expected: "∞"}, 106 {value: "0o" + "7".repeat(341), expected: groupByThree(0o10n ** 341n - 1n)}, 107 {value: "0o" + "7".repeat(342), expected: "∞"}, 108 {value: "0x" + "f".repeat(255), expected: groupByThree(0x10n ** 255n - 1n)}, 109 {value: "0x" + "f".repeat(256), expected: "∞"}, 110 111 // Non-decimal strings don't accept a sign. 112 {value: "+0xbad", expected: "NaN"}, 113 {value: "-0xbad", expected: "NaN"}, 114 ]; 115 116 // https://tc39.es/ecma262/#prod-StrWhiteSpaceChar 117 const strWhiteSpaceChar = [ 118 "", 119 120 // https://tc39.es/ecma262/#sec-white-space 121 "\t", "\v", "\f", " ", "\u00A0", "\uFEFF", 122 "\u1680", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005", "\u2006", 123 "\u2007", "\u2008", "\u2009", "\u200A", "\u202F", "\u205F", "\u3000", 124 125 // https://tc39.es/ecma262/#sec-line-terminators 126 "\n", "\r", "\u2028", "\u2029", 127 ]; 128 129 let nf = new Intl.NumberFormat("en", {maximumFractionDigits: 20}); 130 for (let {value, expected} of tests) { 131 for (let ws of strWhiteSpaceChar) { 132 assertEq(nf.format(ws + value), expected); 133 assertEq(nf.format(value + ws), expected); 134 assertEq(nf.format(ws + value + ws), expected); 135 } 136 } 137 138 // Combine extreme values with other rounding modes. 139 { 140 let nf = new Intl.NumberFormat("en", { 141 minimumFractionDigits: 20, 142 roundingMode: "ceil", 143 roundingIncrement: 5000, 144 }); 145 assertEq(nf.format(".1e-999999998"), "0.00000000000000000000"); 146 } 147 148 if (typeof reportCompare === "function") 149 reportCompare(true, true);