Home | History | Annotate | Download | only in GlobalObject
      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