test262/website/resources/scripts/global/sta.js

304 lines
10 KiB
JavaScript
Raw Normal View History

2011-09-12 22:34:49 +02:00
/// Copyright (c) 2009 Microsoft Corporation
///
/// Redistribution and use in source and binary forms, with or without modification, are permitted provided
2011-09-12 22:34:49 +02:00
/// that the following conditions are met:
/// * Redistributions of source code must retain the above copyright notice, this list of conditions and
2011-09-12 22:34:49 +02:00
/// the following disclaimer.
/// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
/// the following disclaimer in the documentation and/or other materials provided with the distribution.
/// * Neither the name of Microsoft nor the names of its contributors may be used to
/// endorse or promote products derived from this software without specific prior written permission.
2011-09-12 22:34:49 +02:00
///
/// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
/// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
/// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
/// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
/// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
/// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
/// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2011-09-12 22:34:49 +02:00
/// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------
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;
}
//-----------------------------------------------------------------------------
test\harness\*: - a lot of JS harness code written in strings have been moved out to actual physical files such as ed.js (syntax error detection for globally scoped tests) and gs.js (global scope test case validator). This change makes it far easier to maintain the test harness code - reorganized helper.js providing a clear indication which methods are used by external objects, which are implementation details, and which are unequivocally test262-specific. I've also added, openErrorWindow, which will be used to open a descriptive error message window for each test case failure reported on the 'Run' tab - improved the error message for syntax errors occurring when a test case fails to load - sta.js no longer tries to pickle all helper functions it contains! Instead, we load the file directly from sth.js. The performance of fnGlobalObject has been improved. Finally, the ES5Harness object has been moved from sth.js (in a string) to here - sth.js now has a browser implementer hook, controller.implementerHook, which allows browser implementers to handle test case failures in their own way (e.g., log to the filesystem). The 'run' function was basically re-written Added 37 new test cases from the "IE Test Center" Build release. There were 14 modifications to existing test cases as well. Refactored SputnikGlobalScope.js such that test case paths are now used as indices into the GlobalScopeTests array. TestCasePackager.py had the concept of templated test harnesses introduced - see templates\runner.test262.html. Also added support for one HTML test harness per ES5 chapter. Last but not least, TestCasePackagerConfig.py now has a 'source control' abstraction class which abstracts away source control adds|edits when dynamically generating *.json and *.html test chapters.
2011-08-25 20:18:44 +02:00
var __globalObject = Function("return this;")();
function fnGlobalObject() {
test\harness\*: - a lot of JS harness code written in strings have been moved out to actual physical files such as ed.js (syntax error detection for globally scoped tests) and gs.js (global scope test case validator). This change makes it far easier to maintain the test harness code - reorganized helper.js providing a clear indication which methods are used by external objects, which are implementation details, and which are unequivocally test262-specific. I've also added, openErrorWindow, which will be used to open a descriptive error message window for each test case failure reported on the 'Run' tab - improved the error message for syntax errors occurring when a test case fails to load - sta.js no longer tries to pickle all helper functions it contains! Instead, we load the file directly from sth.js. The performance of fnGlobalObject has been improved. Finally, the ES5Harness object has been moved from sth.js (in a string) to here - sth.js now has a browser implementer hook, controller.implementerHook, which allows browser implementers to handle test case failures in their own way (e.g., log to the filesystem). The 'run' function was basically re-written Added 37 new test cases from the "IE Test Center" Build release. There were 14 modifications to existing test cases as well. Refactored SputnikGlobalScope.js such that test case paths are now used as indices into the GlobalScopeTests array. TestCasePackager.py had the concept of templated test harnesses introduced - see templates\runner.test262.html. Also added support for one HTML test harness per ES5 chapter. Last but not least, TestCasePackagerConfig.py now has a 'source control' abstraction class which abstracts away source control adds|edits when dynamically generating *.json and *.html test chapters.
2011-08-25 20:18:44 +02:00
return __globalObject;
}
//-----------------------------------------------------------------------------
function fnSupportsStrict() {
"use strict";
2011-09-12 22:34:49 +02:00
try {
eval('with ({}) {}');
return false;
2011-09-12 22:34:49 +02:00
} 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;
}
test\harness\*: - a lot of JS harness code written in strings have been moved out to actual physical files such as ed.js (syntax error detection for globally scoped tests) and gs.js (global scope test case validator). This change makes it far easier to maintain the test harness code - reorganized helper.js providing a clear indication which methods are used by external objects, which are implementation details, and which are unequivocally test262-specific. I've also added, openErrorWindow, which will be used to open a descriptive error message window for each test case failure reported on the 'Run' tab - improved the error message for syntax errors occurring when a test case fails to load - sta.js no longer tries to pickle all helper functions it contains! Instead, we load the file directly from sth.js. The performance of fnGlobalObject has been improved. Finally, the ES5Harness object has been moved from sth.js (in a string) to here - sth.js now has a browser implementer hook, controller.implementerHook, which allows browser implementers to handle test case failures in their own way (e.g., log to the filesystem). The 'run' function was basically re-written Added 37 new test cases from the "IE Test Center" Build release. There were 14 modifications to existing test cases as well. Refactored SputnikGlobalScope.js such that test case paths are now used as indices into the GlobalScopeTests array. TestCasePackager.py had the concept of templated test harnesses introduced - see templates\runner.test262.html. Also added support for one HTML test harness per ES5 chapter. Last but not least, TestCasePackagerConfig.py now has a 'source control' abstraction class which abstracts away source control adds|edits when dynamically generating *.json and *.html test chapters.
2011-08-25 20:18:44 +02:00
//-----------------------------------------------------------------------------
test\harness\*: - a lot of JS harness code written in strings have been moved out to actual physical files such as ed.js (syntax error detection for globally scoped tests) and gs.js (global scope test case validator). This change makes it far easier to maintain the test harness code - reorganized helper.js providing a clear indication which methods are used by external objects, which are implementation details, and which are unequivocally test262-specific. I've also added, openErrorWindow, which will be used to open a descriptive error message window for each test case failure reported on the 'Run' tab - improved the error message for syntax errors occurring when a test case fails to load - sta.js no longer tries to pickle all helper functions it contains! Instead, we load the file directly from sth.js. The performance of fnGlobalObject has been improved. Finally, the ES5Harness object has been moved from sth.js (in a string) to here - sth.js now has a browser implementer hook, controller.implementerHook, which allows browser implementers to handle test case failures in their own way (e.g., log to the filesystem). The 'run' function was basically re-written Added 37 new test cases from the "IE Test Center" Build release. There were 14 modifications to existing test cases as well. Refactored SputnikGlobalScope.js such that test case paths are now used as indices into the GlobalScopeTests array. TestCasePackager.py had the concept of templated test harnesses introduced - see templates\runner.test262.html. Also added support for one HTML test harness per ES5 chapter. Last but not least, TestCasePackagerConfig.py now has a 'source control' abstraction class which abstracts away source control adds|edits when dynamically generating *.json and *.html test chapters.
2011-08-25 20:18:44 +02:00
var NotEarlyErrorString = "NotEarlyError";
var EarlyErrorRePat = "^((?!" + NotEarlyErrorString + ").)*$";
var NotEarlyError = new Error(NotEarlyErrorString);
//--Test case registration-----------------------------------------------------
var ES5Harness = {};
ES5Harness.registerTest = function (test) {
var error;
//Has a test precondition set, but the precondition fails
if (test.precondition && !test.precondition()) {
testRun(test.id, test.path, test.description, test.test.toString(),
typeof test.precondition !== 'undefined' ? test.precondition.toString() : '',
'fail', Error('Precondition Failed'));
}
//We're good to actually run the test case
else {
try {
if (test.strict!==undefined) {
var res = test.test();
} else {
var res = test.test.call(window);
}
} catch (e) {
res = 'fail';
error = e;
if (!(e instanceof Error)) {
try {
error = Error(e.toString());
} catch (e2) {
error = Error("test262: unknown error in test case or ECMAScript implementation");
}
}
}
//Sputnik and IE Test Center tests are a bit different in terms of return values.
//That is, IE Test Center will always return 'true' IFF the test passed. Sputnik
//test cases will return either 'true' or 'undefined' if they pass.
var retVal = /^s/i.test(test.id) ? (res === true || typeof res === 'undefined' ? 'pass' : 'fail') : (res === true ? 'pass' : 'fail');
testRun(test.id, test.path, test.description, test.test.toString(),
typeof test.precondition !== 'undefined' ? test.precondition.toString() : '',
retVal, error);
}
}