2014-10-07 16:24:59 +00:00
|
|
|
// Copyright 2014 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
// Flags: --harmony
|
|
|
|
|
|
|
|
(function TestBasics() {
|
|
|
|
var C = class C {}
|
|
|
|
assertEquals(typeof C, 'function');
|
|
|
|
assertEquals(C.__proto__, Function.prototype);
|
|
|
|
assertEquals(Object.prototype, Object.getPrototypeOf(C.prototype));
|
|
|
|
assertEquals(Function.prototype, Object.getPrototypeOf(C));
|
|
|
|
assertEquals('C', C.name);
|
|
|
|
|
|
|
|
class D {}
|
|
|
|
assertEquals(typeof D, 'function');
|
|
|
|
assertEquals(D.__proto__, Function.prototype);
|
|
|
|
assertEquals(Object.prototype, Object.getPrototypeOf(D.prototype));
|
|
|
|
assertEquals(Function.prototype, Object.getPrototypeOf(D));
|
|
|
|
assertEquals('D', D.name);
|
|
|
|
|
|
|
|
var E = class {}
|
|
|
|
assertEquals('', E.name);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestBasicsExtends() {
|
|
|
|
class C extends null {}
|
|
|
|
assertEquals(typeof C, 'function');
|
|
|
|
assertEquals(C.__proto__, Function.prototype);
|
|
|
|
assertEquals(null, Object.getPrototypeOf(C.prototype));
|
|
|
|
|
|
|
|
class D extends C {}
|
|
|
|
assertEquals(typeof D, 'function');
|
|
|
|
assertEquals(D.__proto__, C);
|
|
|
|
assertEquals(C.prototype, Object.getPrototypeOf(D.prototype));
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestSideEffectInExtends() {
|
|
|
|
var calls = 0;
|
|
|
|
class C {}
|
|
|
|
class D extends (calls++, C) {}
|
|
|
|
assertEquals(1, calls);
|
|
|
|
assertEquals(typeof D, 'function');
|
|
|
|
assertEquals(D.__proto__, C);
|
|
|
|
assertEquals(C.prototype, Object.getPrototypeOf(D.prototype));
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestInvalidExtends() {
|
|
|
|
assertThrows(function() {
|
|
|
|
class C extends 42 {}
|
|
|
|
}, TypeError);
|
|
|
|
|
|
|
|
assertThrows(function() {
|
|
|
|
// Function but its .prototype is not null or a function.
|
|
|
|
class C extends Math.abs {}
|
|
|
|
}, TypeError);
|
|
|
|
|
|
|
|
assertThrows(function() {
|
|
|
|
Math.abs.prototype = 42;
|
|
|
|
class C extends Math.abs {}
|
|
|
|
}, TypeError);
|
|
|
|
delete Math.abs.prototype;
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestConstructorProperty() {
|
|
|
|
class C {}
|
|
|
|
assertEquals(C, C.prototype.constructor);
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(C.prototype, 'constructor');
|
|
|
|
assertTrue(descr.configurable);
|
|
|
|
assertFalse(descr.enumerable);
|
|
|
|
assertTrue(descr.writable);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestPrototypeProperty() {
|
|
|
|
class C {}
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(C, 'prototype');
|
|
|
|
assertFalse(descr.configurable);
|
|
|
|
assertFalse(descr.enumerable);
|
|
|
|
assertFalse(descr.writable);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestConstructor() {
|
|
|
|
var count = 0;
|
|
|
|
class C {
|
|
|
|
constructor() {
|
|
|
|
assertEquals(Object.getPrototypeOf(this), C.prototype);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assertEquals(C, C.prototype.constructor);
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(C.prototype, 'constructor');
|
|
|
|
assertTrue(descr.configurable);
|
|
|
|
assertFalse(descr.enumerable);
|
|
|
|
assertTrue(descr.writable);
|
|
|
|
|
|
|
|
var c = new C();
|
|
|
|
assertEquals(1, count);
|
|
|
|
assertEquals(Object.getPrototypeOf(c), C.prototype);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestImplicitConstructor() {
|
|
|
|
class C {}
|
|
|
|
var c = new C();
|
|
|
|
assertEquals(Object.getPrototypeOf(c), C.prototype);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestConstructorStrict() {
|
|
|
|
class C {
|
|
|
|
constructor() {
|
|
|
|
assertThrows(function() {
|
|
|
|
nonExistingBinding = 42;
|
|
|
|
}, ReferenceError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new C();
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestSuperInConstructor() {
|
|
|
|
var calls = 0;
|
|
|
|
class B {}
|
|
|
|
B.prototype.x = 42;
|
|
|
|
|
|
|
|
class C extends B {
|
|
|
|
constructor() {
|
|
|
|
calls++;
|
|
|
|
assertEquals(42, super.x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
new C;
|
|
|
|
assertEquals(1, calls);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestStrictMode() {
|
|
|
|
class C {}
|
|
|
|
|
|
|
|
with ({a: 1}) {
|
|
|
|
assertEquals(1, a);
|
|
|
|
}
|
|
|
|
|
|
|
|
assertThrows('class C extends function B() { with ({}); return B; }() {}',
|
|
|
|
SyntaxError);
|
|
|
|
|
|
|
|
})();
|
|
|
|
|
2014-10-28 12:43:05 +00:00
|
|
|
|
|
|
|
(function TestToString() {
|
|
|
|
class C {}
|
|
|
|
assertEquals('class C {}', C.toString());
|
|
|
|
|
|
|
|
class D { constructor() { 42; } }
|
|
|
|
assertEquals('class D { constructor() { 42; } }', D.toString());
|
|
|
|
|
|
|
|
class E { x() { 42; } }
|
|
|
|
assertEquals('class E { x() { 42; } }', E.toString());
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
function assertMethodDescriptor(object, name) {
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(object, name);
|
|
|
|
assertTrue(descr.configurable);
|
|
|
|
assertTrue(descr.enumerable);
|
|
|
|
assertTrue(descr.writable);
|
|
|
|
assertEquals('function', typeof descr.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertGetterDescriptor(object, name) {
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(object, name);
|
|
|
|
assertTrue(descr.configurable);
|
|
|
|
assertTrue(descr.enumerable);
|
|
|
|
assertEquals('function', typeof descr.get);
|
|
|
|
assertEquals(undefined, descr.set);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function assertSetterDescriptor(object, name) {
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(object, name);
|
|
|
|
assertTrue(descr.configurable);
|
|
|
|
assertTrue(descr.enumerable);
|
|
|
|
assertEquals(undefined, descr.get);
|
|
|
|
assertEquals('function', typeof descr.set);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function assertAccessorDescriptor(object, name) {
|
|
|
|
var descr = Object.getOwnPropertyDescriptor(object, name);
|
|
|
|
assertTrue(descr.configurable);
|
|
|
|
assertTrue(descr.enumerable);
|
|
|
|
assertEquals('function', typeof descr.get);
|
|
|
|
assertEquals('function', typeof descr.set);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
(function TestMethods() {
|
|
|
|
class C {
|
|
|
|
method() { return 1; }
|
|
|
|
static staticMethod() { return 2; }
|
|
|
|
method2() { return 3; }
|
|
|
|
static staticMethod2() { return 4; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertMethodDescriptor(C.prototype, 'method');
|
|
|
|
assertMethodDescriptor(C.prototype, 'method2');
|
|
|
|
assertMethodDescriptor(C, 'staticMethod');
|
|
|
|
assertMethodDescriptor(C, 'staticMethod2');
|
|
|
|
|
|
|
|
assertEquals(1, new C().method());
|
|
|
|
assertEquals(2, C.staticMethod());
|
|
|
|
assertEquals(3, new C().method2());
|
|
|
|
assertEquals(4, C.staticMethod2());
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestGetters() {
|
|
|
|
class C {
|
|
|
|
get x() { return 1; }
|
|
|
|
static get staticX() { return 2; }
|
|
|
|
get y() { return 3; }
|
|
|
|
static get staticY() { return 4; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertGetterDescriptor(C.prototype, 'x');
|
|
|
|
assertGetterDescriptor(C.prototype, 'y');
|
|
|
|
assertGetterDescriptor(C, 'staticX');
|
|
|
|
assertGetterDescriptor(C, 'staticY');
|
|
|
|
|
|
|
|
assertEquals(1, new C().x);
|
|
|
|
assertEquals(2, C.staticX);
|
|
|
|
assertEquals(3, new C().y);
|
|
|
|
assertEquals(4, C.staticY);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function TestSetters() {
|
|
|
|
var x, staticX, y, staticY;
|
|
|
|
class C {
|
|
|
|
set x(v) { x = v; }
|
|
|
|
static set staticX(v) { staticX = v; }
|
|
|
|
set y(v) { y = v; }
|
|
|
|
static set staticY(v) { staticY = v; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertSetterDescriptor(C.prototype, 'x');
|
|
|
|
assertSetterDescriptor(C.prototype, 'y');
|
|
|
|
assertSetterDescriptor(C, 'staticX');
|
|
|
|
assertSetterDescriptor(C, 'staticY');
|
|
|
|
|
|
|
|
assertEquals(1, new C().x = 1);
|
|
|
|
assertEquals(1, x);
|
|
|
|
assertEquals(2, C.staticX = 2);
|
|
|
|
assertEquals(2, staticX);
|
|
|
|
assertEquals(3, new C().y = 3);
|
|
|
|
assertEquals(3, y);
|
|
|
|
assertEquals(4, C.staticY = 4);
|
|
|
|
assertEquals(4, staticY);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestSideEffectsInPropertyDefine() {
|
|
|
|
function B() {}
|
|
|
|
B.prototype = {
|
|
|
|
constructor: B,
|
|
|
|
set m(v) {
|
|
|
|
throw Error();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class C extends B {
|
|
|
|
m() { return 1; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, new C().m());
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestAccessors() {
|
|
|
|
class C {
|
|
|
|
constructor(x) {
|
|
|
|
this._x = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
get x() { return this._x; }
|
|
|
|
set x(v) { this._x = v; }
|
|
|
|
|
|
|
|
static get staticX() { return this._x; }
|
|
|
|
static set staticX(v) { this._x = v; }
|
|
|
|
}
|
|
|
|
|
|
|
|
assertAccessorDescriptor(C.prototype, 'x');
|
|
|
|
assertAccessorDescriptor(C, 'staticX');
|
|
|
|
|
|
|
|
var c = new C(1);
|
|
|
|
c._x = 1;
|
|
|
|
assertEquals(1, c.x);
|
|
|
|
c.x = 2;
|
|
|
|
assertEquals(2, c._x);
|
|
|
|
|
|
|
|
C._x = 3;
|
|
|
|
assertEquals(3, C.staticX);
|
|
|
|
C._x = 4;
|
|
|
|
assertEquals(4, C.staticX );
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestProto() {
|
|
|
|
class C {
|
|
|
|
__proto__() { return 1; }
|
|
|
|
}
|
|
|
|
assertMethodDescriptor(C.prototype, '__proto__');
|
|
|
|
assertEquals(1, new C().__proto__());
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestProtoStatic() {
|
|
|
|
class C {
|
|
|
|
static __proto__() { return 1; }
|
|
|
|
}
|
|
|
|
assertMethodDescriptor(C, '__proto__');
|
|
|
|
assertEquals(1, C.__proto__());
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestProtoAccessor() {
|
|
|
|
class C {
|
|
|
|
get __proto__() { return this._p; }
|
|
|
|
set __proto__(v) { this._p = v; }
|
|
|
|
}
|
|
|
|
assertAccessorDescriptor(C.prototype, '__proto__');
|
|
|
|
var c = new C();
|
|
|
|
c._p = 1;
|
|
|
|
assertEquals(1, c.__proto__);
|
|
|
|
c.__proto__ = 2;
|
|
|
|
assertEquals(2, c.__proto__);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestStaticProtoAccessor() {
|
|
|
|
class C {
|
|
|
|
static get __proto__() { return this._p; }
|
|
|
|
static set __proto__(v) { this._p = v; }
|
|
|
|
}
|
|
|
|
assertAccessorDescriptor(C, '__proto__');
|
|
|
|
C._p = 1;
|
|
|
|
assertEquals(1, C.__proto__);
|
|
|
|
C.__proto__ = 2;
|
|
|
|
assertEquals(2, C.__proto__);
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
|
|
(function TestSettersOnProto() {
|
|
|
|
function Base() {}
|
|
|
|
Base.prototype = {
|
|
|
|
set constructor(_) {
|
|
|
|
assertUnreachable();
|
|
|
|
},
|
|
|
|
set m(_) {
|
|
|
|
assertUnreachable();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Object.defineProperty(Base, 'staticM', {
|
|
|
|
set: function() {
|
|
|
|
assertUnreachable();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
class C extends Base {
|
|
|
|
m() {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static staticM() {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assertEquals(1, new C().m());
|
|
|
|
assertEquals(2, C.staticM());
|
|
|
|
})();
|
|
|
|
|
2014-10-07 16:24:59 +00:00
|
|
|
/* TODO(arv): Implement
|
|
|
|
(function TestNameBindingInConstructor() {
|
|
|
|
class C {
|
|
|
|
constructor() {
|
|
|
|
assertThrows(function() {
|
|
|
|
C = 42;
|
|
|
|
}, ReferenceError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new C();
|
|
|
|
})();
|
|
|
|
*/
|