Bug 1066238 - Tests. (r=jorendorff)

This commit is contained in:
Eric Faust 2015-02-26 15:05:26 -08:00
parent 8bdb7090c2
commit b0eef835a3
4 changed files with 145 additions and 10 deletions

View File

@ -18,6 +18,40 @@ Object.defineProperty(desiredPrototype, "constructor", { writable: true,
enumerable: false,
value: a });
assertDeepEq(prototype, desiredPrototype);
try {
eval(\`class a {
constructor() { };
static [\"prototype\"]() { };
}\`);
} catch (e if e instanceof TypeError) {
throw new Error("Congrats on making initprop respect non-writable " +
"non-configurable properties. Uncomment the test below " +
"for bonus points.");
/*
// As such, it should by a TypeError to try and overwrite "prototype" with a
// static member. The only way to try is with a computed property name; the rest
// are early errors.
assertThrowsInstanceOf(() => eval(\`
class a {
constructor() { };
static ["prototype"]() { }
}
\`), TypeError);
assertThrowsInstanceOf(() => eval(\`
class a {
constructor() { };
static get ["prototype"]() { }
}
\`), TypeError);
assertThrowsInstanceOf(() => eval(\`
class a {
constructor() { };
static set ["prototype"](x) { }
}
\`), TypeError);
*/
}
`;
if (classesEnabled())

View File

@ -6,11 +6,17 @@ var methodCalled = false;
var getterCalled = false;
var setterCalled = false;
var constructorCalled = false;
var staticMethodCalled = false;
var staticGetterCalled = false;
var staticSetterCalled = false;
class a {
constructor() { constructorCalled = true; }
__proto__() { methodCalled = true }
get getter() { getterCalled = true; }
set setter(x) { setterCalled = true; }
static staticMethod() { staticMethodCalled = true; }
static get staticGetter() { staticGetterCalled = true; }
static set staticSetter(x) { staticSetterCalled = true; }
*[Symbol.iterator]() { yield "cow"; yield "pig"; }
}
var aConstDesc = Object.getOwnPropertyDescriptor(a.prototype, \"constructor\");
@ -42,6 +48,28 @@ aSetDesc.set();
assertEq(setterCalled, true);
assertDeepEq(aSetDesc, Object.getOwnPropertyDescriptor(a.prototype, \"setter\"));
assertEq(Object.getOwnPropertyDescriptor(new a(), \"staticMethod\"), undefined);
var aStaticMethDesc = Object.getOwnPropertyDescriptor(a, \"staticMethod\");
assertEq(aStaticMethDesc.configurable, true);
assertEq(aStaticMethDesc.enumerable, true);
assertEq(aStaticMethDesc.writable, true);
aStaticMethDesc.value();
assertEq(staticMethodCalled, true);
assertEq(Object.getOwnPropertyDescriptor(new a(), \"staticGetter\"), undefined);
var aStaticGetDesc = Object.getOwnPropertyDescriptor(a, \"staticGetter\");
assertEq(aStaticGetDesc.configurable, true);
assertEq(aStaticGetDesc.enumerable, true);
aStaticGetDesc.get();
assertEq(staticGetterCalled, true);
assertEq(Object.getOwnPropertyDescriptor(new a(), \"staticSetter\"), undefined);
var aStaticSetDesc = Object.getOwnPropertyDescriptor(a, \"staticSetter\");
assertEq(aStaticSetDesc.configurable, true);
assertEq(aStaticSetDesc.enumerable, true);
aStaticSetDesc.set();
assertEq(staticSetterCalled, true);
assertEq([...new a()].join(), "cow,pig");
`;

View File

@ -0,0 +1,22 @@
var test = `
// basic static method test
class X {
static count() { return ++this.hits; }
constructor() { }
}
X.hits = 0;
assertEq(X.count(), 1);
// A static method is just a function.
assertEq(X.count instanceof Function, true);
assertEq(X.count.length, 0);
assertEq(X.count.bind({hits: 77})(), 78);
`;
if (classesEnabled())
eval(test);
if (typeof reportCompare === "function")
reportCompare(0, 0, "OK");

View File

@ -1161,14 +1161,19 @@ function testClasses() {
// No unnamed class statements.
assertError("class { constructor() { } }", SyntaxError);
function simpleMethod(id, kind, generator, args=[]) {
function simpleMethod(id, kind, generator, args=[], isStatic=false) {
assertEq(generator && kind === "method", generator);
let idN = ident(id);
let methodMaker = generator ? genFunExpr : funExpr;
let methodName = kind !== "method" ? null : idN;
let methodFun = methodMaker(methodName, args.map(ident), blockStmt([]));
return classMethod(idN, methodFun, kind, false);
return classMethod(idN, methodFun, kind, isStatic);
}
function emptyCPNMethod(id, isStatic) {
return classMethod(computedName(lit(id)),
funExpr(null, [], blockStmt([])),
"method", isStatic);
}
function setClassMethods(class_, methods) {
class_.template.body = methods;
@ -1191,17 +1196,60 @@ function testClasses() {
setClassMethods(stmt, [simpleConstructor, simpleMethod("method", "set", false, ["x"])]);
assertStmt("class Foo { constructor() { } set method(x) { } }", stmt);
/* Static */
setClassMethods(stmt, [simpleConstructor,
simpleMethod("method", "method", false, [], true),
simpleMethod("methodGen", "method", true, [], true),
simpleMethod("getter", "get", false, [], true),
simpleMethod("setter", "set", false, ["x"], true)]);
assertStmt(`class Foo {
constructor() { };
static method() { };
static *methodGen() { };
static get getter() { };
static set setter(x) { }
}`, stmt);
// It's not an error to have a method named static, static, or not.
setClassMethods(stmt, [simpleConstructor, simpleMethod("static", "method", false, [], false)]);
assertStmt("class Foo{ constructor() { } static() { } }", stmt);
setClassMethods(stmt, [simpleMethod("static", "method", false, [], true), simpleConstructor]);
assertStmt("class Foo{ static static() { }; constructor() { } }", stmt);
setClassMethods(stmt, [simpleMethod("static", "get", false, [], true), simpleConstructor]);
assertStmt("class Foo { static get static() { }; constructor() { } }", stmt);
setClassMethods(stmt, [simpleConstructor, simpleMethod("static", "set", false, ["x"], true)]);
assertStmt("class Foo { constructor() { }; static set static(x) { } }", stmt);
// You do, however, have to put static in the right spot
assertError("class Foo { constructor() { }; get static foo() { } }", SyntaxError);
// Spec disallows "prototype" as a static member in a class, since that
// one's important to make the desugaring work
assertError("class Foo { constructor() { } static prototype() { } }", SyntaxError);
assertError("class Foo { constructor() { } static *prototype() { } }", SyntaxError);
assertError("class Foo { static get prototype() { }; constructor() { } }", SyntaxError);
assertError("class Foo { static set prototype(x) { }; constructor() { } }", SyntaxError);
// You are, however, allowed to have a CPN called prototype as a static
setClassMethods(stmt, [simpleConstructor, emptyCPNMethod("prototype", true)]);
assertStmt("class Foo { constructor() { }; static [\"prototype\"]() { } }", stmt);
/* Constructor */
// Currently, we do not allow default constructors
assertError("class Foo { }", TypeError);
// It is an error to have two methods named constructor, but not other
// names, regardless if one is an accessor or a generator.
// names, regardless if one is an accessor or a generator or static.
assertError("class Foo { constructor() { } constructor(a) { } }", SyntaxError);
let methods = [["method() { }", simpleMethod("method", "method", false)],
["*method() { }", simpleMethod("method", "method", true)],
["get method() { }", simpleMethod("method", "get", false)],
["set method(x) { }", simpleMethod("method", "set", false, ["x"])]];
["set method(x) { }", simpleMethod("method", "set", false, ["x"])],
["static method() { }", simpleMethod("method", "method", false, [], true)],
["static *method() { }", simpleMethod("method", "method", true, [], true)],
["static get method() { }", simpleMethod("method", "get", false, [], true)],
["static set method(x) { }", simpleMethod("method", "set", false, ["x"], true)]];
let i,j;
for (i=0; i < methods.length; i++) {
for (j=0; j < methods.length; j++) {
@ -1218,12 +1266,8 @@ function testClasses() {
// It is, however, not an error to have a constructor, and a method with a
// computed property name 'constructor'
assertStmt("class Foo { constructor () { } [\"constructor\"] () { } }",
classStmt(ident("Foo"), null,
[simpleConstructor,
classMethod(computedName(lit("constructor")),
funExpr(null, [], blockStmt([])),
"method", false)]));
setClassMethods(stmt, [simpleConstructor, emptyCPNMethod("constructor", false)]);
assertStmt("class Foo { constructor () { } [\"constructor\"] () { } }", stmt);
// It is an error to have a generator or accessor named constructor
assertError("class Foo { *constructor() { } }", SyntaxError);
@ -1283,6 +1327,13 @@ function testClasses() {
assertError("class Foo { constructor()", SyntaxError);
assertError("class Foo { constructor() {", SyntaxError);
assertError("class Foo { constructor() { }", SyntaxError);
assertError("class Foo { static", SyntaxError);
assertError("class Foo { static y", SyntaxError);
assertError("class Foo { static *", SyntaxError);
assertError("class Foo { static *y", SyntaxError);
assertError("class Foo { static get", SyntaxError);
assertError("class Foo { static get y", SyntaxError);
}
if (classesEnabled())