swc/ecmascript/transforms/src/compat/es2015/classes/tests.rs

748 lines
12 KiB
Rust
Raw Normal View History

use super::*;
test!(
Classes::default(),
basic,
r#"class Test {
constructor(name) {
this.name = name;
}
logger () {
console.log("Hello", this.name);
}
}"#,
r#"var Test = function () {
function Test(name) {
_classCallCheck(this, Test);
this.name = name;
}
_createClass(Test, [{
key: "logger",
value: function logger() {
console.log("Hello", this.name);
}
}]);
return Test;
}();"#
);
test!(
Classes::default(),
method_hoisted,
r#"class Foo {
foo(){
}
constructor(s){
}
}"#,
r#"var Foo = function () {
function Foo(s) {
_classCallCheck(this, Foo);
}
_createClass(Foo, [{
key: "foo",
value: function foo() {}
}]);
return Foo;
}();"#
);
test!(
Classes::default(),
static_method,
r#"class Foo {
static st(){}
}"#,
r#"var Foo = function () {
function Foo() {
_classCallCheck(this, Foo);
}
_createClass(Foo, null, [{
key: "st",
value: function st() {}
}]);
return Foo;
}();"#
);
test!(
Classes::default(),
complex_with_consturctor,
r#"class Foo {
foo(){
}
constructor(s){
}
static st(){}
}"#,
r#"var Foo = function () {
function Foo(s) {
_classCallCheck(this, Foo);
}
_createClass(Foo, [{
key: "foo",
value: function foo() {}
}], [{
key: "st",
value: function st() {}
}]);
return Foo;
}();"#
);
test!(
Classes::default(),
super_access,
r#"class Parent {
foo(a){}
}
class Child extends Parent {
foo(a, b){
super.foo(a);
super.f;
super.f.f.f.f;
}
bar(){
}
}"#,
r#"var Parent = function () {
function Parent() {
_classCallCheck(this, Parent);
}
_createClass(Parent, [{
key: "foo",
value: function foo(a) {}
}]);
return Parent;
}();
var Child = function (_Parent) {
_inherits(Child, _Parent);
function Child() {
_classCallCheck(this, Child);
return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments));
}
_createClass(Child, [{
key: "foo",
value: function foo(a, b) {
_get(Child.prototype.__proto__ || Object.getPrototypeOf(Child.prototype), "foo", this).call(this, a);
_get(Child.prototype.__proto__ || Object.getPrototypeOf(Child.prototype), "f", this);
_get(Child.prototype.__proto__ || Object.getPrototypeOf(Child.prototype), "f", this).f.f.f;
}
}, {
key: "bar",
value: function bar() {}
}]);
return Child;
}(Parent);"#
);
test!(
Classes::default(),
method_override,
r#"class Parent {
foo(a){}
}
class Child extends Parent {
foo(a, b){
super.foo(a);
}
bar(){
}
}"#,
r#"var Parent = function () {
function Parent() {
_classCallCheck(this, Parent);
}
_createClass(Parent, [{
key: "foo",
value: function foo(a) {}
}]);
return Parent;
}();
var Child = function (_Parent) {
_inherits(Child, _Parent);
function Child() {
_classCallCheck(this, Child);
return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments));
}
_createClass(Child, [{
key: "foo",
value: function foo(a, b) {
_get(Child.prototype.__proto__ || Object.getPrototypeOf(Child.prototype), "foo", this).call(this, a);
}
}, {
key: "bar",
value: function bar() {}
}]);
return Child;
}(Parent);"#
);
test!(Classes::default(), inherit_constructor, r#"class Parent {
constructor(){
}
foo(){}
}
class Child extends Parent {
}"#, r#"var Parent = function () {
function Parent() {
_classCallCheck(this, Parent);
}
_createClass(Parent, [{
key: "foo",
value: function foo() {}
}]);
return Parent;
}();
var Child = function (_Parent) {
_inherits(Child, _Parent);
function Child() {
_classCallCheck(this, Child);
return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments));
}
return Child;
}(Parent);"#);
test!(
Classes::default(),
custom_constructor,
r#"class Parent {
constructor(){
}
foo(){}
}
class Child extends Parent {
constructor(){
super();
}
}"#,
r#"var Parent = function () {
function Parent() {
_classCallCheck(this, Parent);
}
_createClass(Parent, [{
key: "foo",
value: function foo() {}
}]);
return Parent;
}();
var Child = function (_Parent) {
_inherits(Child, _Parent);
function Child() {
_classCallCheck(this, Child);
return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this));
}
return Child;
}(Parent);"#
);
test!(
Classes::default(),
custom_constructor_super_order,
r#"class Parent {
constructor(){
}
foo(){}
}
class Child extends Parent {
constructor(){
console.log('foo');
super();
console.log('bar');
}
}"#,
r#"var Parent = function () {
function Parent() {
_classCallCheck(this, Parent);
}
_createClass(Parent, [{
key: 'foo',
value: function foo() {}
}]);
return Parent;
}();
var Child = function (_Parent) {
_inherits(Child, _Parent);
function Child() {
_classCallCheck(this, Child);
console.log('foo');
var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this));
console.log('bar');
return _this;
}
return Child;
}(Parent);"#
);
test_exec!(
|helpers| Classes { helpers },
get_semantics_getter_defined_on_parent,
r#"
"use strict";
class Base {
get test() {
expect(this).toBe(obj);
return 1;
}
}
class Obj extends Base {
get() {
return super.test;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.test).toBe(2);
expect(obj.get()).toBe(1);"#
);
test_exec!(
|helpers| Classes { helpers },
get_semantics_not_defined_on_parent,
r#"
"use strict";
class Base {
}
class Obj extends Base {
get() {
return super.test;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.test).toBe(2);
expect(obj.get()).toBeUndefined();
"#
);
test_exec!(
|helpers| Classes { helpers },
get_semantics_setter_defined_on_parent,
r#"
"use strict";
class Base {
set test(v) {
throw new Error("called");
}
}
class Obj extends Base {
get() {
return super.test;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.test).toBe(2);
expect(obj.get()).toBeUndefined();
"#
);
test_exec!(
|helpers| Classes { helpers },
call_semantics_data_defined_on_parent,
r#""use strict";
class Base {
test(...args) {
expect(this).toBe(obj);
expect(args).toEqual([1, 2, 3]);
return 1;
}
}
class Obj extends Base {
call() {
super.test(1, 2, 3);
super.test(1, ...[2, 3]);
super.test(...[1, 2, 3]);
return super.test(...arguments);
}
test() {
throw new Error("called");
}
}
const obj = new Obj();
expect(obj.call(1, 2, 3)).toBe(1);"#
);
test_exec!(
|helpers| Classes { helpers },
call_semantics_getter_defined_on_parent,
r#"
"use strict";
class Base {
get test() {
expect(this).toBe(obj);
return function(...args) {
expect(this).toBe(obj);
expect(args).toEqual([1, 2, 3]);
return 1;
};
}
}
class Obj extends Base {
call() {
super.test(1, 2, 3);
super.test(1, ...[2, 3]);
super.test(...[1, 2, 3]);
return super.test(...arguments);
}
test() {
throw new Error("called");
}
}
const obj = new Obj();
expect(obj.call(1, 2, 3)).toBe(1);"#
);
test_exec!(
|helpers| Classes { helpers },
call_semantics_not_defined_on_parent,
r#"
"use strict";
class Base {
}
class Obj extends Base {
call() {
return super.test();
}
test() {
throw new Error("gobbledygook");
}
}
const obj = new Obj();
expect(() => {
obj.call();
// Asser that this throws, but that it's not
// Obj.p.test's error that is thrown
}).toThrowError(TypeError)"#
);
test_exec!(
|helpers| Classes { helpers },
call_semantics_setter_defined_on_parent,
r#"
"use strict";
class Base {
set test(v) {
throw new Error("gobbledygook");
}
}
class Obj extends Base {
call() {
return super.test();
}
test() {
throw new Error("gobbledygook");
}
}
const obj = new Obj();
expect(() => {
obj.call();
// Asser that this throws, but that it's not
// a gobbledygook error that is thrown
}).toThrowError(TypeError)"#
);
test_exec!(
|helpers| Classes { helpers },
get_semantics_data_defined_on_parent,
r#"
"use strict";
class Base {
}
Object.defineProperty(Base.prototype, 'test', {
value: 1,
writable: true,
configurable: true,
});
class Obj extends Base {
get() {
return super.test;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.test).toBe(2);
expect(obj.get()).toBe(1);"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_data_defined_on_parent,
r#"
"use strict";
class Base {
}
Object.defineProperty(Base.prototype, 'test', {
value: 1,
writable: true,
configurable: true,
});
class Obj extends Base {
set() {
return super.test = 3;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.set()).toBe(3);
expect(Base.prototype.test).toBe(1);
expect(Obj.prototype.test).toBe(2);
expect(obj.test).toBe(3);
"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_getter_defined_on_parent,
r#"
"use strict";
let called = false;
class Base {
get test() {
called = true;
return 1;
}
};
class Obj extends Base {
set() {
return super.test = 3;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(() => {
obj.set();
}).toThrow();
expect(called).toBe(false);
expect(Base.prototype.test).toBe(1);
expect(Obj.prototype.test).toBe(2);
expect(obj.test).toBe(2);"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_not_defined_on_parent_data_on_obj,
r#"
"use strict";
class Base {
}
class Obj extends Base {
set() {
return super.test = 3;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.set()).toBe(3);
expect(Base.prototype.test).toBeUndefined();
expect(Obj.prototype.test).toBe(2);
expect(obj.test).toBe(3);"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_not_defined_on_parent_getter_on_obj,
r#"
"use strict";
class Base {
}
let called = false;
class Obj extends Base {
get test() {
called = true;
}
set() {
return super.test = 3;
}
}
const obj = new Obj();
expect(obj.set()).toBe(3);
expect(called).toBe(false);
expect(Base.prototype.test).toBeUndefined();
expect(Obj.prototype.test).toBeUndefined();
expect(obj.test).toBe(3);"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_not_defined_on_parent_not_on_obj,
r#"
"use strict";
class Base {
}
class Obj extends Base {
set() {
return super.test = 3;
}
}
const obj = new Obj();
expect(obj.set()).toBe(3);
expect(Base.prototype.test).toBeUndefined();
expect(Obj.prototype.test).toBeUndefined();
expect(obj.test).toBe(3);"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_not_defined_on_parent_setter_on_obj,
r#"
"use strict";
class Base {
}
let value = 2;
class Obj extends Base {
set test(v) {
value = v;
}
set() {
return super.test = 3;
}
}
const obj = new Obj();
expect(obj.set()).toBe(3);
expect(Base.prototype.test).toBeUndefined();
expect(Obj.prototype.test).toBeUndefined();
expect(value).toBe(2);
expect(obj.test).toBe(3);"#
);
test_exec!(
|helpers| Classes { helpers },
set_semantics_setter_defined_on_parent,
r#"
"use strict";
let value = 1;
class Base {
set test(v) {
value = v;
}
}
class Obj extends Base {
set() {
return super.test = 3;
}
}
Object.defineProperty(Obj.prototype, 'test', {
value: 2,
writable: true,
configurable: true,
});
const obj = new Obj();
expect(obj.set()).toBe(3);
expect(value).toBe(3);
expect(Base.prototype.test).toBeUndefined();
expect(Obj.prototype.test).toBe(2);
expect(obj.test).toBe(2);"#
);