Home | History | Annotate | Download | only in ecma
      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  * JavaScript shared functions file for running the tests in either
     24  * stand-alone JavaScript engine.  To run a test, first load this file,
     25  * then load the test script.
     26  */
     27 
     28 var	completed =	false;
     29 var	testcases;
     30 var tc = 0;
     31 
     32 SECTION	= "";
     33 VERSION	= "";
     34 BUGNUMBER =	"";
     35 
     36 /*
     37  * constant strings
     38  */
     39 var	GLOBAL = "[object global]";
     40 var PASSED = " PASSED!"
     41 var FAILED = " FAILED! expected: ";
     42 
     43 var	DEBUG =	false;
     44 
     45 
     46 
     47 /* wrapper for test cas constructor that doesn't require the SECTION
     48  * argument.
     49  */
     50 
     51 function AddTestCase( description, expect, actual ) {
     52     testcases[tc++] = new TestCase( SECTION, description, expect, actual );
     53 }
     54 
     55 /*
     56  * TestCase constructor
     57  *
     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  * Compare expected result to the actual result and figure out whether
    123  * the test case passed.
    124  */
    125 function getTestCaseResult(	expect,	actual ) {
    126 	//	because	( NaN == NaN ) always returns false, need to do
    127 	//	a special compare to see if	we got the right result.
    128 		if ( actual	!= actual )	{
    129 			if ( typeof	actual == "object" ) {
    130 				actual = "NaN object";
    131 			} else {
    132 				actual = "NaN number";
    133 			}
    134 		}
    135 		if ( expect	!= expect )	{
    136 			if ( typeof	expect == "object" ) {
    137 				expect = "NaN object";
    138 			} else {
    139 				expect = "NaN number";
    140 			}
    141 		}
    142 
    143 		var	passed = ( expect == actual	) ?	true : false;
    144 
    145 	//	if both	objects	are	numbers
    146 	// need	to replace w/ IEEE standard	for	rounding
    147 		if (	!passed
    148 				&& typeof(actual) == "number"
    149 				&& typeof(expect) == "number"
    150 			) {
    151 				if ( Math.abs(actual-expect) < 0.0000001 ) {
    152 					passed = true;
    153 				}
    154 		}
    155 
    156 	//	verify type	is the same
    157 		if ( typeof(expect)	!= typeof(actual) )	{
    158 			passed = false;
    159 		}
    160 
    161 		return passed;
    162 }
    163 
    164 /*
    165  * Begin printing functions.  These functions use the shell's
    166  * print function.  When running tests in the browser, these
    167  * functions, override these functions with functions that use
    168  * document.write.
    169  */
    170 
    171 function writeTestCaseResult( expect, actual, string ) {
    172 		var	passed = getTestCaseResult(	expect,	actual );
    173 		writeFormattedResult( expect, actual, string, passed );
    174 		return passed;
    175 }
    176 function writeFormattedResult( expect, actual, string, passed ) {
    177         var s = string ;
    178         s += ( passed ) ? PASSED : FAILED + expect;
    179         writeLineToLog( s);
    180         return passed;
    181 }
    182 function writeLineToLog( string	) {
    183 	print( string );
    184 }
    185 function writeHeaderToLog( string )	{
    186 	print( string );
    187 }
    188 /* end of print functions */
    189 
    190 
    191 /*
    192  * When running in the shell, run the garbage collector after the
    193  * test has completed.
    194  */
    195 
    196 function stopTest()	{
    197  	var gc;
    198 	if ( gc != undefined ) {
    199 		gc();
    200 	}
    201 }
    202 
    203 /*
    204  * Convenience function for displaying failed test cases.  Useful
    205  * when running tests manually.
    206  *
    207  */
    208 function getFailedCases() {
    209   for (	var	i =	0; i < testcases.length; i++ ) {
    210 	 if	( !	testcases[i].passed	) {
    211 		print( testcases[i].description	+" = " +testcases[i].actual	+" expected: "+	testcases[i].expect	);
    212 	 }
    213   }
    214 }
    215  /*
    216   *	Date functions used	by tests in	Date suite
    217   *
    218   */
    219 var	msPerDay =			86400000;
    220 var	HoursPerDay	=		24;
    221 var	MinutesPerHour =	60;
    222 var	SecondsPerMinute =	60;
    223 var	msPerSecond	=		1000;
    224 var	msPerMinute	=		60000;		//	msPerSecond	* SecondsPerMinute
    225 var	msPerHour =			3600000;	//	msPerMinute	* MinutesPerHour
    226 var             TZ_DIFF	= getTimeZoneDiff();  // offset of tester's timezone from UTC
    227 var             TZ_PST = -8;  // offset of Pacific Standard Time from UTC
    228 var             PST_DIFF = TZ_DIFF - TZ_PST;  // offset of tester's timezone from PST
    229 var	TIME_1970	 = 0;
    230 var	TIME_2000	 = 946684800000;
    231 var	TIME_1900	 = -2208988800000;
    232 var     TIME_YEAR_0      = -62167219200000;
    233 
    234 
    235 /*
    236  * Originally, the test suite used a hard-coded value TZ_DIFF = -8.
    237  * But that was only valid for testers in the Pacific Standard Time Zone!
    238  * We calculate the proper number dynamically for any tester. We just
    239  * have to be careful not to use a date subject to Daylight Savings Time...
    240 */
    241 function getTimeZoneDiff()
    242 {
    243   return -((new Date(2000, 1, 1)).getTimezoneOffset())/60;
    244 }
    245 
    246 
    247 /*
    248  * Date test "ResultArrays" are hard-coded for Pacific Standard Time.
    249  * We must adjust them for the tester's own timezone -
    250  */
    251 function adjustResultArray(ResultArray, msMode)
    252 {
    253   // If the tester's system clock is in PST, no need to continue -
    254   if (!PST_DIFF) {return;}
    255 
    256   /* The date testcases instantiate Date objects in two different ways:
    257    *
    258    *        millisecond mode: e.g.   dt = new Date(10000000);
    259    *        year-month-day mode:  dt = new Date(2000, 5, 1, ...);
    260    *
    261    * In the first case, the date is measured from Time 0 in Greenwich (i.e. UTC).
    262    * In the second case, it is measured with reference to the tester's local timezone.
    263    *
    264    * In the first case we must correct those values expected for local measurements,
    265    * like dt.getHours() etc. No correction is necessary for dt.getUTCHours() etc.
    266    *
    267    * In the second case, it is exactly the other way around -
    268   */
    269   if (msMode)
    270   {
    271     // The hard-coded UTC milliseconds from Time 0 derives from a UTC date.
    272     // Shift to the right by the offset between UTC and the tester.
    273     var t = ResultArray[TIME]  +  TZ_DIFF*msPerHour;
    274 
    275     // Use our date arithmetic functions to determine the local hour, day, etc.
    276     ResultArray[HOURS] = HourFromTime(t);
    277     ResultArray[DAY] = WeekDay(t);
    278     ResultArray[DATE] = DateFromTime(t);
    279     ResultArray[MONTH] = MonthFromTime(t);
    280     ResultArray[YEAR] = YearFromTime(t);
    281   }
    282   else
    283   {
    284     // The hard-coded UTC milliseconds from Time 0 derives from a PST date.
    285     // Shift to the left by the offset between PST and the tester.
    286     var t = ResultArray[TIME]  -  PST_DIFF*msPerHour;
    287 
    288     // Use our date arithmetic functions to determine the UTC hour, day, etc.
    289     ResultArray[TIME] = t;
    290     ResultArray[UTC_HOURS] = HourFromTime(t);
    291     ResultArray[UTC_DAY] = WeekDay(t);
    292     ResultArray[UTC_DATE] = DateFromTime(t);
    293     ResultArray[UTC_MONTH] = MonthFromTime(t);
    294     ResultArray[UTC_YEAR] = YearFromTime(t);
    295   }
    296 }
    297 
    298 
    299 function Day( t	) {
    300 	return ( Math.floor(t/msPerDay ) );
    301 }
    302 function DaysInYear( y ) {
    303 	if ( y % 4 != 0	) {
    304 		return 365;
    305 	}
    306 	if ( (y	% 4	== 0) && (y	% 100 != 0)	) {
    307 		return 366;
    308 	}
    309 	if ( (y	% 100 == 0)	&&	(y % 400 !=	0) ) {
    310 		return 365;
    311 	}
    312 	if ( (y	% 400 == 0)	){
    313 		return 366;
    314 	} else {
    315 		return "ERROR: DaysInYear("	+ y	+ ") case not covered";
    316 	}
    317 }
    318 function TimeInYear( y ) {
    319 	return ( DaysInYear(y) * msPerDay );
    320 }
    321 function DayNumber(	t )	{
    322 	return ( Math.floor( t / msPerDay )	);
    323 }
    324 function TimeWithinDay(	t )	{
    325 	if ( t < 0 ) {
    326 		return ( (t	% msPerDay)	+ msPerDay );
    327 	} else {
    328 		return ( t % msPerDay );
    329 	}
    330 }
    331 function YearNumber( t ) {
    332 }
    333 function TimeFromYear( y ) {
    334 	return ( msPerDay *	DayFromYear(y) );
    335 }
    336 function DayFromYear( y	) {
    337 	return (	365*(y-1970) +
    338 				Math.floor((y-1969)/4) -
    339 				Math.floor((y-1901)/100) +
    340 				Math.floor((y-1601)/400) );
    341 }
    342 function InLeapYear( t ) {
    343 	if ( DaysInYear(YearFromTime(t)) ==	365	) {
    344 		return 0;
    345 	}
    346 	if ( DaysInYear(YearFromTime(t)) ==	366	) {
    347 		return 1;
    348 	} else {
    349 		return "ERROR:  InLeapYear("+ t + ") case not covered";
    350 	}
    351 }
    352 function YearFromTime( t ) {
    353 	t =	Number(	t );
    354 	var	sign = ( t < 0 ) ? -1 :	1;
    355 	var	year = ( sign <	0 )	? 1969 : 1970;
    356 	for	(	var	timeToTimeZero = t;	;  ) {
    357 	//	subtract the current year's	time from the time that's left.
    358 		timeToTimeZero -= sign * TimeInYear(year)
    359 
    360 	//	if there's less	than the current year's	worth of time left,	then break.
    361 		if ( sign <	0 )	{
    362 			if ( sign *	timeToTimeZero <= 0	) {
    363 				break;
    364 			} else {
    365 				year +=	sign;
    366 			}
    367 		} else {
    368 			if ( sign *	timeToTimeZero < 0 ) {
    369 				break;
    370 			} else {
    371 				year +=	sign;
    372 			}
    373 		}
    374 	}
    375 	return ( year );
    376 }
    377 function MonthFromTime(	t )	{
    378 	//	i know i could use switch but i'd rather not until it's	part of	ECMA
    379 	var	day	= DayWithinYear( t );
    380 	var	leap = InLeapYear(t);
    381 
    382 	if ( (0	<= day)	&& (day	< 31) )	{
    383 		return 0;
    384 	}
    385 	if ( (31 <=	day) &&	(day < (59+leap)) )	{
    386 		return 1;
    387 	}
    388 	if ( ((59+leap)	<= day)	&& (day	< (90+leap)) ) {
    389 		return 2;
    390 	}
    391 	if ( ((90+leap)	<= day)	&& (day	< (120+leap)) )	{
    392 		return 3;
    393 	}
    394 	if ( ((120+leap) <=	day) &&	(day < (151+leap)) ) {
    395 		return 4;
    396 	}
    397 	if ( ((151+leap) <=	day) &&	(day < (181+leap)) ) {
    398 		return 5;
    399 	}
    400 	if ( ((181+leap) <=	day) &&	(day < (212+leap)) ) {
    401 		return 6;
    402 	}
    403 	if ( ((212+leap) <=	day) &&	(day < (243+leap)) ) {
    404 		return 7;
    405 	}
    406 	if ( ((243+leap) <=	day) &&	(day < (273+leap)) ) {
    407 		return 8;
    408 	}
    409 	if ( ((273+leap) <=	day) &&	(day < (304+leap)) ) {
    410 		return 9;
    411 	}
    412 	if ( ((304+leap) <=	day) &&	(day < (334+leap)) ) {
    413 		return 10;
    414 	}
    415 	if ( ((334+leap) <=	day) &&	(day < (365+leap)) ) {
    416 		return 11;
    417 	} else {
    418 		return "ERROR:	MonthFromTime("+t+") not known";
    419 	}
    420 }
    421 function DayWithinYear(	t )	{
    422 		return(	Day(t) - DayFromYear(YearFromTime(t)));
    423 }
    424 function DateFromTime( t ) {
    425 	var	day	= DayWithinYear(t);
    426 	var	month =	MonthFromTime(t);
    427 
    428 	if ( month == 0	) {
    429 		return ( day + 1 );
    430 	}
    431 	if ( month == 1	) {
    432 		return ( day - 30 );
    433 	}
    434 	if ( month == 2	) {
    435 		return ( day - 58 -	InLeapYear(t) );
    436 	}
    437 	if ( month == 3	) {
    438 		return ( day - 89 -	InLeapYear(t));
    439 	}
    440 	if ( month == 4	) {
    441 		return ( day - 119 - InLeapYear(t));
    442 	}
    443 	if ( month == 5	) {
    444 		return ( day - 150-	InLeapYear(t));
    445 	}
    446 	if ( month == 6	) {
    447 		return ( day - 180-	InLeapYear(t));
    448 	}
    449 	if ( month == 7	) {
    450 		return ( day - 211-	InLeapYear(t));
    451 	}
    452 	if ( month == 8	) {
    453 		return ( day - 242-	InLeapYear(t));
    454 	}
    455 	if ( month == 9	) {
    456 		return ( day - 272-	InLeapYear(t));
    457 	}
    458 	if ( month == 10 ) {
    459 		return ( day - 303-	InLeapYear(t));
    460 	}
    461 	if ( month == 11 ) {
    462 		return ( day - 333-	InLeapYear(t));
    463 	}
    464 
    465 	return ("ERROR:	 DateFromTime("+t+") not known"	);
    466 }
    467 function WeekDay( t	) {
    468 	var	weekday	= (Day(t)+4) % 7;
    469 	return(	weekday	< 0	? 7	+ weekday :	weekday	);
    470 }
    471 
    472 // missing daylight	savins time	adjustment
    473 
    474 function HourFromTime( t ) {
    475 	var	h =	Math.floor(	t /	msPerHour )	% HoursPerDay;
    476 	return ( (h<0) ? HoursPerDay + h : h  );
    477 }
    478 function MinFromTime( t	) {
    479 	var	min	= Math.floor( t	/ msPerMinute )	% MinutesPerHour;
    480 	return(	( min <	0 )	? MinutesPerHour + min : min  );
    481 }
    482 function SecFromTime( t	) {
    483 	var	sec	= Math.floor( t	/ msPerSecond )	% SecondsPerMinute;
    484 	return ( (sec <	0 )	? SecondsPerMinute + sec : sec );
    485 }
    486 function msFromTime( t ) {
    487 	var	ms = t % msPerSecond;
    488 	return ( (ms < 0 ) ? msPerSecond + ms :	ms );
    489 }
    490 function LocalTZA()	{
    491 	return ( TZ_DIFF * msPerHour );
    492 }
    493 function UTC( t	) {
    494 	return ( t - LocalTZA()	- DaylightSavingTA(t - LocalTZA()) );
    495 }
    496 
    497 function DaylightSavingTA( t ) {
    498 	t =	t -	LocalTZA();
    499 
    500 	var	dst_start = GetSecondSundayInMarch(t) + 2*msPerHour;
    501 	var	dst_end	  = GetFirstSundayInNovember(t)+ 2*msPerHour;
    502 
    503 	if ( t >= dst_start	&& t < dst_end ) {
    504 		return msPerHour;
    505 	} else {
    506 		return 0;
    507 	}
    508 
    509 	// Daylight	Savings	Time starts	on the first Sunday	in April at	2:00AM in
    510 	// PST.	 Other time	zones will need	to override	this function.
    511 
    512 	print( new Date( UTC(dst_start + LocalTZA())) );
    513 
    514 	return UTC(dst_start  +	LocalTZA());
    515 }
    516 
    517 function GetFirstSundayInApril( t ) {
    518     var year = YearFromTime(t);
    519     var leap = InLeapYear(t);
    520 
    521     var april = TimeFromYear(year) + TimeInMonth(0, leap) + TimeInMonth(1,leap) +
    522     TimeInMonth(2,leap);
    523 
    524     for ( var first_sunday = april; WeekDay(first_sunday) > 0;
    525         first_sunday += msPerDay )
    526     {
    527         ;
    528     }
    529 
    530     return first_sunday;
    531 }
    532 function GetLastSundayInOctober( t ) {
    533     var year = YearFromTime(t);
    534     var leap = InLeapYear(t);
    535 
    536     for ( var oct = TimeFromYear(year), m = 0; m < 9; m++ ) {
    537         oct += TimeInMonth(m, leap);
    538     }
    539     for ( var last_sunday = oct + 30*msPerDay; WeekDay(last_sunday) > 0;
    540         last_sunday -= msPerDay )
    541     {
    542         ;
    543     }
    544     return last_sunday;
    545 }
    546 
    547 // Added these two functions because DST rules changed for the US.
    548 function GetSecondSundayInMarch( t ) {
    549 	var	year = YearFromTime(t);
    550 	var	leap = InLeapYear(t);
    551 
    552 	var	march =	TimeFromYear(year) + TimeInMonth(0, leap) + TimeInMonth(1,leap);
    553 
    554 	var sundayCount = 0;
    555 	var flag = true;
    556 	for ( var second_sunday = march; flag; second_sunday += msPerDay )
    557 	{
    558 		if (WeekDay(second_sunday) == 0) {
    559 			if(++sundayCount == 2)
    560 				flag = false;
    561 		}
    562 	}
    563 
    564 	return second_sunday;
    565 }
    566 function GetFirstSundayInNovember( t ) {
    567 	var year = YearFromTime(t);
    568 	var leap = InLeapYear(t);
    569 
    570 	for ( var nov = TimeFromYear(year), m =	0; m < 10; m++ ) {
    571 		nov += TimeInMonth(m, leap);
    572 	}
    573 	for ( var first_sunday = nov; WeekDay(first_sunday) > 0;
    574 		first_sunday += msPerDay	)
    575 	{
    576 		;
    577 	}
    578 	return first_sunday;
    579 }
    580 function LocalTime(	t )	{
    581 	return ( t + LocalTZA()	+ DaylightSavingTA(t) );
    582 }
    583 function MakeTime( hour, min, sec, ms )	{
    584 	if ( isNaN(	hour ) || isNaN( min ) || isNaN( sec ) || isNaN( ms	) )	{
    585 		return Number.NaN;
    586 	}
    587 
    588 	hour = ToInteger(hour);
    589 	min	 = ToInteger( min);
    590 	sec	 = ToInteger( sec);
    591 	ms	 = ToInteger( ms );
    592 
    593 	return(	(hour*msPerHour) + (min*msPerMinute) +
    594 			(sec*msPerSecond) +	ms );
    595 }
    596 function MakeDay( year,	month, date	) {
    597 	if ( isNaN(year) ||	isNaN(month) ||	isNaN(date)	) {
    598 		return Number.NaN;
    599 	}
    600 	year = ToInteger(year);
    601 	month =	ToInteger(month);
    602 	date = ToInteger(date );
    603 
    604 	var	sign = ( year <	1970 ) ? -1	: 1;
    605 	var	t =	   ( year <	1970 ) ? 1 :  0;
    606 	var	y =	   ( year <	1970 ) ? 1969 :	1970;
    607 
    608 	var	result5	= year + Math.floor( month/12 );
    609 	var	result6	= month	% 12;
    610 
    611 	if ( year <	1970 ) {
    612 	   for ( y = 1969; y >=	year; y	+= sign	) {
    613 		 t += sign * TimeInYear(y);
    614 	   }
    615 	} else {
    616 		for	( y	= 1970 ; y < year; y +=	sign ) {
    617 			t += sign *	TimeInYear(y);
    618 		}
    619 	}
    620 
    621 	var	leap = InLeapYear( t );
    622 
    623 	for	( var m	= 0; m < month;	m++	) {
    624 		t += TimeInMonth( m, leap );
    625 	}
    626 
    627 	if ( YearFromTime(t) !=	result5	) {
    628 		return Number.NaN;
    629 	}
    630 	if ( MonthFromTime(t) != result6 ) {
    631 		return Number.NaN;
    632 	}
    633 	if ( DateFromTime(t) !=	1 )	{
    634 		return Number.NaN;
    635 	}
    636 
    637 	return ( (Day(t)) +	date - 1 );
    638 }
    639 function TimeInMonth( month, leap )	{
    640 	// september april june	november
    641 	// jan 0  feb 1	 mar 2	apr	3	may	4  june	5  jul 6
    642 	// aug 7  sep 8	 oct 9	nov	10	dec	11
    643 
    644 	if ( month == 3	|| month ==	5 || month == 8	|| month ==	10 ) {
    645 		return ( 30*msPerDay );
    646 	}
    647 
    648 	// all the rest
    649 	if ( month == 0	|| month ==	2 || month == 4	|| month ==	6 ||
    650 		 month == 7	|| month ==	9 || month == 11 ) {
    651 		return ( 31*msPerDay );
    652 	 }
    653 
    654 	// save	february
    655 	return ( (leap == 0) ? 28*msPerDay : 29*msPerDay );
    656 }
    657 function MakeDate( day,	time ) {
    658 	if (	day	== Number.POSITIVE_INFINITY	||
    659 			day	== Number.NEGATIVE_INFINITY	||
    660 			day	== Number.NaN )	{
    661 		return Number.NaN;
    662 	}
    663 	if (	time ==	Number.POSITIVE_INFINITY ||
    664 			time ==	Number.POSITIVE_INFINITY ||
    665 			day	== Number.NaN) {
    666 		return Number.NaN;
    667 	}
    668 	return ( day * msPerDay	) +	time;
    669 }
    670 function TimeClip( t ) {
    671 	if ( isNaN(	t )	) {
    672 		return ( Number.NaN	);
    673 	}
    674 	if ( Math.abs( t ) > 8.64e15 ) {
    675 		return ( Number.NaN	);
    676 	}
    677 
    678 	return ( ToInteger(	t )	);
    679 }
    680 function ToInteger(	t )	{
    681 	t =	Number(	t );
    682 
    683 	if ( isNaN(	t )	){
    684 		return ( Number.NaN	);
    685 	}
    686 	if ( t == 0	|| t ==	-0 ||
    687 		 t == Number.POSITIVE_INFINITY || t	== Number.NEGATIVE_INFINITY	) {
    688 		 return	0;
    689 	}
    690 
    691 	var	sign = ( t < 0 ) ? -1 :	1;
    692 
    693 	return ( sign *	Math.floor(	Math.abs( t	) )	);
    694 }
    695 function Enumerate ( o ) {
    696 	var	p;
    697 	for	( p	in o ) {
    698 		print( p +": " + o[p] );
    699 	}
    700 }
    701 
    702 /* these functions are useful for running tests manually in Rhino */
    703 
    704 function GetContext() {
    705 	return Packages.com.netscape.javascript.Context.getCurrentContext();
    706 }
    707 function OptLevel( i ) {
    708 	i =	Number(i);
    709 	var	cx = GetContext();
    710 	cx.setOptimizationLevel(i);
    711 }
    712 /* end of Rhino functions */
    713