• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* The contents of this file are subject to the Netscape Public
2 * License Version 1.1 (the "License"); you may not use this file
3 * except in compliance with the License. You may obtain a copy of
4 * the License at http://www.mozilla.org/NPL/
5 *
6 * Software distributed under the License is distributed on an "AS
7 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
8 * implied. See the License for the specific language governing
9 * rights and limitations under the License.
10 *
11 * The Original Code is Mozilla Communicator client code, released March
12 * 31, 1998.
13 *
14 * The Initial Developer of the Original Code is Netscape Communications
15 * Corporation. Portions created by Netscape are
16 * Copyright (C) 1998 Netscape Communications Corporation. All
17 * Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 */
22/**
23    File Name:          15.1.2.2-1.js
24    ECMA Section:       15.1.2.2 Function properties of the global object
25                        parseInt( string, radix )
26
27    Description:
28
29    The parseInt function produces an integer value dictated by intepretation
30    of the contents of the string argument according to the specified radix.
31
32    When the parseInt function is called, the following steps are taken:
33
34   1.   Call ToString(string).
35   2.   Compute a substring of Result(1) consisting of the leftmost character
36        that is not a StrWhiteSpaceChar and all characters to the right of
37        that character. (In other words, remove leading whitespace.)
38   3.   Let sign be 1.
39   4.   If Result(2) is not empty and the first character of Result(2) is a
40        minus sign -, let sign be -1.
41   5.   If Result(2) is not empty and the first character of Result(2) is a
42        plus sign + or a minus sign -, then Result(5) is the substring of
43        Result(2) produced by removing the first character; otherwise, Result(5)
44        is Result(2).
45   6.   If the radix argument is not supplied, go to step 12.
46   7.   Call ToInt32(radix).
47   8.   If Result(7) is zero, go to step 12; otherwise, if Result(7) < 2 or
48        Result(7) > 36, return NaN.
49   9.   Let R be Result(7).
50  10.   If R = 16 and the length of Result(5) is at least 2 and the first two
51        characters of Result(5) are either "0x" or "0X", let S be the substring
52        of Result(5) consisting of all but the first two characters; otherwise,
53        let S be Result(5).
54  11.   Go to step 22.
55  12.   If Result(5) is empty or the first character of Result(5) is not 0,
56        go to step 20.
57  13.   If the length of Result(5) is at least 2 and the second character of
58        Result(5) is x or X, go to step 17.
59  14.   Let R be 8.
60  15.   Let S be Result(5).
61  16.   Go to step 22.
62  17.   Let R be 16.
63  18.   Let S be the substring of Result(5) consisting of all but the first
64        two characters.
65  19.   Go to step 22.
66  20.   Let R be 10.
67  21.   Let S be Result(5).
68  22.   If S contains any character that is not a radix-R digit, then let Z be
69        the substring of S consisting of all characters to the left of the
70        leftmost such character; otherwise, let Z be S.
71  23.   If Z is empty, return NaN.
72  24.   Compute the mathematical integer value that is represented by Z in
73        radix-R notation. (But if R is 10 and Z contains more than 20
74        significant digits, every digit after the 20th may be replaced by a 0
75        digit, at the option of the implementation; and if R is not 2, 4, 8,
76        10, 16, or 32, then Result(24) may be an implementation-dependent
77        approximation to the mathematical integer value that is represented
78        by Z in radix-R notation.)
79  25.   Compute the number value for Result(24).
80  26.   Return sign Result(25).
81
82    Note that parseInt may interpret only a leading portion of the string as
83    an integer value; it ignores any characters that cannot be interpreted as
84    part of the notation of an integer, and no indication is given that any
85    such characters were ignored.
86
87    Author:             christine@netscape.com
88    Date:               28 october 1997
89
90*/
91    var SECTION = "15.1.2.2-1";
92    var VERSION = "ECMA_1";
93    startTest();
94    var TITLE   = "parseInt(string, radix)";
95    var BUGNUMBER="111199";
96
97    writeHeaderToLog( SECTION + " "+ TITLE);
98
99    var testcases = getTestCases();
100
101    test();
102
103function getTestCases() {
104    var array = new Array();
105    var item = 0;
106
107    var HEX_STRING = "0x0";
108    var HEX_VALUE = 0;
109
110    array[item++] = new TestCase( SECTION,  "parseInt.length",      2,      parseInt.length );
111    array[item++] = new TestCase( SECTION,  "parseInt.length = 0; parseInt.length",     2,      eval("parseInt.length = 0; parseInt.length") );
112    array[item++] = new TestCase( SECTION,  "var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS",   "", eval("var PROPS=''; for ( var p in parseInt ) { PROPS += p; }; PROPS") );
113    array[item++] = new TestCase( SECTION,  "delete parseInt.length",   false,  delete parseInt.length );
114    array[item++] = new TestCase( SECTION,  "delete parseInt.length; parseInt.length",  2,  eval("delete parseInt.length; parseInt.length") );
115    array[item++] = new TestCase( SECTION,  "parseInt.length = null; parseInt.length",  2,  eval("parseInt.length = null; parseInt.length") );
116
117    array[item++] = new TestCase( SECTION,  "parseInt()",       NaN,    parseInt() );
118    array[item++] = new TestCase( SECTION,  "parseInt('')",     NaN,    parseInt("") );
119    array[item++] = new TestCase( SECTION,  "parseInt('','')",  NaN,    parseInt("","") );
120    array[item++] = new TestCase( SECTION,
121                    "parseInt(\"     0xabcdef     ",
122                    11259375,
123                    parseInt( "      0xabcdef     " ));
124
125    array[item++] = new TestCase( SECTION,
126                    "parseInt(\"     0XABCDEF     ",
127                    11259375,
128                    parseInt( "      0XABCDEF     " ) );
129
130    array[item++] = new TestCase( SECTION,
131                    "parseInt( 0xabcdef )",
132                    11259375,
133                    parseInt( "0xabcdef") );
134
135    array[item++] = new TestCase( SECTION,
136                    "parseInt( 0XABCDEF )",
137                    11259375,
138                    parseInt( "0XABCDEF") );
139
140    for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
141        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+")",    HEX_VALUE,  parseInt(HEX_STRING) );
142        HEX_VALUE += Math.pow(16,POWER)*15;
143    }
144    for ( HEX_STRING = "0X0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
145        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+")",    HEX_VALUE,  parseInt(HEX_STRING) );
146        HEX_VALUE += Math.pow(16,POWER)*15;
147    }
148    for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
149        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+",16)",    HEX_VALUE,  parseInt(HEX_STRING,16) );
150        HEX_VALUE += Math.pow(16,POWER)*15;
151    }
152    for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
153        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+",16)",    HEX_VALUE,  parseInt(HEX_STRING,16) );
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        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+",null)",    HEX_VALUE,  parseInt(HEX_STRING,null) );
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        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+", void 0)",    HEX_VALUE,  parseInt(HEX_STRING, void 0) );
162        HEX_VALUE += Math.pow(16,POWER)*15;
163    }
164
165    // a few tests with spaces
166
167    for ( var space = " ", HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0;
168        POWER < 15;
169        POWER++, HEX_STRING = HEX_STRING +"f", space += " ")
170    {
171        array[item++] = new TestCase( SECTION, "parseInt("+space+HEX_STRING+space+", void 0)",    HEX_VALUE,  parseInt(space+HEX_STRING+space, void 0) );
172        HEX_VALUE += Math.pow(16,POWER)*15;
173    }
174
175    // a few tests with negative numbers
176    for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
177        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+")",    HEX_VALUE,  parseInt(HEX_STRING) );
178        HEX_VALUE -= Math.pow(16,POWER)*15;
179    }
180
181    // we should stop parsing when we get to a value that is not a numeric literal for the type we expect
182
183    for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
184        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+"g,16)",    HEX_VALUE,  parseInt(HEX_STRING+"g",16) );
185        HEX_VALUE += Math.pow(16,POWER)*15;
186    }
187    for ( HEX_STRING = "0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
188        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+"g,16)",    HEX_VALUE,  parseInt(HEX_STRING+"G",16) );
189        HEX_VALUE += Math.pow(16,POWER)*15;
190    }
191
192    for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
193        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+")",    HEX_VALUE,  parseInt(HEX_STRING) );
194        HEX_VALUE -= Math.pow(16,POWER)*15;
195    }
196    for ( HEX_STRING = "-0X0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
197        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+")",    HEX_VALUE,  parseInt(HEX_STRING) );
198        HEX_VALUE -= Math.pow(16,POWER)*15;
199    }
200    for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
201        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+",16)",    HEX_VALUE,  parseInt(HEX_STRING,16) );
202        HEX_VALUE -= Math.pow(16,POWER)*15;
203    }
204    for ( HEX_STRING = "-0x0", HEX_VALUE = 0, POWER = 0; POWER < 15; POWER++, HEX_STRING = HEX_STRING +"f" ) {
205        array[item++] = new TestCase( SECTION, "parseInt("+HEX_STRING+",16)",    HEX_VALUE,  parseInt(HEX_STRING,16) );
206        HEX_VALUE -= Math.pow(16,POWER)*15;
207    }
208
209    //  let us do some octal tests.  numbers that start with 0 and do not provid a radix should
210    //  default to using "0" as a radix.
211
212    var OCT_STRING = "0";
213    var OCT_VALUE = 0;
214
215    for ( OCT_STRING = "0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) {
216        array[item++] = new TestCase( SECTION, "parseInt("+OCT_STRING+")",    OCT_VALUE,  parseInt(OCT_STRING) );
217        OCT_VALUE += Math.pow(8,POWER)*7;
218    }
219
220    for ( OCT_STRING = "-0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) {
221        array[item++] = new TestCase( SECTION, "parseInt("+OCT_STRING+")",    OCT_VALUE,  parseInt(OCT_STRING) );
222        OCT_VALUE -= Math.pow(8,POWER)*7;
223    }
224
225    // should get the same results as above if we provid the radix of 8 (or 010)
226
227    for ( OCT_STRING = "0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) {
228        array[item++] = new TestCase( SECTION, "parseInt("+OCT_STRING+",8)",    OCT_VALUE,  parseInt(OCT_STRING,8) );
229        OCT_VALUE += Math.pow(8,POWER)*7;
230    }
231    for ( OCT_STRING = "-0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) {
232        array[item++] = new TestCase( SECTION, "parseInt("+OCT_STRING+",010)",    OCT_VALUE,  parseInt(OCT_STRING,010) );
233        OCT_VALUE -= Math.pow(8,POWER)*7;
234    }
235
236    // we shall stop parsing digits when we get one that isn't a numeric literal of the type we think
237    // it should be.
238    for ( OCT_STRING = "0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) {
239        array[item++] = new TestCase( SECTION, "parseInt("+OCT_STRING+"8,8)",    OCT_VALUE,  parseInt(OCT_STRING+"8",8) );
240        OCT_VALUE += Math.pow(8,POWER)*7;
241    }
242    for ( OCT_STRING = "-0", OCT_VALUE = 0, POWER = 0; POWER < 15; POWER++, OCT_STRING = OCT_STRING +"7" ) {
243        array[item++] = new TestCase( SECTION, "parseInt("+OCT_STRING+"8,010)",    OCT_VALUE,  parseInt(OCT_STRING+"8",010) );
244        OCT_VALUE -= Math.pow(8,POWER)*7;
245    }
246
247    array[item++] = new TestCase( SECTION, "parseInt( '0x' )",              NaN,        parseInt("0x") );
248    array[item++] = new TestCase( SECTION, "parseInt( '0X' )",              NaN,        parseInt("0X") );
249
250    array[item++] = new TestCase( SECTION, "parseInt( '11111111112222222222' )",    11111111112222222222,   parseInt("11111111112222222222") );
251    array[item++] = new TestCase( SECTION, "parseInt( '111111111122222222223' )",    111111111122222222220,   parseInt("111111111122222222223") );
252    array[item++] = new TestCase( SECTION, "parseInt( '11111111112222222222',10 )",    11111111112222222222,   parseInt("11111111112222222222",10) );
253    array[item++] = new TestCase( SECTION, "parseInt( '111111111122222222223',10 )",    111111111122222222220,   parseInt("111111111122222222223",10) );
254
255    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', -1 )",  Number.NaN,    parseInt("01234567890",-1) );
256    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 0 )",  Number.NaN,     parseInt("01234567890",1) );
257    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 1 )",  Number.NaN,     parseInt("01234567890",1) );
258    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 2 )",  1,              parseInt("01234567890",2) );
259    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 3 )",  5,              parseInt("01234567890",3) );
260    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 4 )",  27,             parseInt("01234567890",4) );
261    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 5 )",  194,            parseInt("01234567890",5) );
262    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 6 )",  1865,           parseInt("01234567890",6) );
263    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 7 )",  22875,          parseInt("01234567890",7) );
264    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 8 )",  342391,         parseInt("01234567890",8) );
265    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 9 )",  6053444,        parseInt("01234567890",9) );
266    array[item++] = new TestCase( SECTION, "parseInt( '01234567890', 10 )", 1234567890,     parseInt("01234567890",10) );
267
268    // need more test cases with hex radix
269
270    array[item++] = new TestCase( SECTION, "parseInt( '1234567890', '0xa')", 1234567890, parseInt("1234567890","0xa") );
271
272    array[item++] = new TestCase( SECTION, "parseInt( '012345', 11 )",      17715,          parseInt("012345",11) );
273
274    array[item++] = new TestCase( SECTION, "parseInt( '012345', 35 )",      1590195,        parseInt("012345",35) );
275    array[item++] = new TestCase( SECTION, "parseInt( '012345', 36 )",      1776965,        parseInt("012345",36) );
276    array[item++] = new TestCase( SECTION, "parseInt( '012345', 37 )",      Number.NaN,     parseInt("012345",37) );
277
278    return ( array );
279}
280function test( array ) {
281    for ( tc=0 ; tc < testcases.length; tc++ ) {
282        testcases[tc].passed = writeTestCaseResult(
283                            testcases[tc].expect,
284                            testcases[tc].actual,
285                            testcases[tc].description +" = "+ testcases[tc].actual );
286
287        testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
288    }
289    stopTest();
290    return ( testcases );
291}
292