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 (at) 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 103 function 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 } 280 function 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