/// Copyright (c) 2012 Ecma International. All rights reserved. /// Ecma International makes this code available under the terms and conditions set /// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the /// "Use Terms"). Any redistribution of this code must retain the above /// copyright and this notice and otherwise comply with the Use Terms. //----------------------------------------------------------------------------- function compareArray(aExpected, aActual) { if (aActual.length != aExpected.length) { return false; } aExpected.sort(); aActual.sort(); var s; for (var i = 0; i < aExpected.length; i++) { if (aActual[i] !== aExpected[i]) { return false; } } return true; } //----------------------------------------------------------------------------- function arrayContains(arr, expected) { var found; for (var i = 0; i < expected.length; i++) { found = false; for (var j = 0; j < arr.length; j++) { if (expected[i] === arr[j]) { found = true; break; } } if (!found) { return false; } } return true; } //----------------------------------------------------------------------------- var supportsArrayIndexGettersOnArrays = undefined; function fnSupportsArrayIndexGettersOnArrays() { if (typeof supportsArrayIndexGettersOnArrays !== "undefined") { return supportsArrayIndexGettersOnArrays; } supportsArrayIndexGettersOnArrays = false; if (fnExists(Object.defineProperty)) { var arr = []; Object.defineProperty(arr, "0", { get: function () { supportsArrayIndexGettersOnArrays = true; return 0; } }); var res = arr[0]; } return supportsArrayIndexGettersOnArrays; } //----------------------------------------------------------------------------- var supportsArrayIndexGettersOnObjects = undefined; function fnSupportsArrayIndexGettersOnObjects() { if (typeof supportsArrayIndexGettersOnObjects !== "undefined") return supportsArrayIndexGettersOnObjects; supportsArrayIndexGettersOnObjects = false; if (fnExists(Object.defineProperty)) { var obj = {}; Object.defineProperty(obj, "0", { get: function () { supportsArrayIndexGettersOnObjects = true; return 0; } }); var res = obj[0]; } return supportsArrayIndexGettersOnObjects; } //----------------------------------------------------------------------------- function ConvertToFileUrl(pathStr) { return "file:" + pathStr.replace(/\\/g, "/"); } //----------------------------------------------------------------------------- function fnExists(/*arguments*/) { for (var i = 0; i < arguments.length; i++) { if (typeof (arguments[i]) !== "function") return false; } return true; } //----------------------------------------------------------------------------- var __globalObject = Function("return this;")(); function fnGlobalObject() { return __globalObject; } //----------------------------------------------------------------------------- function fnSupportsStrict() { "use strict"; try { eval('with ({}) {}'); return false; } catch (e) { return true; } } //----------------------------------------------------------------------------- //Verify all attributes specified data property of given object: //value, writable, enumerable, configurable //If all attribute values are expected, return true, otherwise, return false function dataPropertyAttributesAreCorrect(obj, name, value, writable, enumerable, configurable) { var attributesCorrect = true; if (obj[name] !== value) { if (typeof obj[name] === "number" && isNaN(obj[name]) && typeof value === "number" && isNaN(value)) { // keep empty } else { attributesCorrect = false; } } try { if (obj[name] === "oldValue") { obj[name] = "newValue"; } else { obj[name] = "OldValue"; } } catch (we) { } var overwrited = false; if (obj[name] !== value) { if (typeof obj[name] === "number" && isNaN(obj[name]) && typeof value === "number" && isNaN(value)) { // keep empty } else { overwrited = true; } } if (overwrited !== writable) { attributesCorrect = false; } var enumerated = false; for (var prop in obj) { if (obj.hasOwnProperty(prop) && prop === name) { enumerated = true; } } if (enumerated !== enumerable) { attributesCorrect = false; } var deleted = false; try { delete obj[name]; } catch (de) { } if (!obj.hasOwnProperty(name)) { deleted = true; } if (deleted !== configurable) { attributesCorrect = false; } return attributesCorrect; } //----------------------------------------------------------------------------- //Verify all attributes specified accessor property of given object: //get, set, enumerable, configurable //If all attribute values are expected, return true, otherwise, return false function accessorPropertyAttributesAreCorrect(obj, name, get, set, setVerifyHelpProp, enumerable, configurable) { var attributesCorrect = true; if (get !== undefined) { if (obj[name] !== get()) { if (typeof obj[name] === "number" && isNaN(obj[name]) && typeof get() === "number" && isNaN(get())) { // keep empty } else { attributesCorrect = false; } } } else { if (obj[name] !== undefined) { attributesCorrect = false; } } try { var desc = Object.getOwnPropertyDescriptor(obj, name); if (typeof desc.set === "undefined") { if (typeof set !== "undefined") { attributesCorrect = false; } } else { obj[name] = "toBeSetValue"; if (obj[setVerifyHelpProp] !== "toBeSetValue") { attributesCorrect = false; } } } catch (se) { throw se; } var enumerated = false; for (var prop in obj) { if (obj.hasOwnProperty(prop) && prop === name) { enumerated = true; } } if (enumerated !== enumerable) { attributesCorrect = false; } var deleted = false; try { delete obj[name]; } catch (de) { throw de; } if (!obj.hasOwnProperty(name)) { deleted = true; } if (deleted !== configurable) { attributesCorrect = false; } return attributesCorrect; } //----------------------------------------------------------------------------- var NotEarlyErrorString = "NotEarlyError"; var EarlyErrorRePat = "^((?!" + NotEarlyErrorString + ").)*$"; var NotEarlyError = new Error(NotEarlyErrorString); //----------------------------------------------------------------------------- // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. function Test262Error(message) { if (message) this.message = message; } Test262Error.prototype.toString = function () { return "Test262 Error: " + this.message; }; function testFailed(message) { throw new Test262Error(message); } function testPrint(message) { } //adaptors for Test262 framework function $PRINT(message) { } function $INCLUDE(message) { } function $ERROR(message) { testFailed(message); } function $FAIL(message) { testFailed(message); } //Sputnik library definitions //Ultimately these should be namespaced some how and only made //available to tests that explicitly include them. //For now, we just define the globally //math_precision.js // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. function getPrecision(num) { //TODO: Create a table of prec's, // because using Math for testing Math isn't that correct. var log2num = Math.log(Math.abs(num)) / Math.LN2; var pernum = Math.ceil(log2num); return (2 * Math.pow(2, -52 + pernum)); //return(0); } //math_isequal.js // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. var prec; function isEqual(num1, num2) { if ((num1 === Infinity) && (num2 === Infinity)) { return (true); } if ((num1 === -Infinity) && (num2 === -Infinity)) { return (true); } prec = getPrecision(Math.min(Math.abs(num1), Math.abs(num2))); return (Math.abs(num1 - num2) <= prec); //return(num1 === num2); } //numeric_conversion.js // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. function ToInteger(p) { var x = Number(p); if (isNaN(x)) { return +0; } if ((x === +0) || (x === -0) || (x === Number.POSITIVE_INFINITY) || (x === Number.NEGATIVE_INFINITY)) { return x; } var sign = (x < 0) ? -1 : 1; return (sign * Math.floor(Math.abs(x))); } //Date_constants.js // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. var HoursPerDay = 24; var MinutesPerHour = 60; var SecondsPerMinute = 60; var msPerDay = 86400000; var msPerSecond = 1000; var msPerMinute = 60000; var msPerHour = 3600000; var date_1899_end = -2208988800001; var date_1900_start = -2208988800000; var date_1969_end = -1; var date_1970_start = 0; var date_1999_end = 946684799999; var date_2000_start = 946684800000; var date_2099_end = 4102444799999; var date_2100_start = 4102444800000; // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. //the following values are normally generated by the sputnik.py driver var $LocalTZ, $DST_start_month, $DST_start_sunday, $DST_start_hour, $DST_start_minutes, $DST_end_month, $DST_end_sunday, $DST_end_hour, $DST_end_minutes; (function () { /** * Finds the first date, starting from |start|, where |predicate| * holds. */ var findNearestDateBefore = function (start, predicate) { var current = start; var month = 1000 * 60 * 60 * 24 * 30; for (var step = month; step > 0; step = Math.floor(step / 3)) { if (!predicate(current)) { while (!predicate(current)) current = new Date(current.getTime() + step); current = new Date(current.getTime() - step); } } while (!predicate(current)) { current = new Date(current.getTime() + 1); } return current; }; var juneDate = new Date(2000, 5, 20, 0, 0, 0, 0); var decemberDate = new Date(2000, 11, 20, 0, 0, 0, 0); var juneOffset = juneDate.getTimezoneOffset(); var decemberOffset = decemberDate.getTimezoneOffset(); var isSouthernHemisphere = (juneOffset > decemberOffset); var winterTime = isSouthernHemisphere ? juneDate : decemberDate; var summerTime = isSouthernHemisphere ? decemberDate : juneDate; var dstStart = findNearestDateBefore(winterTime, function (date) { return date.getTimezoneOffset() == summerTime.getTimezoneOffset(); }); $DST_start_month = dstStart.getMonth(); $DST_start_sunday = dstStart.getDate() > 15 ? '"last"' : '"first"'; $DST_start_hour = dstStart.getHours(); $DST_start_minutes = dstStart.getMinutes(); var dstEnd = findNearestDateBefore(summerTime, function (date) { return date.getTimezoneOffset() == winterTime.getTimezoneOffset(); }); $DST_end_month = dstEnd.getMonth(); $DST_end_sunday = dstEnd.getDate() > 15 ? '"last"' : '"first"'; $DST_end_hour = dstEnd.getHours(); $DST_end_minutes = dstEnd.getMinutes(); return; })(); //Date.library.js // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. //15.9.1.2 Day Number and Time within Day function Day(t) { return Math.floor(t / msPerDay); } function TimeWithinDay(t) { return t % msPerDay; } //15.9.1.3 Year Number function DaysInYear(y) { if (y % 4 != 0) return 365; if (y % 4 == 0 && y % 100 != 0) return 366; if (y % 100 == 0 && y % 400 != 0) return 365; if (y % 400 == 0) return 366; } function DayFromYear(y) { return (365 * (y - 1970) + Math.floor((y - 1969) / 4) - Math.floor((y - 1901) / 100) + Math.floor((y - 1601) / 400)); } function TimeFromYear(y) { return msPerDay * DayFromYear(y); } function YearFromTime(t) { t = Number(t); var sign = (t < 0) ? -1 : 1; var year = (sign < 0) ? 1969 : 1970; for (var time = 0; ; year += sign) { time = TimeFromYear(year); if (sign > 0 && time > t) { year -= sign; break; } else if (sign < 0 && time <= t) { break; } }; return year; } function InLeapYear(t) { if (DaysInYear(YearFromTime(t)) == 365) return 0; if (DaysInYear(YearFromTime(t)) == 366) return 1; } function DayWithinYear(t) { return Day(t) - DayFromYear(YearFromTime(t)); } //15.9.1.4 Month Number function MonthFromTime(t) { var day = DayWithinYear(t); var leap = InLeapYear(t); if ((0 <= day) && (day < 31)) return 0; if ((31 <= day) && (day < (59 + leap))) return 1; if (((59 + leap) <= day) && (day < (90 + leap))) return 2; if (((90 + leap) <= day) && (day < (120 + leap))) return 3; if (((120 + leap) <= day) && (day < (151 + leap))) return 4; if (((151 + leap) <= day) && (day < (181 + leap))) return 5; if (((181 + leap) <= day) && (day < (212 + leap))) return 6; if (((212 + leap) <= day) && (day < (243 + leap))) return 7; if (((243 + leap) <= day) && (day < (273 + leap))) return 8; if (((273 + leap) <= day) && (day < (304 + leap))) return 9; if (((304 + leap) <= day) && (day < (334 + leap))) return 10; if (((334 + leap) <= day) && (day < (365 + leap))) return 11; } //15.9.1.5 Date Number function DateFromTime(t) { var day = DayWithinYear(t); var month = MonthFromTime(t); var leap = InLeapYear(t); if (month == 0) return day + 1; if (month == 1) return day - 30; if (month == 2) return day - 58 - leap; if (month == 3) return day - 89 - leap; if (month == 4) return day - 119 - leap; if (month == 5) return day - 150 - leap; if (month == 6) return day - 180 - leap; if (month == 7) return day - 211 - leap; if (month == 8) return day - 242 - leap; if (month == 9) return day - 272 - leap; if (month == 10) return day - 303 - leap; if (month == 11) return day - 333 - leap; } //15.9.1.6 Week Day function WeekDay(t) { var weekday = (Day(t) + 4) % 7; return (weekday < 0 ? 7 + weekday : weekday); } //15.9.1.9 Daylight Saving Time Adjustment $LocalTZ = (new Date()).getTimezoneOffset() / -60; if (DaylightSavingTA((new Date()).valueOf()) !== 0) { $LocalTZ -= 1; } var LocalTZA = $LocalTZ * msPerHour; function DaysInMonth(m, leap) { m = m % 12; //April, June, Sept, Nov if (m == 3 || m == 5 || m == 8 || m == 10) { return 30; } //Jan, March, May, July, Aug, Oct, Dec if (m == 0 || m == 2 || m == 4 || m == 6 || m == 7 || m == 9 || m == 11) { return 31; } //Feb return 28 + leap; } function GetSundayInMonth(t, m, count) { var year = YearFromTime(t); var tempDate; if (count === '"first"') { for (var d = 1; d <= DaysInMonth(m, InLeapYear(t)) ; d++) { tempDate = new Date(year, m, d); if (tempDate.getDay() === 0) { return tempDate.valueOf(); } } } else if (count === '"last"') { for (var d = DaysInMonth(m, InLeapYear(t)) ; d > 0; d--) { tempDate = new Date(year, m, d); if (tempDate.getDay() === 0) { return tempDate.valueOf(); } } } throw new Error("Unsupported 'count' arg:" + count); } /* function GetSundayInMonth(t, m, count){ var year = YearFromTime(t); var leap = InLeapYear(t); var day = 0; if(m >= 1) day += DaysInMonth(0, leap); if(m >= 2) day += DaysInMonth(1, leap); if(m >= 3) day += DaysInMonth(2, leap); if(m >= 4) day += DaysInMonth(3, leap); if(m >= 5) day += DaysInMonth(4, leap); if(m >= 6) day += DaysInMonth(5, leap); if(m >= 7) day += DaysInMonth(6, leap); if(m >= 8) day += DaysInMonth(7, leap); if(m >= 9) day += DaysInMonth(8, leap); if(m >= 10) day += DaysInMonth(9, leap); if(m >= 11) day += DaysInMonth(10, leap); var month_start = TimeFromYear(year)+day*msPerDay; var sunday = 0; if(count === "last"){ for(var last_sunday = month_start+DaysInMonth(m, leap)*msPerDay; WeekDay(last_sunday)>0; last_sunday -= msPerDay ){}; sunday = last_sunday; } else { for(var first_sunday = month_start; WeekDay(first_sunday)>0; first_sunday += msPerDay ){}; sunday = first_sunday+7*msPerDay*(count-1); } return sunday; }*/ function DaylightSavingTA(t) { // t = t-LocalTZA; var DST_start = GetSundayInMonth(t, $DST_start_month, $DST_start_sunday) + $DST_start_hour * msPerHour + $DST_start_minutes * msPerMinute; var k = new Date(DST_start); var DST_end = GetSundayInMonth(t, $DST_end_month, $DST_end_sunday) + $DST_end_hour * msPerHour + $DST_end_minutes * msPerMinute; if (t >= DST_start && t < DST_end) { return msPerHour; } else { return 0; } } //15.9.1.9 Local Time function LocalTime(t) { return t + LocalTZA + DaylightSavingTA(t); } function UTC(t) { return t - LocalTZA - DaylightSavingTA(t - LocalTZA); } //15.9.1.10 Hours, Minutes, Second, and Milliseconds function HourFromTime(t) { return Math.floor(t / msPerHour) % HoursPerDay; } function MinFromTime(t) { return Math.floor(t / msPerMinute) % MinutesPerHour; } function SecFromTime(t) { return Math.floor(t / msPerSecond) % SecondsPerMinute; } function msFromTime(t) { return t % msPerSecond; } //15.9.1.11 MakeTime (hour, min, sec, ms) function MakeTime(hour, min, sec, ms) { if (!isFinite(hour) || !isFinite(min) || !isFinite(sec) || !isFinite(ms)) { return Number.NaN; } hour = ToInteger(hour); min = ToInteger(min); sec = ToInteger(sec); ms = ToInteger(ms); return ((hour * msPerHour) + (min * msPerMinute) + (sec * msPerSecond) + ms); } //15.9.1.12 MakeDay (year, month, date) function MakeDay(year, month, date) { if (!isFinite(year) || !isFinite(month) || !isFinite(date)) { return Number.NaN; } year = ToInteger(year); month = ToInteger(month); date = ToInteger(date); var result5 = year + Math.floor(month / 12); var result6 = month % 12; var sign = (year < 1970) ? -1 : 1; var t = (year < 1970) ? 1 : 0; var y = (year < 1970) ? 1969 : 1970; if (sign == -1) { for (y = 1969; y >= year; y += sign) { t += sign * DaysInYear(y) * msPerDay; } } else { for (y = 1970 ; y < year; y += sign) { t += sign * DaysInYear(y) * msPerDay; } } var leap = 0; for (var m = 0; m < month; m++) { //if year is changed, than we need to recalculate leep leap = InLeapYear(t); t += DaysInMonth(m, leap) * msPerDay; } if (YearFromTime(t) != result5) { return Number.NaN; } if (MonthFromTime(t) != result6) { return Number.NaN; } if (DateFromTime(t) != 1) { return Number.NaN; } return Day(t) + date - 1; } //15.9.1.13 MakeDate (day, time) function MakeDate(day, time) { if (!isFinite(day) || !isFinite(time)) { return Number.NaN; } return day * msPerDay + time; } //15.9.1.14 TimeClip (time) function TimeClip(time) { if (!isFinite(time) || Math.abs(time) > 8.64e15) { return Number.NaN; } return ToInteger(time); } //Test Functions //ConstructDate is considered deprecated, and should not be used directly from //test262 tests as it's incredibly sensitive to DST start/end dates that //vary with geographic location. function ConstructDate(year, month, date, hours, minutes, seconds, ms) { /* * 1. Call ToNumber(year) * 2. Call ToNumber(month) * 3. If date is supplied use ToNumber(date); else use 1 * 4. If hours is supplied use ToNumber(hours); else use 0 * 5. If minutes is supplied use ToNumber(minutes); else use 0 * 6. If seconds is supplied use ToNumber(seconds); else use 0 * 7. If ms is supplied use ToNumber(ms); else use 0 * 8. If Result(1) is not NaN and 0 <= ToInteger(Result(1)) <= 99, Result(8) is * 1900+ToInteger(Result(1)); otherwise, Result(8) is Result(1) * 9. Compute MakeDay(Result(8), Result(2), Result(3)) * 10. Compute MakeTime(Result(4), Result(5), Result(6), Result(7)) * 11. Compute MakeDate(Result(9), Result(10)) * 12. Set the [[Value]] property of the newly constructed object to TimeClip(UTC(Result(11))) */ var r1 = Number(year); var r2 = Number(month); var r3 = ((date && arguments.length > 2) ? Number(date) : 1); var r4 = ((hours && arguments.length > 3) ? Number(hours) : 0); var r5 = ((minutes && arguments.length > 4) ? Number(minutes) : 0); var r6 = ((seconds && arguments.length > 5) ? Number(seconds) : 0); var r7 = ((ms && arguments.length > 6) ? Number(ms) : 0); var r8 = r1; if (!isNaN(r1) && (0 <= ToInteger(r1)) && (ToInteger(r1) <= 99)) r8 = 1900 + r1; var r9 = MakeDay(r8, r2, r3); var r10 = MakeTime(r4, r5, r6, r7); var r11 = MakeDate(r9, r10); var retVal = TimeClip(UTC(r11)); return retVal; } /**** Python code for initialize the above constants // We may want to replicate the following in JavaScript. // However, using JS date operations to generate parameters that are then used to // test those some date operations seems unsound. However, it isn't clear if there //is a good interoperable alternative. # Copyright 2009 the Sputnik authors. All rights reserved. # This code is governed by the BSD license found in the LICENSE file. def GetDaylightSavingsTimes(): # Is the given floating-point time in DST? def IsDst(t): return time.localtime(t)[-1] # Binary search to find an interval between the two times no greater than # delta where DST switches, returning the midpoint. def FindBetween(start, end, delta): while end - start > delta: middle = (end + start) / 2 if IsDst(middle) == IsDst(start): start = middle else: end = middle return (start + end) / 2 now = time.time() one_month = (30 * 24 * 60 * 60) # First find a date with different daylight savings. To avoid corner cases # we try four months before and after today. after = now + 4 * one_month before = now - 4 * one_month if IsDst(now) == IsDst(before) and IsDst(now) == IsDst(after): logger.warning("Was unable to determine DST info.") return None # Determine when the change occurs between now and the date we just found # in a different DST. if IsDst(now) != IsDst(before): first = FindBetween(before, now, 1) else: first = FindBetween(now, after, 1) # Determine when the change occurs between three and nine months from the # first. second = FindBetween(first + 3 * one_month, first + 9 * one_month, 1) # Find out which switch is into and which if out of DST if IsDst(first - 1) and not IsDst(first + 1): start = second end = first else: start = first end = second return (start, end) def GetDaylightSavingsAttribs(): times = GetDaylightSavingsTimes() if not times: return None (start, end) = times def DstMonth(t): return time.localtime(t)[1] - 1 def DstHour(t): return time.localtime(t - 1)[3] + 1 def DstSunday(t): if time.localtime(t)[2] > 15: return "'last'" else: return "'first'" def DstMinutes(t): return (time.localtime(t - 1)[4] + 1) % 60 attribs = { } attribs['start_month'] = DstMonth(start) attribs['end_month'] = DstMonth(end) attribs['start_sunday'] = DstSunday(start) attribs['end_sunday'] = DstSunday(end) attribs['start_hour'] = DstHour(start) attribs['end_hour'] = DstHour(end) attribs['start_minutes'] = DstMinutes(start) attribs['end_minutes'] = DstMinutes(end) return attribs *********/ //--Test case registration----------------------------------------------------- function runTestCase(testcase) { if (testcase() !== true) { $ERROR("Test case returned non-true value!"); } }