]>
git.saurik.com Git - apple/javascriptcore.git/blob - tests/mozilla/ecma/shell.js
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/
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.
11 * The Original Code is Mozilla Communicator client code, released March
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
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.
28 var completed
= false;
39 var GLOBAL
= "[object global]";
40 var PASSED
= " PASSED!"
41 var FAILED
= " FAILED! expected: ";
47 /* wrapper for test cas constructor that doesn't require the SECTION
51 function AddTestCase( description
, expect
, actual
) {
52 testcases
[tc
++] = new TestCase( SECTION
, description
, expect
, actual
);
56 * TestCase constructor
60 function TestCase( n
, d
, e
, a
) {
67 this.bugnumber
= BUGNUMBER
;
69 this.passed
= getTestCaseResult( this.expect
, this.actual
);
71 writeLineToLog( "added " + this.description
);
76 * Set up test environment.
79 function startTest() {
81 // JavaScript 1.3 is supposed to be compliant ecma version 1.0
82 if ( VERSION
== "ECMA_1" ) {
85 if ( VERSION
== "JS_1.3" ) {
88 if ( VERSION
== "JS_1.2" ) {
91 if ( VERSION
== "JS_1.1" ) {
94 // for ecma version 2.0, we will leave the javascript version to
95 // the default ( for now ).
98 // print out bugnumber
101 writeLineToLog ("BUGNUMBER: " + BUGNUMBER
);
104 testcases
= new Array();
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 ";
118 return ( testcases
);
122 * Compare expected result to the actual result and figure out whether
123 * the test case passed.
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";
132 actual
= "NaN number";
135 if ( expect
!= expect
) {
136 if ( typeof expect
== "object" ) {
137 expect
= "NaN object";
139 expect
= "NaN number";
143 var passed
= ( expect
== actual
) ? true : false;
145 // if both objects are numbers
146 // need to replace w/ IEEE standard for rounding
148 && typeof(actual
) == "number"
149 && typeof(expect
) == "number"
151 if ( Math
.abs(actual
-expect
) < 0.0000001 ) {
156 // verify type is the same
157 if ( typeof(expect
) != typeof(actual
) ) {
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
171 function writeTestCaseResult( expect
, actual
, string
) {
172 var passed
= getTestCaseResult( expect
, actual
);
173 writeFormattedResult( expect
, actual
, string
, passed
);
176 function writeFormattedResult( expect
, actual
, string
, passed
) {
178 s
+= ( passed
) ? PASSED : FAILED
+ expect
;
182 function writeLineToLog( string
) {
185 function writeHeaderToLog( string
) {
188 /* end of print functions */
192 * When running in the shell, run the garbage collector after the
193 * test has completed.
196 function stopTest() {
198 if ( gc
!= undefined ) {
204 * Convenience function for displaying failed test cases. Useful
205 * when running tests manually.
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
);
216 * Date functions used by tests in Date suite
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
230 var TIME_2000
= 946684800000;
231 var TIME_1900
= -2208988800000;
232 var TIME_YEAR_0
= -62167219200000;
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...
241 function getTimeZoneDiff()
243 return -((new Date(2000, 1, 1)).getTimezoneOffset())/60;
248 * Date test "ResultArrays" are hard-coded for Pacific Standard Time.
249 * We must adjust them for the tester's own timezone -
251 function adjustResultArray(ResultArray
, msMode
)
253 // If the tester's system clock is in PST, no need to continue -
254 if (!PST_DIFF
) {return;}
256 /* The date testcases instantiate Date objects in two different ways:
258 * millisecond mode: e.g. dt = new Date(10000000);
259 * year-month-day mode: dt = new Date(2000, 5, 1, ...);
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.
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.
267 * In the second case, it is exactly the other way around -
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
;
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
);
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
;
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
);
300 return ( Math
.floor(t
/msPerDay
) );
302 function DaysInYear( y
) {
306 if ( (y
% 4 == 0) && (y
% 100 != 0) ) {
309 if ( (y
% 100 == 0) && (y
% 400 != 0) ) {
312 if ( (y
% 400 == 0) ){
315 return "ERROR: DaysInYear(" + y
+ ") case not covered";
318 function TimeInYear( y
) {
319 return ( DaysInYear(y
) * msPerDay
);
321 function DayNumber( t
) {
322 return ( Math
.floor( t
/ msPerDay
) );
324 function TimeWithinDay( t
) {
326 return ( (t
% msPerDay
) + msPerDay
);
328 return ( t
% msPerDay
);
331 function YearNumber( t
) {
333 function TimeFromYear( y
) {
334 return ( msPerDay
* DayFromYear(y
) );
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) );
342 function InLeapYear( t
) {
343 if ( DaysInYear(YearFromTime(t
)) == 365 ) {
346 if ( DaysInYear(YearFromTime(t
)) == 366 ) {
349 return "ERROR: InLeapYear("+ t
+ ") case not covered";
352 function YearFromTime( 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
)
360 // if there's less than the current year's worth of time left, then break.
362 if ( sign
* timeToTimeZero
<= 0 ) {
368 if ( sign
* timeToTimeZero
< 0 ) {
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
);
382 if ( (0 <= day
) && (day
< 31) ) {
385 if ( (31 <= day
) && (day
< (59+leap
)) ) {
388 if ( ((59+leap
) <= day
) && (day
< (90+leap
)) ) {
391 if ( ((90+leap
) <= day
) && (day
< (120+leap
)) ) {
394 if ( ((120+leap
) <= day
) && (day
< (151+leap
)) ) {
397 if ( ((151+leap
) <= day
) && (day
< (181+leap
)) ) {
400 if ( ((181+leap
) <= day
) && (day
< (212+leap
)) ) {
403 if ( ((212+leap
) <= day
) && (day
< (243+leap
)) ) {
406 if ( ((243+leap
) <= day
) && (day
< (273+leap
)) ) {
409 if ( ((273+leap
) <= day
) && (day
< (304+leap
)) ) {
412 if ( ((304+leap
) <= day
) && (day
< (334+leap
)) ) {
415 if ( ((334+leap
) <= day
) && (day
< (365+leap
)) ) {
418 return "ERROR: MonthFromTime("+t
+") not known";
421 function DayWithinYear( t
) {
422 return( Day(t
) - DayFromYear(YearFromTime(t
)));
424 function DateFromTime( t
) {
425 var day
= DayWithinYear(t
);
426 var month
= MonthFromTime(t
);
435 return ( day
- 58 - InLeapYear(t
) );
438 return ( day
- 89 - InLeapYear(t
));
441 return ( day
- 119 - InLeapYear(t
));
444 return ( day
- 150- InLeapYear(t
));
447 return ( day
- 180- InLeapYear(t
));
450 return ( day
- 211- InLeapYear(t
));
453 return ( day
- 242- InLeapYear(t
));
456 return ( day
- 272- InLeapYear(t
));
459 return ( day
- 303- InLeapYear(t
));
462 return ( day
- 333- InLeapYear(t
));
465 return ("ERROR: DateFromTime("+t
+") not known" );
467 function WeekDay( t
) {
468 var weekday
= (Day(t
)+4) % 7;
469 return( weekday
< 0 ? 7 + weekday : weekday
);
472 // missing daylight savins time adjustment
474 function HourFromTime( t
) {
475 var h
= Math
.floor( t
/ msPerHour
) % HoursPerDay
;
476 return ( (h
<0) ? HoursPerDay
+ h : h
);
478 function MinFromTime( t
) {
479 var min
= Math
.floor( t
/ msPerMinute
) % MinutesPerHour
;
480 return( ( min
< 0 ) ? MinutesPerHour
+ min : min
);
482 function SecFromTime( t
) {
483 var sec
= Math
.floor( t
/ msPerSecond
) % SecondsPerMinute
;
484 return ( (sec
< 0 ) ? SecondsPerMinute
+ sec : sec
);
486 function msFromTime( t
) {
487 var ms
= t
% msPerSecond
;
488 return ( (ms
< 0 ) ? msPerSecond
+ ms : ms
);
490 function LocalTZA() {
491 return ( TZ_DIFF
* msPerHour
);
494 return ( t
- LocalTZA() - DaylightSavingTA(t
- LocalTZA()) );
497 function DaylightSavingTA( t
) {
500 var dst_start
= GetSecondSundayInMarch(t
) + 2*msPerHour
;
501 var dst_end
= GetFirstSundayInNovember(t
)+ 2*msPerHour
;
503 if ( t
>= dst_start
&& t
< dst_end
) {
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.
512 print( new Date( UTC(dst_start
+ LocalTZA())) );
514 return UTC(dst_start
+ LocalTZA());
517 function GetFirstSundayInApril( t
) {
518 var year
= YearFromTime(t
);
519 var leap
= InLeapYear(t
);
521 var april
= TimeFromYear(year
) + TimeInMonth(0, leap
) + TimeInMonth(1,leap
) +
524 for ( var first_sunday
= april
; WeekDay(first_sunday
) > 0;
525 first_sunday
+= msPerDay
)
532 function GetLastSundayInOctober( t
) {
533 var year
= YearFromTime(t
);
534 var leap
= InLeapYear(t
);
536 for ( var oct
= TimeFromYear(year
), m
= 0; m
< 9; m
++ ) {
537 oct
+= TimeInMonth(m
, leap
);
539 for ( var last_sunday
= oct
+ 30*msPerDay
; WeekDay(last_sunday
) > 0;
540 last_sunday
-= msPerDay
)
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
);
552 var march
= TimeFromYear(year
) + TimeInMonth(0, leap
) + TimeInMonth(1,leap
);
556 for ( var second_sunday
= march
; flag
; second_sunday
+= msPerDay
)
558 if (WeekDay(second_sunday
) == 0) {
559 if(++sundayCount
== 2)
564 return second_sunday
;
566 function GetFirstSundayInNovember( t
) {
567 var year
= YearFromTime(t
);
568 var leap
= InLeapYear(t
);
570 for ( var nov
= TimeFromYear(year
), m
= 0; m
< 10; m
++ ) {
571 nov
+= TimeInMonth(m
, leap
);
573 for ( var first_sunday
= nov
; WeekDay(first_sunday
) > 0;
574 first_sunday
+= msPerDay
)
580 function LocalTime( t
) {
581 return ( t
+ LocalTZA() + DaylightSavingTA(t
) );
583 function MakeTime( hour
, min
, sec
, ms
) {
584 if ( isNaN( hour
) || isNaN( min
) || isNaN( sec
) || isNaN( ms
) ) {
588 hour
= ToInteger(hour
);
589 min
= ToInteger( min
);
590 sec
= ToInteger( sec
);
591 ms
= ToInteger( ms
);
593 return( (hour
*msPerHour
) + (min
*msPerMinute
) +
594 (sec
*msPerSecond
) + ms
);
596 function MakeDay( year
, month
, date
) {
597 if ( isNaN(year
) || isNaN(month
) || isNaN(date
) ) {
600 year
= ToInteger(year
);
601 month
= ToInteger(month
);
602 date
= ToInteger(date
);
604 var sign
= ( year
< 1970 ) ? -1 : 1;
605 var t
= ( year
< 1970 ) ? 1 : 0;
606 var y
= ( year
< 1970 ) ? 1969 : 1970;
608 var result5
= year
+ Math
.floor( month
/12 );
609 var result6
= month
% 12;
612 for ( y
= 1969; y
>= year
; y
+= sign
) {
613 t
+= sign
* TimeInYear(y
);
616 for ( y
= 1970 ; y
< year
; y
+= sign
) {
617 t
+= sign
* TimeInYear(y
);
621 var leap
= InLeapYear( t
);
623 for ( var m
= 0; m
< month
; m
++ ) {
624 t
+= TimeInMonth( m
, leap
);
627 if ( YearFromTime(t
) != result5
) {
630 if ( MonthFromTime(t
) != result6
) {
633 if ( DateFromTime(t
) != 1 ) {
637 return ( (Day(t
)) + date
- 1 );
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
644 if ( month
== 3 || month
== 5 || month
== 8 || month
== 10 ) {
645 return ( 30*msPerDay
);
649 if ( month
== 0 || month
== 2 || month
== 4 || month
== 6 ||
650 month
== 7 || month
== 9 || month
== 11 ) {
651 return ( 31*msPerDay
);
655 return ( (leap
== 0) ? 28*msPerDay : 29*msPerDay
);
657 function MakeDate( day
, time
) {
658 if ( day
== Number
.POSITIVE_INFINITY
||
659 day
== Number
.NEGATIVE_INFINITY
||
660 day
== Number
.NaN
) {
663 if ( time
== Number
.POSITIVE_INFINITY
||
664 time
== Number
.POSITIVE_INFINITY
||
668 return ( day
* msPerDay
) + time
;
670 function TimeClip( t
) {
672 return ( Number
.NaN
);
674 if ( Math
.abs( t
) > 8.64e15
) {
675 return ( Number
.NaN
);
678 return ( ToInteger( t
) );
680 function ToInteger( t
) {
684 return ( Number
.NaN
);
686 if ( t
== 0 || t
== -0 ||
687 t
== Number
.POSITIVE_INFINITY
|| t
== Number
.NEGATIVE_INFINITY
) {
691 var sign
= ( t
< 0 ) ? -1 : 1;
693 return ( sign
* Math
.floor( Math
.abs( t
) ) );
695 function Enumerate ( o
) {
698 print( p
+": " + o
[p
] );
702 /* these functions are useful for running tests manually in Rhino */
704 function GetContext() {
705 return Packages
.com
.netscape
.javascript
.Context
.getCurrentContext();
707 function OptLevel( i
) {
709 var cx
= GetContext();
710 cx
.setOptimizationLevel(i
);
712 /* end of Rhino functions */