archives

« Bugzilla Issues Index

#10 — Some tests assume some non-standard properties ('window', 'document', 'ActiveXObject') exist


There's a number of tests which depend upon the 'window' or 'document' web browser hosts objects being present and will fail if they're not.

This assumption is incorrect as ES5 does not specify which host objects a JavaScript implementation must support. Furthermore, this implies we'll see many failures for console-based JavaScript interpreters.


Here are a couple of them (Based on Jeff Walden e-mail (https://mail.mozilla.org/pipermail/es5-discuss/2011-February/003915.html)):
* 15.2.3.6-3-263: Assumes the global object has a 'document' property.
* 15.2.3.6-4-354-4, 15.2.3.6-4-531-13, 15.2.3.6-4-531-4: depends on there being an object-valued "window" global variable.
* 15.2.3.6-4-401: depends on there being an ActiveXObject global property

The global object doesn't have to be called "window" in ES5-compliant environments.
A classic way to get the global object is to do:
var obj = (function(){return this;}).call();
Using undefined as the "this" argument of call makes that this evaluates to the global object. This was true in non-strict mode, this isn't anymore in strict mode for which I don't know how to retrieve the global object.

In general, I think that all tests attempting to test something on host objects should be removed. As said in ES5.1 8.6.2, "Every object (including host objects) must implement all of the internal properties listed in Table 8.". However, there is no constraint whatsoever in what should/should not happen with these implementation. There is at most a hope that host objects will roughly behave like native objects do, but that hope isn't testable.

Test regarding 'window' or 'document' had better being in a WebIDL (http://dev.w3.org/2006/webapi/WebIDL/) or DOM test suite.
The ActiveXObject has never been part of any standard I'd be aware of.


As said here (https://mail.mozilla.org/pipermail/es5-discuss/2011-February/003920.html), to retrieve the global object in an standard and interoperable way, you can do the following:

var o = Function("return this")();

Works in strict and non-strict mode as far as I can tell. Tested on FF4b11.


A search on "document." and "window." throughout Test Center contributions shows the following:
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-150.js(33): document.value = "document";
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-176.js(33): document.writable = true;
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-229.js(32): document.get = function () {
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-233.js(32): get: document.getElementsByTagName
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-259.js(33): document.set = function (value) {
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-263.js(32): set: document.getElementsByTagName
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-44.js(34): document.enumerable = true;
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-97.js(33): document.configurable = true;
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-4-44.js(38): delete document.foo;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.14\15.4.4.14-1-16.js(33): var oldLen = document.length;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.14\15.4.4.14-2-16.js(33): var oldLen = document.length;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.14\15.4.4.14-9-b-i-24.js(34): var oldLen = document.length;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.15\15.4.4.15-1-16.js(35): var oldLen = document.length;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.15\15.4.4.15-2-16.js(33): var oldLen = document.length;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.15\15.4.4.15-8-b-i-24.js(34): var oldLen = document.length;

test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-151.js(33): window.value = "window";
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-177.js(33): window.writable = true;
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-230.js(32): window.get = function () {
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-260.js(33): window.set = function (value) {
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-45.js(35): window.enumerable = true;
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-3-98.js(33): window.configurable = true;
test\suite\ietestcenter\chapter15\15.2\15.2.3\15.2.3.6\15.2.3.6-4-45.js(38): delete window.foo;
test\suite\ietestcenter\chapter15\15.4\15.4.4\15.4.4.19\15.4.4.19-5-1.js(31): window._15_4_4_19_5_1 = true;


Didn't look at all of them, but a number appear to be valid if they would just use the global object instead of document or window directly. Regardless, there are no checks present which let them pass if window/document do not exist => I'm disabling them for now.


For the record, another solution has been provided to retrieve the global object both in strict and non-strict mode:
https://mail.mozilla.org/pipermail/es5-discuss/2011-February/003925.html

var global = ("global", eval)("this");


I've (blindly) converted all references to 'window' to 'fnGlobalObject()' and will be pushing this to Test262 soon. That said, some tests still look fishy to me WRT their expectations on the global object:
- 15.2.3.13-2-29.js. Can we count on [[Extensible]]===true on the global object? I'd hope so...
- 15.2.3.5-4-124.js. Changing this.configurable to a new value. No safety checks
- 15.2.3.5-4-177.js. Very real chance this this.value already exists. No safety checks
- 15.2.3.5-4-203.js. Adding this.writable
- 15.2.3.5-4-256.js. Adding this.get
- 15.2.3.5-4-291.js. Adding this.set
- 15.2.3.5-4-71.js. Adding this.enumerable
- 15.2.3.6-3-151.js. Adding this.value
- 15.2.3.6-3-177.js. Adding this.writable
- 15.2.3.6-3-230.js. Adding this.get
- 15.2.3.6-3-260.js. Adding this.set
- 15.2.3.6-3-45.js. Adding this.enumerable
- 15.2.3.6-3-98.js. Adding this.configurable
- 15.2.3.6-4-354-4.js. Adding this.property
- 15.2.3.6-4-354-8.js. Adding this.prop
- 15.2.3.6-4-45.js. Adding this.foo
- 15.2.3.6-4-531-13.js. Adding this[0]
- 15.2.3.6-4-531-4.js. Adding this.property
- 15.2.3.7-2-18.js. Adding this.prop
- 15.2.3.7-5-b-137.js. Adding this.value
- 15.2.3.7-5-b-163.js. Adding this.writable
- 15.2.3.7-5-b-216.js. Adding this.get
- 15.2.3.7-5-b-31.js. Adding this.enumerable
- 15.2.3.7-5-b-84.js. Adding this.configurable
- 15.2.3.7-6-a-24.js. Adding this.prop
- 15.3.4.5-2-17.js. DEFINITELY NEEDS TO BE REWRITTEN. DEPENDENT UPON window.alert!
- 15.4.3.2-1-15.js. Can the global object be of Array type? I don't think so...
- 15.4.4.16-2-16.js. DEFINITELY INVALID. Depends on this.document
- 15.4.4.16-5-8.js. DEFINITELY INVALID. Depends on this.alert
- 15.4.4.17-2-16.js. DEFINITELY INVALID. Depends on this.document
- 15.4.4.17-5-8.js. DEFINITELY INVALID. Depends on this.alert
- 15.4.4.18-2-16.js. DEFINITELY INVALID. Depends on this.document
- 15.4.4.18-5-8.js. DEFINITELY INVALID. Depends on this.alert
- 15.4.4.19-2-16.js. DEFINITELY INVALID. Depends on this.document
- 15.4.4.20-2-16.js. DEFINITELY INVALID. Depends on this.document
- 15.4.4.20-5-8.js. DEFINITELY INVALID. Depends on this.alert
- 15.4.4.21-2-16.js. DEFINITELY INVALID. Depends on this.document
- 15.4.4.22-2-16.js. DEFINITELY INVALID. Depends on this.document



(In reply to comment #5)
> I've (blindly) converted all references to 'window' to 'fnGlobalObject()' and
> will be pushing this to Test262 soon. That said, some tests still look fishy
> to me WRT their expectations on the global object:
> - 15.2.3.13-2-29.js. Can we count on [[Extensible]]===true on the global
> object? I'd hope so...
I haven't found this test. Where is it?
Otherwise, ES5.1, section 15 Standard Built-in ECMAScript Objects, "Unless specified otherwise, the [[Extensible]] internal property of a built-in object initially has the value true."
In the section dealing with the global object (15.1), nothing is specified te negate this.

> - 15.2.3.5-4-124.js. Changing this.configurable to a new value. No safety
> checks
> - 15.2.3.5-4-177.js. Very real chance this this.value already exists. No
> safety checks
> - 15.2.3.5-4-203.js. Adding this.writable
> - 15.2.3.5-4-256.js. Adding this.get
> - 15.2.3.5-4-291.js. Adding this.set
> - 15.2.3.5-4-71.js. Adding this.enumerable
I haven't been able to find these tests either

> - 15.2.3.6-3-151.js. Adding this.value
> - 15.2.3.6-3-177.js. Adding this.writable
> - 15.2.3.6-3-230.js. Adding this.get
> - 15.2.3.6-3-260.js. Adding this.set
> - 15.2.3.6-3-45.js. Adding this.enumerable
> - 15.2.3.6-3-98.js. Adding this.configurable
> - 15.2.3.6-4-354-4.js. Adding this.property
> - 15.2.3.6-4-354-8.js. Adding this.prop
> - 15.2.3.6-4-45.js. Adding this.foo
> - 15.2.3.6-4-531-13.js. Adding this[0]
> - 15.2.3.6-4-531-4.js. Adding this.property
> - 15.2.3.7-2-18.js. Adding this.prop
> - 15.2.3.7-5-b-137.js. Adding this.value
> - 15.2.3.7-5-b-163.js. Adding this.writable
> - 15.2.3.7-5-b-216.js. Adding this.get
> - 15.2.3.7-5-b-31.js. Adding this.enumerable
> - 15.2.3.7-5-b-84.js. Adding this.configurable
> - 15.2.3.7-6-a-24.js. Adding this.prop
> - 15.3.4.5-2-17.js. DEFINITELY NEEDS TO BE REWRITTEN. DEPENDENT UPON
> window.alert!
> - 15.4.3.2-1-15.js. Can the global object be of Array type? I don't think
> so...
What do you mean by "Array type"?
- Since the global object is an object, typeof globalObject === "object" stands as a language invariant (it could actually be a test to add).
- Based on what is written in 15.1 "The values of the [[Prototype]] and [[Class]] internal properties of the global object are implementation-dependent.", we could imagine an implementation in which: [[Class]] be equal to "Array" which would make that "Array.isArray(globalObject) === true" and [[Prototype]] could be the native Array.prototype object which would make that "globalObject instanceOf Array === true".

So, my answer to your question is: yes, it could be of "Array type", but that's implementation-dependent so that shouldn't be considered in a test.

I cannot find most of the tests you mention. Are they under "/test/suite/ietestcenter/"?


The tests below currently absent from Test262 haven't gone through our internal process around releasing sources publically yet. I'm working on this now so it should happen soon. Of course the invalid tests identified below will not make the cut for Test262:)


All tests identified as having direct references to 'window' have either been updated to use a global object helper function or removed outright. If you notice anything I've inadvertantly missed, please reopen this bug or a file a new one. Thanks!


Reopening because test 15.2.3.6-4-401 (http://hg.ecmascript.org/tests/test262/file/93d928736a0d/test/suite/ietestcenter/chapter15/15.2/15.2.3/15.2.3.6/15.2.3.6-4-401.js) is in the test suite and shouldn't.
ActiveXObject is an IE-specific feature. Not part of any standard I know especially not ECMAScript


Looks like one of our internal tests slipped into IE Test Center/test262 by mistake. Removed from Hg a few minutes ago.

Double-checked that we're still good on 'window' and 'document', but I'm going to leave this bug open for the time being.


Test has been removed from the live website now as well. Thanks for spotting this David!


Closing hopefully for the last time.

We now have a small tool at tools/misc/InvalidTestDetector.py which should help catch many of these types of problems in the future.