|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 |
|
7 /** |
|
8 File Name: 15.1.2.2-1.js |
|
9 ECMA Section: 15.1.2.2 Function properties of the global object |
|
10 parseInt( string, radix ) |
|
11 |
|
12 Description: |
|
13 |
|
14 The parseInt function produces an integer value dictated by intepretation |
|
15 of the contents of the string argument according to the specified radix. |
|
16 |
|
17 When the parseInt function is called, the following steps are taken: |
|
18 |
|
19 1. Call ToString(string). |
|
20 2. Compute a substring of Result(1) consisting of the leftmost character |
|
21 that is not a StrWhiteSpaceChar and all characters to the right of |
|
22 that character. (In other words, remove leading whitespace.) |
|
23 3. Let sign be 1. |
|
24 4. If Result(2) is not empty and the first character of Result(2) is a |
|
25 minus sign -, let sign be -1. |
|
26 5. If Result(2) is not empty and the first character of Result(2) is a |
|
27 plus sign + or a minus sign -, then Result(5) is the substring of |
|
28 Result(2) produced by removing the first character; otherwise, Result(5) |
|
29 is Result(2). |
|
30 6. If the radix argument is not supplied, go to step 12. |
|
31 7. Call ToInt32(radix). |
|
32 8. If Result(7) is zero, go to step 12; otherwise, if Result(7) < 2 or |
|
33 Result(7) > 36, return NaN. |
|
34 9. Let R be Result(7). |
|
35 10. If R = 16 and the length of Result(5) is at least 2 and the first two |
|
36 characters of Result(5) are either "0x" or "0X", let S be the substring |
|
37 of Result(5) consisting of all but the first two characters; otherwise, |
|
38 let S be Result(5). |
|
39 11. Go to step 22. |
|
40 12. If Result(5) is empty or the first character of Result(5) is not 0, |
|
41 go to step 20. |
|
42 13. If the length of Result(5) is at least 2 and the second character of |
|
43 Result(5) is x or X, go to step 17. |
|
44 14. Let R be 8. |
|
45 15. Let S be Result(5). |
|
46 16. Go to step 22. |
|
47 17. Let R be 16. |
|
48 18. Let S be the substring of Result(5) consisting of all but the first |
|
49 two characters. |
|
50 19. Go to step 22. |
|
51 20. Let R be 10. |
|
52 21. Let S be Result(5). |
|
53 22. If S contains any character that is not a radix-R digit, then let Z be |
|
54 the substring of S consisting of all characters to the left of the |
|
55 leftmost such character; otherwise, let Z be S. |
|
56 23. If Z is empty, return NaN. |
|
57 24. Compute the mathematical integer value that is represented by Z in |
|
58 radix-R notation. (But if R is 10 and Z contains more than 20 |
|
59 significant digits, every digit after the 20th may be replaced by a 0 |
|
60 digit, at the option of the implementation; and if R is not 2, 4, 8, |
|
61 10, 16, or 32, then Result(24) may be an implementation-dependent |
|
62 approximation to the mathematical integer value that is represented |
|
63 by Z in radix-R notation.) |
|
64 25. Compute the number value for Result(24). |
|
65 26. Return sign Result(25). |
|
66 |
|
67 Note that parseInt may interpret only a leading portion of the string as |
|
68 an integer value; it ignores any characters that cannot be interpreted as |
|
69 part of the notation of an integer, and no indication is given that any |
|
70 such characters were ignored. |
|
71 |
|
72 Author: christine@netscape.com |
|
73 Date: 28 october 1997 |
|
74 |
|
75 */ |
|
76 var SECTION = "15.1.2.2-1"; |
|
77 var VERSION = "ECMA_1"; |
|
78 var TITLE = "parseInt(string, radix)"; |
|
79 var BUGNUMBER = "none"; |
|
80 |
|
81 startTest(); |
|
82 |
|
83 writeHeaderToLog( SECTION + " "+ TITLE); |
|
84 |
|
85 var HEX_STRING = "0x0"; |
|
86 var HEX_VALUE = 0; |
|
87 |
|
88 new TestCase( SECTION, |
|
89 "parseInt.length", |
|
90 2, |
|
91 parseInt.length ); |
|
92 |
|
93 new TestCase( SECTION, |
|
94 "parseInt.length = 0; parseInt.length", |
|
95 2, |
|
96 eval("parseInt.length = 0; parseInt.length") ); |
|
97 |
|
98 new TestCase( SECTION, |
|
99 "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS", "", |
|
100 eval("var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS") ); |
|
101 |
|
102 new TestCase( SECTION, |
|
103 "delete parseInt.length", |
|
104 false, |
|
105 delete parseInt.length ); |
|
106 |
|
107 new TestCase( SECTION, |
|
108 "delete parseInt.length; parseInt.length", |
|
109 2, |
|
110 eval("delete parseInt.length; parseInt.length") ); |
|
111 |
|
112 new TestCase( SECTION, |
|
113 "parseInt.length = null; parseInt.length", |
|
114 2, |
|
115 eval("parseInt.length = null; parseInt.length") ); |
|
116 |
|
117 new TestCase( SECTION, |
|
118 "parseInt()", |
|
119 NaN, |
|
120 parseInt() ); |
|
121 |
|
122 new TestCase( SECTION, |
|
123 "parseInt('')", |
|
124 NaN, |
|
125 parseInt("") ); |
|
126 |
|
127 new TestCase( SECTION, |
|
128 "parseInt('','')", |
|
129 NaN, |
|
130 parseInt("","") ); |
|
131 |
|
132 new TestCase( SECTION, |
|
133 "parseInt(\" 0xabcdef ", |
|
134 11259375, |
|
135 parseInt( " 0xabcdef " )); |
|
136 |
|
137 new TestCase( SECTION, |
|
138 "parseInt(\" 0XABCDEF ", |
|
139 11259375, |
|
140 parseInt( " 0XABCDEF " ) ); |
|
141 |
|
142 new TestCase( SECTION, |
|
143 "parseInt( 0xabcdef )", |
|
144 11259375, |
|
145 parseInt( "0xabcdef") ); |
|
146 |
|
147 new TestCase( SECTION, |
|
148 "parseInt( 0XABCDEF )", |
|
149 11259375, |
|
150 parseInt( "0XABCDEF") ); |
|
151 |
|
152 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
153 new TestCase( SECTION, "parseInt('"+HEX_STRING+"')", HEX_VALUE, parseInt(HEX_STRING) ); |
|
154 HEX_VALUE += Math.pow(16,POWER)*15; |
|
155 } |
|
156 for ( HEX_STRING = "0X0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
157 new TestCase( SECTION, "parseInt('"+HEX_STRING+"')", HEX_VALUE, parseInt(HEX_STRING) ); |
|
158 HEX_VALUE += Math.pow(16,POWER)*15; |
|
159 } |
|
160 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
161 new TestCase( SECTION, "parseInt('"+HEX_STRING+"', 16)", HEX_VALUE, parseInt(HEX_STRING,16) ); |
|
162 HEX_VALUE += Math.pow(16,POWER)*15; |
|
163 } |
|
164 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
165 new TestCase( SECTION, "parseInt('"+HEX_STRING+"', 16)", HEX_VALUE, parseInt(HEX_STRING,16) ); |
|
166 HEX_VALUE += Math.pow(16,POWER)*15; |
|
167 } |
|
168 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
169 new TestCase( SECTION, "parseInt('"+HEX_STRING+"', null)", HEX_VALUE, parseInt(HEX_STRING,null) ); |
|
170 HEX_VALUE += Math.pow(16,POWER)*15; |
|
171 } |
|
172 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
173 new TestCase( SECTION, "parseInt('"+HEX_STRING+"', void 0)", HEX_VALUE, parseInt(HEX_STRING, void 0) ); |
|
174 HEX_VALUE += Math.pow(16,POWER)*15; |
|
175 } |
|
176 |
|
177 // a few tests with spaces |
|
178 |
|
179 for ( var space = " ", HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; |
|
180 POWER < 15; |
|
181 POWER++, HEX_STRING = HEX_STRING +"f", space += " ") |
|
182 { |
|
183 new TestCase( SECTION, "parseInt('"+space+HEX_STRING+space+"', void 0)", HEX_VALUE, parseInt(space+HEX_STRING+space, void 0) ); |
|
184 HEX_VALUE += Math.pow(16,POWER)*15; |
|
185 } |
|
186 |
|
187 new TestCase(SECTION, "parseInt(BOM + '123', 10)", 123, parseInt("\uFEFF" + "123", 10)); |
|
188 |
|
189 // a few tests with negative numbers |
|
190 for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
191 new TestCase( SECTION, "parseInt('"+HEX_STRING+"')", HEX_VALUE, parseInt(HEX_STRING) ); |
|
192 HEX_VALUE -= Math.pow(16,POWER)*15; |
|
193 } |
|
194 |
|
195 // we should stop parsing when we get to a value that is not a numeric literal for the type we expect |
|
196 |
|
197 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
198 new TestCase( SECTION, "parseInt('"+HEX_STRING+"g', 16)", HEX_VALUE, parseInt(HEX_STRING+"g",16) ); |
|
199 HEX_VALUE += Math.pow(16,POWER)*15; |
|
200 } |
|
201 for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
202 new TestCase( SECTION, "parseInt('"+HEX_STRING+"G', 16)", HEX_VALUE, parseInt(HEX_STRING+"G",16) ); |
|
203 HEX_VALUE += Math.pow(16,POWER)*15; |
|
204 } |
|
205 |
|
206 for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
207 new TestCase( SECTION, "parseInt('"+HEX_STRING+"')", HEX_VALUE, parseInt(HEX_STRING) ); |
|
208 HEX_VALUE -= Math.pow(16,POWER)*15; |
|
209 } |
|
210 for ( HEX_STRING = "-0X0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
211 new TestCase( SECTION, "parseInt('"+HEX_STRING+"')", HEX_VALUE, parseInt(HEX_STRING) ); |
|
212 HEX_VALUE -= Math.pow(16,POWER)*15; |
|
213 } |
|
214 for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
215 new TestCase( SECTION, "parseInt('"+HEX_STRING+"', 16)", HEX_VALUE, parseInt(HEX_STRING,16) ); |
|
216 HEX_VALUE -= Math.pow(16,POWER)*15; |
|
217 } |
|
218 for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) { |
|
219 new TestCase( SECTION, "parseInt('"+HEX_STRING+"', 16)", HEX_VALUE, parseInt(HEX_STRING,16) ); |
|
220 HEX_VALUE -= Math.pow(16,POWER)*15; |
|
221 } |
|
222 |
|
223 // Numbers that start with 0 and do not provide a radix should use 10 as radix |
|
224 // per ES5, not octal (as it was in ES3). |
|
225 |
|
226 var OCT_STRING = "0"; |
|
227 var OCT_VALUE = 0; |
|
228 |
|
229 for ( OCT_STRING = "0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) { |
|
230 new TestCase( SECTION, "parseInt('"+OCT_STRING+"')", OCT_VALUE, parseInt(OCT_STRING) ); |
|
231 OCT_VALUE += Math.pow(10,POWER)*7; |
|
232 } |
|
233 |
|
234 for ( OCT_STRING = "-0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) { |
|
235 new TestCase( SECTION, "parseInt('"+OCT_STRING+"')", OCT_VALUE, parseInt(OCT_STRING) ); |
|
236 OCT_VALUE -= Math.pow(10,POWER)*7; |
|
237 } |
|
238 |
|
239 // should get octal-based results if we provid the radix of 8 (or 010) |
|
240 |
|
241 for ( OCT_STRING = "0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) { |
|
242 new TestCase( SECTION, "parseInt('"+OCT_STRING+"', 8)", OCT_VALUE, parseInt(OCT_STRING,8) ); |
|
243 OCT_VALUE += Math.pow(8,POWER)*7; |
|
244 } |
|
245 for ( OCT_STRING = "-0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) { |
|
246 new TestCase( SECTION, "parseInt('"+OCT_STRING+"', 010)", OCT_VALUE, parseInt(OCT_STRING,010) ); |
|
247 OCT_VALUE -= Math.pow(8,POWER)*7; |
|
248 } |
|
249 |
|
250 // we shall stop parsing digits when we get one that isn't a numeric literal of the type we think |
|
251 // it should be. |
|
252 for ( OCT_STRING = "0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) { |
|
253 new TestCase( SECTION, "parseInt('"+OCT_STRING+"8', 8)", OCT_VALUE, parseInt(OCT_STRING+"8",8) ); |
|
254 OCT_VALUE += Math.pow(8,POWER)*7; |
|
255 } |
|
256 for ( OCT_STRING = "-0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) { |
|
257 new TestCase( SECTION, "parseInt('"+OCT_STRING+"8', 010)", OCT_VALUE, parseInt(OCT_STRING+"8",010) ); |
|
258 OCT_VALUE -= Math.pow(8,POWER)*7; |
|
259 } |
|
260 |
|
261 new TestCase( SECTION, |
|
262 "parseInt( '0x' )", |
|
263 NaN, |
|
264 parseInt("0x") ); |
|
265 |
|
266 new TestCase( SECTION, |
|
267 "parseInt( '0X' )", |
|
268 NaN, |
|
269 parseInt("0X") ); |
|
270 |
|
271 new TestCase( SECTION, |
|
272 "parseInt( '11111111112222222222' )", |
|
273 11111111112222222222, |
|
274 parseInt("11111111112222222222") ); |
|
275 |
|
276 new TestCase( SECTION, |
|
277 "parseInt( '111111111122222222223' )", |
|
278 111111111122222222220, |
|
279 parseInt("111111111122222222223") ); |
|
280 |
|
281 new TestCase( SECTION, |
|
282 "parseInt( '11111111112222222222',10 )", |
|
283 11111111112222222222, |
|
284 parseInt("11111111112222222222",10) ); |
|
285 |
|
286 new TestCase( SECTION, |
|
287 "parseInt( '111111111122222222223',10 )", |
|
288 111111111122222222220, |
|
289 parseInt("111111111122222222223",10) ); |
|
290 |
|
291 new TestCase( SECTION, |
|
292 "parseInt( '01234567890', -1 )", |
|
293 Number.NaN, |
|
294 parseInt("01234567890",-1) ); |
|
295 |
|
296 new TestCase( SECTION, |
|
297 "parseInt( '01234567890', 0 )", |
|
298 1234567890, |
|
299 parseInt("01234567890", 0) ); |
|
300 |
|
301 new TestCase( SECTION, |
|
302 "parseInt( '01234567890', 1 )", |
|
303 Number.NaN, |
|
304 parseInt("01234567890",1) ); |
|
305 |
|
306 new TestCase( SECTION, |
|
307 "parseInt( '01234567890', 2 )", |
|
308 1, |
|
309 parseInt("01234567890",2) ); |
|
310 |
|
311 new TestCase( SECTION, |
|
312 "parseInt( '01234567890', 3 )", |
|
313 5, |
|
314 parseInt("01234567890",3) ); |
|
315 |
|
316 new TestCase( SECTION, |
|
317 "parseInt( '01234567890', 4 )", |
|
318 27, |
|
319 parseInt("01234567890",4) ); |
|
320 |
|
321 new TestCase( SECTION, |
|
322 "parseInt( '01234567890', 5 )", |
|
323 194, |
|
324 parseInt("01234567890",5) ); |
|
325 |
|
326 new TestCase( SECTION, |
|
327 "parseInt( '01234567890', 6 )", |
|
328 1865, |
|
329 parseInt("01234567890",6) ); |
|
330 |
|
331 new TestCase( SECTION, |
|
332 "parseInt( '01234567890', 7 )", |
|
333 22875, |
|
334 parseInt("01234567890",7) ); |
|
335 |
|
336 new TestCase( SECTION, |
|
337 "parseInt( '01234567890', 8 )", |
|
338 342391, |
|
339 parseInt("01234567890",8) ); |
|
340 |
|
341 new TestCase( SECTION, |
|
342 "parseInt( '01234567890', 9 )", |
|
343 6053444, |
|
344 parseInt("01234567890",9) ); |
|
345 |
|
346 new TestCase( SECTION, |
|
347 "parseInt( '01234567890', 10 )", |
|
348 1234567890, |
|
349 parseInt("01234567890",10) ); |
|
350 |
|
351 // need more test cases with hex radix |
|
352 |
|
353 new TestCase( SECTION, |
|
354 "parseInt( '1234567890', '0xa')", |
|
355 1234567890, |
|
356 parseInt("1234567890","0xa") ); |
|
357 |
|
358 new TestCase( SECTION, |
|
359 "parseInt( '012345', 11 )", |
|
360 17715, |
|
361 parseInt("012345",11) ); |
|
362 |
|
363 new TestCase( SECTION, |
|
364 "parseInt( '012345', 35 )", |
|
365 1590195, |
|
366 parseInt("012345",35) ); |
|
367 |
|
368 new TestCase( SECTION, |
|
369 "parseInt( '012345', 36 )", |
|
370 1776965, |
|
371 parseInt("012345",36) ); |
|
372 |
|
373 new TestCase( SECTION, |
|
374 "parseInt( '012345', 37 )", |
|
375 Number.NaN, |
|
376 parseInt("012345",37) ); |
|
377 |
|
378 test(); |