/*
Distributed under both the W3C Test Suite License [1] and the W3C
3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
policies and contribution forms [3].

[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
[3] http://www.w3.org/2004/10/27-testcases
*/

/* For user documentation see docs/_writing-tests/idlharness.md */

/**
 * Notes for people who want to edit this file (not just use it as a library):
 *
 * Most of the interesting stuff happens in the derived classes of IdlObject,
 * especially IdlInterface.  The entry point for all IdlObjects is .test(),
 * which is called by IdlArray.test().  An IdlObject is conceptually just
 * "thing we want to run tests on", and an IdlArray is an array of IdlObjects
 * with some additional data thrown in.
 *
 * The object model is based on what WebIDLParser.js produces, which is in turn
 * based on its pegjs grammar.  If you want to figure out what properties an
 * object will have from WebIDLParser.js, the best way is to look at the
 * grammar:
 *
 *   https://github.com/darobin/webidl.js/blob/master/lib/grammar.peg
 *
 * So for instance:
 *
 *   // interface definition
 *   interface
 *       =   extAttrs:extendedAttributeList? S? "interface" S name:identifier w herit:ifInheritance? w "{" w mem:ifMember* w "}" w ";" w
 *           { return { type: "interface", name: name, inheritance: herit, members: mem, extAttrs: extAttrs }; }
 *
 * This means that an "interface" object will have a .type property equal to
 * the string "interface", a .name property equal to the identifier that the
 * parser found, an .inheritance property equal to either null or the result of
 * the "ifInheritance" production found elsewhere in the grammar, and so on.
 * After each grammatical production is a JavaScript function in curly braces
 * that gets called with suitable arguments and returns some JavaScript value.
 *
 * (Note that the version of WebIDLParser.js we use might sometimes be
 * out-of-date or forked.)
 *
 * The members and methods of the classes defined by this file are all at least
 * briefly documented, hopefully.
 */
(function(){
"use strict";
// Support subsetTestByKey from /common/subset-tests-by-key.js, but make it optional
if (!('subsetTestByKey' in self)) {
    self.subsetTestByKey = function(key, callback, ...args) {
      return callback(...args);
    }
    self.shouldRunSubTest = () => true;
}
/// Helpers ///
function constValue (cnt)
{
    if (cnt.type === "null") return null;
    if (cnt.type === "NaN") return NaN;
    if (cnt.type === "Infinity") return cnt.negative ? -Infinity : Infinity;
    if (cnt.type === "number") return +cnt.value;
    return cnt.value;
}

function minOverloadLength(overloads)
{
    // "The value of the Function object’s “length” property is
    // a Number determined as follows:
    // ". . .
    // "Return the length of the shortest argument list of the
    // entries in S."
    if (!overloads.length) {
        return 0;
    }

    return overloads.map(function(attr) {
        return attr.arguments ? attr.arguments.filter(function(arg) {
            return !arg.optional && !arg.variadic;
        }).length : 0;
    })
    .reduce(function(m, n) { return Math.min(m, n); });
}

function throwOrReject(a_test, operation, fn, obj, args, message, cb)
{
    if (operation.idlType.generic !== "Promise") {
        assert_throws(new TypeError(), function() {
            fn.apply(obj, args);
        }, message);
        cb();
    } else {
        try {
            promise_rejects(a_test, new TypeError(), fn.apply(obj, args), message).then(cb, cb);
        } catch (e){
            a_test.step(function() {
                assert_unreached("Throws \"" + e + "\" instead of rejecting promise");
                cb();
            });
        }
    }
}

function awaitNCallbacks(n, cb, ctx)
{
    var counter = 0;
    return function() {
        counter++;
        if (counter >= n) {
            cb();
        }
    };
}

var fround =
(function(){
    if (Math.fround) return Math.fround;

    var arr = new Float32Array(1);
    return function fround(n) {
        arr[0] = n;
        return arr[0];
    };
})();

/// IdlHarnessError ///
// Entry point
self.IdlHarnessError = function(message)
{
    /**
     * Message to be printed as the error's toString invocation.
     */
    this.message = message;
};

IdlHarnessError.prototype = Object.create(Error.prototype);

IdlHarnessError.prototype.toString = function()
{
    return this.message;
};


/// IdlArray ///
// Entry point
self.IdlArray = function()
{
    /**
     * A map from strings to the corresponding named IdlObject, such as
     * IdlInterface or IdlException.  These are the things that test() will run
     * tests on.
     */
    this.members = {};

    /**
     * A map from strings to arrays of strings.  The keys are interface or
     * exception names, and are expected to also exist as keys in this.members
     * (otherwise they'll be ignored).  This is populated by add_objects() --
     * see documentation at the start of the file.  The actual tests will be
     * run by calling this.members[name].test_object(obj) for each obj in
     * this.objects[name].  obj is a string that will be eval'd to produce a
     * JavaScript value, which is supposed to be an object implementing the
     * given IdlObject (interface, exception, etc.).
     */
    this.objects = {};

    /**
     * When adding multiple collections of IDLs one at a time, an earlier one
     * might contain a partial interface or implements statement that depends
     * on a later one.  Save these up and handle them right before we run
     * tests.
     *
     * .partials is simply an array of objects from WebIDLParser.js'
     * "partialinterface" production.  .implements maps strings to arrays of
     * strings, such that
     *
     *   A implements B;
     *   A implements C;
     *   D implements E;
     *
     * results in this["implements"] = { A: ["B", "C"], D: ["E"] }.
     *
     * Similarly,
     *
     *   interface A : B {};
     *   interface B : C {};
     *
     * results in this["inheritance"] = { A: "B", B: "C" }
     */
    this.partials = [];
    this["implements"] = {};
    this["includes"] = {};
    this["inheritance"] = {};

    /**
     * Record of skipped IDL items, in case we later realize that they are a
     * dependency (to retroactively process them).
     */
    this.skipped = new Map();
};

IdlArray.prototype.add_idls = function(raw_idls, options)
{
    /** Entry point.  See documentation at beginning of file. */
    this.internal_add_idls(WebIDL2.parse(raw_idls), options);
};

IdlArray.prototype.add_untested_idls = function(raw_idls, options)
{
    /** Entry point.  See documentation at beginning of file. */
    var parsed_idls = WebIDL2.parse(raw_idls);
    this.mark_as_untested(parsed_idls);
    this.internal_add_idls(parsed_idls, options);
};

IdlArray.prototype.mark_as_untested = function (parsed_idls)
{
    for (var i = 0; i < parsed_idls.length; i++) {
        parsed_idls[i].untested = true;
        if ("members" in parsed_idls[i]) {
            for (var j = 0; j < parsed_idls[i].members.length; j++) {
                parsed_idls[i].members[j].untested = true;
            }
        }
    }
};

IdlArray.prototype.is_excluded_by_options = function (name, options)
{
    return options &&
        (options.except && options.except.includes(name)
         || options.only && !options.only.includes(name));
};

IdlArray.prototype.add_dependency_idls = function(raw_idls, options)
{
    const parsed_idls = WebIDL2.parse(raw_idls);
    const new_options = { only: [] }

    const all_deps = new Set();
    Object.values(this.inheritance).forEach(v => all_deps.add(v));
    Object.entries(this.implements).forEach(([k, v]) => {
        all_deps.add(k);
        all_deps.add(v);
    });
    // NOTE: If 'A includes B' for B that we care about, then A is also a dep.
    Object.keys(this.includes).forEach(k => {
        all_deps.add(k);
        this.includes[k].forEach(v => all_deps.add(v));
    });
    this.partials.forEach(p => all_deps.add(p.name));
    // Add 'TypeOfType' for each "typedef TypeOfType MyType;" entry.
    Object.entries(this.members).forEach(([k, v]) => {
        if (v instanceof IdlTypedef) {
            let defs = v.idlType.union
                ? v.idlType.idlType.map(t => t.idlType)
                : [v.idlType.idlType];
            defs.forEach(d => all_deps.add(d));
        }
    });

    // Add the attribute idlTypes of all the nested members of idls.
    const attrDeps = parsedIdls => {
        return parsedIdls.reduce((deps, parsed) => {
            if (parsed.members) {
                for (const attr of Object.values(parsed.members).filter(m => m.type === 'attribute')) {
                    let attrType = attr.idlType;
                    // Check for generic members (e.g. FrozenArray<MyType>)
                    if (attrType.generic) {
                        deps.add(attrType.generic);
                        attrType = attrType.idlType;
                    }
                    deps.add(attrType.idlType);
                }
            }
            if (parsed.base in this.members) {
                attrDeps([this.members[parsed.base]]).forEach(dep => deps.add(dep));
            }
            return deps;
        }, new Set());
    };

    const testedMembers = Object.values(this.members).filter(m => !m.untested && m.members);
    attrDeps(testedMembers).forEach(dep => all_deps.add(dep));

    const testedPartials = this.partials.filter(m => !m.untested && m.members);
    attrDeps(testedPartials).forEach(dep => all_deps.add(dep));


    if (options && options.except && options.only) {
        throw new IdlHarnessError("The only and except options can't be used together.");
    }

    const defined_or_untested = name => {
        // NOTE: Deps are untested, so we're lenient, and skip re-encountered definitions.
        // e.g. for 'idl' containing A:B, B:C, C:D
        //      array.add_idls(idl, {only: ['A','B']}).
        //      array.add_dependency_idls(idl);
        // B would be encountered as tested, and encountered as a dep, so we ignore.
        return name in this.members
            || this.is_excluded_by_options(name, options);
    }
    // Maps name -> [parsed_idl, ...]
    const process = function(parsed) {
        var deps = [];
        if (parsed.name) {
            deps.push(parsed.name);
        } else if (parsed.type === "implements") {
            deps.push(parsed.target);
            deps.push(parsed.implements);
        } else if (parsed.type === "includes") {
            deps.push(parsed.target);
            deps.push(parsed.includes);
        }

        deps = deps.filter(function(name) {
            if (!name
                || name === parsed.name && defined_or_untested(name)
                || !all_deps.has(name)) {
                // Flag as skipped, if it's not already processed, so we can
                // come back to it later if we retrospectively call it a dep.
                if (name && !(name in this.members)) {
                    this.skipped.has(name)
                        ? this.skipped.get(name).push(parsed)
                        : this.skipped.set(name, [parsed]);
                }
                return false;
            }
            return true;
        }.bind(this));

        deps.forEach(function(name) {
            if (!new_options.only.includes(name)) {
                new_options.only.push(name);
            }

            const follow_up = new Set();
            for (const dep_type of ["inheritance", "implements", "includes"]) {
                if (parsed[dep_type]) {
                    const inheriting = parsed[dep_type];
                    const inheritor = parsed.name || parsed.target;
                    const deps = [inheriting];
                    // For A includes B, we can ignore A, unless B (or some of its
                    // members) is being tested.
                    if (dep_type !== "includes"
                        || inheriting in this.members && !this.members[inheriting].untested
                        || this.partials.some(function(p) {
                                return p.name === inheriting;
                            })) {
                        deps.push(inheritor);
                    }
                    for (const dep of deps) {
                        if (!new_options.only.includes(dep)) {
                            new_options.only.push(dep);
                        }
                        all_deps.add(dep);
                        follow_up.add(dep);
                    }
                }
            }

            for (const deferred of follow_up) {
                if (this.skipped.has(deferred)) {
                    const next = this.skipped.get(deferred);
                    this.skipped.delete(deferred);
                    next.forEach(process);
                }
            }
        }.bind(this));
    }.bind(this);

    for (let parsed of parsed_idls) {
        process(parsed);
    }

    this.mark_as_untested(parsed_idls);

    if (new_options.only.length) {
        this.internal_add_idls(parsed_idls, new_options);
    }
}

IdlArray.prototype.internal_add_idls = function(parsed_idls, options)
{
    /**
     * Internal helper called by add_idls() and add_untested_idls().
     *
     * parsed_idls is an array of objects that come from WebIDLParser.js's
     * "definitions" production.  The add_untested_idls() entry point
     * additionally sets an .untested property on each object (and its
     * .members) so that they'll be skipped by test() -- they'll only be
     * used for base interfaces of tested interfaces, return types, etc.
     *
     * options is a dictionary that can have an only or except member which are
     * arrays. If only is given then only members, partials and interface
     * targets listed will be added, and if except is given only those that
     * aren't listed will be added. Only one of only and except can be used.
     */

    if (options && options.only && options.except)
    {
        throw new IdlHarnessError("The only and except options can't be used together.");
    }

    var should_skip = name => {
        return this.is_excluded_by_options(name, options);
    }

    parsed_idls.forEach(function(parsed_idl)
    {
        var partial_types = [
            "interface",
            "interface mixin",
            "dictionary",
            "namespace",
        ];
        if (parsed_idl.partial && partial_types.includes(parsed_idl.type))
        {
            if (should_skip(parsed_idl.name))
            {
                return;
            }
            this.partials.push(parsed_idl);
            return;
        }

        if (parsed_idl.type == "implements")
        {
            if (should_skip(parsed_idl.target))
            {
                return;
            }
            if (!(parsed_idl.target in this["implements"]))
            {
                this["implements"][parsed_idl.target] = [];
            }
            this["implements"][parsed_idl.target].push(parsed_idl["implements"]);
            return;
        }

        if (parsed_idl.type == "includes")
        {
            if (should_skip(parsed_idl.target))
            {
                return;
            }
            if (!(parsed_idl.target in this["includes"]))
            {
                this["includes"][parsed_idl.target] = [];
            }
            this["includes"][parsed_idl.target].push(parsed_idl["includes"]);
            return;
        }

        parsed_idl.array = this;
        if (should_skip(parsed_idl.name))
        {
            return;
        }
        if (parsed_idl.name in this.members)
        {
            throw new IdlHarnessError("Duplicate identifier " + parsed_idl.name);
        }

        if (parsed_idl["inheritance"]) {
            // NOTE: Clash should be impossible (would require redefinition of parsed_idl.name).
            if (parsed_idl.name in this["inheritance"]
                && parsed_idl["inheritance"] != this["inheritance"][parsed_idl.name]) {
                throw new IdlHarnessError(
                    `Inheritance for ${parsed_idl.name} was already defined`);
            }
            this["inheritance"][parsed_idl.name] = parsed_idl["inheritance"];
        }

        switch(parsed_idl.type)
        {
        case "interface":
            this.members[parsed_idl.name] =
                new IdlInterface(parsed_idl, /* is_callback = */ false, /* is_mixin = */ false);
            break;

        case "interface mixin":
            this.members[parsed_idl.name] =
                new IdlInterface(parsed_idl, /* is_callback = */ false, /* is_mixin = */ true);
            break;

        case "dictionary":
            // Nothing to test, but we need the dictionary info around for type
            // checks
            this.members[parsed_idl.name] = new IdlDictionary(parsed_idl);
            break;

        case "typedef":
            this.members[parsed_idl.name] = new IdlTypedef(parsed_idl);
            break;

        case "callback":
            this.members[parsed_idl.name] = new IdlCallback(parsed_idl);
            break;

        case "enum":
            this.members[parsed_idl.name] = new IdlEnum(parsed_idl);
            break;

        case "callback interface":
            this.members[parsed_idl.name] =
                new IdlInterface(parsed_idl, /* is_callback = */ true, /* is_mixin = */ false);
            break;

        case "namespace":
            this.members[parsed_idl.name] = new IdlNamespace(parsed_idl);
            break;

        default:
            throw parsed_idl.name + ": " + parsed_idl.type + " not yet supported";
        }
    }.bind(this));
};

IdlArray.prototype.add_objects = function(dict)
{
    /** Entry point.  See documentation at beginning of file. */
    for (var k in dict)
    {
        if (k in this.objects)
        {
            this.objects[k] = this.objects[k].concat(dict[k]);
        }
        else
        {
            this.objects[k] = dict[k];
        }
    }
};

IdlArray.prototype.prevent_multiple_testing = function(name)
{
    /** Entry point.  See documentation at beginning of file. */
    this.members[name].prevent_multiple_testing = true;
};

IdlArray.prototype.recursively_get_implements = function(interface_name)
{
    /**
     * Helper function for test().  Returns an array of things that implement
     * interface_name, so if the IDL contains
     *
     *   A implements B;
     *   B implements C;
     *   B implements D;
     *
     * then recursively_get_implements("A") should return ["B", "C", "D"].
     */
    var ret = this["implements"][interface_name];
    if (ret === undefined)
    {
        return [];
    }
    for (var i = 0; i < this["implements"][interface_name].length; i++)
    {
        ret = ret.concat(this.recursively_get_implements(ret[i]));
        if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i]))
        {
            throw new IdlHarnessError("Circular implements statements involving " + ret[i]);
        }
    }
    return ret;
};

IdlArray.prototype.recursively_get_includes = function(interface_name)
{
    /**
     * Helper function for test().  Returns an array of things that implement
     * interface_name, so if the IDL contains
     *
     *   A includes B;
     *   B includes C;
     *   B includes D;
     *
     * then recursively_get_includes("A") should return ["B", "C", "D"].
     */
    var ret = this["includes"][interface_name];
    if (ret === undefined)
    {
        return [];
    }
    for (var i = 0; i < this["includes"][interface_name].length; i++)
    {
        ret = ret.concat(this.recursively_get_includes(ret[i]));
        if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i]))
        {
            throw new IdlHarnessError("Circular includes statements involving " + ret[i]);
        }
    }
    return ret;
};

IdlArray.prototype.is_json_type = function(type)
{
    /**
     * Checks whether type is a JSON type as per
     * https://heycam.github.io/webidl/#dfn-json-types
     */

    var idlType = type.idlType;

    if (type.generic == "Promise") { return false; }

    //  nullable and annotated types don't need to be handled separately,
    //  as webidl2 doesn't represent them wrapped-up (as they're described
    //  in WebIDL).

    // union and record types
    if (type.union || type.generic == "record") {
        return idlType.every(this.is_json_type, this);
    }

    // sequence types
    if (type.generic == "sequence" || type.generic == "FrozenArray") {
        return this.is_json_type(idlType[0]);
    }

    if (typeof idlType != "string") { throw new Error("Unexpected type " + JSON.stringify(idlType)); }

    switch (idlType)
    {
       //  Numeric types
       case "byte":
       case "octet":
       case "short":
       case "unsigned short":
       case "long":
       case "unsigned long":
       case "long long":
       case "unsigned long long":
       case "float":
       case "double":
       case "unrestricted float":
       case "unrestricted double":
       // boolean
       case "boolean":
       // string types
       case "DOMString":
       case "ByteString":
       case "USVString":
       // object type
       case "object":
           return true;
       case "Error":
       case "DOMException":
       case "Int8Array":
       case "Int16Array":
       case "Int32Array":
       case "Uint8Array":
       case "Uint16Array":
       case "Uint32Array":
       case "Uint8ClampedArray":
       case "Float32Array":
       case "ArrayBuffer":
       case "DataView":
       case "any":
           return false;
       default:
           var thing = this.members[idlType];
           if (!thing) { throw new Error("Type " + idlType + " not found"); }
           if (thing instanceof IdlEnum) { return true; }

           if (thing instanceof IdlTypedef) {
               return this.is_json_type(thing.idlType);
           }

           //  dictionaries where all of their members are JSON types
           if (thing instanceof IdlDictionary) {
               var stack = thing.get_inheritance_stack();
               var map = new Map();
               while (stack.length)
               {
                   stack.pop().members.forEach(function(m) {
                       map.set(m.name, m.idlType)
                   });
               }
               return Array.from(map.values()).every(this.is_json_type, this);
           }

           //  interface types that have a toJSON operation declared on themselves or
           //  one of their inherited or consequential interfaces.
           if (thing instanceof IdlInterface) {
               var base;
               while (thing)
               {
                   if (thing.has_to_json_regular_operation()) { return true; }
                   var mixins = this.implements[thing.name] || this.includes[thing.name];
                   if (mixins) {
                       mixins = mixins.map(function(id) {
                           var mixin = this.members[id];
                           if (!mixin) {
                               throw new Error("Interface " + id + " not found (implemented by " + thing.name + ")");
                           }
                           return mixin;
                       }, this);
                       if (mixins.some(function(m) { return m.has_to_json_regular_operation() } )) { return true; }
                   }
                   if (!thing.base) { return false; }
                   base = this.members[thing.base];
                   if (!base) {
                       throw new Error("Interface " + thing.base + " not found (inherited by " + thing.name + ")");
                   }
                   thing = base;
               }
               return false;
           }
           return false;
    }
};

function exposure_set(object, default_set) {
    var exposed = object.extAttrs && object.extAttrs.filter(a => a.name === "Exposed");
    if (exposed && exposed.length > 1) {
        throw new IdlHarnessError(
            `Multiple 'Exposed' extended attributes on ${object.name}`);
    }

    let result = default_set || ["Window"];
    if (result && !(result instanceof Set)) {
        result = new Set(result);
    }
    if (exposed && exposed.length) {
        const { rhs } = exposed[0];
        // Could be a list or a string.
        const set = rhs.type === "identifier-list" ?
            rhs.value.map(id => id.value) :
            [ rhs.value ];
        result = new Set(set);
    }
    if (result && result.has("Worker")) {
        result.delete("Worker");
        result.add("DedicatedWorker");
        result.add("ServiceWorker");
        result.add("SharedWorker");
    }
    return result;
}

function exposed_in(globals) {
    if ('document' in self) {
        return globals.has("Window");
    }
    if ('DedicatedWorkerGlobalScope' in self &&
        self instanceof DedicatedWorkerGlobalScope) {
        return globals.has("DedicatedWorker");
    }
    if ('SharedWorkerGlobalScope' in self &&
        self instanceof SharedWorkerGlobalScope) {
        return globals.has("SharedWorker");
    }
    if ('ServiceWorkerGlobalScope' in self &&
        self instanceof ServiceWorkerGlobalScope) {
        return globals.has("ServiceWorker");
    }
    throw new IdlHarnessError("Unexpected global object");
}

/**
 * Asserts that the given error message is thrown for the given function.
 * @param {string|IdlHarnessError} error Expected Error message.
 * @param {Function} idlArrayFunc Function operating on an IdlArray that should throw.
 */
IdlArray.prototype.assert_throws = function(error, idlArrayFunc)
{
    try {
        idlArrayFunc.call(this, this);
    } catch (e) {
        if (e instanceof AssertionError) {
            throw e;
        }
        // Assertions for behaviour of the idlharness.js engine.
        if (error instanceof IdlHarnessError) {
            error = error.message;
        }
        if (e.message !== error) {
            throw new IdlHarnessError(`${idlArrayFunc} threw "${e}", not the expected IdlHarnessError "${error}"`);
        }
        return;
    }
    throw new IdlHarnessError(`${idlArrayFunc} did not throw the expected IdlHarnessError`);
}

IdlArray.prototype.test = function()
{
    /** Entry point.  See documentation at beginning of file. */

    // First merge in all the partial interfaces and implements statements we
    // encountered.
    this.collapse_partials();

    for (var lhs in this["implements"])
    {
        this.recursively_get_implements(lhs).forEach(function(rhs)
        {
            var errStr = lhs + " implements " + rhs + ", but ";
            if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";
            if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";
            if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";
            if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";
            this.members[rhs].members.forEach(function(member)
            {
                this.members[lhs].members.push(new IdlInterfaceMember(member));
            }.bind(this));
        }.bind(this));
    }
    this["implements"] = {};

    for (var lhs in this["includes"])
    {
        this.recursively_get_includes(lhs).forEach(function(rhs)
        {
            var errStr = lhs + " includes " + rhs + ", but ";
            if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";
            if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";
            if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";
            if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";
            this.members[rhs].members.forEach(function(member)
            {
                this.members[lhs].members.push(new IdlInterfaceMember(member));
            }.bind(this));
        }.bind(this));
    }
    this["includes"] = {};

    // Assert B defined for A : B
    for (const member of Object.values(this.members).filter(m => m.base)) {
        const lhs = member.name;
        const rhs = member.base;
        if (!(rhs in this.members)) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is undefined.`);
        const lhs_is_interface = this.members[lhs] instanceof IdlInterface;
        const rhs_is_interface = this.members[rhs] instanceof IdlInterface;
        if (rhs_is_interface != lhs_is_interface) {
            if (!lhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${lhs} is not an interface.`);
            if (!rhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is not an interface.`);
        }
        // Check for circular dependencies.
        member.get_inheritance_stack();
    }

    Object.getOwnPropertyNames(this.members).forEach(function(memberName) {
        var member = this.members[memberName];
        if (!(member instanceof IdlInterface)) {
            return;
        }

        var globals = exposure_set(member);
        member.exposed = exposed_in(globals);
        member.exposureSet = globals;
    }.bind(this));

    // Now run test() on every member, and test_object() for every object.
    for (var name in this.members)
    {
        this.members[name].test();
        if (name in this.objects)
        {
            const objects = this.objects[name];
            if (!objects || !Array.isArray(objects)) {
                throw new IdlHarnessError(`Invalid or empty objects for member ${name}`);
            }
            objects.forEach(function(str)
            {
                if (!this.members[name] || !(this.members[name] instanceof IdlInterface)) {
                    throw new IdlHarnessError(`Invalid object member name ${name}`);
                }
                this.members[name].test_object(str);
            }.bind(this));
        }
    }
};

IdlArray.prototype.collapse_partials = function()
{
    const testedPartials = new Map();
    this.partials.forEach(function(parsed_idl)
    {
        const originalExists = parsed_idl.name in this.members
            && (this.members[parsed_idl.name] instanceof IdlInterface
                || this.members[parsed_idl.name] instanceof IdlDictionary
                || this.members[parsed_idl.name] instanceof IdlNamespace);

        let partialTestName = parsed_idl.name;
        if (!parsed_idl.untested) {
            // Ensure unique test name in case of multiple partials.
            let partialTestCount = 1;
            if (testedPartials.has(parsed_idl.name)) {
                partialTestCount += testedPartials.get(parsed_idl.name);
                partialTestName = `${partialTestName}[${partialTestCount}]`;
            }
            testedPartials.set(parsed_idl.name, partialTestCount);

            test(function () {
                assert_true(originalExists, `Original ${parsed_idl.type} should be defined`);

                var expected = IdlInterface;
                switch (parsed_idl.type) {
                    case 'interface': expected = IdlInterface; break;
                    case 'dictionary': expected = IdlDictionary; break;
                    case 'namespace': expected = IdlNamespace; break;
                }
                assert_true(
                    expected.prototype.isPrototypeOf(this.members[parsed_idl.name]),
                    `Original ${parsed_idl.name} definition should have type ${parsed_idl.type}`);
            }.bind(this), `Partial ${parsed_idl.type} ${partialTestName}: original ${parsed_idl.type} defined`);
        }
        if (!originalExists) {
            // Not good.. but keep calm and carry on.
            return;
        }

        if (parsed_idl.extAttrs)
        {
            // Special-case "Exposed". Must be a subset of original interface's exposure.
            // Exposed on a partial is the equivalent of having the same Exposed on all nested members.
            // See https://github.com/heycam/webidl/issues/154 for discrepency between Exposed and
            // other extended attributes on partial interfaces.
            const exposureAttr = parsed_idl.extAttrs.find(a => a.name === "Exposed");
            if (exposureAttr) {
                if (!parsed_idl.untested) {
                    test(function () {
                        const partialExposure = exposure_set(parsed_idl);
                        const memberExposure = exposure_set(this.members[parsed_idl.name]);
                        partialExposure.forEach(name => {
                            if (!memberExposure || !memberExposure.has(name)) {
                                throw new IdlHarnessError(
                                    `Partial ${parsed_idl.name} ${parsed_idl.type} is exposed to '${name}', the original ${parsed_idl.type} is not.`);
                            }
                        });
                    }.bind(this), `Partial ${parsed_idl.type} ${partialTestName}: valid exposure set`);
                }
                parsed_idl.members.forEach(function (member) {
                    member.extAttrs.push(exposureAttr);
                }.bind(this));
            }

            parsed_idl.extAttrs.forEach(function(extAttr)
            {
                // "Exposed" already handled above.
                if (extAttr.name === "Exposed") {
                    return;
                }
                this.members[parsed_idl.name].extAttrs.push(extAttr);
            }.bind(this));
        }
        parsed_idl.members.forEach(function(member)
        {
            this.members[parsed_idl.name].members.push(new IdlInterfaceMember(member));
        }.bind(this));
    }.bind(this));
    this.partials = [];
}

IdlArray.prototype.assert_type_is = function(value, type)
{
    if (type.idlType in this.members
    && this.members[type.idlType] instanceof IdlTypedef) {
        this.assert_type_is(value, this.members[type.idlType].idlType);
        return;
    }
    if (type.union) {
        for (var i = 0; i < type.idlType.length; i++) {
            try {
                this.assert_type_is(value, type.idlType[i]);
                // No AssertionError, so we match one type in the union
                return;
            } catch(e) {
                if (e instanceof AssertionError) {
                    // We didn't match this type, let's try some others
                    continue;
                }
                throw e;
            }
        }
        // TODO: Is there a nice way to list the union's types in the message?
        assert_true(false, "Attribute has value " + format_value(value)
                    + " which doesn't match any of the types in the union");

    }

    /**
     * Helper function that tests that value is an instance of type according
     * to the rules of WebIDL.  value is any JavaScript value, and type is an
     * object produced by WebIDLParser.js' "type" production.  That production
     * is fairly elaborate due to the complexity of WebIDL's types, so it's
     * best to look at the grammar to figure out what properties it might have.
     */
    if (type.idlType == "any")
    {
        // No assertions to make
        return;
    }

    if (type.nullable && value === null)
    {
        // This is fine
        return;
    }

    if (type.array)
    {
        // TODO: not supported yet
        return;
    }

    if (type.generic === "sequence")
    {
        assert_true(Array.isArray(value), "should be an Array");
        if (!value.length)
        {
            // Nothing we can do.
            return;
        }
        this.assert_type_is(value[0], type.idlType[0]);
        return;
    }

    if (type.generic === "Promise") {
        assert_true("then" in value, "Attribute with a Promise type should have a then property");
        // TODO: Ideally, we would check on project fulfillment
        // that we get the right type
        // but that would require making the type check async
        return;
    }

    if (type.generic === "FrozenArray") {
        assert_true(Array.isArray(value), "Value should be array");
        assert_true(Object.isFrozen(value), "Value should be frozen");
        if (!value.length)
        {
            // Nothing we can do.
            return;
        }
        this.assert_type_is(value[0], type.idlType[0]);
        return;
    }

    type = Array.isArray(type.idlType) ? type.idlType[0] : type.idlType;

    switch(type)
    {
        case "void":
            assert_equals(value, undefined);
            return;

        case "boolean":
            assert_equals(typeof value, "boolean");
            return;

        case "byte":
            assert_equals(typeof value, "number");
            assert_equals(value, Math.floor(value), "should be an integer");
            assert_true(-128 <= value && value <= 127, "byte " + value + " should be in range [-128, 127]");
            return;

        case "octet":
            assert_equals(typeof value, "number");
            assert_equals(value, Math.floor(value), "should be an integer");
            assert_true(0 <= value && value <= 255, "octet " + value + " should be in range [0, 255]");
            return;

        case "short":
            assert_equals(typeof value, "number");
            assert_equals(value, Math.floor(value), "should be an integer");
            assert_true(-32768 <= value && value <= 32767, "short " + value + " should be in range [-32768, 32767]");
            return;

        case "unsigned short":
            assert_equals(typeof value, "number");
            assert_equals(value, Math.floor(value), "should be an integer");
            assert_true(0 <= value && value <= 65535, "unsigned short " + value + " should be in range [0, 65535]");
            return;

        case "long":
            assert_equals(typeof value, "number");
            assert_equals(value, Math.floor(value), "should be an integer");
            assert_true(-2147483648 <= value && value <= 2147483647, "long " + value + " should be in range [-2147483648, 2147483647]");
            return;

        case "unsigned long":
            assert_equals(typeof value, "number");
            assert_equals(value, Math.floor(value), "should be an integer");
            assert_true(0 <= value && value <= 4294967295, "unsigned long " + value + " should be in range [0, 4294967295]");
            return;

        case "long long":
            assert_equals(typeof value, "number");
            return;

        case "unsigned long long":
        case "DOMTimeStamp":
            assert_equals(typeof value, "number");
            assert_true(0 <= value, "unsigned long long should be positive");
            return;

        case "float":
            assert_equals(typeof value, "number");
            assert_equals(value, fround(value), "float rounded to 32-bit float should be itself");
            assert_not_equals(value, Infinity);
            assert_not_equals(value, -Infinity);
            assert_not_equals(value, NaN);
            return;

        case "DOMHighResTimeStamp":
        case "double":
            assert_equals(typeof value, "number");
            assert_not_equals(value, Infinity);
            assert_not_equals(value, -Infinity);
            assert_not_equals(value, NaN);
            return;

        case "unrestricted float":
            assert_equals(typeof value, "number");
            assert_equals(value, fround(value), "unrestricted float rounded to 32-bit float should be itself");
            return;

        case "unrestricted double":
            assert_equals(typeof value, "number");
            return;

        case "DOMString":
            assert_equals(typeof value, "string");
            return;

        case "ByteString":
            assert_equals(typeof value, "string");
            assert_regexp_match(value, /^[\x00-\x7F]*$/);
            return;

        case "USVString":
            assert_equals(typeof value, "string");
            assert_regexp_match(value, /^([\x00-\ud7ff\ue000-\uffff]|[\ud800-\udbff][\udc00-\udfff])*$/);
            return;

        case "object":
            assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");
            return;
    }

    if (!(type in this.members))
    {
        throw new IdlHarnessError("Unrecognized type " + type);
    }

    if (this.members[type] instanceof IdlInterface)
    {
        // We don't want to run the full
        // IdlInterface.prototype.test_instance_of, because that could result
        // in an infinite loop.  TODO: This means we don't have tests for
        // NoInterfaceObject interfaces, and we also can't test objects that
        // come from another self.
        assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");
        if (value instanceof Object
        && !this.members[type].has_extended_attribute("NoInterfaceObject")
        && type in self)
        {
            assert_true(value instanceof self[type], "instanceof " + type);
        }
    }
    else if (this.members[type] instanceof IdlEnum)
    {
        assert_equals(typeof value, "string");
    }
    else if (this.members[type] instanceof IdlDictionary)
    {
        // TODO: Test when we actually have something to test this on
    }
    else if (this.members[type] instanceof IdlCallback)
    {
        assert_equals(typeof value, "function");
    }
    else
    {
        throw new IdlHarnessError("Type " + type + " isn't an interface, callback or dictionary");
    }
};

/// IdlObject ///
function IdlObject() {}
IdlObject.prototype.test = function()
{
    /**
     * By default, this does nothing, so no actual tests are run for IdlObjects
     * that don't define any (e.g., IdlDictionary at the time of this writing).
     */
};

IdlObject.prototype.has_extended_attribute = function(name)
{
    /**
     * This is only meaningful for things that support extended attributes,
     * such as interfaces, exceptions, and members.
     */
    return this.extAttrs.some(function(o)
    {
        return o.name == name;
    });
};


/// IdlDictionary ///
// Used for IdlArray.prototype.assert_type_is
function IdlDictionary(obj)
{
    /**
     * obj is an object produced by the WebIDLParser.js "dictionary"
     * production.
     */

    /** Self-explanatory. */
    this.name = obj.name;

    /** A back-reference to our IdlArray. */
    this.array = obj.array;

    /** An array of objects produced by the "dictionaryMember" production. */
    this.members = obj.members;

    /**
     * The name (as a string) of the dictionary type we inherit from, or null
     * if there is none.
     */
    this.base = obj.inheritance;
}

IdlDictionary.prototype = Object.create(IdlObject.prototype);

IdlDictionary.prototype.get_inheritance_stack = function() {
    return IdlInterface.prototype.get_inheritance_stack.call(this);
};

/// IdlInterface ///
function IdlInterface(obj, is_callback, is_mixin)
{
    /**
     * obj is an object produced by the WebIDLParser.js "interface" production.
     */

    /** Self-explanatory. */
    this.name = obj.name;

    /** A back-reference to our IdlArray. */
    this.array = obj.array;

    /**
     * An indicator of whether we should run tests on the interface object and
     * interface prototype object. Tests on members are controlled by .untested
     * on each member, not this.
     */
    this.untested = obj.untested;

    /** An array of objects produced by the "ExtAttr" production. */
    this.extAttrs = obj.extAttrs;

    /** An array of IdlInterfaceMembers. */
    this.members = obj.members.map(function(m){return new IdlInterfaceMember(m); });
    if (this.has_extended_attribute("Unforgeable")) {
        this.members
            .filter(function(m) { return m.special !== "static" && (m.type == "attribute" || m.type == "operation"); })
            .forEach(function(m) { return m.isUnforgeable = true; });
    }

    /**
     * The name (as a string) of the type we inherit from, or null if there is
     * none.
     */
    this.base = obj.inheritance;

    this._is_callback = is_callback;
    this._is_mixin = is_mixin;
}
IdlInterface.prototype = Object.create(IdlObject.prototype);
IdlInterface.prototype.is_callback = function()
{
    return this._is_callback;
};

IdlInterface.prototype.is_mixin = function()
{
    return this._is_mixin;
};

IdlInterface.prototype.has_constants = function()
{
    return this.members.some(function(member) {
        return member.type === "const";
    });
};

IdlInterface.prototype.get_unscopables = function()
{
    return this.members.filter(function(member) {
        return member.isUnscopable;
    });
};

IdlInterface.prototype.is_global = function()
{
    return this.extAttrs.some(function(attribute) {
        return attribute.name === "Global";
    });
};

/**
 * Value of the LegacyNamespace extended attribute, if any.
 *
 * https://heycam.github.io/webidl/#LegacyNamespace
 */
IdlInterface.prototype.get_legacy_namespace = function()
{
    var legacyNamespace = this.extAttrs.find(function(attribute) {
        return attribute.name === "LegacyNamespace";
    });
    return legacyNamespace ? legacyNamespace.rhs.value : undefined;
};

IdlInterface.prototype.get_interface_object_owner = function()
{
    var legacyNamespace = this.get_legacy_namespace();
    return legacyNamespace ? self[legacyNamespace] : self;
};

IdlInterface.prototype.assert_interface_object_exists = function()
{
    var owner = this.get_legacy_namespace() || "self";
    assert_own_property(self[owner], this.name, owner + " does not have own property " + format_value(this.name));
};

IdlInterface.prototype.get_interface_object = function() {
    if (this.has_extended_attribute("NoInterfaceObject")) {
        throw new IdlHarnessError(this.name + " has no interface object due to NoInterfaceObject");
    }

    return this.get_interface_object_owner()[this.name];
};

IdlInterface.prototype.get_qualified_name = function() {
    // https://heycam.github.io/webidl/#qualified-name
    var legacyNamespace = this.get_legacy_namespace();
    if (legacyNamespace) {
        return legacyNamespace + "." + this.name;
    }
    return this.name;
};

IdlInterface.prototype.has_to_json_regular_operation = function() {
    return this.members.some(function(m) {
        return m.is_to_json_regular_operation();
    });
};

IdlInterface.prototype.has_default_to_json_regular_operation = function() {
    return this.members.some(function(m) {
        return m.is_to_json_regular_operation() && m.has_extended_attribute("Default");
    });
};

IdlInterface.prototype.get_inheritance_stack = function() {
    /**
     * See https://heycam.github.io/webidl/#create-an-inheritance-stack
     *
     * Returns an array of IdlInterface objects which contains itself
     * and all of its inherited interfaces.
     *
     * So given:
     *
     *   A : B {};
     *   B : C {};
     *   C {};
     *
     * then A.get_inheritance_stack() should return [A, B, C],
     * and B.get_inheritance_stack() should return [B, C].
     *
     * Note: as dictionary inheritance is expressed identically by the AST,
     * this works just as well for getting a stack of inherited dictionaries.
     */

    var stack = [this];
    var idl_interface = this;
    while (idl_interface.base) {
        var base = this.array.members[idl_interface.base];
        if (!base) {
            throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")");
        } else if (stack.indexOf(base) > -1) {
            stack.push(base);
            let dep_chain = stack.map(i => i.name).join(',');
            throw new IdlHarnessError(`${this.name} has a circular dependency: ${dep_chain}`);
        }
        idl_interface = base;
        stack.push(idl_interface);
    }
    return stack;
};

/**
 * Implementation of
 * https://heycam.github.io/webidl/#default-tojson-operation
 * for testing purposes.
 *
 * Collects the IDL types of the attributes that meet the criteria
 * for inclusion in the default toJSON operation for easy
 * comparison with actual value
 */
IdlInterface.prototype.default_to_json_operation = function(callback) {
    var map = new Map(), isDefault = false;
    this.traverse_inherited_and_consequential_interfaces(function(I) {
        if (I.has_default_to_json_regular_operation()) {
            isDefault = true;
            I.members.forEach(function(m) {
                if (m.special !== "static" && m.type == "attribute" && I.array.is_json_type(m.idlType)) {
                    map.set(m.name, m.idlType);
                }
            });
        } else if (I.has_to_json_regular_operation()) {
            isDefault = false;
        }
    });
    return isDefault ? map : null;
};

/**
 * Traverses inherited interfaces from the top down
 * and imeplemented interfaces inside out.
 * Invokes |callback| on each interface.
 *
 * This is an abstract implementation of the traversal
 * algorithm specified in:
 * https://heycam.github.io/webidl/#collect-attribute-values
 * Given the following inheritance tree:
 *
 *           F
 *           |
 *       C   E - I
 *       |   |
 *       B - D
 *       |
 *   G - A - H - J
 *
 * Invoking traverse_inherited_and_consequential_interfaces() on A
 * would traverse the tree in the following order:
 * C -> B -> F -> E -> I -> D -> A -> G -> H -> J
 */

IdlInterface.prototype.traverse_inherited_and_consequential_interfaces = function(callback) {
    if (typeof callback != "function") {
        throw new TypeError();
    }
    var stack = this.get_inheritance_stack();
    _traverse_inherited_and_consequential_interfaces(stack, callback);
};

function _traverse_inherited_and_consequential_interfaces(stack, callback) {
    var I = stack.pop();
    callback(I);
    var mixins = I.array["implements"][I.name] || I.array["includes"][I.name];
    if (mixins) {
        mixins.forEach(function(id) {
            var mixin = I.array.members[id];
            if (!mixin) {
                throw new Error("Interface " + id + " not found (implemented by " + I.name + ")");
            }
            var interfaces = mixin.get_inheritance_stack();
            _traverse_inherited_and_consequential_interfaces(interfaces, callback);
        });
    }
    if (stack.length > 0) {
        _traverse_inherited_and_consequential_interfaces(stack, callback);
    }
}

IdlInterface.prototype.test = function()
{
    if (this.has_extended_attribute("NoInterfaceObject") || this.is_mixin())
    {
        // No tests to do without an instance.  TODO: We should still be able
        // to run tests on the prototype object, if we obtain one through some
        // other means.
        return;
    }

    if (!this.exposed) {
        subsetTestByKey(this.name, test, function() {
            assert_false(this.name in self);
        }.bind(this), this.name + " interface: existence and properties of interface object");
        return;
    }

    if (!this.untested)
    {
        // First test things to do with the exception/interface object and
        // exception/interface prototype object.
        this.test_self();
    }
    // Then test things to do with its members (constants, fields, attributes,
    // operations, . . .).  These are run even if .untested is true, because
    // members might themselves be marked as .untested.  This might happen to
    // interfaces if the interface itself is untested but a partial interface
    // that extends it is tested -- then the interface itself and its initial
    // members will be marked as untested, but the members added by the partial
    // interface are still tested.
    this.test_members();
};

// This supports both Constructor extended attributes and constructor
// operations until all idl fragments have been updated.
IdlInterface.prototype.constructors = function()
{
    var extendedAttributes = this.extAttrs
        .filter(function(attr) { return attr.name == "Constructor"; });
    var operations = this.members
        .filter(function(m) { return m.type == "constructor"; });
    return extendedAttributes.concat(operations);
}

IdlInterface.prototype.test_self = function()
{
    subsetTestByKey(this.name, test, function()
    {
        // This function tests WebIDL as of 2015-01-13.

        // "For every interface that is exposed in a given ECMAScript global
        // environment and:
        // * is a callback interface that has constants declared on it, or
        // * is a non-callback interface that is not declared with the
        //   [NoInterfaceObject] extended attribute,
        // a corresponding property MUST exist on the ECMAScript global object.
        // The name of the property is the identifier of the interface, and its
        // value is an object called the interface object.
        // The property has the attributes { [[Writable]]: true,
        // [[Enumerable]]: false, [[Configurable]]: true }."
        if (this.is_callback() && !this.has_constants()) {
            return;
        }

        // TODO: Should we test here that the property is actually writable
        // etc., or trust getOwnPropertyDescriptor?
        this.assert_interface_object_exists();
        var desc = Object.getOwnPropertyDescriptor(this.get_interface_object_owner(), this.name);
        assert_false("get" in desc, "self's property " + format_value(this.name) + " should not have a getter");
        assert_false("set" in desc, "self's property " + format_value(this.name) + " should not have a setter");
        assert_true(desc.writable, "self's property " + format_value(this.name) + " should be writable");
        assert_false(desc.enumerable, "self's property " + format_value(this.name) + " should not be enumerable");
        assert_true(desc.configurable, "self's property " + format_value(this.name) + " should be configurable");

        if (this.is_callback()) {
            // "The internal [[Prototype]] property of an interface object for
            // a callback interface must be the Function.prototype object."
            assert_equals(Object.getPrototypeOf(this.get_interface_object()), Function.prototype,
                          "prototype of self's property " + format_value(this.name) + " is not Object.prototype");

            return;
        }

        // "The interface object for a given non-callback interface is a
        // function object."
        // "If an object is defined to be a function object, then it has
        // characteristics as follows:"

        // Its [[Prototype]] internal property is otherwise specified (see
        // below).

        // "* Its [[Get]] internal property is set as described in ECMA-262
        //    section 9.1.8."
        // Not much to test for this.

        // "* Its [[Construct]] internal property is set as described in
        //    ECMA-262 section 19.2.2.3."
        // Tested below if no constructor is defined.  TODO: test constructors
        // if defined.

        // "* Its @@hasInstance property is set as described in ECMA-262
        //    section 19.2.3.8, unless otherwise specified."
        // TODO

        // ES6 (rev 30) 19.1.3.6:
        // "Else, if O has a [[Call]] internal method, then let builtinTag be
        // "Function"."
        assert_class_string(this.get_interface_object(), "Function", "class string of " + this.name);

        // "The [[Prototype]] internal property of an interface object for a
        // non-callback interface is determined as follows:"
        var prototype = Object.getPrototypeOf(this.get_interface_object());
        if (this.base) {
            // "* If the interface inherits from some other interface, the
            //    value of [[Prototype]] is the interface object for that other
            //    interface."
            var inherited_interface = this.array.members[this.base];
            if (!inherited_interface.has_extended_attribute("NoInterfaceObject")) {
                inherited_interface.assert_interface_object_exists();
                assert_equals(prototype, inherited_interface.get_interface_object(),
                              'prototype of ' + this.name + ' is not ' +
                              this.base);
            }
        } else {
            // "If the interface doesn't inherit from any other interface, the
            // value of [[Prototype]] is %FunctionPrototype% ([ECMA-262],
            // section 6.1.7.4)."
            assert_equals(prototype, Function.prototype,
                          "prototype of self's property " + format_value(this.name) + " is not Function.prototype");
        }

        if (!this.constructors().length) {
            // "The internal [[Call]] method of the interface object behaves as
            // follows . . .
            //
            // "If I was not declared with a [Constructor] extended attribute,
            // then throw a TypeError."
            var interface_object = this.get_interface_object();
            assert_throws(new TypeError(), function() {
                interface_object();
            }, "interface object didn't throw TypeError when called as a function");
            assert_throws(new TypeError(), function() {
                new interface_object();
            }, "interface object didn't throw TypeError when called as a constructor");
        }
    }.bind(this), this.name + " interface: existence and properties of interface object");

    if (!this.is_callback()) {
        subsetTestByKey(this.name, test, function() {
            // This function tests WebIDL as of 2014-10-25.
            // https://heycam.github.io/webidl/#es-interface-call

            this.assert_interface_object_exists();

            // "Interface objects for non-callback interfaces MUST have a
            // property named “length” with attributes { [[Writable]]: false,
            // [[Enumerable]]: false, [[Configurable]]: true } whose value is
            // a Number."
            assert_own_property(this.get_interface_object(), "length");
            var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "length");
            assert_false("get" in desc, this.name + ".length should not have a getter");
            assert_false("set" in desc, this.name + ".length should not have a setter");
            assert_false(desc.writable, this.name + ".length should not be writable");
            assert_false(desc.enumerable, this.name + ".length should not be enumerable");
            assert_true(desc.configurable, this.name + ".length should be configurable");

            var constructors = this.constructors();
            var expected_length = minOverloadLength(constructors);
            assert_equals(this.get_interface_object().length, expected_length, "wrong value for " + this.name + ".length");
        }.bind(this), this.name + " interface object length");
    }

    if (!this.is_callback() || this.has_constants()) {
        subsetTestByKey(this.name, test, function() {
            // This function tests WebIDL as of 2015-11-17.
            // https://heycam.github.io/webidl/#interface-object

            this.assert_interface_object_exists();

            // "All interface objects must have a property named “name” with
            // attributes { [[Writable]]: false, [[Enumerable]]: false,
            // [[Configurable]]: true } whose value is the identifier of the
            // corresponding interface."

            assert_own_property(this.get_interface_object(), "name");
            var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "name");
            assert_false("get" in desc, this.name + ".name should not have a getter");
            assert_false("set" in desc, this.name + ".name should not have a setter");
            assert_false(desc.writable, this.name + ".name should not be writable");
            assert_false(desc.enumerable, this.name + ".name should not be enumerable");
            assert_true(desc.configurable, this.name + ".name should be configurable");
            assert_equals(this.get_interface_object().name, this.name, "wrong value for " + this.name + ".name");
        }.bind(this), this.name + " interface object name");
    }


    if (this.has_extended_attribute("LegacyWindowAlias")) {
        subsetTestByKey(this.name, test, function()
        {
            var aliasAttrs = this.extAttrs.filter(function(o) { return o.name === "LegacyWindowAlias"; });
            if (aliasAttrs.length > 1) {
                throw new IdlHarnessError("Invalid IDL: multiple LegacyWindowAlias extended attributes on " + this.name);
            }
            if (this.is_callback()) {
                throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on non-interface " + this.name);
            }
            if (!this.exposureSet.has("Window")) {
                throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window");
            }
            // TODO: when testing of [NoInterfaceObject] interfaces is supported,
            // check that it's not specified together with LegacyWindowAlias.

            // TODO: maybe check that [LegacyWindowAlias] is not specified on a partial interface.

            var rhs = aliasAttrs[0].rhs;
            if (!rhs) {
                throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " without identifier");
            }
            var aliases;
            if (rhs.type === "identifier-list") {
                aliases = rhs.value.map(id => id.value);
            } else { // rhs.type === identifier
                aliases = [ rhs.value ];
            }

            // OK now actually check the aliases...
            var alias;
            if (exposed_in(exposure_set(this, this.exposureSet)) && 'document' in self) {
                for (alias of aliases) {
                    assert_true(alias in self, alias + " should exist");
                    assert_equals(self[alias], this.get_interface_object(), "self." + alias + " should be the same value as self." + this.get_qualified_name());
                    var desc = Object.getOwnPropertyDescriptor(self, alias);
                    assert_equals(desc.value, this.get_interface_object(), "wrong value in " + alias + " property descriptor");
                    assert_true(desc.writable, alias + " should be writable");
                    assert_false(desc.enumerable, alias + " should not be enumerable");
                    assert_true(desc.configurable, alias + " should be configurable");
                    assert_false('get' in desc, alias + " should not have a getter");
                    assert_false('set' in desc, alias + " should not have a setter");
                }
            } else {
                for (alias of aliases) {
                    assert_false(alias in self, alias + " should not exist");
                }
            }

        }.bind(this), this.name + " interface: legacy window alias");
    }

    if (this.has_extended_attribute("NamedConstructor")) {
        var constructors = this.extAttrs
            .filter(function(attr) { return attr.name == "NamedConstructor"; });
        if (constructors.length !== 1) {
            throw new IdlHarnessError("Internal error: missing support for multiple NamedConstructor extended attributes");
        }
        var constructor = constructors[0];
        var min_length = minOverloadLength([constructor]);

        subsetTestByKey(this.name, test, function()
        {
            // This function tests WebIDL as of 2019-01-14.

            // "for every [NamedConstructor] extended attribute on an exposed
            // interface, a corresponding property must exist on the ECMAScript
            // global object. The name of the property is the
            // [NamedConstructor]'s identifier, and its value is an object
            // called a named constructor, ... . The property has the attributes
            // { [[Writable]]: true, [[Enumerable]]: false,
            // [[Configurable]]: true }."
            var name = constructor.rhs.value;
            assert_own_property(self, name);
            var desc = Object.getOwnPropertyDescriptor(self, name);
            assert_equals(desc.value, self[name], "wrong value in " + name + " property descriptor");
            assert_true(desc.writable, name + " should be writable");
            assert_false(desc.enumerable, name + " should not be enumerable");
            assert_true(desc.configurable, name + " should be configurable");
            assert_false("get" in desc, name + " should not have a getter");
            assert_false("set" in desc, name + " should not have a setter");
        }.bind(this), this.name + " interface: named constructor");

        subsetTestByKey(this.name, test, function()
        {
            // This function tests WebIDL as of 2019-01-14.

            // "2. Let F be ! CreateBuiltinFunction(realm, steps,
            //     realm.[[Intrinsics]].[[%FunctionPrototype%]])."
            var name = constructor.rhs.value;
            var value = self[name];
            assert_equals(typeof value, "function", "type of value in " + name + " property descriptor");
            assert_not_equals(value, this.get_interface_object(), "wrong value in " + name + " property descriptor");
            assert_equals(Object.getPrototypeOf(value), Function.prototype, "wrong value for " + name + "'s prototype");
        }.bind(this), this.name + " interface: named constructor object");

        subsetTestByKey(this.name, test, function()
        {
            // This function tests WebIDL as of 2019-01-14.

            // "7. Let proto be the interface prototype object of interface I
            //     in realm.
            // "8. Perform ! DefinePropertyOrThrow(F, "prototype",
            //     PropertyDescriptor{
            //         [[Value]]: proto, [[Writable]]: false,
            //         [[Enumerable]]: false, [[Configurable]]: false
            //     })."
            var name = constructor.rhs.value;
            var expected = this.get_interface_object().prototype;
            var desc = Object.getOwnPropertyDescriptor(self[name], "prototype");
            assert_equals(desc.value, expected, "wrong value for " + name + ".prototype");
            assert_false(desc.writable, "prototype should not be writable");
            assert_false(desc.enumerable, "prototype should not be enumerable");
            assert_false(desc.configurable, "prototype should not be configurable");
            assert_false("get" in desc, "prototype should not have a getter");
            assert_false("set" in desc, "prototype should not have a setter");
        }.bind(this), this.name + " interface: named constructor prototype property");

        subsetTestByKey(this.name, test, function()
        {
            // This function tests WebIDL as of 2019-01-14.

            // "3. Perform ! SetFunctionName(F, id)."
            var name = constructor.rhs.value;
            var desc = Object.getOwnPropertyDescriptor(self[name], "name");
            assert_equals(desc.value, name, "wrong value for " + name + ".name");
            assert_false(desc.writable, "name should not be writable");
            assert_false(desc.enumerable, "name should not be enumerable");
            assert_true(desc.configurable, "name should be configurable");
            assert_false("get" in desc, "name should not have a getter");
            assert_false("set" in desc, "name should not have a setter");
        }.bind(this), this.name + " interface: named constructor name");

        subsetTestByKey(this.name, test, function()
        {
            // This function tests WebIDL as of 2019-01-14.

            // "4. Initialize S to the effective overload set for constructors
            //     with identifier id on interface I and with argument count 0.
            // "5. Let length be the length of the shortest argument list of
            //     the entries in S.
            // "6. Perform ! SetFunctionLength(F, length)."
            var name = constructor.rhs.value;
            var desc = Object.getOwnPropertyDescriptor(self[name], "length");
            assert_equals(desc.value, min_length, "wrong value for " + name + ".length");
            assert_false(desc.writable, "length should not be writable");
            assert_false(desc.enumerable, "length should not be enumerable");
            assert_true(desc.configurable, "length should be configurable");
            assert_false("get" in desc, "length should not have a getter");
            assert_false("set" in desc, "length should not have a setter");
        }.bind(this), this.name + " interface: named constructor length");

        subsetTestByKey(this.name, test, function()
        {
            // This function tests WebIDL as of 2019-01-14.

            // "1. Let steps be the following steps:
            // "    1. If NewTarget is undefined, then throw a TypeError."
            var name = constructor.rhs.value;
            var args = constructor.arguments.map(function(arg) {
                return create_suitable_object(arg.idlType);
            });
            assert_throws(new TypeError(), function() {
                self[name](...args);
            }.bind(this));
        }.bind(this), this.name + " interface: named constructor without 'new'");
    }

    subsetTestByKey(this.name, test, function()
    {
        // This function tests WebIDL as of 2015-01-21.
        // https://heycam.github.io/webidl/#interface-object

        if (this.is_callback() && !this.has_constants()) {
            return;
        }

        this.assert_interface_object_exists();

        if (this.is_callback()) {
            assert_false("prototype" in this.get_interface_object(),
                         this.name + ' should not have a "prototype" property');
            return;
        }

        // "An interface object for a non-callback interface must have a
        // property named “prototype” with attributes { [[Writable]]: false,
        // [[Enumerable]]: false, [[Configurable]]: false } whose value is an
        // object called the interface prototype object. This object has
        // properties that correspond to the regular attributes and regular
        // operations defined on the interface, and is described in more detail
        // in section 4.5.4 below."
        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');
        var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "prototype");
        assert_false("get" in desc, this.name + ".prototype should not have a getter");
        assert_false("set" in desc, this.name + ".prototype should not have a setter");
        assert_false(desc.writable, this.name + ".prototype should not be writable");
        assert_false(desc.enumerable, this.name + ".prototype should not be enumerable");
        assert_false(desc.configurable, this.name + ".prototype should not be configurable");

        // Next, test that the [[Prototype]] of the interface prototype object
        // is correct. (This is made somewhat difficult by the existence of
        // [NoInterfaceObject].)
        // TODO: Aryeh thinks there's at least other place in this file where
        //       we try to figure out if an interface prototype object is
        //       correct. Consolidate that code.

        // "The interface prototype object for a given interface A must have an
        // internal [[Prototype]] property whose value is returned from the
        // following steps:
        // "If A is declared with the [Global] extended
        // attribute, and A supports named properties, then return the named
        // properties object for A, as defined in §3.6.4 Named properties
        // object.
        // "Otherwise, if A is declared to inherit from another interface, then
        // return the interface prototype object for the inherited interface.
        // "Otherwise, return %ObjectPrototype%.
        //
        // "In the ECMAScript binding, the DOMException type has some additional
        // requirements:
        //
        //     "Unlike normal interface types, the interface prototype object
        //     for DOMException must have as its [[Prototype]] the intrinsic
        //     object %ErrorPrototype%."
        //
        if (this.name === "Window") {
            assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype),
                                'WindowProperties',
                                'Class name for prototype of Window' +
                                '.prototype is not "WindowProperties"');
        } else {
            var inherit_interface, inherit_interface_interface_object;
            if (this.base) {
                inherit_interface = this.base;
                var parent = this.array.members[inherit_interface];
                if (!parent.has_extended_attribute("NoInterfaceObject")) {
                    parent.assert_interface_object_exists();
                    inherit_interface_interface_object = parent.get_interface_object();
                }
            } else if (this.name === "DOMException") {
                inherit_interface = 'Error';
                inherit_interface_interface_object = self.Error;
            } else {
                inherit_interface = 'Object';
                inherit_interface_interface_object = self.Object;
            }
            if (inherit_interface_interface_object) {
                assert_not_equals(inherit_interface_interface_object, undefined,
                                  'should inherit from ' + inherit_interface + ', but there is no such property');
                assert_own_property(inherit_interface_interface_object, 'prototype',
                                    'should inherit from ' + inherit_interface + ', but that object has no "prototype" property');
                assert_equals(Object.getPrototypeOf(this.get_interface_object().prototype),
                              inherit_interface_interface_object.prototype,
                              'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype');
            } else {
                // We can't test that we get the correct object, because this is the
                // only way to get our hands on it. We only test that its class
                // string, at least, is correct.
                assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype),
                                    inherit_interface + 'Prototype',
                                    'Class name for prototype of ' + this.name +
                                    '.prototype is not "' + inherit_interface + 'Prototype"');
            }
        }

        // "The class string of an interface prototype object is the
        // concatenation of the interface’s qualified identifier and the string
        // “Prototype”."

        // Skip these tests for now due to a specification issue about
        // prototype name.
        // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28244

        // assert_class_string(this.get_interface_object().prototype, this.get_qualified_name() + "Prototype",
        //                     "class string of " + this.name + ".prototype");

        // String() should end up calling {}.toString if nothing defines a
        // stringifier.
        if (!this.has_stringifier()) {
            // assert_equals(String(this.get_interface_object().prototype), "[object " + this.get_qualified_name() + "Prototype]",
            //         "String(" + this.name + ".prototype)");
        }
    }.bind(this), this.name + " interface: existence and properties of interface prototype object");

    // "If the interface is declared with the [Global]
    // extended attribute, or the interface is in the set of inherited
    // interfaces for any other interface that is declared with one of these
    // attributes, then the interface prototype object must be an immutable
    // prototype exotic object."
    // https://heycam.github.io/webidl/#interface-prototype-object
    if (this.is_global()) {
        this.test_immutable_prototype("interface prototype object", this.get_interface_object().prototype);
    }

    subsetTestByKey(this.name, test, function()
    {
        if (this.is_callback() && !this.has_constants()) {
            return;
        }

        this.assert_interface_object_exists();

        if (this.is_callback()) {
            assert_false("prototype" in this.get_interface_object(),
                         this.name + ' should not have a "prototype" property');
            return;
        }

        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');

        // "If the [NoInterfaceObject] extended attribute was not specified on
        // the interface, then the interface prototype object must also have a
        // property named “constructor” with attributes { [[Writable]]: true,
        // [[Enumerable]]: false, [[Configurable]]: true } whose value is a
        // reference to the interface object for the interface."
        assert_own_property(this.get_interface_object().prototype, "constructor",
                            this.name + '.prototype does not have own property "constructor"');
        var desc = Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, "constructor");
        assert_false("get" in desc, this.name + ".prototype.constructor should not have a getter");
        assert_false("set" in desc, this.name + ".prototype.constructor should not have a setter");
        assert_true(desc.writable, this.name + ".prototype.constructor should be writable");
        assert_false(desc.enumerable, this.name + ".prototype.constructor should not be enumerable");
        assert_true(desc.configurable, this.name + ".prototype.constructor should be configurable");
        assert_equals(this.get_interface_object().prototype.constructor, this.get_interface_object(),
                      this.name + '.prototype.constructor is not the same object as ' + this.name);
    }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property');


    subsetTestByKey(this.name, test, function()
    {
        if (this.is_callback() && !this.has_constants()) {
            return;
        }

        this.assert_interface_object_exists();

        if (this.is_callback()) {
            assert_false("prototype" in this.get_interface_object(),
                         this.name + ' should not have a "prototype" property');
            return;
        }

        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');

        // If the interface has any member declared with the [Unscopable] extended
        // attribute, then there must be a property on the interface prototype object
        // whose name is the @@unscopables symbol, which has the attributes
        // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true },
        // and whose value is an object created as follows...
        var unscopables = this.get_unscopables().map(m => m.name);
        var proto = this.get_interface_object().prototype;
        if (unscopables.length != 0) {
            assert_own_property(
                proto, Symbol.unscopables,
                this.name + '.prototype should have an @@unscopables property');
            var desc = Object.getOwnPropertyDescriptor(proto, Symbol.unscopables);
            assert_false("get" in desc,
                         this.name + ".prototype[Symbol.unscopables] should not have a getter");
            assert_false("set" in desc, this.name + ".prototype[Symbol.unscopables] should not have a setter");
            assert_false(desc.writable, this.name + ".prototype[Symbol.unscopables] should not be writable");
            assert_false(desc.enumerable, this.name + ".prototype[Symbol.unscopables] should not be enumerable");
            assert_true(desc.configurable, this.name + ".prototype[Symbol.unscopables] should be configurable");
            assert_equals(desc.value, proto[Symbol.unscopables],
                          this.name + '.prototype[Symbol.unscopables] should be in the descriptor');
            assert_equals(typeof desc.value, "object",
                          this.name + '.prototype[Symbol.unscopables] should be an object');
            assert_equals(Object.getPrototypeOf(desc.value), null,
                          this.name + '.prototype[Symbol.unscopables] should have a null prototype');
            assert_equals(Object.getOwnPropertySymbols(desc.value).length,
                          0,
                          this.name + '.prototype[Symbol.unscopables] should have the right number of symbol-named properties');

            // Check that we do not have _extra_ unscopables.  Checking that we
            // have all the ones we should will happen in the per-member tests.
            var observed = Object.getOwnPropertyNames(desc.value);
            for (var prop of observed) {
                assert_not_equals(unscopables.indexOf(prop),
                                  -1,
                                  this.name + '.prototype[Symbol.unscopables] has unexpected property "' + prop + '"');
            }
        } else {
            assert_equals(Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, Symbol.unscopables),
                          undefined,
                          this.name + '.prototype should not have @@unscopables');
        }
    }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s @@unscopables property');
};

IdlInterface.prototype.test_immutable_prototype = function(type, obj)
{
    if (typeof Object.setPrototypeOf !== "function") {
        return;
    }

    subsetTestByKey(this.name, test, function(t) {
        var originalValue = Object.getPrototypeOf(obj);
        var newValue = Object.create(null);

        t.add_cleanup(function() {
            try {
                Object.setPrototypeOf(obj, originalValue);
            } catch (err) {}
        });

        assert_throws(new TypeError(), function() {
            Object.setPrototypeOf(obj, newValue);
        });

        assert_equals(
                Object.getPrototypeOf(obj),
                originalValue,
                "original value not modified"
            );
    }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +
        "of " + type + " - setting to a new value via Object.setPrototypeOf " +
        "should throw a TypeError");

    subsetTestByKey(this.name, test, function(t) {
        var originalValue = Object.getPrototypeOf(obj);
        var newValue = Object.create(null);

        t.add_cleanup(function() {
            var setter = Object.getOwnPropertyDescriptor(
                Object.prototype, '__proto__'
            ).set;

            try {
                setter.call(obj, originalValue);
            } catch (err) {}
        });

        assert_throws(new TypeError(), function() {
            obj.__proto__ = newValue;
        });

        assert_equals(
                Object.getPrototypeOf(obj),
                originalValue,
                "original value not modified"
            );
    }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +
        "of " + type + " - setting to a new value via __proto__ " +
        "should throw a TypeError");

    subsetTestByKey(this.name, test, function(t) {
        var originalValue = Object.getPrototypeOf(obj);
        var newValue = Object.create(null);

        t.add_cleanup(function() {
            try {
                Reflect.setPrototypeOf(obj, originalValue);
            } catch (err) {}
        });

        assert_false(Reflect.setPrototypeOf(obj, newValue));

        assert_equals(
                Object.getPrototypeOf(obj),
                originalValue,
                "original value not modified"
            );
    }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +
        "of " + type + " - setting to a new value via Reflect.setPrototypeOf " +
        "should return false");

    subsetTestByKey(this.name, test, function() {
        var originalValue = Object.getPrototypeOf(obj);

        Object.setPrototypeOf(obj, originalValue);
    }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +
        "of " + type + " - setting to its original value via Object.setPrototypeOf " +
        "should not throw");

    subsetTestByKey(this.name, test, function() {
        var originalValue = Object.getPrototypeOf(obj);

        obj.__proto__ = originalValue;
    }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +
        "of " + type + " - setting to its original value via __proto__ " +
        "should not throw");

    subsetTestByKey(this.name, test, function() {
        var originalValue = Object.getPrototypeOf(obj);

        assert_true(Reflect.setPrototypeOf(obj, originalValue));
    }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +
        "of " + type + " - setting to its original value via Reflect.setPrototypeOf " +
        "should return true");
};

IdlInterface.prototype.test_member_const = function(member)
{
    if (!this.has_constants()) {
        throw new IdlHarnessError("Internal error: test_member_const called without any constants");
    }

    subsetTestByKey(this.name, test, function()
    {
        this.assert_interface_object_exists();

        // "For each constant defined on an interface A, there must be
        // a corresponding property on the interface object, if it
        // exists."
        assert_own_property(this.get_interface_object(), member.name);
        // "The value of the property is that which is obtained by
        // converting the constant’s IDL value to an ECMAScript
        // value."
        assert_equals(this.get_interface_object()[member.name], constValue(member.value),
                      "property has wrong value");
        // "The property has attributes { [[Writable]]: false,
        // [[Enumerable]]: true, [[Configurable]]: false }."
        var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name);
        assert_false("get" in desc, "property should not have a getter");
        assert_false("set" in desc, "property should not have a setter");
        assert_false(desc.writable, "property should not be writable");
        assert_true(desc.enumerable, "property should be enumerable");
        assert_false(desc.configurable, "property should not be configurable");
    }.bind(this), this.name + " interface: constant " + member.name + " on interface object");

    // "In addition, a property with the same characteristics must
    // exist on the interface prototype object."
    subsetTestByKey(this.name, test, function()
    {
        this.assert_interface_object_exists();

        if (this.is_callback()) {
            assert_false("prototype" in this.get_interface_object(),
                         this.name + ' should not have a "prototype" property');
            return;
        }

        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');

        assert_own_property(this.get_interface_object().prototype, member.name);
        assert_equals(this.get_interface_object().prototype[member.name], constValue(member.value),
                      "property has wrong value");
        var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name);
        assert_false("get" in desc, "property should not have a getter");
        assert_false("set" in desc, "property should not have a setter");
        assert_false(desc.writable, "property should not be writable");
        assert_true(desc.enumerable, "property should be enumerable");
        assert_false(desc.configurable, "property should not be configurable");
    }.bind(this), this.name + " interface: constant " + member.name + " on interface prototype object");
};


IdlInterface.prototype.test_member_attribute = function(member)
  {
    if (!shouldRunSubTest(this.name)) {
        return;
    }
    var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: attribute " + member.name);
    a_test.step(function()
    {
        if (this.is_callback() && !this.has_constants()) {
            a_test.done()
            return;
        }

        this.assert_interface_object_exists();
        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');

        if (member.special === "static") {
            assert_own_property(this.get_interface_object(), member.name,
                "The interface object must have a property " +
                format_value(member.name));
            a_test.done();
            return;
        }

        this.do_member_unscopable_asserts(member);

        if (this.is_global()) {
            assert_own_property(self, member.name,
                "The global object must have a property " +
                format_value(member.name));
            assert_false(member.name in this.get_interface_object().prototype,
                "The prototype object should not have a property " +
                format_value(member.name));

            var getter = Object.getOwnPropertyDescriptor(self, member.name).get;
            assert_equals(typeof(getter), "function",
                          format_value(member.name) + " must have a getter");

            // Try/catch around the get here, since it can legitimately throw.
            // If it does, we obviously can't check for equality with direct
            // invocation of the getter.
            var gotValue;
            var propVal;
            try {
                propVal = self[member.name];
                gotValue = true;
            } catch (e) {
                gotValue = false;
            }
            if (gotValue) {
                assert_equals(propVal, getter.call(undefined),
                              "Gets on a global should not require an explicit this");
            }

            // do_interface_attribute_asserts must be the last thing we do,
            // since it will call done() on a_test.
            this.do_interface_attribute_asserts(self, member, a_test);
        } else {
            assert_true(member.name in this.get_interface_object().prototype,
                "The prototype object must have a property " +
                format_value(member.name));

            if (!member.has_extended_attribute("LenientThis")) {
                if (member.idlType.generic !== "Promise") {
                    assert_throws(new TypeError(), function() {
                        this.get_interface_object().prototype[member.name];
                    }.bind(this), "getting property on prototype object must throw TypeError");
                    // do_interface_attribute_asserts must be the last thing we
                    // do, since it will call done() on a_test.
                    this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test);
                } else {
                    promise_rejects(a_test, new TypeError(),
                                    this.get_interface_object().prototype[member.name])
                        .then(function() {
                            // do_interface_attribute_asserts must be the last
                            // thing we do, since it will call done() on a_test.
                            this.do_interface_attribute_asserts(this.get_interface_object().prototype,
                                                                member, a_test);
                        }.bind(this));
                }
            } else {
                assert_equals(this.get_interface_object().prototype[member.name], undefined,
                              "getting property on prototype object must return undefined");
              // do_interface_attribute_asserts must be the last thing we do,
              // since it will call done() on a_test.
              this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test);
            }
        }
    }.bind(this));
};

IdlInterface.prototype.test_member_operation = function(member)
{
    if (!shouldRunSubTest(this.name)) {
        return;
    }
    var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: operation " + member.name +
                            "(" + member.arguments.map(
                                function(m) {return m.idlType.idlType; } ).join(", ")
                            +")");
    a_test.step(function()
    {
        // This function tests WebIDL as of 2015-12-29.
        // https://heycam.github.io/webidl/#es-operations

        if (this.is_callback() && !this.has_constants()) {
            a_test.done();
            return;
        }

        this.assert_interface_object_exists();

        if (this.is_callback()) {
            assert_false("prototype" in this.get_interface_object(),
                         this.name + ' should not have a "prototype" property');
            a_test.done();
            return;
        }

        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');

        // "For each unique identifier of an exposed operation defined on the
        // interface, there must exist a corresponding property, unless the
        // effective overload set for that identifier and operation and with an
        // argument count of 0 has no entries."

        // TODO: Consider [Exposed].

        // "The location of the property is determined as follows:"
        var memberHolderObject;
        // "* If the operation is static, then the property exists on the
        //    interface object."
        if (member.special === "static") {
            assert_own_property(this.get_interface_object(), member.name,
                    "interface object missing static operation");
            memberHolderObject = this.get_interface_object();
        // "* Otherwise, [...] if the interface was declared with the [Global]
        //    extended attribute, then the property exists
        //    on every object that implements the interface."
        } else if (this.is_global()) {
            assert_own_property(self, member.name,
                    "global object missing non-static operation");
            memberHolderObject = self;
        // "* Otherwise, the property exists solely on the interface’s
        //    interface prototype object."
        } else {
            assert_own_property(this.get_interface_object().prototype, member.name,
                    "interface prototype object missing non-static operation");
            memberHolderObject = this.get_interface_object().prototype;
        }
        this.do_member_unscopable_asserts(member);
        this.do_member_operation_asserts(memberHolderObject, member, a_test);
    }.bind(this));
};

IdlInterface.prototype.do_member_unscopable_asserts = function(member)
{
    // Check that if the member is unscopable then it's in the
    // @@unscopables object properly.
    if (!member.isUnscopable) {
        return;
    }

    var unscopables = this.get_interface_object().prototype[Symbol.unscopables];
    var prop = member.name;
    var propDesc = Object.getOwnPropertyDescriptor(unscopables, prop);
    assert_equals(typeof propDesc, "object",
                  this.name + '.prototype[Symbol.unscopables].' + prop + ' must exist')
    assert_false("get" in propDesc,
                 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no getter');
    assert_false("set" in propDesc,
                 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no setter');
    assert_true(propDesc.writable,
                this.name + '.prototype[Symbol.unscopables].' + prop + ' must be writable');
    assert_true(propDesc.enumerable,
                this.name + '.prototype[Symbol.unscopables].' + prop + ' must be enumerable');
    assert_true(propDesc.configurable,
                this.name + '.prototype[Symbol.unscopables].' + prop + ' must be configurable');
    assert_equals(propDesc.value, true,
                  this.name + '.prototype[Symbol.unscopables].' + prop + ' must have the value `true`');
};

IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member, a_test)
{
    var done = a_test.done.bind(a_test);
    var operationUnforgeable = member.isUnforgeable;
    var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);
    // "The property has attributes { [[Writable]]: B,
    // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the
    // operation is unforgeable on the interface, and true otherwise".
    assert_false("get" in desc, "property should not have a getter");
    assert_false("set" in desc, "property should not have a setter");
    assert_equals(desc.writable, !operationUnforgeable,
                  "property should be writable if and only if not unforgeable");
    assert_true(desc.enumerable, "property should be enumerable");
    assert_equals(desc.configurable, !operationUnforgeable,
                  "property should be configurable if and only if not unforgeable");
    // "The value of the property is a Function object whose
    // behavior is as follows . . ."
    assert_equals(typeof memberHolderObject[member.name], "function",
                  "property must be a function");

    const ctors = this.members.filter(function(m) {
        return m.type == "operation" && m.name == member.name;
    });
    assert_equals(
        memberHolderObject[member.name].length,
        minOverloadLength(ctors),
        "property has wrong .length");

    // Make some suitable arguments
    var args = member.arguments.map(function(arg) {
        return create_suitable_object(arg.idlType);
    });

    // "Let O be a value determined as follows:
    // ". . .
    // "Otherwise, throw a TypeError."
    // This should be hit if the operation is not static, there is
    // no [ImplicitThis] attribute, and the this value is null.
    //
    // TODO: We currently ignore the [ImplicitThis] case.  Except we manually
    // check for globals, since otherwise we'll invoke window.close().  And we
    // have to skip this test for anything that on the proto chain of "self",
    // since that does in fact have implicit-this behavior.
    if (member.special !== "static") {
        var cb;
        if (!this.is_global() &&
            memberHolderObject[member.name] != self[member.name])
        {
            cb = awaitNCallbacks(2, done);
            throwOrReject(a_test, member, memberHolderObject[member.name], null, args,
                          "calling operation with this = null didn't throw TypeError", cb);
        } else {
            cb = awaitNCallbacks(1, done);
        }

        // ". . . If O is not null and is also not a platform object
        // that implements interface I, throw a TypeError."
        //
        // TODO: Test a platform object that implements some other
        // interface.  (Have to be sure to get inheritance right.)
        throwOrReject(a_test, member, memberHolderObject[member.name], {}, args,
                      "calling operation with this = {} didn't throw TypeError", cb);
    } else {
        done();
    }
}

IdlInterface.prototype.test_to_json_operation = function(desc, memberHolderObject, member) {
    var instanceName = memberHolderObject && memberHolderObject.constructor.name
        || member.name + " object";
    if (member.has_extended_attribute("Default")) {
        subsetTestByKey(this.name, test, function() {
            var map = this.default_to_json_operation();
            var json = memberHolderObject.toJSON();
            map.forEach(function(type, k) {
                assert_true(k in json, "property " + JSON.stringify(k) + " should be present in the output of " + this.name + ".prototype.toJSON()");
                var descriptor = Object.getOwnPropertyDescriptor(json, k);
                assert_true(descriptor.writable, "property " + k + " should be writable");
                assert_true(descriptor.configurable, "property " + k + " should be configurable");
                assert_true(descriptor.enumerable, "property " + k + " should be enumerable");
                this.array.assert_type_is(json[k], type);
                delete json[k];
            }, this);
        }.bind(this), this.name + " interface: default toJSON operation on " + desc);
    } else {
        subsetTestByKey(this.name, test, function() {
            assert_true(this.array.is_json_type(member.idlType), JSON.stringify(member.idlType) + " is not an appropriate return value for the toJSON operation of " + instanceName);
            this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType);
        }.bind(this), this.name + " interface: toJSON operation on " + desc);
    }
};

IdlInterface.prototype.test_member_iterable = function(member)
{
    subsetTestByKey(this.name, test, function()
    {
        var isPairIterator = member.idlType.length === 2;
        var proto = this.get_interface_object().prototype;
        var descriptor = Object.getOwnPropertyDescriptor(proto, Symbol.iterator);

        assert_true(descriptor.writable, "@@iterator property should be writable");
        assert_true(descriptor.configurable, "@@iterator property should be configurable");
        assert_false(descriptor.enumerable, "@@iterator property should not be enumerable");
        assert_equals(typeof descriptor.value, "function", "@@iterator property should be a function");
        assert_equals(descriptor.value.length, 0, "@@iterator function object length should be 0");
        assert_equals(descriptor.value.name, isPairIterator ? "entries" : "values", "@@iterator function object should have the right name");

        if (isPairIterator) {
            assert_equals(proto["entries"], proto[Symbol.iterator], "entries method should be the same as @@iterator method");
        } else {
            assert_equals(proto[Symbol.iterator], Array.prototype[Symbol.iterator], "@@iterator method should be the same as Array prototype's");
            ["entries", "keys", "values", "forEach", Symbol.iterator].forEach(function(property) {
                var propertyName = property === Symbol.iterator ? "@@iterator" : property;
                assert_equals(proto[property], Array.prototype[property], propertyName + " method should be the same as Array prototype's");
            }.bind(this));
        }
    }.bind(this), this.name + " interface: iterable<" + member.idlType.map(function(t) { return t.idlType; }).join(", ") + ">");
};

IdlInterface.prototype.test_member_stringifier = function(member)
{
    subsetTestByKey(this.name, test, function()
    {
        if (this.is_callback() && !this.has_constants()) {
            return;
        }

        this.assert_interface_object_exists();

        if (this.is_callback()) {
            assert_false("prototype" in this.get_interface_object(),
                         this.name + ' should not have a "prototype" property');
            return;
        }

        assert_own_property(this.get_interface_object(), "prototype",
                            'interface "' + this.name + '" does not have own property "prototype"');

        // ". . . the property exists on the interface prototype object."
        var interfacePrototypeObject = this.get_interface_object().prototype;
        assert_own_property(interfacePrototypeObject, "toString",
                "interface prototype object missing non-static operation");

        var stringifierUnforgeable = member.isUnforgeable;
        var desc = Object.getOwnPropertyDescriptor(interfacePrototypeObject, "toString");
        // "The property has attributes { [[Writable]]: B,
        // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the
        // stringifier is unforgeable on the interface, and true otherwise."
        assert_false("get" in desc, "property should not have a getter");
        assert_false("set" in desc, "property should not have a setter");
        assert_equals(desc.writable, !stringifierUnforgeable,
                      "property should be writable if and only if not unforgeable");
        assert_true(desc.enumerable, "property should be enumerable");
        assert_equals(desc.configurable, !stringifierUnforgeable,
                      "property should be configurable if and only if not unforgeable");
        // "The value of the property is a Function object, which behaves as
        // follows . . ."
        assert_equals(typeof interfacePrototypeObject.toString, "function",
                      "property must be a function");
        // "The value of the Function object’s “length” property is the Number
        // value 0."
        assert_equals(interfacePrototypeObject.toString.length, 0,
            "property has wrong .length");

        // "Let O be the result of calling ToObject on the this value."
        assert_throws(new TypeError(), function() {
            interfacePrototypeObject.toString.apply(null, []);
        }, "calling stringifier with this = null didn't throw TypeError");

        // "If O is not an object that implements the interface on which the
        // stringifier was declared, then throw a TypeError."
        //
        // TODO: Test a platform object that implements some other
        // interface.  (Have to be sure to get inheritance right.)
        assert_throws(new TypeError(), function() {
            interfacePrototypeObject.toString.apply({}, []);
        }, "calling stringifier with this = {} didn't throw TypeError");
    }.bind(this), this.name + " interface: stringifier");
};

IdlInterface.prototype.test_members = function()
{
    for (var i = 0; i < this.members.length; i++)
    {
        var member = this.members[i];
        if (member.untested) {
            continue;
        }

        if (!exposed_in(exposure_set(member, this.exposureSet))) {
            subsetTestByKey(this.name, test, function() {
                // It's not exposed, so we shouldn't find it anywhere.
                assert_false(member.name in this.get_interface_object(),
                             "The interface object must not have a property " +
                             format_value(member.name));
                assert_false(member.name in this.get_interface_object().prototype,
                             "The prototype object must not have a property " +
                             format_value(member.name));
            }.bind(this), this.name + " interface: member " + member.name);
            continue;
        }

        switch (member.type) {
        case "const":
            this.test_member_const(member);
            break;

        case "attribute":
            // For unforgeable attributes, we do the checks in
            // test_interface_of instead.
            if (!member.isUnforgeable)
            {
                this.test_member_attribute(member);
            }
            if (member.special === "stringifier") {
                this.test_member_stringifier(member);
            }
            break;

        case "operation":
            // TODO: Need to correctly handle multiple operations with the same
            // identifier.
            // For unforgeable operations, we do the checks in
            // test_interface_of instead.
            if (member.name) {
                if (!member.isUnforgeable)
                {
                    this.test_member_operation(member);
                }
            } else if (member.special === "stringifier") {
                this.test_member_stringifier(member);
            }
            break;

        case "iterable":
            this.test_member_iterable(member);
            break;
        default:
            // TODO: check more member types.
            break;
        }
    }
};

IdlInterface.prototype.test_object = function(desc)
{
    var obj, exception = null;
    try
    {
        obj = eval(desc);
    }
    catch(e)
    {
        exception = e;
    }

    var expected_typeof =
        this.members.some(function(member) { return member.legacycaller; })
        ? "function"
        : "object";

    this.test_primary_interface_of(desc, obj, exception, expected_typeof);

    var current_interface = this;
    while (current_interface)
    {
        if (!(current_interface.name in this.array.members))
        {
            throw new IdlHarnessError("Interface " + current_interface.name + " not found (inherited by " + this.name + ")");
        }
        if (current_interface.prevent_multiple_testing && current_interface.already_tested)
        {
            return;
        }
        current_interface.test_interface_of(desc, obj, exception, expected_typeof);
        current_interface = this.array.members[current_interface.base];
    }
};

IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception, expected_typeof)
{
    // Only the object itself, not its members, are tested here, so if the
    // interface is untested, there is nothing to do.
    if (this.untested)
    {
        return;
    }

    // "The internal [[SetPrototypeOf]] method of every platform object that
    // implements an interface with the [Global] extended
    // attribute must execute the same algorithm as is defined for the
    // [[SetPrototypeOf]] internal method of an immutable prototype exotic
    // object."
    // https://heycam.github.io/webidl/#platform-object-setprototypeof
    if (this.is_global())
    {
        this.test_immutable_prototype("global platform object", obj);
    }


    // We can't easily test that its prototype is correct if there's no
    // interface object, or the object is from a different global environment
    // (not instanceof Object).  TODO: test in this case that its prototype at
    // least looks correct, even if we can't test that it's actually correct.
    if (!this.has_extended_attribute("NoInterfaceObject")
    && (typeof obj != expected_typeof || obj instanceof Object))
    {
        subsetTestByKey(this.name, test, function()
        {
            assert_equals(exception, null, "Unexpected exception when evaluating object");
            assert_equals(typeof obj, expected_typeof, "wrong typeof object");
            this.assert_interface_object_exists();
            assert_own_property(this.get_interface_object(), "prototype",
                                'interface "' + this.name + '" does not have own property "prototype"');

            // "The value of the internal [[Prototype]] property of the
            // platform object is the interface prototype object of the primary
            // interface from the platform object’s associated global
            // environment."
            assert_equals(Object.getPrototypeOf(obj),
                          this.get_interface_object().prototype,
                          desc + "'s prototype is not " + this.name + ".prototype");
        }.bind(this), this.name + " must be primary interface of " + desc);
    }

    // "The class string of a platform object that implements one or more
    // interfaces must be the qualified name of the primary interface of the
    // platform object."
    subsetTestByKey(this.name, test, function()
    {
        assert_equals(exception, null, "Unexpected exception when evaluating object");
        assert_equals(typeof obj, expected_typeof, "wrong typeof object");
        assert_class_string(obj, this.get_qualified_name(), "class string of " + desc);
        if (!this.has_stringifier())
        {
            assert_equals(String(obj), "[object " + this.get_qualified_name() + "]", "String(" + desc + ")");
        }
    }.bind(this), "Stringification of " + desc);
};

IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expected_typeof)
{
    // TODO: Indexed and named properties, more checks on interface members
    this.already_tested = true;
    if (!shouldRunSubTest(this.name)) {
        return;
    }

    for (var i = 0; i < this.members.length; i++)
    {
        var member = this.members[i];
        if (member.untested) {
            continue;
        }
        if (!exposed_in(exposure_set(member, this.exposureSet))) {
            subsetTestByKey(this.name, test, function() {
                assert_equals(exception, null, "Unexpected exception when evaluating object");
                assert_false(member.name in obj);
            }.bind(this), this.name + " interface: " + desc + ' must not have property "' + member.name + '"');
            continue;
        }
        if (member.type == "attribute" && member.isUnforgeable)
        {
            var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: " + desc + ' must have own property "' + member.name + '"');
            a_test.step(function() {
                assert_equals(exception, null, "Unexpected exception when evaluating object");
                assert_equals(typeof obj, expected_typeof, "wrong typeof object");
                // Call do_interface_attribute_asserts last, since it will call a_test.done()
                this.do_interface_attribute_asserts(obj, member, a_test);
            }.bind(this));
        }
        else if (member.type == "operation" &&
                 member.name &&
                 member.isUnforgeable)
        {
            var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: " + desc + ' must have own property "' + member.name + '"');
            a_test.step(function()
            {
                assert_equals(exception, null, "Unexpected exception when evaluating object");
                assert_equals(typeof obj, expected_typeof, "wrong typeof object");
                assert_own_property(obj, member.name,
                                    "Doesn't have the unforgeable operation property");
                this.do_member_operation_asserts(obj, member, a_test);
            }.bind(this));
        }
        else if ((member.type == "const"
        || member.type == "attribute"
        || member.type == "operation")
        && member.name)
        {
            var described_name = member.name;
            if (member.type == "operation")
            {
                described_name += "(" + member.arguments.map(arg => arg.idlType.idlType).join(", ") + ")";
            }
            subsetTestByKey(this.name, test, function()
            {
                assert_equals(exception, null, "Unexpected exception when evaluating object");
                assert_equals(typeof obj, expected_typeof, "wrong typeof object");
                if (member.special !== "static") {
                    if (!this.is_global()) {
                        assert_inherits(obj, member.name);
                    } else {
                        assert_own_property(obj, member.name);
                    }

                    if (member.type == "const")
                    {
                        assert_equals(obj[member.name], constValue(member.value));
                    }
                    if (member.type == "attribute")
                    {
                        // Attributes are accessor properties, so they might
                        // legitimately throw an exception rather than returning
                        // anything.
                        var property, thrown = false;
                        try
                        {
                            property = obj[member.name];
                        }
                        catch (e)
                        {
                            thrown = true;
                        }
                        if (!thrown)
                        {
                            this.array.assert_type_is(property, member.idlType);
                        }
                    }
                    if (member.type == "operation")
                    {
                        assert_equals(typeof obj[member.name], "function");
                    }
                }
            }.bind(this), this.name + " interface: " + desc + ' must inherit property "' + described_name + '" with the proper type');
        }
        // TODO: This is wrong if there are multiple operations with the same
        // identifier.
        // TODO: Test passing arguments of the wrong type.
        if (member.type == "operation" && member.name && member.arguments.length)
        {
            var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: calling " + member.name +
            "(" + member.arguments.map(function(m) { return m.idlType.idlType; }).join(", ") +
            ") on " + desc + " with too few arguments must throw TypeError");
            a_test.step(function()
            {
                assert_equals(exception, null, "Unexpected exception when evaluating object");
                assert_equals(typeof obj, expected_typeof, "wrong typeof object");
                var fn;
                if (member.special !== "static") {
                    if (!this.is_global() && !member.isUnforgeable) {
                        assert_inherits(obj, member.name);
                    } else {
                        assert_own_property(obj, member.name);
                    }
                    fn = obj[member.name];
                }
                else
                {
                    assert_own_property(obj.constructor, member.name, "interface object must have static operation as own property");
                    fn = obj.constructor[member.name];
                }

                var minLength = minOverloadLength(this.members.filter(function(m) {
                    return m.type == "operation" && m.name == member.name;
                }));
                var args = [];
                var cb = awaitNCallbacks(minLength, a_test.done.bind(a_test));
                for (var i = 0; i < minLength; i++) {
                    throwOrReject(a_test, member, fn, obj, args, "Called with " + i + " arguments", cb);

                    args.push(create_suitable_object(member.arguments[i].idlType));
                }
                if (minLength === 0) {
                    cb();
                }
            }.bind(this));
        }

        if (member.is_to_json_regular_operation()) {
            this.test_to_json_operation(desc, obj, member);
        }
    }
};

IdlInterface.prototype.has_stringifier = function()
{
    if (this.name === "DOMException") {
        // toString is inherited from Error, so don't assume we have the
        // default stringifer
        return true;
    }
    if (this.members.some(function(member) { return member.special === "stringifier"; })) {
        return true;
    }
    if (this.base &&
        this.array.members[this.base].has_stringifier()) {
        return true;
    }
    return false;
};

IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member, a_test)
{
    // This function tests WebIDL as of 2015-01-27.
    // TODO: Consider [Exposed].

    // This is called by test_member_attribute() with the prototype as obj if
    // it is not a global, and the global otherwise, and by test_interface_of()
    // with the object as obj.

    var pendingPromises = [];

    // "For each exposed attribute of the interface, whether it was declared on
    // the interface itself or one of its consequential interfaces, there MUST
    // exist a corresponding property. The characteristics of this property are
    // as follows:"

    // "The name of the property is the identifier of the attribute."
    assert_own_property(obj, member.name);

    // "The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]:
    // true, [[Configurable]]: configurable }, where:
    // "configurable is false if the attribute was declared with the
    // [Unforgeable] extended attribute and true otherwise;
    // "G is the attribute getter, defined below; and
    // "S is the attribute setter, also defined below."
    var desc = Object.getOwnPropertyDescriptor(obj, member.name);
    assert_false("value" in desc, 'property descriptor should not have a "value" field');
    assert_false("writable" in desc, 'property descriptor should not have a "writable" field');
    assert_true(desc.enumerable, "property should be enumerable");
    if (member.isUnforgeable)
    {
        assert_false(desc.configurable, "[Unforgeable] property must not be configurable");
    }
    else
    {
        assert_true(desc.configurable, "property must be configurable");
    }


    // "The attribute getter is a Function object whose behavior when invoked
    // is as follows:"
    assert_equals(typeof desc.get, "function", "getter must be Function");

    // "If the attribute is a regular attribute, then:"
    if (member.special !== "static") {
        // "If O is not a platform object that implements I, then:
        // "If the attribute was specified with the [LenientThis] extended
        // attribute, then return undefined.
        // "Otherwise, throw a TypeError."
        if (!member.has_extended_attribute("LenientThis")) {
            if (member.idlType.generic !== "Promise") {
                assert_throws(new TypeError(), function() {
                    desc.get.call({});
                }.bind(this), "calling getter on wrong object type must throw TypeError");
            } else {
                pendingPromises.push(
                    promise_rejects(a_test, new TypeError(), desc.get.call({}),
                                    "calling getter on wrong object type must reject the return promise with TypeError"));
            }
        } else {
            assert_equals(desc.get.call({}), undefined,
                          "calling getter on wrong object type must return undefined");
        }
    }

    // "The value of the Function object’s “length” property is the Number
    // value 0."
    assert_equals(desc.get.length, 0, "getter length must be 0");

    // "Let name be the string "get " prepended to attribute’s identifier."
    // "Perform ! SetFunctionName(F, name)."
    assert_equals(desc.get.name, "get " + member.name,
        "getter must have the name 'get " + member.name + "'");


    // TODO: Test calling setter on the interface prototype (should throw
    // TypeError in most cases).
    if (member.readonly
    && !member.has_extended_attribute("LenientSetter")
    && !member.has_extended_attribute("PutForwards")
    && !member.has_extended_attribute("Replaceable"))
    {
        // "The attribute setter is undefined if the attribute is declared
        // readonly and has neither a [PutForwards] nor a [Replaceable]
        // extended attribute declared on it."
        assert_equals(desc.set, undefined, "setter must be undefined for readonly attributes");
    }
    else
    {
        // "Otherwise, it is a Function object whose behavior when
        // invoked is as follows:"
        assert_equals(typeof desc.set, "function", "setter must be function for PutForwards, Replaceable, or non-readonly attributes");

        // "If the attribute is a regular attribute, then:"
        if (member.special !== "static") {
            // "If /validThis/ is false and the attribute was not specified
            // with the [LenientThis] extended attribute, then throw a
            // TypeError."
            // "If the attribute is declared with a [Replaceable] extended
            // attribute, then: ..."
            // "If validThis is false, then return."
            if (!member.has_extended_attribute("LenientThis")) {
                assert_throws(new TypeError(), function() {
                    desc.set.call({});
                }.bind(this), "calling setter on wrong object type must throw TypeError");
            } else {
                assert_equals(desc.set.call({}), undefined,
                              "calling setter on wrong object type must return undefined");
            }
        }

        // "The value of the Function object’s “length” property is the Number
        // value 1."
        assert_equals(desc.set.length, 1, "setter length must be 1");

        // "Let name be the string "set " prepended to id."
        // "Perform ! SetFunctionName(F, name)."
        assert_equals(desc.set.name, "set " + member.name,
            "The attribute setter must have the name 'set " + member.name + "'");
    }

    Promise.all(pendingPromises).then(a_test.done.bind(a_test));
}

/// IdlInterfaceMember ///
function IdlInterfaceMember(obj)
{
    /**
     * obj is an object produced by the WebIDLParser.js "ifMember" production.
     * We just forward all properties to this object without modification,
     * except for special extAttrs handling.
     */
    for (var k in obj.toJSON())
    {
        this[k] = obj[k];
    }
    if (!("extAttrs" in this))
    {
        this.extAttrs = [];
    }

    this.isUnforgeable = this.has_extended_attribute("Unforgeable");
    this.isUnscopable = this.has_extended_attribute("Unscopable");
}

IdlInterfaceMember.prototype = Object.create(IdlObject.prototype);

IdlInterfaceMember.prototype.toJSON = function() {
    return this;
};

IdlInterfaceMember.prototype.is_to_json_regular_operation = function() {
    return this.type == "operation" && this.special !== "static" && this.name == "toJSON";
};

/// Internal helper functions ///
function create_suitable_object(type)
{
    /**
     * type is an object produced by the WebIDLParser.js "type" production.  We
     * return a JavaScript value that matches the type, if we can figure out
     * how.
     */
    if (type.nullable)
    {
        return null;
    }
    switch (type.idlType)
    {
        case "any":
        case "boolean":
            return true;

        case "byte": case "octet": case "short": case "unsigned short":
        case "long": case "unsigned long": case "long long":
        case "unsigned long long": case "float": case "double":
        case "unrestricted float": case "unrestricted double":
            return 7;

        case "DOMString":
        case "ByteString":
        case "USVString":
            return "foo";

        case "object":
            return {a: "b"};

        case "Node":
            return document.createTextNode("abc");
    }
    return null;
}

/// IdlEnum ///
// Used for IdlArray.prototype.assert_type_is
function IdlEnum(obj)
{
    /**
     * obj is an object produced by the WebIDLParser.js "dictionary"
     * production.
     */

    /** Self-explanatory. */
    this.name = obj.name;

    /** An array of values produced by the "enum" production. */
    this.values = obj.values;

}

IdlEnum.prototype = Object.create(IdlObject.prototype);

/// IdlCallback ///
// Used for IdlArray.prototype.assert_type_is
function IdlCallback(obj)
{
    /**
     * obj is an object produced by the WebIDLParser.js "callback"
     * production.
     */

    /** Self-explanatory. */
    this.name = obj.name;

    /** Arguments for the callback. */
    this.arguments = obj.arguments;
}

IdlCallback.prototype = Object.create(IdlObject.prototype);

/// IdlTypedef ///
// Used for IdlArray.prototype.assert_type_is
function IdlTypedef(obj)
{
    /**
     * obj is an object produced by the WebIDLParser.js "typedef"
     * production.
     */

    /** Self-explanatory. */
    this.name = obj.name;

    /** The idlType that we are supposed to be typedeffing to. */
    this.idlType = obj.idlType;

}

IdlTypedef.prototype = Object.create(IdlObject.prototype);

/// IdlNamespace ///
function IdlNamespace(obj)
{
    this.name = obj.name;
    this.extAttrs = obj.extAttrs;
    this.untested = obj.untested;
    /** A back-reference to our IdlArray. */
    this.array = obj.array;

    /** An array of IdlInterfaceMembers. */
    this.members = obj.members.map(m => new IdlInterfaceMember(m));
}

IdlNamespace.prototype = Object.create(IdlObject.prototype);

IdlNamespace.prototype.do_member_operation_asserts = function (memberHolderObject, member, a_test)
{
    var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);

    assert_false("get" in desc, "property should not have a getter");
    assert_false("set" in desc, "property should not have a setter");
    assert_equals(
        desc.writable,
        !member.isUnforgeable,
        "property should be writable if and only if not unforgeable");
    assert_true(desc.enumerable, "property should be enumerable");
    assert_equals(
        desc.configurable,
        !member.isUnforgeable,
        "property should be configurable if and only if not unforgeable");

    assert_equals(
        typeof memberHolderObject[member.name],
        "function",
         "property must be a function");

    assert_equals(
        memberHolderObject[member.name].length,
        minOverloadLength(this.members.filter(function(m) {
            return m.type == "operation" && m.name == member.name;
        })),
        "operation has wrong .length");
    a_test.done();
}

IdlNamespace.prototype.test_member_operation = function(member)
{
    if (!shouldRunSubTest(this.name)) {
        return;
    }
    var args = member.arguments.map(function(a) {
        var s = a.idlType.idlType;
        if (a.variadic) {
            s += '...';
        }
        return s;
    }).join(", ");
    var a_test = subsetTestByKey(
        this.name,
        async_test,
        this.name + ' namespace: operation ' + member.name + '(' + args + ')');
    a_test.step(function() {
        assert_own_property(
            self[this.name],
            member.name,
            'namespace object missing operation ' + format_value(member.name));

        this.do_member_operation_asserts(self[this.name], member, a_test);
    }.bind(this));
};

IdlNamespace.prototype.test_member_attribute = function (member)
{
    if (!shouldRunSubTest(this.name)) {
        return;
    }
    var a_test = subsetTestByKey(
        this.name,
        async_test,
        this.name + ' namespace: attribute ' + member.name);
    a_test.step(function()
    {
        assert_own_property(
            self[this.name],
            member.name,
            this.name + ' does not have property ' + format_value(member.name));

        var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);
        assert_equals(desc.set, undefined, "setter must be undefined for namespace members");
        a_test.done();
    }.bind(this));
};

IdlNamespace.prototype.test = function ()
{
    /**
     * TODO(lukebjerring): Assert:
     * - "Note that unlike interfaces or dictionaries, namespaces do not create types."
     * - "Of the extended attributes defined in this specification, only the
     *     [Exposed] and [SecureContext] extended attributes are applicable to namespaces."
     * - "Namespaces must be annotated with the [Exposed] extended attribute."
     */

    for (const v of Object.values(this.members)) {
        switch (v.type) {

        case 'operation':
            this.test_member_operation(v);
            break;

        case 'attribute':
            this.test_member_attribute(v);
            break;

        default:
            throw 'Invalid namespace member ' + v.name + ': ' + v.type + ' not supported';
        }
    };
};

}());

/**
 * idl_test is a promise_test wrapper that handles the fetching of the IDL,
 * avoiding repetitive boilerplate.
 *
 * @param {String|String[]} srcs Spec name(s) for source idl files (fetched from
 *      /interfaces/{name}.idl).
 * @param {String|String[]} deps Spec name(s) for dependency idl files (fetched
 *      from /interfaces/{name}.idl). Order is important - dependencies from
 *      each source will only be included if they're already know to be a
 *      dependency (i.e. have already been seen).
 * @param {Function} setup_func Function for extra setup of the idl_array, such
 *      as adding objects. Do not call idl_array.test() in the setup; it is
 *      called by this function (idl_test).
 */
function idl_test(srcs, deps, idl_setup_func) {
    return promise_test(function (t) {
        var idl_array = new IdlArray();
        srcs = (srcs instanceof Array) ? srcs : [srcs] || [];
        deps = (deps instanceof Array) ? deps : [deps] || [];
        var setup_error = null;
        return Promise.all(
            srcs.concat(deps).map(function(spec) {
                return fetch_spec(spec);
            }))
            .then(function(idls) {
                for (var i = 0; i < srcs.length; i++) {
                    idl_array.add_idls(idls[i]);
                }
                for (var i = srcs.length; i < srcs.length + deps.length; i++) {
                    idl_array.add_dependency_idls(idls[i]);
                }
            })
            .then(function() {
                if (idl_setup_func) {
                    return idl_setup_func(idl_array, t);
                }
            })
            .catch(function(e) { setup_error = e || 'IDL setup failed.'; })
            .then(function () {
                var error = setup_error;
                try {
                    idl_array.test(); // Test what we can.
                } catch (e) {
                    // If testing fails hard here, the original setup error
                    // is more likely to be the real cause.
                    error = error || e;
                }
                if (error) {
                    throw error;
                }
            });
    }, 'idl_test setup');
}

/**
 * fetch_spec is a shorthand for a Promise that fetches the spec's content.
 */
function fetch_spec(spec) {
    var url = '/interfaces/' + spec + '.idl';
    return fetch(url).then(function (r) {
        if (!r.ok) {
            throw new IdlHarnessError("Error fetching " + url + ".");
        }
        return r.text();
    });
}
// vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker:
