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'); |
}); |