formatRange.js (12629B)
1 // |reftest| skip-if(!this.hasOwnProperty("Intl")) 2 3 // String representation for Number.MAX_VALUE. 4 const en_Number_MAX_VALUE = "179,769,313,486,231,570" + ",000".repeat(97); 5 const de_Number_MAX_VALUE = en_Number_MAX_VALUE.replaceAll(",", "."); 6 const fr_Number_MAX_VALUE = en_Number_MAX_VALUE.replaceAll(",", " "); 7 8 const tests = { 9 "en": { 10 options: {}, 11 ranges: [ 12 // Values around zero. 13 {start: 0, end: 0, result: "~0"}, 14 {start: 0, end: -0, result: "0–-0"}, 15 {start: -0, end: 0, result: "-0 – 0"}, 16 {start: -0, end: 0.1e-3, result: "-0 – 0"}, 17 {start: -0, end: "0.1e-3", result: "-0 – 0"}, 18 {start: "-0", end: 0.1e-3, result: "-0 – 0"}, 19 {start: -0, end: -0, result: "~-0"}, 20 {start: -0, end: -0.1, result: "-0 – -0.1"}, 21 22 // Values starting at negative infinity. 23 {start: -Infinity, end: -Infinity, result: "~-∞"}, 24 {start: -Infinity, end: -0, result: "-∞ – -0"}, 25 {start: -Infinity, end: +0, result: "-∞ – 0"}, 26 {start: -Infinity, end: +Infinity, result: "-∞ – ∞"}, 27 28 // Values ending at negative infinity. 29 {start: -Number.MAX_VALUE, end: -Infinity, result: "-" + en_Number_MAX_VALUE + " – -∞"}, 30 {start: -0, end: -Infinity, result: "-0 – -∞"}, 31 {start: 0, end: -Infinity, result: "0–-∞"}, 32 {start: Number.MAX_VALUE, end: -Infinity, result: en_Number_MAX_VALUE + "–-∞"}, 33 34 // Values starting at positive infinity. 35 {start: Infinity, end: Number.MAX_VALUE, result: "∞–" + en_Number_MAX_VALUE}, 36 {start: Infinity, end: 0, result: "∞–0"}, 37 {start: Infinity, end: -0, result: "∞–-0"}, 38 {start: Infinity, end: -Number.MAX_VALUE, result: "∞–-" + en_Number_MAX_VALUE}, 39 {start: Infinity, end: -Infinity, result: "∞–-∞"}, 40 41 // Values ending at positive infinity. 42 {start: Infinity, end: Infinity, result: "~∞"}, 43 44 // Non-special cases. 45 {start: 1, end: 100, result: "1–100"}, 46 {start: -100, end: 100, result: "-100 – 100"}, 47 {start: -1000, end: -100, result: "-1,000 – -100"}, 48 {start: Math.PI, end: 123_456.789, result: "3.142–123,456.789"}, 49 {start: -Math.PI, end: Math.E, result: "-3.142 – 2.718"}, 50 { 51 start: Number.MAX_SAFE_INTEGER, 52 end: 9007199254740993, 53 result: "9,007,199,254,740,991–9,007,199,254,740,992", 54 }, 55 { 56 start: Number.MAX_SAFE_INTEGER, 57 end: "9007199254740993", 58 result: "9,007,199,254,740,991–9,007,199,254,740,993", 59 }, 60 61 // Start value is larger than end value. 62 {start: -0, end: -0.1, result: "-0 – -0.1"}, 63 {start: -0, end: -Number.MAX_VALUE, result: "-0 – -" + en_Number_MAX_VALUE}, 64 {start: 1, end: 0, result: "1–0"}, 65 {start: 0, end: -1, result: "0–-1"}, 66 {start: 1, end: -1, result: "1–-1"}, 67 {start: -1, end: -2, result: "-1 – -2"}, 68 {start: "10e2", end: "1e-3", result: "1,000–0.001"}, 69 {start: "0x100", end: "1e1", result: "256–10"}, 70 {start: ".1e-999999", end: ".01e-999999", result: "~0"}, 71 {start: ".1e99999", end: "0", result: "∞–0"}, 72 // Number.MAX_VALUE is 1.7976931348623157e+308. 73 { 74 start: "1.7976931348623158e+308", 75 end: Number.MAX_VALUE, 76 result: "179,769,313,486,231,580" + ",000".repeat(97) + "–" + en_Number_MAX_VALUE, 77 }, 78 // Number.MIN_VALUE is 5e-324. 79 {start: "6e-324", end: Number.MIN_VALUE, result: "~0"}, 80 ], 81 }, 82 "de": { 83 options: {style: "currency", currency: "EUR"}, 84 ranges: [ 85 // Values around zero. 86 {start: 0, end: 0, result: "≈0,00 €"}, 87 {start: 0, end: -0, result: "0,00 € – -0,00 €"}, 88 {start: -0, end: 0, result: "-0,00 € – 0,00 €"}, 89 {start: -0, end: 0.1e-3, result: "-0,00 € – 0,00 €"}, 90 {start: -0, end: "0.1e-3", result: "-0,00 € – 0,00 €"}, 91 {start: "-0", end: 0.1e-3, result: "-0,00 € – 0,00 €"}, 92 {start: -0, end: -0, result: "≈-0,00 €"}, 93 {start: -0, end: -0.1, result: "-0,00–0,10 €"}, 94 95 // Values starting at negative infinity. 96 {start: -Infinity, end: -Infinity, result: "≈-∞ €"}, 97 {start: -Infinity, end: -0, result: "-∞–0,00 €"}, 98 {start: -Infinity, end: +0, result: "-∞ € – 0,00 €"}, 99 {start: -Infinity, end: +Infinity, result: "-∞ € – ∞ €"}, 100 101 // Values ending at negative infinity. 102 {start: -Number.MAX_VALUE, end: -Infinity, result: "-" + de_Number_MAX_VALUE + ",00–∞ €"}, 103 {start: -0, end: -Infinity, result: "-0,00–∞ €"}, 104 {start: 0, end: -Infinity, result: "0,00 € – -∞ €"}, 105 {start: Number.MAX_VALUE, end: -Infinity, result: de_Number_MAX_VALUE + ",00 € – -∞ €"}, 106 107 // Values starting at positive infinity. 108 {start: Infinity, end: Number.MAX_VALUE, result: "∞–" + de_Number_MAX_VALUE + ",00 €"}, 109 {start: Infinity, end: 0, result: "∞–0,00 €"}, 110 {start: Infinity, end: -0, result: "∞ € – -0,00 €"}, 111 {start: Infinity, end: -Number.MAX_VALUE, result: "∞ € – -" + de_Number_MAX_VALUE + ",00 €"}, 112 {start: Infinity, end: -Infinity, result: "∞ € – -∞ €"}, 113 114 // Values ending at positive infinity. 115 {start: Infinity, end: Infinity, result: "≈∞ €"}, 116 117 // Non-special cases. 118 {start: 1, end: 100, result: "1,00–100,00 €"}, 119 {start: -100, end: 100, result: "-100,00 € – 100,00 €"}, 120 {start: -1000, end: -100, result: "-1.000,00–100,00 €"}, 121 {start: Math.PI, end: 123_456.789, result: "3,14–123.456,79 €"}, 122 {start: -Math.PI, end: Math.E, result: "-3,14 € – 2,72 €"}, 123 { 124 start: Number.MAX_SAFE_INTEGER, 125 end: 9007199254740993, 126 result: "9.007.199.254.740.991,00–9.007.199.254.740.992,00 €", 127 }, 128 { 129 start: Number.MAX_SAFE_INTEGER, 130 end: "9007199254740993", 131 result: "9.007.199.254.740.991,00–9.007.199.254.740.993,00 €", 132 }, 133 134 // Start value is larger than end value. 135 {start: -0, end: -0.1, result: "-0,00–0,10 €"}, 136 {start: -0, end: -Number.MAX_VALUE, result: "-0,00–" + de_Number_MAX_VALUE + ",00 €"}, 137 {start: 1, end: 0, result: "1,00–0,00 €"}, 138 {start: 0, end: -1, result: "0,00 € – -1,00 €"}, 139 {start: 1, end: -1, result: "1,00 € – -1,00 €"}, 140 {start: -1, end: -2, result: "-1,00–2,00 €"}, 141 {start: "10e2", end: "1e-3", result: "1.000,00–0,00 €"}, 142 {start: "0x100", end: "1e1", result: "256,00–10,00 €"}, 143 {start: ".1e-999999", end: ".01e-999999", result: "≈0,00 €"}, 144 {start: ".1e99999", end: "0", result: "∞–0,00 €"}, 145 // Number.MAX_VALUE is 1.7976931348623157e+308. 146 { 147 start: "1.7976931348623158e+308", 148 end: Number.MAX_VALUE, 149 result: "179.769.313.486.231.580" + ".000".repeat(97) + ",00–" + de_Number_MAX_VALUE + ",00 €", 150 }, 151 // Number.MIN_VALUE is 5e-324. 152 {start: "6e-324", end: Number.MIN_VALUE, result: "≈0,00 €"}, 153 ], 154 }, 155 "fr": { 156 options: {style: "unit", unit: "meter"}, 157 ranges: [ 158 // Values around zero. 159 {start: 0, end: 0, result: "≃0 m"}, 160 {start: -0, end: 0, result: "-0 – 0 m"}, 161 {start: -0, end: 0, result: "-0 – 0 m"}, 162 {start: -0, end: 0.1e-3, result: "-0 – 0 m"}, 163 {start: -0, end: "0.1e-3", result: "-0 – 0 m"}, 164 {start: "-0", end: 0.1e-3, result: "-0 – 0 m"}, 165 {start: -0, end: -0, result: "≃-0 m"}, 166 {start: -0, end: -0.1, result: "-0 – -0,1 m"}, 167 168 // Values starting at negative infinity. 169 {start: -Infinity, end: -Infinity, result: "≃-∞ m"}, 170 {start: -Infinity, end: -0, result: "-∞ – -0 m"}, 171 {start: -Infinity, end: +0, result: "-∞ – 0 m"}, 172 {start: -Infinity, end: +Infinity, result: "-∞ – ∞ m"}, 173 174 // Values ending at negative infinity. 175 {start: -Number.MAX_VALUE, end: -Infinity, result: "-" + fr_Number_MAX_VALUE + " – -∞ m"}, 176 {start: -0, end: -Infinity, result: "-0 – -∞ m"}, 177 {start: 0, end: -Infinity, result: "0–-∞ m"}, 178 {start: Number.MAX_VALUE, end: -Infinity, result: fr_Number_MAX_VALUE + "–-∞ m"}, 179 180 // Values starting at positive infinity. 181 {start: Infinity, end: Number.MAX_VALUE, result: "∞–" + fr_Number_MAX_VALUE + " m"}, 182 {start: Infinity, end: 0, result: "∞–0 m"}, 183 {start: Infinity, end: -0, result: "∞–-0 m"}, 184 {start: Infinity, end: -Number.MAX_VALUE, result: "∞–-" + fr_Number_MAX_VALUE + " m"}, 185 {start: Infinity, end: -Infinity, result: "∞–-∞ m"}, 186 187 // Values ending at positive infinity. 188 {start: Infinity, end: Infinity, result: "≃∞ m"}, 189 190 // Non-special cases. 191 {start: 1, end: 100, result: "1–100 m"}, 192 {start: -100, end: 100, result: "-100 – 100 m"}, 193 {start: -1000, end: -100, result: "-1 000 – -100 m"}, 194 {start: Math.PI, end: 123_456.789, result: "3,142–123 456,789 m"}, 195 {start: -Math.PI, end: Math.E, result: "-3,142 – 2,718 m"}, 196 { 197 start: Number.MAX_SAFE_INTEGER, 198 end: 9007199254740993, 199 result: "9 007 199 254 740 991–9 007 199 254 740 992 m", 200 }, 201 { 202 start: Number.MAX_SAFE_INTEGER, 203 end: "9007199254740993", 204 result: "9 007 199 254 740 991–9 007 199 254 740 993 m", 205 }, 206 207 // Start value is larger than end value. 208 {start: -0, end: -0.1, result: "-0 – -0,1 m"}, 209 {start: -0, end: -Number.MAX_VALUE, result: "-0 – -" + fr_Number_MAX_VALUE + " m"}, 210 {start: 1, end: 0, result: "1–0 m"}, 211 {start: 0, end: -1, result: "0–-1 m"}, 212 {start: 1, end: -1, result: "1–-1 m"}, 213 {start: -1, end: -2, result: "-1 – -2 m"}, 214 {start: "10e2", end: "1e-3", result: "1 000–0,001 m"}, 215 {start: "0x100", end: "1e1", result: "256–10 m"}, 216 {start: ".1e-999999", end: ".01e-999999", result: "≃0 m"}, 217 {start: ".1e99999", end: "0", result: "∞–0 m"}, 218 // Number.MAX_VALUE is 1.7976931348623157e+308. 219 { 220 start: "1.7976931348623158e+308", 221 end: Number.MAX_VALUE, 222 result: "179 769 313 486 231 580" + " 000".repeat(97) + "–" + fr_Number_MAX_VALUE + " m", 223 }, 224 // Number.MIN_VALUE is 5e-324. 225 {start: "6e-324", end: Number.MIN_VALUE, result: "≃0 m"}, 226 ], 227 }, 228 // Non-ASCII digits. 229 "ar-EG": { 230 options: {}, 231 ranges: [ 232 {start: -2, end: -1, result: "-٢–١"}, 233 {start: -1, end: -1, result: "~-١"}, 234 {start: -1, end: 0, result: "-١ – ٠"}, 235 {start: 0, end: 0, result: "~٠"}, 236 {start: 0, end: 1, result: "٠–١"}, 237 {start: 1, end: 1, result: "~١"}, 238 {start: 1, end: 2, result: "١–٢"}, 239 ], 240 }, 241 "th-u-nu-thai": { 242 options: {}, 243 ranges: [ 244 {start: -2, end: -1, result: "-๒ - -๑"}, 245 {start: -1, end: -1, result: "~-๑"}, 246 {start: -1, end: 0, result: "-๑ - ๐"}, 247 {start: 0, end: 0, result: "~๐"}, 248 {start: 0, end: 1, result: "๐-๑"}, 249 {start: 1, end: 1, result: "~๑"}, 250 {start: 1, end: 2, result: "๑-๒"}, 251 ], 252 }, 253 // Approximation sign may consist of multiple characters. 254 "no": { 255 options: {}, 256 ranges: [ 257 {start: 1, end: 1, result: "ca.1"}, 258 ], 259 }, 260 // Approximation sign can be a word. 261 "ja": { 262 options: {}, 263 ranges: [ 264 {start: 1, end: 1, result: "約1"}, 265 ], 266 }, 267 }; 268 269 for (let [locale, {options, ranges}] of Object.entries(tests)) { 270 let nf = new Intl.NumberFormat(locale, options); 271 for (let {start, end, result} of ranges) { 272 assertEq(nf.formatRange(start, end), result, `${start}-${end}`); 273 assertEq(nf.formatRangeToParts(start, end).reduce((acc, part) => acc + part.value, ""), 274 result, `${start}-${end}`); 275 } 276 } 277 278 // Throws an error if either value is NaN. 279 { 280 const errorTests = [ 281 {start: NaN, end: NaN}, 282 {start: 0, end: NaN}, 283 {start: NaN, end: 0}, 284 {start: Infinity, end: NaN}, 285 {start: NaN, end: Infinity}, 286 ]; 287 288 let nf = new Intl.NumberFormat("en"); 289 for (let {start, end} of errorTests) { 290 assertThrowsInstanceOf(() => nf.formatRange(start, end), RangeError); 291 assertThrowsInstanceOf(() => nf.formatRangeToParts(start, end), RangeError); 292 } 293 } 294 295 if (typeof reportCompare === "function") 296 reportCompare(true, true);