Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a few Web IDL implementation tests. #106

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions WebIDL/tests/submissions/heycam/ArrayClass-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<title>[ArrayClass]</title>
<script src="http://w3c-test.org/resources/testharness.js"></script>
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<div id="log"></div>

<script>
// 4.4.3 Interface prototype object
//
// [ArrayClass] on an interface means that its [[Prototype]] is Array.prototype.

test(function() {
assert_true(NodeList.prototype == Array.prototype, "NodeList.prototype == Array.prototype");
}, "NodeList being [ArrayClass] implies NodeList.prototype == Array.prototype");

test(function() {
var a = document.childNodes.concat();
assert_true(Object.getPrototypeOf(a) == Array.prototype, "nodeList.concat() returns an Array");
assert_array_equals(document.childNodes, a);
}, "nodeList.concat() works");
</script>
49 changes: 49 additions & 0 deletions WebIDL/tests/submissions/heycam/Constructor-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<title>[Constructor]</title>
<script src="http://w3c-test.org/resources/testharness.js"></script>
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<div id="log"></div>

<script>
// 4.4.1.1 Interface object [[Call]] method
//
// Interfaces with [Constructor] have a [[Call]] method that invokes the
// constructor behavior. If it didn't have [Constructor], a TypeError is
// thrown. The returned object must implement the interface. There must
// also be a "length" property on the interface object.

test(function() {
assert_throws({ name: "TypeError" }, function() { new Element(); }, "new Element()");
}, "Calling new on an interface object whose interface does not have [Constructor]")

test(function() {
assert_true(new Event("test") instanceof Event, "new Event(...) instanceof Event");
}, "Event constructor returns an object that is instanceof Event");

test(function() {
assert_true(Event("test") instanceof Event, "Event(...) instanceof Event");
}, "Event constructor called as a function returns an object that is instanceof Event");

test(function() {
assert_true(new XMLHttpRequest() instanceof XMLHttpRequest, "new XMLHttpRequest() instanceof XMLHttpRequest");
}, "XMLHttpRequest constructor returns an object that is instanceof XMLHttpRequest");

test(function() {
assert_true(XMLHttpRequest() instanceof XMLHttpRequest, "XMLHttpRequest() instanceof XMLHttpRequest");
}, "XMLHttpRequest constructor called as a function returns an object that is instanceof XMLHttpRequest");

var lengthProperties = [
"Event", 1,
"XMLHttpRequest", 0
];

for (var i = 0; i < lengthProperties.length; i += 2) {
var intf = lengthProperties[i];
var val = lengthProperties[i + 1];

test(function() {
assert_property(window[intf], "length", { writable: false, enumerable: false, configurable: false, value: val }, intf + ".length");
}, intf + " has correct length property");
}
</script>
56 changes: 56 additions & 0 deletions WebIDL/tests/submissions/heycam/NamedConstructor-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<title>[NamedConstructor]</title>
<script src="http://w3c-test.org/resources/testharness.js"></script>
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<div id="log"></div>

<script>
// 4.4.2 Named constructors
//
// Interfaces with [NamedConstructor] have a function on the global that
// can be called or constructed. The returned object must implement the
// interface. There must also be a "length" property on the interface object.
// And they have a "prototype" property pointing to the interface prototype
// object.

test(function() {
}, "Image named constructor exists with the right attributes");

test(function() {
assert_true(new Image() instanceof HTMLImageElement, "new Image() instanceof HTMLImageElement");
}, "Image named constructor returns an object that is instanceof HTMLImageElement");

test(function() {
assert_true(Image() instanceof HTMLImageElement, "Image() instanceof HTMLImageElement");
}, "Image named constructor called as a function returns an object that is instanceof HTMLImageElement");

test(function() {
assert_true(new Audio() instanceof HTMLAudioElement, "new Audio() instanceof HTMLAudioElement");
}, "Audio named constructor returns an object that is instanceof HTMLAudioElement");

test(function() {
assert_true(Audio() instanceof HTMLAudioElement, "Audio() instanceof HTMLAudioElement");
}, "Audio named constructor called as a function returns an object that is instanceof HTMLAudioElement");

var lengthProperties = [
"Image", 0, "HTMLImageElement",
"Audio", 0, "HTMLAudioElement"
];

for (var i = 0; i < lengthProperties.length; i += 3) {
var named = lengthProperties[i];
var val = lengthProperties[i + 1];
var intf = lengthProperties[i + 2];

test(function() {
assert_property(window, named, { writable: true, enumerable: false, configurable: true }, "window." + named);
}, named + " named constructor exists");
test(function() {
assert_property(window[named], "length", { writable: false, enumerable: false, configurable: false, value: val }, named + ".length");
}, named + " has correct length property");
test(function() {
assert_property(window[named], "prototype", { writable: false, enumerable: false, configurable: false, value: window[intf].prototype }, named + ".prototype");
}, named + " has correct prototype property");
}
</script>
36 changes: 36 additions & 0 deletions WebIDL/tests/submissions/heycam/NamedPropertiesObject-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<title>[NamedPropertiesObject] prototype chain</title>
<script src="http://w3c-test.org/resources/testharness.js"></script>
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<div id="log"></div>

<script>
// 4.4.4 Named properties object
//
// Its [[Prototype]] points to the interface prototype object of any
// interface the one [[Prototype]] is on inherits from, or Object.prototype.

// window -> Window.prototype -> [named properties] -> EventTarget.prototype -> Object.prototype
var chain = prototypeChain(window);

test(function() {
assert_equals(chain[1], Window.prototype);
}, "window has correct [[Prototype]]");

test(function() {
assert_true(chain[2] && chain[2] != EventTarget.prototype && chain[2] != Object.prototype);
}, "Window.prototype doesn't have incorrect [[Prototype]]");

test(function() {
assert_equals(chain[3], EventTarget.prototype);
}, "named properties object has correct [[Prototype]]");

test(function() {
assert_equals(chain[4], Object.prototype);
}, "EventTarget.prototype has correct [[Prototype]]");

test(function() {
assert_equals(chain.length, 5);
}, "window has expected prototype chain length");
</script>
130 changes: 130 additions & 0 deletions WebIDL/tests/submissions/heycam/NamedPropertiesObject-002.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<!DOCTYPE html>
<title>[NamedPropertiesObject] property lookup</title>
<script src="http://w3c-test.org/resources/testharness.js"></script>
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<div id="log"></div>

<div id="hidden" style="visibility: hidden; position: absolute; width: 0; height: 0; overflow: hidden">
<iframe id="f1" name="f1"></iframe>
<iframe id="f2" name="f2"></iframe>
</div>

<script>
// 4.4.4.1 Named properties object [[GetOwnProperty]] method
//
// Named properties are exposed as data properties through [[GetOwnProperty]].
// [[GetOwnProperty]] also exposes other (expando) properties on the named
// properties object.

var hidden = document.getElementById("hidden");
var iframe1 = document.getElementById("f1");
var iframe2 = document.getElementById("f2");

test(function() {
assert_equals(window.f1, iframe1.contentWindow);
}, "properties from the named properties object can be looked up on window");

test(function() {
assert_equals(Window.prototype.f1, iframe1.contentWindow);
}, "properties from the named properties object can be looked up on Window.prototype");

test(function() {
var namedPropertiesObject = Object.getPrototypeOf(Window.prototype);
assert_equals(namedPropertiesObject.f1, iframe1.contentWindow);
}, "named properties can be looked up on the named properties object");

test(function() {
var object = window;
var desc;
while (object && !desc) {
desc = Object.getOwnPropertyDescriptor(object, "f1");
object = Object.getPrototypeOf(object);
}
assert_true(!!desc, "named property exposed through [[GetOwnProperty]]");
assert_descriptor(desc, { writable: false, enumerable: true, configurable: true, value: iframe1.contentWindow }, "f1");
}, "named properties are exposed correctly through [[GetOwnProperty]]");

test(function() {
var namedPropertiesObject = Object.getPrototypeOf(Window.prototype);
namedPropertiesObject.expando1 = 1;
assert_equals(window.expando1, 1);
}, "expando properties on the named properties object are exposed through window");

test(function() {
var namedPropertiesObject = Object.getPrototypeOf(Window.prototype);

// Ensure there's already a named property "f2".
assert_property(namedPropertiesObject, "f2", { writable: false, enumerable: true, configurable: true, value: iframe2.contentWindow }, "#1 namedPropertiesObject.f2");

// Define a property with the same name.
Object.defineProperty(namedPropertiesObject, "f2", { writable: false, enumerable: false, configurable: true, value: "hello" });

// Although the property definition should work, the named property should still shadow it.
assert_property(namedPropertiesObject, "f2", { writable: false, enumerable: true, configurable: true, value: iframe2.contentWindow }, "#2 namedPropertiesObject.f2");

// Remove the named property.
iframe2.parentNode.removeChild(iframe2);

// The expand should now be exposed.
assert_property(namedPropertiesObject, "f2", { writable: false, enumerable: false, configurable: true, value: "hello" }, "#3 namedPropertiesObject.f2");
}, "expando properties with the same as named properties can be set, but named properties will shadow it");

test(function() {
var namedPropertiesObject = Object.getPrototypeOf(Window.prototype);

// Define an expando property.
Object.defineProperty(namedPropertiesObject, "f3", { writable: false, enumerable: false, configurable: true, value: "hello" });

// Check that it's there.
assert_property(namedPropertiesObject, "f3", { writable: false, enumerable: false, configurable: true, value: "hello" }, "#1 namedPropertiesObject.f3");

// Cause a named property with the same name to start existing.
var e = document.createElement("iframe");
e.name = "f3";
hidden.appendChild(e);

// The named property should shadow the expando.
assert_property(namedPropertiesObject, "f3", { writable: false, enumerable: true, configurable: true, value: e.contentWindow }, "#2 namedPropertiesObject.f3");

// Remove the named property.
hidden.removeChild(e);

// The expando should be revealed.
assert_property(namedPropertiesObject, "f3", { writable: false, enumerable: false, configurable: true, value: "hello" }, "#3 namedPropertiesObject.f3");
}, "pre-existing expando properties are shadowed by named properties that start existing");

test(function() {
var namedPropertiesObject = Object.getPrototypeOf(Window.prototype);

// Define an expando property.
Object.defineProperty(namedPropertiesObject, "f4", { writable: false, enumerable: false, configurable: true, value: "hello" });

// Check that it's there.
assert_property(namedPropertiesObject, "f4", { writable: false, enumerable: false, configurable: true, value: "hello" }, "#1 namedPropertiesObject.f4");

// Cause a named property with the same name to start existing.
var e = document.createElement("iframe");
e.name = "f4";
hidden.appendChild(e);

// The named property should shadow the expando.
assert_property(namedPropertiesObject, "f4", { writable: false, enumerable: true, configurable: true, value: e.contentWindow }, "#2 namedPropertiesObject.f4");

// Remove the expando.
assert_true(delete namedPropertiesObject.f4, "delete namedPropertiesObject.f4");

// The named property should still be there.
assert_property(namedPropertiesObject, "f4", { writable: false, enumerable: true, configurable: true, value: e.contentWindow }, "#3 namedPropertiesObject.f4");

// Remove the named property.
hidden.removeChild(e);

// There shouldn't be anything there now.
assert_true(!Object.getOwnPropertyDescriptor(namedPropertiesObject, "f4"), "existence of namedPropertiesObject.f4");
}, "expando properties should be able to be removed while shadowed by a named property");

// XXX We probably shouldn't allow non-configurable properties to be defined
// on the named properties object: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21929
// Once that bug is resolved, we should test this.
</script>
100 changes: 100 additions & 0 deletions WebIDL/tests/submissions/heycam/class-string-001.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<!DOCTYPE html>
<title>Object.prototype.toString looks at class strings</title>
<script src="http://w3c-test.org/resources/testharness.js"></script>
<script src="http://w3c-test.org/resources/testharnessreport.js"></script>
<script src="utils.js"></script>
<div id="log"></div>

<script>
// 4.1 ECMAScript environment
//
// Object.prototype.toString is replaced with a function that looks at
// class strings.

var objects = [

// interface object
interfaceObject("DOMImplementation"), "Function", "DOMImplementation interface object",
interfaceObject("HTMLCollection"), "Function", "HTMLCollection interface object",

// interface object for inherited interface
interfaceObject("Element"), "Function", "Element interface object",
interfaceObject("UIEvent"), "Function", "UIEvent interface object",

// interface prototype object
interfacePrototypeObject("DOMImplementation"), "DOMImplementationPrototype", "DOMImplementation interface prototype object",
interfacePrototypeObject("HTMLCollection"), "HTMLCollectionPrototype", "HTMLCollection interface prototype object",

// interface prototype object for inherited interface
interfacePrototypeObject("Element"), "ElementPrototype", "Element interface prototype object",
interfacePrototypeObject("UIEvent"), "UIEventPrototype", "UIEvent interface prototype object",

// named constructor object
namedConstructorObject("Image"), "Function", "Image named constructor object",
namedConstructorObject("Audio"), "Function", "Audio named constructor object",

// attribute getter
getter("Document", "title"), "Function", "Document.title attribute getter",
getter("HTMLSelectElement", "length"), "Function", "HTMLSelectElement.length attribute getter",

// read only attribute getter
getter("Node", "parentNode"), "Function", "Node.parentNode attribute getter",
getter("HTMLFormElement", "length"), "Function", "HTMLFormElement.length attribute getter",

// attribute setter
setter("Document", "title"), "Function", "Document.title attribute setter",
setter("HTMLSelectElement", "length"), "Function", "HTMLSelectElement.length attribute setter",

// operation function
operation("HTMLElement", "click"), "Function", "HTMLElement.click function",
operation("Node", "appendChild"), "Function", "Node.appendChild function",

// stringifier function
stringifier("DOMTokenList"), "Function", "DOMTokenList stringifier function",

// exception interface object
interfaceObject("DOMException"), "Function", "DOMException exception interface object",

// exception interface prototype object
interfacePrototypeObject("DOMException"), "DOMException", "DOMException exception interface prototype object",

// exception field getter
getter("DOMException", "code"), "Function", "DOMException.code exception field getter",

// platform object implementing an interface
function() { return document.implementation; }, "DOMImplementation", "a platform object implementing DOMImplementation",
function() { return document.getElementsByTagName("div"); }, "HTMLCollection", "a platform object implementing HTMLCollection",

// platform object implementing an inherited interface
function() { return document.createElement("div"); }, "HTMLDivElement", "a platform object implementing Element",
function() { return document.createEvent("UIEvent"); }, "UIEvent", "a platform object implementing UIEvent",

// platform object representing an exception
function() {
try {
document.appendChild(document);
} catch (e) {
return e;
}
}, "DOMException", "a platform object representing a DOMException",

// platform array object
// XXX

// named properties object
function() { return Object.getPrototypeOf(Window.prototype); }, "WindowProperties", "named properties object"
];

var desc = Object.getOwnPropertyDescriptor(Object.prototype, "toString");
test(function() { assert_true(desc.writable); }, "Object.prototype.toString is [[Writable]]");
test(function() { assert_true(!desc.enumerable); }, "Object.prototype.toString is not [[Enumerable]]");
test(function() { assert_true(desc.configurable); }, "Object.prototype.toString is [[Configurable]]");

for (var i = 0; i < objects.length; i += 3) {
test(function() {
var object = objects[i]();
var classString = objects[i + 1];
assert_equals(Object.prototype.toString.call(object), "[object " + classString + "]");
}, objects[i + 2] + " responds correctly to Object.prototype.toString");
}
</script>
Loading