tools, harness: support new YAML frontmatter

parseTestRecord: add support for YAML frontmatter
parseTestRecord: initial unit test for test record parser
parseTestRecord: refactor for testing

factor old parsing; add YAML parsing

runner: support "includes" from YAML frontmatter

support frontmatter "includes" in python runner
use test.includes if present instead of scanning test code with regex

harness: factor individual functions out into files

tools: handle YAML errors

tolerate missing keys in dictionary (flags, includes)
report filename when empty frontmatter block
new option --list-includes to test262.py

harness: factor helper functions into separate files

sth: remove extra close-paren (syntax error)

test_common: TDD; failing parse of YAML

common: use parseTestRecord (YAML-aware)
This commit is contained in:
Sam Mikes 2014-07-18 16:22:37 -06:00 committed by Brian Terlson
parent 0defa37385
commit c33bf0e043
39 changed files with 1350 additions and 931 deletions

3
test/harness/$FAIL.js Normal file
View File

@ -0,0 +1,3 @@
function $FAIL(message) {
testFailed(message);
}

4
test/harness/$PRINT.js Normal file
View File

@ -0,0 +1,4 @@
//adaptors for Test262 framework
function $PRINT(message) {
}

View File

@ -0,0 +1,83 @@
//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;
})();

View File

@ -0,0 +1,439 @@
//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
*********/

View File

@ -0,0 +1,7 @@
//function Test262Error(message) {
// if (message) this.message = message;
//}
//
//Test262Error.prototype.toString = function () {
// return "Test262 Error: " + this.message;
//};

View File

@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
//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;
}

View File

@ -0,0 +1,17 @@
//-----------------------------------------------------------------------------
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;
}

View File

@ -0,0 +1,19 @@
//-----------------------------------------------------------------------------
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;
}

View File

@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
//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;
}

7
test/harness/fnExists.js Normal file
View File

@ -0,0 +1,7 @@
//-----------------------------------------------------------------------------
function fnExists(/*arguments*/) {
for (var i = 0; i < arguments.length; i++) {
if (typeof (arguments[i]) !== "function") return false;
}
return true;
}

View File

@ -0,0 +1,5 @@
//-----------------------------------------------------------------------------
var __globalObject = Function("return this;")();
function fnGlobalObject() {
return __globalObject;
}

View File

@ -0,0 +1,5 @@
function runTestCase(testcase) {
if (testcase() !== true) {
$ERROR("Test case returned non-true value!");
}
}

View File

@ -4,266 +4,7 @@
/// "Use Terms"). Any redistribution of this code must retain the above /// "Use Terms"). Any redistribution of this code must retain the above
/// copyright and this notice and otherwise comply with the Use Terms. /// 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 NotEarlyErrorString = "NotEarlyError";
@ -286,616 +27,8 @@ function testFailed(message) {
throw new Test262Error(message); throw new Test262Error(message);
} }
function testPrint(message) {
}
//adaptors for Test262 framework
function $PRINT(message) {
}
function $INCLUDE(message) { } function $INCLUDE(message) { }
function $ERROR(message) { function $ERROR(message) {
testFailed(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!");
}
}

View File

@ -163,8 +163,14 @@ function BrowserRunner() {
iwin.testFinished = testFinished; iwin.testFinished = testFinished;
//TODO: these should be moved to sta.js //TODO: these should be moved to sta.js
var includes = code.match(/\$INCLUDE\(([^\)]+)\)/g), // find all of the $INCLUDE statements var includes,
include; include;
includes = test.includes;
if (!includes || !(includes.length)) {
// includes not specified via frontmatter; find all of the $INCLUDE statements
includes = code.match(/\$INCLUDE\(([^\)]+)\)/g);
}
if (includes !== null) { if (includes !== null) {
// We have some includes, so loop through each include and // We have some includes, so loop through each include and

View File

@ -9,10 +9,11 @@ es5id: 8.7.2-3-a-2gs
description: > description: >
Strict Mode - 'runtime' error is thrown before LeftHandSide Strict Mode - 'runtime' error is thrown before LeftHandSide
evaluates to an unresolvable Reference evaluates to an unresolvable Reference
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
"use strict"; "use strict";
throw NotEarlyError; throw new Test262Error();
b = 11; b = 11;

View File

@ -9,10 +9,11 @@ es5id: 11.13.1-4-28gs
description: > description: >
Strict Mode - SyntaxError is thrown if the identifier 'Math.PI' Strict Mode - SyntaxError is thrown if the identifier 'Math.PI'
appears as the LeftHandSideExpression of simple assignment(=) appears as the LeftHandSideExpression of simple assignment(=)
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
"use strict"; "use strict";
throw NotEarlyError; throw new Test262Error();
Math.PI = 20; Math.PI = 20;

View File

@ -9,10 +9,11 @@ es5id: 13.0_4-17gs
description: > description: >
Strict Mode - SourceElements is not evaluated as strict mode code Strict Mode - SourceElements is not evaluated as strict mode code
when a Function constructor is contained in strict mode code when a Function constructor is contained in strict mode code
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
"use strict"; "use strict";
var _13_0_4_17_fun = new Function('eval = 42;'); var _13_0_4_17_fun = new Function('eval = 42;');
throw NotEarlyError; throw new Test262Error();

View File

@ -9,11 +9,12 @@ es5id: 13.2-19-b-3gs
description: > description: >
StrictMode - error is thrown when assign a value to the 'caller' StrictMode - error is thrown when assign a value to the 'caller'
property of a function object property of a function object
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
"use strict"; "use strict";
throw NotEarlyError; throw new Test262Error();
function _13_2_19_b_3_gs() {} function _13_2_19_b_3_gs() {}
_13_2_19_b_3_gs.caller = 1; _13_2_19_b_3_gs.caller = 1;

View File

@ -10,10 +10,11 @@ description: >
Strict Mode - SyntaxError is thrown if a function using the Strict Mode - SyntaxError is thrown if a function using the
Function constructor has two identical parameters in (global) Function constructor has two identical parameters in (global)
strict mode strict mode
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
"use strict"; "use strict";
throw NotEarlyError; throw new Test262Error();
var _15_3_2_1_10_4_fun = new Function('param_1', 'param_2', 'param_1', '"use strict"; return 0;'); var _15_3_2_1_10_4_fun = new Function('param_1', 'param_2', 'param_1', '"use strict"; return 0;');

View File

@ -10,9 +10,10 @@ description: >
Strict Mode - SyntaxError is thrown if a function using the Strict Mode - SyntaxError is thrown if a function using the
Function constructor has two identical parameters in (local) Function constructor has two identical parameters in (local)
strict mode strict mode
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
throw NotEarlyError; throw new Test262Error();
var _15_3_2_1_10_6_fun = new Function('param_1', 'param_2', 'param_1', '"use strict";return 0;'); var _15_3_2_1_10_6_fun = new Function('param_1', 'param_2', 'param_1', '"use strict";return 0;');

View File

@ -9,11 +9,12 @@ es5id: 15.3.5-1gs
description: > description: >
StrictMode - error is thrown when reading the 'caller' property of StrictMode - error is thrown when reading the 'caller' property of
a function object a function object
negative: NotEarlyError negative: Test262Error
flags: [onlyStrict] flags: [onlyStrict]
includes: [Test262Error.js]
---*/ ---*/
"use strict"; "use strict";
function _15_3_5_1_gs() {} function _15_3_5_1_gs() {}
throw NotEarlyError; throw new Test262Error();
_15_3_5_1_gs.caller; _15_3_5_1_gs.caller;

View File

@ -5,44 +5,17 @@
# copyright and this notice and otherwise comply with the Use Terms. # copyright and this notice and otherwise comply with the Use Terms.
#--Imports--------------------------------------------------------------------- #--Imports---------------------------------------------------------------------
import re import parseTestRecord
#--Stubs----------------------------------------------------------------------- #--Stubs-----------------------------------------------------------------------
#--Globals--------------------------------------------------------------------- #--Globals---------------------------------------------------------------------
captureCommentPattern = re.compile(r"\/\*\*?((?:\s|\S)*?)\*\/\s*\n")
atattrs = re.compile(r"\s*\n\s*\*\s*@")
stars = re.compile(r"\s*\n\s*\*\s?")
#--Helpers--------------------------------------------------------------------# #--Helpers--------------------------------------------------------------------#
def stripStars(text):
return stars.sub('\n', text).strip()
def convertDocString(docString): def convertDocString(docString):
envelope = {} envelope = parseTestRecord.parseTestRecord(docString, '')
temp = captureCommentPattern.findall(docString)[0] envelope.pop('header', None)
propTexts = atattrs.split(temp) envelope.pop('test', None)
envelope['commentary'] = stripStars(propTexts[0])
del propTexts[0]
for propText in propTexts:
# TODO: error check for mismatch
propName = re.match(r"^\w+", propText).group(0)
propVal = propText[len(propName):]
# Just till last one-time conversion
# strip optional initial colon or final semicolon.
# The initial colon is only stripped if it comes immediately
# after the identifier with no intervening whitespace.
propVal = re.sub(r"^:\s*", '', propVal, 1)
propVal = re.sub(r";\s*$", '', propVal, 1)
propVal = stripStars(propVal)
if propName in envelope:
raise Exception('duplicate: ' + propName)
envelope[propName] = propVal;
return envelope return envelope
#--MAIN------------------------------------------------------------------------

View File

@ -17,6 +17,8 @@ import sys
import tempfile import tempfile
import time import time
import yaml
# from TestCasePackagerConfig import * # from TestCasePackagerConfig import *
headerPatternStr = r"(?:(?:\s*\/\/.*)?\s*\n)*" headerPatternStr = r"(?:(?:\s*\/\/.*)?\s*\n)*"
@ -34,6 +36,9 @@ testRecordPattern = re.compile(r"^(" + headerPatternStr +
stars = re.compile(r"\s*\n\s*\*\s?") stars = re.compile(r"\s*\n\s*\*\s?")
atattrs = re.compile(r"\s*\n\s*\*\s*@") atattrs = re.compile(r"\s*\n\s*\*\s*@")
yamlPattern = re.compile(r"---((?:\s|\S)*)---")
newlinePattern = re.compile(r"\n")
def stripStars(text): def stripStars(text):
return stars.sub('\n', text).strip() return stars.sub('\n', text).strip()
@ -41,25 +46,63 @@ def stripHeader(src):
header = headerPattern.match(src).group(0) header = headerPattern.match(src).group(0)
return src[len(header):] return src[len(header):]
def parseTestRecord(src, name): def matchParts(src, name):
testRecord = {}
match = testRecordPattern.match(src) match = testRecordPattern.match(src)
if match == None: if match == None:
raise Exception('unrecognized: ' + name) raise Exception('unrecognized: ' + name)
return match
def hasYAML(text):
match = yamlPattern.match(text)
if match == None:
return False
return True
def oldAttrParser(testRecord, body, name):
propTexts = atattrs.split(body)
testRecord['commentary'] = stripStars(propTexts[0])
del propTexts[0]
for propText in propTexts:
propMatch = re.match(r"^\w+", propText)
if propMatch == None:
raise Exception('Malformed "@" attribute: ' + name)
propName = propMatch.group(0)
propVal = stripStars(propText[len(propName):])
if propName in testRecord:
raise Exception('duplicate: ' + propName)
testRecord[propName] = propVal;
def yamlAttrParser(testRecord, attrs, name):
match = yamlPattern.match(attrs)
body = match.group(1)
parsed = yaml.load(body)
if (parsed is None):
print "Failed to parse yaml in name %s"%(name)
return
for key in parsed:
value = parsed[key]
if key == "info":
key = "commentary"
testRecord[key] = value
if 'flags' in testRecord:
for flag in testRecord['flags']:
testRecord[flag] = ""
def parseTestRecord(src, name):
testRecord = {}
match = matchParts(src, name)
testRecord['header'] = match.group(1).strip() testRecord['header'] = match.group(1).strip()
testRecord['test'] = match.group(3) # do not trim testRecord['test'] = match.group(3) # do not trim
if match.group(2):
propTexts = atattrs.split(match.group(2)) attrs = match.group(2)
testRecord['commentary'] = stripStars(propTexts[0]) if attrs:
del propTexts[0] if hasYAML(attrs):
for propText in propTexts: yamlAttrParser(testRecord, attrs, name)
propMatch = re.match(r"^\w+", propText) else:
if propMatch == None: oldAttrParser(testRecord, attrs, name)
raise Exception('Malformed "@" attribute: ' + name)
propName = propMatch.group(0)
propVal = stripStars(propText[len(propName):])
if propName in testRecord:
raise Exception('duplicate: ' + propName)
testRecord[propName] = propVal;
return testRecord return testRecord

View File

@ -0,0 +1,11 @@
# Unit tests for python packaging tools
This directory holds tests for the python code, not tests of EMCAScript
## Running tests
````
$ cd tools/packaging/test
$ python test*.py
````

View File

@ -0,0 +1,19 @@
// Copyright 2009 the Sputnik authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* The production Block { } in strict code can't contain function
* declaration;
*
* @path bestPractice/Sbp_A1_T1.js
* @description Trying to declare function at the Block statement
* @onlyStrict
* @negative SyntaxError
* @bestPractice http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls
*/
"use strict";
{
function __func(){}
}

View File

@ -0,0 +1,18 @@
// Copyright 2009 the Sputnik authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
info: >
The production Block { } in strict code can't contain function
declaration;
description: Trying to declare function at the Block statement
negative: SyntaxError
bestPractice: "http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls"
flags: [onlyStrict]
---*/
"use strict";
{
function __func(){}
}

View File

@ -0,0 +1,63 @@
#!/usr/bin/env python
# Copyright 2014 by Sam Mikes. All rights reserved.
# This code is governed by the BSD license found in the LICENSE file.
import unittest
import os
# add parent dir to search path
import sys
sys.path.insert(0, "..")
from common import *
def slurpFile(name):
with open(name) as f:
contents = f.read()
return contents
class TestOldParsing(unittest.TestCase):
def test_test(self):
pass
def test_overview(self):
name = 'fixtures/test262-old-headers.js'
contents = slurpFile(name)
record = convertDocString(contents)
self.assertEqual("""The production Block { } in strict code can't contain function
declaration;""", record['commentary'])
self.assertEqual("bestPractice/Sbp_A1_T1.js", record['path'])
self.assertEqual("Trying to declare function at the Block statement",
record['description'])
self.assertEqual("", record['onlyStrict'])
self.assertEqual("SyntaxError", record['negative'])
self.assertEqual("http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls",
record['bestPractice'])
class TestYAMLParsing(unittest.TestCase):
def test_overview(self):
name = 'fixtures/test262-yaml-headers.js'
contents = slurpFile(name)
record = convertDocString(contents)
self.assertEqual("The production Block { } in strict code can't contain function declaration;\n", record['commentary'])
self.assertEqual("Trying to declare function at the Block statement",
record['description'])
self.assertEqual(['onlyStrict'], record['flags'])
self.assertEqual("", record['onlyStrict'])
self.assertEqual("SyntaxError", record['negative'])
self.assertEqual("http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls",
record['bestPractice'])
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,177 @@
#!/usr/bin/env python
# Copyright 2014 by Sam Mikes. All rights reserved.
# This code is governed by the BSD license found in the LICENSE file.
import unittest
import os
import yaml
# add parent dir to search path
import sys
sys.path.insert(0, "..")
from parseTestRecord import *
def slurpFile(name):
with open(name) as f:
contents = f.read()
return contents
class TestOldParsing(unittest.TestCase):
def test_test(self):
self.assertTrue(True)
def test_overview(self):
name = 'fixtures/test262-old-headers.js'
contents = slurpFile(name)
record = parseTestRecord(contents, name)
self.assertEqual("""// Copyright 2009 the Sputnik authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.""",
record['header'])
self.assertEqual("""The production Block { } in strict code can't contain function
declaration;""", record['commentary'])
self.assertEqual("bestPractice/Sbp_A1_T1.js", record['path'])
self.assertEqual("Trying to declare function at the Block statement",
record['description'])
self.assertEqual("", record['onlyStrict'])
self.assertEqual("SyntaxError", record['negative'])
self.assertEqual("http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls",
record['bestPractice'])
self.assertEqual(""""use strict";
{
function __func(){}
}
""", record['test'])
@unittest.expectedFailure
def test_nomatch(self):
with self.assertRaisesRegexp(Exception, "unrecognized"):
parseTestRecord("#!/usr/bin/env python", "random.py")
def test_duplicate(self):
with self.assertRaisesRegexp(Exception, "duplicate: foo"):
parseTestRecord("""
// Copyright
/**
* @foo bar
* @foo bar
*/
1;
"""
, "name")
def test_malformed(self):
with self.assertRaisesRegexp(Exception, 'Malformed "@" attribute: name'):
parseTestRecord("""
// Copyright
/**
* @ baz
* @foo bar
*/
1;
"""
, "name")
def test_stripStars(self):
self.assertEqual("", stripStars(""))
self.assertEqual("foo", stripStars("\n* foo"))
self.assertEqual("@foo bar", stripStars("\n* @foo bar"))
self.assertEqual("@foo bar", stripStars("\n *@foo bar"))
class TestYAMLParsing(unittest.TestCase):
def test_test(self):
self.assertTrue(True)
def test_split(self):
name = 'fixtures/test262-yaml-headers.js'
contents = slurpFile(name)
self.assertTrue('---' in contents)
match = matchParts(contents, name)
self.assertEqual("""---
info: >
The production Block { } in strict code can't contain function
declaration;
description: Trying to declare function at the Block statement
negative: SyntaxError
bestPractice: "http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls"
flags: [onlyStrict]
---""", match.group(2))
def test_yamlParse(self):
text = """
info: >
The production Block { } in strict code can't contain function
declaration;
description: Trying to declare function at the Block statement
negative: SyntaxError
bestPractice: "http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls"
flags: [onlyStrict]"""
parsed = yaml.load(text)
self.assertEqual("Trying to declare function at the Block statement",
parsed['description'])
self.assertEqual("SyntaxError", parsed['negative'])
self.assertEqual('http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls', parsed['bestPractice'])
self.assertEqual(["onlyStrict"], parsed['flags'])
self.assertEqual("The production Block { } in strict code can't contain function declaration;\n", parsed['info'])
def test_hasYAML(self):
self.assertTrue(hasYAML("---\n some: yaml\n\n---"))
self.assertFalse(hasYAML("\n* Test description\n *\n * @foo bar\n* @noStrict\n"))
def test_fixturehasYAML(self):
name = 'fixtures/test262-yaml-headers.js'
contents = slurpFile(name)
self.assertTrue('---' in contents)
match = matchParts(contents, name)
self.assertTrue(hasYAML(match.group(2)))
def test_missingKeys(self):
result = {}
yamlAttrParser(result, """---
info: some info (note no flags or includes)
---""", "")
self.assertEqual("some info (note no flags or includes)", result['commentary'])
def test_overview(self):
name = 'fixtures/test262-yaml-headers.js'
contents = slurpFile(name)
record = parseTestRecord(contents, name)
self.assertEqual("""// Copyright 2009 the Sputnik authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.""",
record['header'])
self.assertEqual("The production Block { } in strict code can't contain function declaration;\n", record['commentary'])
self.assertEqual("Trying to declare function at the Block statement",
record['description'])
self.assertEqual(['onlyStrict'], record['flags'])
self.assertEqual("", record['onlyStrict'])
self.assertEqual("SyntaxError", record['negative'])
self.assertEqual("http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls",
record['bestPractice'])
self.assertEqual(""""use strict";
{
function __func(){}
}
""", record['test'])
if __name__ == '__main__':
unittest.main()

View File

@ -25,6 +25,7 @@ import json
import stat import stat
import xml.etree.ElementTree as xmlj import xml.etree.ElementTree as xmlj
import unicodedata import unicodedata
from collections import Counter
from parseTestRecord import parseTestRecord, stripHeader from parseTestRecord import parseTestRecord, stripHeader
@ -74,6 +75,8 @@ def BuildOptions():
result.add_option("--loglevel", default="warning", result.add_option("--loglevel", default="warning",
help="sets log level to debug, info, warning, error, or critical") help="sets log level to debug, info, warning, error, or critical")
result.add_option("--print-handle", default="", help="Command to print from console") result.add_option("--print-handle", default="", help="Command to print from console")
result.add_option("--list-includes", default=False, action="store_true",
help="List includes required by tests")
return result return result
@ -251,7 +254,9 @@ class TestCase(object):
return '$DONE' in self.test return '$DONE' in self.test
def GetIncludeList(self): def GetIncludeList(self):
return re.findall('\$INCLUDE\([\'"]([^\)]+)[\'"]\)' ,self.test) if self.testRecord.get('includes'):
return self.testRecord['includes']
return re.findall('\$INCLUDE\([\'"]([^\)]+)[\'"]\)', self.test)
def GetAdditionalIncludes(self): def GetAdditionalIncludes(self):
return '\n'.join([self.suite.GetInclude(include) for include in self.GetIncludeList()]) return '\n'.join([self.suite.GetInclude(include) for include in self.GetIncludeList()])
@ -552,6 +557,16 @@ class TestSuite(object):
if len(cases) > 0: if len(cases) > 0:
cases[0].Print() cases[0].Print()
def ListIncludes(self, tests):
cases = self.EnumerateTests(tests)
includes_dict = Counter()
for case in cases:
includes = case.GetIncludeList()
includes_dict.update(includes)
print includes_dict
def Main(): def Main():
code = 0 code = 0
parser = BuildOptions() parser = BuildOptions()
@ -575,6 +590,8 @@ def Main():
logging.basicConfig(level=logging.CRITICAL) logging.basicConfig(level=logging.CRITICAL)
if options.cat: if options.cat:
test_suite.Print(args) test_suite.Print(args)
elif options.list_includes:
test_suite.ListIncludes(args)
else: else:
code = test_suite.Run(options.command, args, code = test_suite.Run(options.command, args,
options.summary or options.full_summary, options.summary or options.full_summary,

3
website/harness/$FAIL.js Normal file
View File

@ -0,0 +1,3 @@
function $FAIL(message) {
testFailed(message);
}

View File

@ -0,0 +1,4 @@
//adaptors for Test262 framework
function $PRINT(message) {
}

View File

@ -0,0 +1,7 @@
//function Test262Error(message) {
// if (message) this.message = message;
//}
//
//Test262Error.prototype.toString = function () {
// return "Test262 Error: " + this.message;
//};

View File

@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
//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;
}

View File

@ -0,0 +1,17 @@
//-----------------------------------------------------------------------------
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;
}

View File

@ -0,0 +1,19 @@
//-----------------------------------------------------------------------------
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;
}

View File

@ -0,0 +1,74 @@
//-----------------------------------------------------------------------------
//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;
}

View File

@ -0,0 +1,7 @@
//-----------------------------------------------------------------------------
function fnExists(/*arguments*/) {
for (var i = 0; i < arguments.length; i++) {
if (typeof (arguments[i]) !== "function") return false;
}
return true;
}

View File

@ -0,0 +1,5 @@
//-----------------------------------------------------------------------------
var __globalObject = Function("return this;")();
function fnGlobalObject() {
return __globalObject;
}

View File

@ -0,0 +1,5 @@
function runTestCase(testcase) {
if (testcase() !== true) {
$ERROR("Test case returned non-true value!");
}
}