| Index: test/declaration_test.ts
|
| diff --git a/test/declaration_test.ts b/test/declaration_test.ts
|
| index 19b6a4603d3f2e0450f837e2af93dfda3f2d3af7..31829e8689dacf9bbb4966aa967266b51e917283 100644
|
| --- a/test/declaration_test.ts
|
| +++ b/test/declaration_test.ts
|
| @@ -1,65 +1,178 @@
|
| /// <reference path="../typings/mocha/mocha.d.ts"/>
|
| -import {expectTranslate, expectErroneousCode} from './test_support';
|
| +import {expectErroneousCode, expectTranslate} from './test_support';
|
|
|
| describe('variables', () => {
|
| - it('should print variable declaration with initializer',
|
| - () => { expectTranslate('var a:number = 1;').to.equal('num a = 1;'); });
|
| + it('should print variable declaration with initializer', () => {
|
| + expectTranslate('var a:number = 1;').to.equal(`@JS()
|
| +external num get a;
|
| +@JS()
|
| +external set a(num v);`);
|
| + });
|
| it('should print variable declaration', () => {
|
| - expectTranslate('var a:number;').to.equal('num a;');
|
| - expectTranslate('var a;').to.equal('var a;');
|
| - expectTranslate('var a:any;').to.equal('dynamic a;');
|
| + expectTranslate('var a:number;').to.equal(`@JS()
|
| +external num get a;
|
| +@JS()
|
| +external set a(num v);`);
|
| + expectTranslate('var a;').to.equal(`@JS()
|
| +external get a;
|
| +@JS()
|
| +external set a(v);`);
|
| + expectTranslate('var a:any;').to.equal(`@JS()
|
| +external dynamic get a;
|
| +@JS()
|
| +external set a(dynamic v);`);
|
| });
|
| it('should transpile variable declaration lists', () => {
|
| - expectTranslate('var a: A;').to.equal('A a;');
|
| - expectTranslate('var a, b;').to.equal('var a, b;');
|
| + expectTranslate('var a: A;').to.equal(`@JS()
|
| +external A get a;
|
| +@JS()
|
| +external set a(A v);`);
|
| + expectTranslate('var a, b;').to.equal(`@JS()
|
| +external get a;
|
| +@JS()
|
| +external set a(v);
|
| +@JS()
|
| +external get b;
|
| +@JS()
|
| +external set b(v);`);
|
| });
|
| it('should transpile variable declaration lists with initializers', () => {
|
| - expectTranslate('var a = 0;').to.equal('var a = 0;');
|
| - expectTranslate('var a, b = 0;').to.equal('var a, b = 0;');
|
| - expectTranslate('var a = 1, b = 0;').to.equal('var a = 1, b = 0;');
|
| + expectTranslate('var a = 0;').to.equal(`@JS()
|
| +external get a;
|
| +@JS()
|
| +external set a(v);`);
|
| + expectTranslate('var a, b = 0;').to.equal(`@JS()
|
| +external get a;
|
| +@JS()
|
| +external set a(v);
|
| +@JS()
|
| +external get b;
|
| +@JS()
|
| +external set b(v);`);
|
| + expectTranslate('var a = 1, b = 0;').to.equal(`@JS()
|
| +external get a;
|
| +@JS()
|
| +external set a(v);
|
| +@JS()
|
| +external get b;
|
| +@JS()
|
| +external set b(v);`);
|
| });
|
| - it('does not support vardecls containing more than one type (implicit or explicit)', () => {
|
| - let msg = 'Variables in a declaration list of more than one variable cannot by typed';
|
| - expectErroneousCode('var a: A, untyped;').to.throw(msg);
|
| - expectErroneousCode('var untyped, b: B;').to.throw(msg);
|
| - expectErroneousCode('var n: number, s: string;').to.throw(msg);
|
| - expectErroneousCode('var untyped, n: number, s: string;').to.throw(msg);
|
| + it('support vardecls containing more than one type (implicit or explicit)', () => {
|
| + expectTranslate('var a: A, untyped;').to.equal(`@JS()
|
| +external A get a;
|
| +@JS()
|
| +external set a(A v);
|
| +@JS()
|
| +external get untyped;
|
| +@JS()
|
| +external set untyped(v);`);
|
| + expectTranslate('var untyped, b: B;').to.equal(`@JS()
|
| +external get untyped;
|
| +@JS()
|
| +external set untyped(v);
|
| +@JS()
|
| +external B get b;
|
| +@JS()
|
| +external set b(B v);`);
|
| + expectTranslate('var n: number, s: string;').to.equal(`@JS()
|
| +external num get n;
|
| +@JS()
|
| +external set n(num v);
|
| +@JS()
|
| +external String get s;
|
| +@JS()
|
| +external set s(String v);`);
|
| + expectTranslate('var untyped, n: number, s: string;').to.equal(`@JS()
|
| +external get untyped;
|
| +@JS()
|
| +external set untyped(v);
|
| +@JS()
|
| +external num get n;
|
| +@JS()
|
| +external set n(num v);
|
| +@JS()
|
| +external String get s;
|
| +@JS()
|
| +external set s(String v);`);
|
| });
|
|
|
| it('supports const', () => {
|
| - // NB: const X = CONST_EXPR(1); is translated as deep-const, see tests in facade_converter_test.
|
| - // Arbitrary expressions translate const ==> final...
|
| - expectTranslate('const A = 1 + 2;').to.equal('final A = 1 + 2;');
|
| + // Arbitrary expressions essentially translate const ==> final
|
| + // but Dart doesn't allow external fields so we use getters instead.
|
| + expectTranslate('const A = 1 + 2;').to.equal(`@JS()
|
| +external get A;`);
|
| // ... but literals are special cased to be deep const.
|
| - expectTranslate('const A = 1, B = 2;').to.equal('const A = 1, B = 2;');
|
| - expectTranslate('const A: number = 1;').to.equal('const num A = 1;');
|
| + expectTranslate('const A = 1, B = 2;').to.equal(`@JS()
|
| +external get A;
|
| +@JS()
|
| +external get B;`);
|
| + expectTranslate('const A: number = 1;').to.equal(`@JS()
|
| +external num get A;`);
|
| });
|
| });
|
|
|
| describe('classes', () => {
|
| - it('should translate classes', () => { expectTranslate('class X {}').to.equal('class X {}'); });
|
| - it('should support extends',
|
| - () => { expectTranslate('class X extends Y {}').to.equal('class X extends Y {}'); });
|
| + it('should translate classes', () => {
|
| + expectTranslate('class X {}').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| +}`);
|
| + });
|
| + it('should support extends', () => {
|
| + expectTranslate('class X extends Y {}').to.equal(`@JS()
|
| +class X extends Y {
|
| + // @Ignore
|
| + X.fakeConstructor$() : super.fakeConstructor$();
|
| +}`);
|
| + });
|
| it('should support implements', () => {
|
| - expectTranslate('class X implements Y, Z {}').to.equal('class X implements Y, Z {}');
|
| + expectTranslate('class X implements Y, Z {}').to.equal(`@JS()
|
| +class X implements Y, Z {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| +}`);
|
| });
|
| it('should support implements', () => {
|
| - expectTranslate('class X extends Y implements Z {}')
|
| - .to.equal('class X extends Y implements Z {}');
|
| + expectTranslate('class X extends Y implements Z {}').to.equal(`@JS()
|
| +class X extends Y implements Z {
|
| + // @Ignore
|
| + X.fakeConstructor$() : super.fakeConstructor$();
|
| +}`);
|
| + });
|
| + it('should support abstract', () => {
|
| + expectTranslate('abstract class X {}').to.equal(`@JS()
|
| +abstract class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| +}`);
|
| });
|
| - it('should support abstract',
|
| - () => { expectTranslate('abstract class X {}').to.equal('abstract class X {}'); });
|
|
|
| describe('members', () => {
|
| - it('supports empty declarations',
|
| - () => { expectTranslate('class X { ; }').to.equal('class X {}'); });
|
| + it('supports empty declarations', () => {
|
| + expectTranslate('class X { ; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| +}`);
|
| + });
|
| it('supports fields', () => {
|
| - expectTranslate('class X { x: number; y: string; }').to.equal(`class X {
|
| - num x;
|
| - String y;
|
| + expectTranslate('class X { x: number; y: string; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num get x;
|
| + external set x(num v);
|
| + external String get y;
|
| + external set y(String v);
|
| }`);
|
| - expectTranslate('class X { x; }').to.equal(`class X {
|
| - var x;
|
| + expectTranslate('class X { x; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get x;
|
| + external set x(v);
|
| }`);
|
| });
|
| it('supports function typed fields', () => {
|
| @@ -68,89 +181,149 @@ describe('classes', () => {
|
| 'class X { x: FnDef; }')
|
| .to.equal(`typedef String FnDef(num y);
|
|
|
| +@JS()
|
| class X {
|
| - FnDef x;
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external FnDef get x;
|
| + external set x(FnDef v);
|
| }`);
|
| });
|
| it('supports field initializers', () => {
|
| - expectTranslate('class X { x: number = 42; }').to.equal(`class X {
|
| - num x = 42;
|
| + expectTranslate('class X { x: number = 42; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num get x;
|
| + external set x(num v);
|
| }`);
|
| });
|
| // TODO(martinprobst): Re-enable once Angular is migrated to TS.
|
| it('supports visibility modifiers', () => {
|
| - expectTranslate('class X { private _x; x; }').to.equal(`class X {
|
| - var _x;
|
| - var x;
|
| + expectTranslate('class X { private _x; x; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get JS$_x;
|
| + external set JS$_x(v);
|
| + external get x;
|
| + external set x(v);
|
| +}`);
|
| + expectTranslate('class X { private x; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get x;
|
| + external set x(v);
|
| +}`);
|
| + expectTranslate('class X { constructor (private x) {} }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get x;
|
| + external set x(v);
|
| + external factory X(x);
|
| +}`);
|
| + expectTranslate('class X { _x; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get JS$_x;
|
| + external set JS$_x(v);
|
| }`);
|
| - expectErroneousCode('class X { private x; }')
|
| - .to.throw('private members must be prefixed with "_"');
|
| - expectErroneousCode('class X { constructor (private x) {} }')
|
| - .to.throw('private members must be prefixed with "_"');
|
| - expectErroneousCode('class X { _x; }')
|
| - .to.throw('public members must not be prefixed with "_"');
|
| });
|
| - it('does not support protected', () => {
|
| - expectErroneousCode('class X { protected x; }')
|
| - .to.throw('protected declarations are unsupported');
|
| + it('allow protected', () => {
|
| + expectTranslate('class X { protected x; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get x;
|
| + external set x(v);
|
| +}`);
|
| });
|
| it('supports static fields', () => {
|
| - expectTranslate('class X { static x: number = 42; }').to.equal(`class X {
|
| - static num x = 42;
|
| + expectTranslate('class X { static x: number = 42; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external static num get x;
|
| + external static set x(num v);
|
| }`);
|
| });
|
| it('supports methods', () => {
|
| - expectTranslate('class X { x() { return 42; } }').to.equal(`class X {
|
| - x() {
|
| - return 42;
|
| - }
|
| + expectTranslate('class X { x() { return 42; } }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external x();
|
| }`);
|
| });
|
| it('supports abstract methods', () => {
|
| - expectTranslate('abstract class X { abstract x(); }').to.equal(`abstract class X {
|
| - x();
|
| + expectTranslate('abstract class X { abstract x(); }').to.equal(`@JS()
|
| +abstract class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external x();
|
| }`);
|
| });
|
| it('supports method return types', () => {
|
| - expectTranslate('class X { x(): number { return 42; } }').to.equal(`class X {
|
| - num x() {
|
| - return 42;
|
| - }
|
| + expectTranslate('class X { x(): number { return 42; } }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num x();
|
| }`);
|
| });
|
| it('supports method params', () => {
|
| - expectTranslate('class X { x(a, b) { return 42; } }').to.equal(`class X {
|
| - x(a, b) {
|
| - return 42;
|
| - }
|
| + expectTranslate('class X { x(a, b) { return 42; } }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external x(a, b);
|
| }`);
|
| });
|
| it('supports method return types', () => {
|
| - expectTranslate('class X { x( a : number, b : string ) { return 42; } }').to.equal(`class X {
|
| - x(num a, String b) {
|
| - return 42;
|
| - }
|
| + expectTranslate('class X { x( a : number, b : string ) { return 42; } }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external x(num a, String b);
|
| }`);
|
| });
|
| it('supports get methods', () => {
|
| - expectTranslate('class X { get y(): number {} }').to.equal(`class X {
|
| - num get y {}
|
| + expectTranslate('class X { get y(): number {} }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num get y;
|
| }`);
|
| - expectTranslate('class X { static get Y(): number {} }').to.equal(`class X {
|
| - static num get Y {}
|
| + expectTranslate('class X { static get Y(): number {} }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external static num get Y;
|
| }`);
|
| });
|
| it('supports set methods', () => {
|
| - expectTranslate('class X { set y(n: number) {} }').to.equal(`class X {
|
| - set y(num n) {}
|
| + expectTranslate('class X { set y(n: number) {} }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external set y(num n);
|
| }`);
|
| - expectTranslate('class X { static get Y(): number {} }').to.equal(`class X {
|
| - static num get Y {}
|
| + expectTranslate('class X { static get Y(): number {} }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external static num get Y;
|
| }`);
|
| });
|
| it('supports constructors', () => {
|
| - expectTranslate('class X { constructor() {} }').to.equal(`class X {
|
| - X() {}
|
| + expectTranslate('class X { constructor() {} }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external factory X();
|
| }`);
|
| });
|
| it('supports parameter properties', () => {
|
| @@ -159,40 +332,64 @@ class X {
|
| ' constructor(private _bar: B, ' +
|
| 'public foo: string = "hello", ' +
|
| 'private _goggles: boolean = true) {} }')
|
| - .to.equal(`class X {
|
| - B _bar;
|
| - String foo;
|
| - bool _goggles;
|
| - num c;
|
| - X(this._bar, [this.foo = "hello", this._goggles = true]) {}
|
| + .to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external B get JS$_bar;
|
| + external set JS$_bar(B v);
|
| + external String get foo;
|
| + external set foo(String v);
|
| + external bool get JS$_goggles;
|
| + external set JS$_goggles(bool v);
|
| + external num get c;
|
| + external set c(num v);
|
| + external factory X(B JS$_bar, [String foo, bool JS$_goggles]);
|
| }`);
|
| expectTranslate(
|
| '@CONST class X { ' +
|
| 'constructor(public foo: string, b: number, private _marbles: boolean = true) {} }')
|
| - .to.equal(`class X {
|
| - final String foo;
|
| - final bool _marbles;
|
| - const X(this.foo, num b, [this._marbles = true]);
|
| + .to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external String get foo;
|
| + external set foo(String v);
|
| + external bool get JS$_marbles;
|
| + external set JS$_marbles(bool v);
|
| + external factory X(String foo, num b, [bool JS$_marbles]);
|
| }`);
|
| });
|
| });
|
| });
|
|
|
| describe('interfaces', () => {
|
| - it('translates interfaces to abstract classes',
|
| - () => { expectTranslate('interface X {}').to.equal('abstract class X {}'); });
|
| + it('translates interfaces to abstract classes', () => {
|
| + expectTranslate('interface X {}').to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X {}`);
|
| + });
|
| it('translates interface extends to class implements', () => {
|
| - expectTranslate('interface X extends Y, Z {}').to.equal('abstract class X implements Y, Z {}');
|
| + expectTranslate('interface X extends Y, Z {}').to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X implements Y, Z {}`);
|
| });
|
| it('supports abstract methods', () => {
|
| - expectTranslate('interface X { x(); }').to.equal(`abstract class X {
|
| - x();
|
| + expectTranslate('interface X { x(); }').to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X {
|
| + external x();
|
| }`);
|
| });
|
| it('supports interface properties', () => {
|
| - expectTranslate('interface X { x: string; y; }').to.equal(`abstract class X {
|
| - String x;
|
| - var y;
|
| + expectTranslate('interface X { x: string; y; }').to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X {
|
| + external String get x;
|
| + external set x(String v);
|
| + external get y;
|
| + external set y(v);
|
| + external factory X({String x, y});
|
| }`);
|
| });
|
| });
|
| @@ -208,22 +405,28 @@ describe('single call signature interfaces', () => {
|
|
|
| describe('enums', () => {
|
| it('should support basic enum declaration', () => {
|
| - expectTranslate('enum Color { Red, Green, Blue }').to.equal('enum Color { Red, Green, Blue }');
|
| + expectTranslate('enum Color { Red, Green, Blue }').to.equal(`@JS()
|
| +class Color {
|
| + external static num get Red;
|
| + external static num get Green;
|
| + external static num get Blue;
|
| +}`);
|
| });
|
| - it('does not support empty enum',
|
| - () => { expectErroneousCode('enum Empty {}').to.throw('empty enums are not supported'); });
|
| - it('does not support enum with initializer', () => {
|
| - expectErroneousCode('enum Color { Red = 1, Green, Blue = 4 }')
|
| - .to.throw('enum initializers are not supported');
|
| + it('allow empty enum', () => {
|
| + expectTranslate('enum Empty {}').to.equal(`@JS()
|
| +class Empty {}`);
|
| });
|
| - it('should support switch over enum', () => {
|
| - expectTranslate('switch(c) { case Color.Red: break; default: break; }').to.equal(`switch (c) {
|
| - case Color.Red:
|
| - break;
|
| - default:
|
| - break;
|
| + it('enum with initializer', () => {
|
| + expectTranslate('enum Color { Red = 1, Green, Blue = 4 }').to.equal(`@JS()
|
| +class Color {
|
| + external static num get Red;
|
| + external static num get Green;
|
| + external static num get Blue;
|
| }`);
|
| });
|
| + it('should ingore switch', () => {
|
| + expectTranslate('switch(c) { case Color.Red: break; default: break; }').to.equal('');
|
| + });
|
| it('does not support const enum', () => {
|
| expectErroneousCode('const enum Color { Red }').to.throw('const enums are not supported');
|
| });
|
|
|