Home | History | Annotate | Download | only in ecma
      1 var completed = false;
      2 var testcases;
      3 var tc = 0;
      4 
      5 SECTION	= "";
      6 VERSION	= "";
      7 BUGNUMBER =	"";
      8 TITLE  = "";
      9 
     10 /*
     11  * constant strings
     12  */
     13 var	GLOBAL = "[object global]";
     14 var PASSED = " PASSED!"
     15 var FAILED = " FAILED! expected: ";
     16 var	DEBUG =	false;
     17 
     18 TZ_DIFF = -8;
     19 
     20 var TT = "";
     21 var TT_ = "";
     22 var BR = "";
     23 var NBSP = " ";
     24 var CR = "\n";
     25 var FONT = "";
     26 var FONT_ = "";
     27 var FONT_RED = "";
     28 var FONT_GREEN = "";
     29 var B = "";
     30 var B_ = ""
     31 var H2 = "";
     32 var H2_ = "";
     33 var HR = "";
     34 var DEBUG = false;
     35 
     36 var PASSED = " PASSED!"
     37 var FAILED = " FAILED! expected: ";
     38 
     39 function test() {
     40     for ( tc=0; tc < testcases.length; tc++ ) {
     41         testcases[tc].passed = writeTestCaseResult(
     42                             testcases[tc].expect,
     43                             testcases[tc].actual,
     44                             testcases[tc].description +" = "+
     45                             testcases[tc].actual );
     46 
     47         testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
     48     }
     49     stopTest();
     50     return ( testcases );
     51 }
     52 /* wrapper for test cas constructor that doesn't require the SECTION
     53  * argument.
     54  */
     55 
     56 function AddTestCase( description, expect, actual ) {
     57     testcases[tc++] = new TestCase( SECTION, description, expect, actual );
     58 }
     59 
     60 function TestCase( n, d, e, a ) {
     61     this.name        = n;
     62     this.description = d;
     63     this.expect      = e;
     64     this.actual      = a;
     65     this.passed      = true;
     66     this.reason      = "";
     67     this.bugnumber   = BUGNUMBER;
     68 
     69     this.passed = getTestCaseResult( this.expect, this.actual );
     70     if ( DEBUG ) {
     71         writeLineToLog( "added " + this.description );
     72     }
     73 }
     74 
     75 /*
     76  * Set up test environment.
     77  *
     78  */
     79 function startTest() {
     80     if ( version ) {
     81     	//	JavaScript 1.3 is supposed to be compliant ecma	version	1.0
     82 	    if ( VERSION ==	"ECMA_1" ) {
     83 		    version	( "130"	);
     84     	}
     85 	    if ( VERSION ==	"JS_1.3" ) {
     86 		    version	( "130"	);
     87     	}
     88 	    if ( VERSION ==	"JS_1.2" ) {
     89 		    version	( "120"	);
     90     	}
     91 	    if ( VERSION  == "JS_1.1" )	{
     92 		    version	( "110"	);
     93     	}
     94 	    // for ecma	version	2.0, we	will leave the javascript version to
     95     	// the default ( for now ).
     96     }
     97 
     98     // print out bugnumber
     99 
    100     if ( BUGNUMBER ) {
    101             writeLineToLog ("BUGNUMBER: " + BUGNUMBER );
    102     }
    103 
    104     testcases = new Array();
    105     tc = 0;
    106 }
    107 
    108 
    109 function test() {
    110     for ( tc=0; tc < testcases.length; tc++ ) {
    111         testcases[tc].passed = writeTestCaseResult(
    112                             testcases[tc].expect,
    113                             testcases[tc].actual,
    114                             testcases[tc].description +" = "+ testcases[tc].actual );
    115         testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
    116     }
    117     stopTest();
    118     return ( testcases );
    119 }
    120 
    121 
    122 function getTestCaseResult( expect, actual ) {
    123     //  because ( NaN == NaN ) always returns false, need to do
    124     //  a special compare to see if we got the right result.
    125         if ( actual != actual ) {
    126             if ( typeof actual == "object" ) {
    127                 actual = "NaN object";
    128             } else {
    129                 actual = "NaN number";
    130             }
    131         }
    132         if ( expect != expect ) {
    133             if ( typeof expect == "object" ) {
    134                 expect = "NaN object";
    135             } else {
    136                 expect = "NaN number";
    137             }
    138         }
    139 
    140         var passed = ( expect == actual ) ? true : false;
    141 
    142     //  if both objects are numbers
    143     // need to replace w/ IEEE standard for rounding
    144         if (    !passed
    145                 && typeof(actual) == "number"
    146                 && typeof(expect) == "number"
    147             ) {
    148                 if ( Math.abs(actual-expect) < 0.0000001 ) {
    149                     passed = true;
    150                 }
    151         }
    152 
    153     //  verify type is the same
    154         if ( typeof(expect) != typeof(actual) ) {
    155             passed = false;
    156         }
    157 
    158         return passed;
    159 }
    160 function writeTestCaseResult( expect, actual, string ) {
    161         var passed = getTestCaseResult( expect, actual );
    162         writeFormattedResult( expect, actual, string, passed );
    163         return passed;
    164 }
    165 function writeFormattedResult( expect, actual, string, passed ) {
    166         var s = TT + string ;
    167 
    168         for ( k = 0;
    169               k <  (60 - string.length >= 0 ? 60 - string.length : 5) ;
    170               k++ ) {
    171         }
    172 
    173         s += B ;
    174         s += ( passed ) ? FONT_GREEN + NBSP + PASSED : FONT_RED + NBSP + FAILED + expect + TT_ ;
    175 
    176         writeLineToLog( s + FONT_ + B_ + TT_ );
    177 
    178         return passed;
    179 }
    180 
    181 function writeLineToLog( string ) {
    182     print( string + BR + CR );
    183 }
    184 function writeHeaderToLog( string ) {
    185     print( H2 + string + H2_ );
    186 }
    187 function stopTest()
    188 {
    189     var sizeTag  = "<#TEST CASES SIZE>";
    190     var doneTag  = "<#TEST CASES DONE>";
    191     var beginTag = "<#TEST CASE ";
    192     var endTag   = ">";
    193 
    194     print(sizeTag);
    195     print(testcases.length);
    196     for (tc = 0; tc < testcases.length; tc++)
    197     {
    198         print(beginTag + 'PASSED'      + endTag);
    199         print(testcases[tc].passed);
    200         print(beginTag + 'NAME'        + endTag);
    201         print(testcases[tc].name);
    202         print(beginTag + 'EXPECTED'    + endTag);
    203         print(testcases[tc].expect);
    204         print(beginTag + 'ACTUAL'      + endTag);
    205         print(testcases[tc].actual);
    206         print(beginTag + 'DESCRIPTION' + endTag);
    207         print(testcases[tc].description);
    208         print(beginTag + 'REASON'      + endTag);
    209         print(( testcases[tc].passed ) ? "" : "wrong value ");
    210         print(beginTag + 'BUGNUMBER'   + endTag);
    211         print( BUGNUMBER );
    212     }
    213     print(doneTag);
    214     print( HR );
    215     gc();
    216 }
    217 function getFailedCases() {
    218   for ( var i = 0; i < testcases.length; i++ ) {
    219      if ( ! testcases[i].passed ) {
    220         print( testcases[i].description +" = " +testcases[i].actual +" expected: "+ testcases[i].expect );
    221      }
    222   }
    223 }
    224 function err( msg, page, line ) {
    225     testcases[tc].actual = "error";
    226     testcases[tc].reason = msg;
    227     writeTestCaseResult( testcases[tc].expect,
    228                          testcases[tc].actual,
    229                          testcases[tc].description +" = "+ testcases[tc].actual +
    230                          ": " + testcases[tc].reason );
    231     stopTest();
    232     return true;
    233 }
    234 
    235 /**
    236  *  Type Conversion functions used by Type Conversion
    237  *
    238  */
    239 
    240 
    241 
    242  /*
    243   * Date functions used by tests in Date suite
    244   *
    245   */
    246 var msPerDay =          86400000;
    247 var HoursPerDay =       24;
    248 var MinutesPerHour =    60;
    249 var SecondsPerMinute =  60;
    250 var msPerSecond =       1000;
    251 var msPerMinute =       60000;      //  msPerSecond * SecondsPerMinute
    252 var msPerHour =         3600000;    //  msPerMinute * MinutesPerHour
    253 
    254 var TIME_1970    = 0;
    255 var TIME_2000    = 946684800000;
    256 var TIME_1900    = -2208988800000;
    257 
    258 function Day( t ) {
    259     return ( Math.floor(t/msPerDay ) );
    260 }
    261 function DaysInYear( y ) {
    262     if ( y % 4 != 0 ) {
    263         return 365;
    264     }
    265     if ( (y % 4 == 0) && (y % 100 != 0) ) {
    266         return 366;
    267     }
    268     if ( (y % 100 == 0) &&  (y % 400 != 0) ) {
    269         return 365;
    270     }
    271     if ( (y % 400 == 0) ){
    272         return 366;
    273     } else {
    274         return "ERROR: DaysInYear(" + y + ") case not covered";
    275     }
    276 }
    277 function TimeInYear( y ) {
    278     return ( DaysInYear(y) * msPerDay );
    279 }
    280 function DayNumber( t ) {
    281     return ( Math.floor( t / msPerDay ) );
    282 }
    283 function TimeWithinDay( t ) {
    284     if ( t < 0 ) {
    285         return ( (t % msPerDay) + msPerDay );
    286     } else {
    287         return ( t % msPerDay );
    288     }
    289 }
    290 function YearNumber( t ) {
    291 }
    292 function TimeFromYear( y ) {
    293     return ( msPerDay * DayFromYear(y) );
    294 }
    295 function DayFromYear( y ) {
    296     return (    365*(y-1970) +
    297                 Math.floor((y-1969)/4) -
    298                 Math.floor((y-1901)/100) +
    299                 Math.floor((y-1601)/400) );
    300 }
    301 function InLeapYear( t ) {
    302     if ( DaysInYear(YearFromTime(t)) == 365 ) {
    303         return 0;
    304     }
    305     if ( DaysInYear(YearFromTime(t)) == 366 ) {
    306         return 1;
    307     } else {
    308         return "ERROR:  InLeapYear("+t+") case not covered";
    309     }
    310 }
    311 function YearFromTime( t ) {
    312     t = Number( t );
    313     var sign = ( t < 0 ) ? -1 : 1;
    314     var year = ( sign < 0 ) ? 1969 : 1970;
    315     for (   var timeToTimeZero = t; ;  ) {
    316     //  subtract the current year's time from the time that's left.
    317         timeToTimeZero -= sign * TimeInYear(year)
    318 
    319     //  if there's less than the current year's worth of time left, then break.
    320         if ( sign < 0 ) {
    321             if ( sign * timeToTimeZero <= 0 ) {
    322                 break;
    323             } else {
    324                 year += sign;
    325             }
    326         } else {
    327             if ( sign * timeToTimeZero < 0 ) {
    328                 break;
    329             } else {
    330                 year += sign;
    331             }
    332         }
    333     }
    334     return ( year );
    335 }
    336 function MonthFromTime( t ) {
    337     //  i know i could use switch but i'd rather not until it's part of ECMA
    338     var day = DayWithinYear( t );
    339     var leap = InLeapYear(t);
    340 
    341     if ( (0 <= day) && (day < 31) ) {
    342         return 0;
    343     }
    344     if ( (31 <= day) && (day < (59+leap)) ) {
    345         return 1;
    346     }
    347     if ( ((59+leap) <= day) && (day < (90+leap)) ) {
    348         return 2;
    349     }
    350     if ( ((90+leap) <= day) && (day < (120+leap)) ) {
    351         return 3;
    352     }
    353     if ( ((120+leap) <= day) && (day < (151+leap)) ) {
    354         return 4;
    355     }
    356     if ( ((151+leap) <= day) && (day < (181+leap)) ) {
    357         return 5;
    358     }
    359     if ( ((181+leap) <= day) && (day < (212+leap)) ) {
    360         return 6;
    361     }
    362     if ( ((212+leap) <= day) && (day < (243+leap)) ) {
    363         return 7;
    364     }
    365     if ( ((243+leap) <= day) && (day < (273+leap)) ) {
    366         return 8;
    367     }
    368     if ( ((273+leap) <= day) && (day < (304+leap)) ) {
    369         return 9;
    370     }
    371     if ( ((304+leap) <= day) && (day < (334+leap)) ) {
    372         return 10;
    373     }
    374     if ( ((334+leap) <= day) && (day < (365+leap)) ) {
    375         return 11;
    376     } else {
    377         return "ERROR:  MonthFromTime("+t+") not known";
    378     }
    379 }
    380 function DayWithinYear( t ) {
    381         return( Day(t) - DayFromYear(YearFromTime(t)));
    382 }
    383 function DateFromTime( t ) {
    384     var day = DayWithinYear(t);
    385     var month = MonthFromTime(t);
    386 
    387     if ( month == 0 ) {
    388         return ( day + 1 );
    389     }
    390     if ( month == 1 ) {
    391         return ( day - 30 );
    392     }
    393     if ( month == 2 ) {
    394         return ( day - 58 - InLeapYear(t) );
    395     }
    396     if ( month == 3 ) {
    397         return ( day - 89 - InLeapYear(t));
    398     }
    399     if ( month == 4 ) {
    400         return ( day - 119 - InLeapYear(t));
    401     }
    402     if ( month == 5 ) {
    403         return ( day - 150- InLeapYear(t));
    404     }
    405     if ( month == 6 ) {
    406         return ( day - 180- InLeapYear(t));
    407     }
    408     if ( month == 7 ) {
    409         return ( day - 211- InLeapYear(t));
    410     }
    411     if ( month == 8 ) {
    412         return ( day - 242- InLeapYear(t));
    413     }
    414     if ( month == 9 ) {
    415         return ( day - 272- InLeapYear(t));
    416     }
    417     if ( month == 10 ) {
    418         return ( day - 303- InLeapYear(t));
    419     }
    420     if ( month == 11 ) {
    421         return ( day - 333- InLeapYear(t));
    422     }
    423 
    424     return ("ERROR:  DateFromTime("+t+") not known" );
    425 }
    426 function WeekDay( t ) {
    427     var weekday = (Day(t)+4) % 7;
    428     return( weekday < 0 ? 7 + weekday : weekday );
    429 }
    430 
    431 // missing daylight savins time adjustment
    432 
    433 function HourFromTime( t ) {
    434     var h = Math.floor( t / msPerHour ) % HoursPerDay;
    435     return ( (h<0) ? HoursPerDay + h : h  );
    436 }
    437 function MinFromTime( t ) {
    438     var min = Math.floor( t / msPerMinute ) % MinutesPerHour;
    439     return( ( min < 0 ) ? MinutesPerHour + min : min  );
    440 }
    441 function SecFromTime( t ) {
    442     var sec = Math.floor( t / msPerSecond ) % SecondsPerMinute;
    443     return ( (sec < 0 ) ? SecondsPerMinute + sec : sec );
    444 }
    445 function msFromTime( t ) {
    446     var ms = t % msPerSecond;
    447     return ( (ms < 0 ) ? msPerSecond + ms : ms );
    448 }
    449 function LocalTZA() {
    450     return ( TZ_DIFF * msPerHour );
    451 }
    452 function UTC( t ) {
    453     return ( t - LocalTZA() - DaylightSavingTA(t - LocalTZA()) );
    454 }
    455 function DaylightSavingTA( t ) {
    456     t = t - LocalTZA();
    457 
    458     var dst_start = GetSecondSundayInMarch(t) + 2*msPerHour;
    459     var dst_end   = GetFirstSundayInNovember(t)+ 2*msPerHour;
    460 
    461     if ( t >= dst_start && t < dst_end ) {
    462         return msPerHour;
    463     } else {
    464         return 0;
    465     }
    466 
    467     // Daylight Savings Time starts on the first Sunday in April at 2:00AM in
    468     // PST.  Other time zones will need to override this function.
    469 
    470     print( new Date( UTC(dst_start + LocalTZA())) );
    471 
    472     return UTC(dst_start  + LocalTZA());
    473 }
    474 function GetFirstSundayInApril( t ) {
    475     var year = YearFromTime(t);
    476     var leap = InLeapYear(t);
    477 
    478     var april = TimeFromYear(year) + TimeInMonth(0, leap) + TimeInMonth(1,leap) +
    479     TimeInMonth(2,leap);
    480 
    481     for ( var first_sunday = april; WeekDay(first_sunday) > 0;
    482         first_sunday += msPerDay )
    483     {
    484         ;
    485     }
    486 
    487     return first_sunday;
    488 }
    489 function GetLastSundayInOctober( t ) {
    490     var year = YearFromTime(t);
    491     var leap = InLeapYear(t);
    492 
    493     for ( var oct = TimeFromYear(year), m = 0; m < 9; m++ ) {
    494         oct += TimeInMonth(m, leap);
    495     }
    496     for ( var last_sunday = oct + 30*msPerDay; WeekDay(last_sunday) > 0;
    497         last_sunday -= msPerDay )
    498     {
    499         ;
    500     }
    501     return last_sunday;
    502 }
    503 
    504 // Added these two functions because DST rules changed for the US.
    505 function GetSecondSundayInMarch( t ) {
    506 	var	year = YearFromTime(t);
    507 	var	leap = InLeapYear(t);
    508 
    509 	var	march =	TimeFromYear(year) + TimeInMonth(0, leap) + TimeInMonth(1,leap);
    510 
    511 	var sundayCount = 0;
    512 	var flag = true;
    513 	for ( var second_sunday = march; flag; second_sunday += msPerDay )
    514 	{
    515 		if (WeekDay(second_sunday) == 0) {
    516 			if(++sundayCount == 2)
    517 				flag = false;
    518 		}
    519 	}
    520 
    521 	return second_sunday;
    522 }
    523 function GetFirstSundayInNovember( t ) {
    524 	var year = YearFromTime(t);
    525 	var leap = InLeapYear(t);
    526 
    527 	for ( var nov = TimeFromYear(year), m =	0; m < 10; m++ ) {
    528 		nov += TimeInMonth(m, leap);
    529 	}
    530 	for ( var first_sunday = nov; WeekDay(first_sunday) > 0;
    531 		first_sunday += msPerDay	)
    532 	{
    533 		;
    534 	}
    535 	return first_sunday;
    536 }
    537 function LocalTime( t ) {
    538     return ( t + LocalTZA() + DaylightSavingTA(t) );
    539 }
    540 function MakeTime( hour, min, sec, ms ) {
    541     if ( isNaN( hour ) || isNaN( min ) || isNaN( sec ) || isNaN( ms ) ) {
    542         return Number.NaN;
    543     }
    544 
    545     hour = ToInteger(hour);
    546     min  = ToInteger( min);
    547     sec  = ToInteger( sec);
    548     ms   = ToInteger( ms );
    549 
    550     return( (hour*msPerHour) + (min*msPerMinute) +
    551             (sec*msPerSecond) + ms );
    552 }
    553 function MakeDay( year, month, date ) {
    554     if ( isNaN(year) || isNaN(month) || isNaN(date) ) {
    555         return Number.NaN;
    556     }
    557     year = ToInteger(year);
    558     month = ToInteger(month);
    559     date = ToInteger(date );
    560 
    561     var sign = ( year < 1970 ) ? -1 : 1;
    562     var t =    ( year < 1970 ) ? 1 :  0;
    563     var y =    ( year < 1970 ) ? 1969 : 1970;
    564 
    565     var result5 = year + Math.floor( month/12 );
    566     var result6 = month % 12;
    567 
    568     if ( year < 1970 ) {
    569        for ( y = 1969; y >= year; y += sign ) {
    570          t += sign * TimeInYear(y);
    571        }
    572     } else {
    573         for ( y = 1970 ; y < year; y += sign ) {
    574             t += sign * TimeInYear(y);
    575         }
    576     }
    577 
    578     var leap = InLeapYear( t );
    579 
    580     for ( var m = 0; m < month; m++ ) {
    581         t += TimeInMonth( m, leap );
    582     }
    583 
    584     if ( YearFromTime(t) != result5 ) {
    585         return Number.NaN;
    586     }
    587     if ( MonthFromTime(t) != result6 ) {
    588         return Number.NaN;
    589     }
    590     if ( DateFromTime(t) != 1 ) {
    591         return Number.NaN;
    592     }
    593 
    594     return ( (Day(t)) + date - 1 );
    595 }
    596 function TimeInMonth( month, leap ) {
    597     // september april june november
    598     // jan 0  feb 1  mar 2  apr 3   may 4  june 5  jul 6
    599     // aug 7  sep 8  oct 9  nov 10  dec 11
    600 
    601     if ( month == 3 || month == 5 || month == 8 || month == 10 ) {
    602         return ( 30*msPerDay );
    603     }
    604 
    605     // all the rest
    606     if ( month == 0 || month == 2 || month == 4 || month == 6 ||
    607          month == 7 || month == 9 || month == 11 ) {
    608         return ( 31*msPerDay );
    609      }
    610 
    611     // save february
    612     return ( (leap == 0) ? 28*msPerDay : 29*msPerDay );
    613 }
    614 function MakeDate( day, time ) {
    615     if (    day == Number.POSITIVE_INFINITY ||
    616             day == Number.NEGATIVE_INFINITY ||
    617             day == Number.NaN ) {
    618         return Number.NaN;
    619     }
    620     if (    time == Number.POSITIVE_INFINITY ||
    621             time == Number.POSITIVE_INFINITY ||
    622             day == Number.NaN) {
    623         return Number.NaN;
    624     }
    625     return ( day * msPerDay ) + time;
    626 }
    627 function TimeClip( t ) {
    628     if ( isNaN( t ) ) {
    629         return ( Number.NaN );
    630     }
    631     if ( Math.abs( t ) > 8.64e15 ) {
    632         return ( Number.NaN );
    633     }
    634 
    635     return ( ToInteger( t ) );
    636 }
    637 function ToInteger( t ) {
    638     t = Number( t );
    639 
    640     if ( isNaN( t ) ){
    641         return ( Number.NaN );
    642     }
    643     if ( t == 0 || t == -0 ||
    644          t == Number.POSITIVE_INFINITY || t == Number.NEGATIVE_INFINITY ) {
    645          return 0;
    646     }
    647 
    648     var sign = ( t < 0 ) ? -1 : 1;
    649 
    650     return ( sign * Math.floor( Math.abs( t ) ) );
    651 }
    652 function Enumerate ( o ) {
    653     var properties = new Array();
    654     for ( p in o ) {
    655        properties[ properties.length ] = new Array( p, o[p] );
    656     }
    657     return properties;
    658 }
    659 function AddTestCase( description, expect, actual ) {
    660     testcases[tc++] = new TestCase( SECTION, description, expect, actual );
    661 }
    662 
    663 function getFailedCases() {
    664   for ( var i = 0; i < testcases.length; i++ ) {
    665      if ( ! testcases[i].passed ) {
    666         print( testcases[i].description +" = " +testcases[i].actual +" expected: "+ testcases[i].expect );
    667      }
    668   }
    669 }
    670