| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2014 the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import "dart:math" show pow; |
| 6 import "package:expect/expect.dart"; |
| 7 |
| 8 const whiteSpace = const [ |
| 9 "", |
| 10 "\x09", |
| 11 "\x0a", |
| 12 "\x0b", |
| 13 "\x0c", |
| 14 "\x0d", |
| 15 "\x85", /// 01: ok |
| 16 "\xa0", |
| 17 "\u1680", |
| 18 "\u180e", |
| 19 "\u2000", |
| 20 "\u2001", |
| 21 "\u2002", |
| 22 "\u2003", |
| 23 "\u2004", |
| 24 "\u2005", |
| 25 "\u2006", |
| 26 "\u2007", |
| 27 "\u2008", |
| 28 "\u2009", |
| 29 "\u200a", |
| 30 "\u2028", |
| 31 "\u2029", |
| 32 "\u202f", |
| 33 "\u205f", |
| 34 "\u3000", |
| 35 "\uFEFF" |
| 36 ]; |
| 37 |
| 38 void expectNumEquals(double expect, var actual, String message) { |
| 39 if (expect.isNaN) { |
| 40 Expect.isTrue(actual is double && actual.isNaN, "isNaN: $message"); |
| 41 } else { |
| 42 Expect.identical(expect, actual, message); |
| 43 } |
| 44 } |
| 45 |
| 46 // Test source surrounded by any combination of whitespace. |
| 47 void testParseAllWhitespace(String source, double result) { |
| 48 for (String ws1 in whiteSpace) { |
| 49 for (String ws2 in whiteSpace) { |
| 50 String padded = "$ws1$source$ws2"; |
| 51 // Use Expect.identical because it also handles NaN and 0.0/-0.0. |
| 52 // Except on dart2js: http://dartbug.com/11551 |
| 53 expectNumEquals(result, double.parse(padded), "parse '$padded'"); |
| 54 padded = "$ws1$ws2$source"; |
| 55 expectNumEquals(result, double.parse(padded), "parse '$padded'"); |
| 56 padded = "$source$ws1$ws2"; |
| 57 expectNumEquals(result, double.parse(padded), "parse '$padded'"); |
| 58 } |
| 59 } |
| 60 } |
| 61 |
| 62 // Test source and -source surrounded by any combination of whitespace. |
| 63 void testParseWhitespace(String source, double result) { |
| 64 assert(result >= 0); |
| 65 testParseAllWhitespace(source, result); |
| 66 testParseAllWhitespace("-$source", -result); |
| 67 } |
| 68 |
| 69 // Test parsing source, optionally preceeded and/or followed by whitespace. |
| 70 void testParse(String source, double result, [name = ""]) { |
| 71 expectNumEquals(result, double.parse(source), "parse '$source:$name"); |
| 72 expectNumEquals(result, double.parse(" $source"), |
| 73 "parse ' $source':$name"); |
| 74 expectNumEquals(result, double.parse("$source "), |
| 75 "parse '$source ':$name"); |
| 76 expectNumEquals(result, double.parse(" $source "), |
| 77 "parse ' $source ':$name"); |
| 78 |
| 79 expectNumEquals(result, double.parse("+$source"), |
| 80 "parse '+$source:$name"); |
| 81 expectNumEquals(result, double.parse(" +$source"), |
| 82 "parse ' +$source':$name"); |
| 83 expectNumEquals(result, double.parse("+$source "), |
| 84 "parse '+$source ':$name"); |
| 85 expectNumEquals(result, double.parse(" +$source "), |
| 86 "parse ' +$source ':$name"); |
| 87 |
| 88 expectNumEquals(-result, double.parse("-$source"), |
| 89 "parse '-$source:$name"); |
| 90 expectNumEquals(-result, double.parse(" -$source"), |
| 91 "parse ' -$source':$name"); |
| 92 expectNumEquals(-result, double.parse("-$source "), |
| 93 "parse '-$source ':$name"); |
| 94 expectNumEquals(-result, double.parse(" -$source "), |
| 95 "parse ' -$source ':$name"); |
| 96 } |
| 97 |
| 98 void testDouble(double value) { |
| 99 testParse("$value", value); |
| 100 if (value.isFinite) { |
| 101 String exp = value.toStringAsExponential(); |
| 102 String lcexp = exp.toLowerCase(); |
| 103 testParse(lcexp, value); |
| 104 String ucexp = exp.toUpperCase(); |
| 105 testParse(ucexp, value); |
| 106 } |
| 107 } |
| 108 |
| 109 void testFail(String source) { |
| 110 var object = new Object(); |
| 111 Expect.throws(() { |
| 112 double.parse(source, (s) { |
| 113 Expect.equals(source, s); |
| 114 throw object; |
| 115 }); |
| 116 }, (e) => identical(object, e), "Fail: '$source'"); |
| 117 } |
| 118 |
| 119 void main() { |
| 120 testDouble(0.0); |
| 121 testDouble(5e-324); |
| 122 testDouble(2.225073858507201e-308); |
| 123 testDouble(2.2250738585072014e-308); |
| 124 testDouble(0.49999999999999994); |
| 125 testDouble(0.5); |
| 126 testDouble(0.50000000000000006); |
| 127 testDouble(0.9999999999999999); |
| 128 testDouble(1.0); |
| 129 testDouble(1.0000000000000002); |
| 130 testDouble(4294967295.0); |
| 131 testDouble(4294967296.0); |
| 132 testDouble(4503599627370495.5); |
| 133 testDouble(4503599627370497.0); |
| 134 testDouble(9007199254740991.0); |
| 135 testDouble(9007199254740992.0); |
| 136 testDouble(1.7976931348623157e+308); |
| 137 testDouble(double.INFINITY); |
| 138 testDouble(double.NAN); |
| 139 |
| 140 // Strings that cannot occur from toString of a number. |
| 141 testParse("000000000000", 0.0); |
| 142 testParse("000000000001", 1.0); |
| 143 testParse("000000000000.0000000000000", 0.0); |
| 144 testParse("000000000001.0000000000000", 1.0); |
| 145 testParse("0e0", 0.0); |
| 146 testParse("0e+0", 0.0); |
| 147 testParse("0e-0", 0.0); |
| 148 testParse("1e0", 1.0); |
| 149 testParse("1e+0", 1.0); |
| 150 testParse("1e-0", 1.0); |
| 151 testParse("1.", 1.0); |
| 152 testParse(".1", 0.1); |
| 153 testParse("1.e1", 10.0); |
| 154 testParse(".1e1", 1.0); |
| 155 testParse("Infinity", double.INFINITY); |
| 156 testParse("NaN", double.NAN); |
| 157 |
| 158 // Cases where mantissa and 10^exponent are representable as a double. |
| 159 for (int i = -22; i <= 22; i++) { |
| 160 for (double j in [1.0, 9007199254740991.0, 9007199254740992.0]) { |
| 161 var value = (i >= 0) ? j * pow(10.0, i) : j / pow(10.0, -i); |
| 162 testParse("${j}e$i", value, "$i/$j"); |
| 163 testParse("${j}E$i", value, "$i/$j"); |
| 164 if (i >= 0) { |
| 165 testParse("${j}e+$i", value, "$i/$j"); |
| 166 testParse("${j}E+$i", value, "$i/$j"); |
| 167 } |
| 168 } |
| 169 } |
| 170 for (int i = 0; i <= 22; i++) { |
| 171 var digits = "9007199254740991"; |
| 172 for (int i = 0; i < digits.length; i++) { |
| 173 int dotIndex = digits.length - i; |
| 174 var string = "${digits.substring(0, dotIndex)}." |
| 175 "${digits.substring(dotIndex)}e$i"; |
| 176 testParse(string, 9007199254740991.0); |
| 177 } |
| 178 } |
| 179 |
| 180 testParse("9007199254740993", 9007199254740992.0); |
| 181 testParse("9.007199254740993e15", 9007199254740992.0); |
| 182 testParse("0.00000009007199254740991e23", 9007199254740991.0); |
| 183 |
| 184 testParse("0.000000000000000000000000000000000000000000000000" |
| 185 "00000000000000000000000000000000000000000000000000" |
| 186 "00000000000000000000000000000000000000000000000000" |
| 187 "00000000000000000000000000000000000000000000000000" |
| 188 "00000000000000000000000000000000000000000000000000" |
| 189 "00000000000000000000000000000000000000000000000000" |
| 190 "00000000000000000000000004940656458412465441765687" |
| 191 "92868221372365059802614324764425585682500675507270" |
| 192 "20875186529983636163599237979656469544571773092665" |
| 193 "67103559397963987747960107818781263007131903114045" |
| 194 "27845817167848982103688718636056998730723050006387" |
| 195 "40915356498438731247339727316961514003171538539807" |
| 196 "41262385655911710266585566867681870395603106249319" |
| 197 "45271591492455329305456544401127480129709999541931" |
| 198 "98940908041656332452475714786901472678015935523861" |
| 199 "15501348035264934720193790268107107491703332226844" |
| 200 "75333572083243193609238289345836806010601150616980" |
| 201 "97530783422773183292479049825247307763759272478746" |
| 202 "56084778203734469699533647017972677717585125660551" |
| 203 "19913150489110145103786273816725095583738973359899" |
| 204 "36648099411642057026370902792427675445652290875386" |
| 205 "82506419718265533447265625", 5e-324); |
| 206 |
| 207 testParse("0.000000000000000000000000000000000000000000000000" |
| 208 "00000000000000000000000000000000000000000000000000" |
| 209 "00000000000000000000000000000000000000000000000000" |
| 210 "00000000000000000000000000000000000000000000000000" |
| 211 "00000000000000000000000000000000000000000000000000" |
| 212 "00000000000000000000000000000000000000000000000000" |
| 213 "00000000000000000000000002470328229206232720882843" |
| 214 "96434110686182529901307162382212792841250337753635" |
| 215 "10437593264991818081799618989828234772285886546332" |
| 216 "83551779698981993873980053909390631503565951557022" |
| 217 "63922908583924491051844359318028499365361525003193" |
| 218 "70457678249219365623669863658480757001585769269903" |
| 219 "70631192827955855133292783433840935197801553124659" |
| 220 "72635795746227664652728272200563740064854999770965" |
| 221 "99470454020828166226237857393450736339007967761930" |
| 222 "57750674017632467360096895134053553745851666113422" |
| 223 "37666786041621596804619144672918403005300575308490" |
| 224 "48765391711386591646239524912623653881879636239373" |
| 225 "28042389101867234849766823508986338858792562830275" |
| 226 "59956575244555072551893136908362547791869486679949" |
| 227 "68324049705821028513185451396213837722826145437693" |
| 228 "412532098591327667236328126", 5e-324); |
| 229 |
| 230 testParse("0.000000000000000000000000000000000000000000000000" |
| 231 "00000000000000000000000000000000000000000000000000" |
| 232 "00000000000000000000000000000000000000000000000000" |
| 233 "00000000000000000000000000000000000000000000000000" |
| 234 "00000000000000000000000000000000000000000000000000" |
| 235 "00000000000000000000000000000000000000000000000000" |
| 236 "00000000000000000000000002470328229206232720882843" |
| 237 "96434110686182529901307162382212792841250337753635" |
| 238 "10437593264991818081799618989828234772285886546332" |
| 239 "83551779698981993873980053909390631503565951557022" |
| 240 "63922908583924491051844359318028499365361525003193" |
| 241 "70457678249219365623669863658480757001585769269903" |
| 242 "70631192827955855133292783433840935197801553124659" |
| 243 "72635795746227664652728272200563740064854999770965" |
| 244 "99470454020828166226237857393450736339007967761930" |
| 245 "57750674017632467360096895134053553745851666113422" |
| 246 "37666786041621596804619144672918403005300575308490" |
| 247 "48765391711386591646239524912623653881879636239373" |
| 248 "28042389101867234849766823508986338858792562830275" |
| 249 "59956575244555072551893136908362547791869486679949" |
| 250 "68324049705821028513185451396213837722826145437693" |
| 251 "412532098591327667236328125", 0.0); |
| 252 |
| 253 testParse("0.0000000000000000000000000000000000000000000000000" |
| 254 "000000000000000000000000000000000000000000000000000" |
| 255 "000000000000000000000000000000000000000000000000000" |
| 256 "000000000000000000000000000000000000000000000000000" |
| 257 "000000000000000000000000000000000000000000000000000" |
| 258 "000000000000000000000000000000000000000000000000000" |
| 259 "00022250738585072011", 2.225073858507201e-308); |
| 260 |
| 261 testParse("0.0000000000000000000000000000000000000000000000000" |
| 262 "000000000000000000000000000000000000000000000000000" |
| 263 "000000000000000000000000000000000000000000000000000" |
| 264 "000000000000000000000000000000000000000000000000000" |
| 265 "000000000000000000000000000000000000000000000000000" |
| 266 "000000000000000000000000000000000000000000000000000" |
| 267 "00022250738585072012", 2.2250738585072014e-308); |
| 268 |
| 269 testParse("0.49999999999999994", 0.49999999999999994); |
| 270 testParse("0.49999999999999997219", 0.49999999999999994); |
| 271 testParse("0.49999999999999999", 0.5); |
| 272 |
| 273 testParseWhitespace("1", 1.0); |
| 274 testParseWhitespace("1.0", 1.0); |
| 275 testParseWhitespace("1e1", 10.0); |
| 276 testParseWhitespace(".1e1", 1.0); |
| 277 testParseWhitespace("1.e1", 10.0); |
| 278 testParseWhitespace("1e+1", 10.0); |
| 279 testParseWhitespace("1e-1", 0.1); |
| 280 |
| 281 // Negative tests - things not to allow. |
| 282 |
| 283 // Spaces inside the numeral. |
| 284 testFail("- 1"); |
| 285 testFail("+ 1"); |
| 286 testFail("2 2"); |
| 287 testFail("1 ."); |
| 288 testFail(". 1"); |
| 289 testFail("1e 2"); |
| 290 testFail("1 e2"); |
| 291 // Invalid characters. |
| 292 testFail("0x0"); |
| 293 testFail("0x1H"); |
| 294 testFail("12H"); |
| 295 testFail("1x2"); |
| 296 testFail("00x2"); |
| 297 testFail("0x2.2"); |
| 298 // Double exponent without value. |
| 299 testFail(".e1"); |
| 300 testFail("e1"); |
| 301 testFail("e+1"); |
| 302 testFail("e-1"); |
| 303 testFail("-e1"); |
| 304 testFail("-e+1"); |
| 305 testFail("-e-1"); |
| 306 // Too many signs. |
| 307 testFail("--1"); |
| 308 testFail("-+1"); |
| 309 testFail("+-1"); |
| 310 testFail("++1"); |
| 311 // Incorrect ways to write NaN/Infinity. |
| 312 testFail("infinity"); |
| 313 testFail("INFINITY"); |
| 314 testFail("1.#INF"); |
| 315 testFail("inf"); |
| 316 testFail("nan"); |
| 317 testFail("NAN"); |
| 318 testFail("1.#IND"); |
| 319 testFail("indef"); |
| 320 testFail("qnan"); |
| 321 testFail("snan"); |
| 322 } |
| OLD | NEW |