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