| Index: test/js_interop_test.ts
|
| diff --git a/test/js_interop_test.ts b/test/js_interop_test.ts
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..488fb76faab1c34aed98dc05083b3192d83ab29a
|
| --- /dev/null
|
| +++ b/test/js_interop_test.ts
|
| @@ -0,0 +1,862 @@
|
| +/// <reference path="../typings/mocha/mocha.d.ts"/>
|
| +import {expectTranslate} from './test_support';
|
| +
|
| +// TODO(jacobr): merge these tests back in with the other tests. These tests are
|
| +// only separate because we expected at one point to integrate with TS2Dart
|
| +// instead of refactoring TS2Dart to only output facades.
|
| +describe('variables', () => {
|
| + it('should print variable declaration', () => {
|
| + 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(`@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('support vardecls containing more than one type (implicit or explicit)', () => {
|
| + expectTranslate('var a: A, b: B;').to.equal(`@JS()
|
| +external A get a;
|
| +@JS()
|
| +external set a(A v);
|
| +@JS()
|
| +external B get b;
|
| +@JS()
|
| +external set b(B v);`);
|
| + expectTranslate('var a: number, b: string;').to.equal(`@JS()
|
| +external num get a;
|
| +@JS()
|
| +external set a(num v);
|
| +@JS()
|
| +external String get b;
|
| +@JS()
|
| +external set b(String v);`);
|
| + });
|
| +
|
| + it('supports const', () => {
|
| + expectTranslate('const a:number = 1;').to.equal(`@JS()
|
| +external num get a;`);
|
| +
|
| + expectTranslate('const a:number = 1, b:number = 2;').to.equal(`@JS()
|
| +external num get a;
|
| +@JS()
|
| +external num get b;`);
|
| +
|
| + expectTranslate('const a:string').to.equal(`@JS()
|
| +external String get a;`);
|
| +
|
| + expectTranslate('const a:number, b:number;').to.equal(`@JS()
|
| +external num get a;
|
| +@JS()
|
| +external num get b;`);
|
| + });
|
| +});
|
| +
|
| +describe('classes', () => {
|
| + 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(`@JS()
|
| +class X implements Y, Z {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| +}`);
|
| + });
|
| + it('should support implements', () => {
|
| + 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$();
|
| +}`);
|
| + });
|
| + describe('members', () => {
|
| + 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(`@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(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external get x;
|
| + external set x(v);
|
| +}`);
|
| + });
|
| + it('ignore field initializers', () => {
|
| + expectTranslate('class X { x: number = 42; }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num get x;
|
| + external set x(num v);
|
| +}`);
|
| + });
|
| + it('supports visibility modifiers', () => {
|
| + 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);
|
| +}`);
|
| + });
|
| + it('does not support 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(`@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(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external x();
|
| +}`);
|
| + });
|
| + it('supports abstract methods', () => {
|
| + 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(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num x();
|
| +}`);
|
| + });
|
| + it('supports method params', () => {
|
| + expectTranslate('class X { x(a, b); }').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 ) : num }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external num x(num a, String b);
|
| +}`);
|
| + });
|
| + it('supports get methods', () => {
|
| + 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(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external static num get Y;
|
| +}`);
|
| + });
|
| + it('supports set methods', () => {
|
| + 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(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external static num get Y;
|
| +}`);
|
| + });
|
| + it('supports generic methods', () => {
|
| + expectTranslate('class X<T> { static Z<T>(): X<T> {} }').to.equal(`@JS()
|
| +class X<T> {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external static X<dynamic/*=T*/ > Z/*<T>*/();
|
| +}`);
|
| + expectTranslate('class X<T> { Z(): X<T> {} }').to.equal(`@JS()
|
| +class X<T> {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external X<T> Z();
|
| +}`);
|
| + });
|
| + it('merge overrides', () => {
|
| + expectTranslate(`
|
| +class X {
|
| + createElement(tagName: "img"): HTMLImageElement;
|
| + createElement(tagName: "video"): HTMLVideoElement;
|
| + createElement(tagName: string): HTMLElement;
|
| +}`).to.equal(`import "dart:html";
|
| +
|
| +@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + /*external ImageElement createElement("img" tagName);*/
|
| + /*external VideoElement createElement("video" tagName);*/
|
| + /*external HtmlElement createElement(String tagName);*/
|
| + external dynamic /*ImageElement|VideoElement|HtmlElement*/ createElement(
|
| + String tagName);
|
| +}`);
|
| + expectTranslate(`
|
| +class X {
|
| + F(a:string):num;
|
| + F(a:string, b: string|num):string;
|
| + F(a2:string, b: string, c: num):string;
|
| +}`).to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + /*external num F(String a);*/
|
| + /*external String F(String a, String|num b);*/
|
| + /*external String F(String a2, String b, num c);*/
|
| + external dynamic /*num|String*/ F(String a_a2,
|
| + [dynamic /*String|num*/ b, num c]);
|
| +}`);
|
| +
|
| + expectTranslate(`
|
| +class X {
|
| + Y(a:string):num {};
|
| + Y(a:string, b: num):string {};
|
| + Y(a2:string, b: string, c: num):string {};
|
| +}`).to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + /*external num Y(String a);*/
|
| + /*external String Y(String a, num b);*/
|
| + /*external String Y(String a2, String b, num c);*/
|
| + external dynamic /*num|String*/ Y(String a_a2,
|
| + [dynamic /*num|String*/ b, num c]);
|
| +}`);
|
| + expectTranslate(`
|
| +class X {
|
| + firstElement(elements: HTMLImageElement[]): HTMLImageElement;
|
| + firstElement(elements: HTMLVideoElement[]): HTMLVideoElement;
|
| + firstElement(elements: HTMLElement[]): HTMLElement;
|
| +}`).to.equal(`import "dart:html";
|
| +
|
| +@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + /*external ImageElement firstElement(List<ImageElement> elements);*/
|
| + /*external VideoElement firstElement(List<VideoElement> elements);*/
|
| + /*external HtmlElement firstElement(List<HtmlElement> elements);*/
|
| + external dynamic /*ImageElement|VideoElement|HtmlElement*/ firstElement(
|
| + List<
|
| + HtmlElement> /*List<ImageElement>|List<VideoElement>|List<HtmlElement>*/ elements);
|
| +}`);
|
| +
|
| + // TODO(jacobr): we should consider special casing so EventLister and
|
| + // EventListenerObject are treated as the same in Dart even though they
|
| + // are different.
|
| + expectTranslate(`
|
| +interface SampleAudioNode {
|
| + addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
|
| + addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
| +}`).to.equal(`import "dart:html";
|
| +import "package:func/func.dart";
|
| +
|
| +@anonymous
|
| +@JS()
|
| +abstract class SampleAudioNode {
|
| + /*external void addEventListener("ended" type, dynamic listener(Event ev), [bool useCapture]);*/
|
| + /*external void addEventListener(String type, EventListener|EventListenerObject listener, [bool useCapture]);*/
|
| + external void addEventListener(String type,
|
| + dynamic /*Func1<Event, dynamic>|EventListener|EventListenerObject*/ listener,
|
| + [bool useCapture]);
|
| +}`);
|
| +
|
| + expectTranslate(`
|
| +interface ListenObject {
|
| + someDummyMethod(evt: string): void;
|
| +}
|
| +
|
| +interface ExampleListener {
|
| + (evt: string): void;
|
| +}
|
| +
|
| +interface DummySample {
|
| + addEventListener(type: "ended", listener: ListenObject): void;
|
| + addEventListener(type: string, listener: ExampleListener): void;
|
| +}`).to.equal(`@anonymous
|
| +@JS()
|
| +abstract class ListenObject {
|
| + external void someDummyMethod(String evt);
|
| +}
|
| +
|
| +typedef void ExampleListener(String evt);
|
| +
|
| +@anonymous
|
| +@JS()
|
| +abstract class DummySample {
|
| + /*external void addEventListener("ended" type, ListenObject listener);*/
|
| + /*external void addEventListener(String type, ExampleListener listener);*/
|
| + external void addEventListener(
|
| + String type, dynamic /*ListenObject|ExampleListener*/ listener);
|
| +}`);
|
| +
|
| + expectTranslate(`
|
| +interface ListenAny {
|
| + (evt: any): void;
|
| +}
|
| +
|
| +interface ExampleListener {
|
| + (evt: string): void;
|
| +}
|
| +
|
| +interface DummySample {
|
| + addEventListener(type: "ended", listener: ListenAny): void;
|
| + addEventListener(type: string, listener: ExampleListener): void;
|
| +}`).to.equal(`typedef void ListenAny(dynamic evt);
|
| +typedef void ExampleListener(String evt);
|
| +
|
| +@anonymous
|
| +@JS()
|
| +abstract class DummySample {
|
| + /*external void addEventListener("ended" type, ListenAny listener);*/
|
| + /*external void addEventListener(String type, ExampleListener listener);*/
|
| + external void addEventListener(
|
| + String type, Function /*ListenAny|ExampleListener*/ listener);
|
| +}`);
|
| +
|
| + });
|
| + it('dot dot dot', () => {
|
| + expectTranslate(`
|
| +function buildName(firstName: string, ...restOfName: string[]): string;
|
| +`).to.equal(`@JS()
|
| +external String buildName(String firstName,
|
| + [String restOfName1,
|
| + String restOfName2,
|
| + String restOfName3,
|
| + String restOfName4,
|
| + String restOfName5]);`);
|
| + expectTranslate(`
|
| +function log(...args);`)
|
| + .to.equal(`@JS()
|
| +external log([args1, args2, args3, args4, args5]);`);
|
| + });
|
| + it('interface constructors', () => {
|
| + expectTranslate(`
|
| +interface C {
|
| + oncached: (ev: Event) => any;
|
| +}
|
| +declare var C: {new(): C; CHECKING: number; }`)
|
| + .to.equal(`import "package:func/func.dart";
|
| +import "dart:html";
|
| +
|
| +@JS()
|
| +abstract class C {
|
| + external Func1<Event, dynamic> get oncached;
|
| + external set oncached(Func1<Event, dynamic> v);
|
| + external factory C();
|
| + external static num get CHECKING;
|
| + external static set CHECKING(num v);
|
| +}`);
|
| + });
|
| + it('property bag interfaces', () => {
|
| + expectTranslate(`
|
| +interface X {
|
| + a: string;
|
| + b: num;
|
| + c: X;
|
| +}
|
| +interface Y extends X {
|
| + d: num;
|
| + /* example comment */
|
| + e: any;
|
| +}`).to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X {
|
| + external String get a;
|
| + external set a(String v);
|
| + external num get b;
|
| + external set b(num v);
|
| + external X get c;
|
| + external set c(X v);
|
| + external factory X({String a, num b, X c});
|
| +}
|
| +
|
| +@anonymous
|
| +@JS()
|
| +abstract class Y implements X {
|
| + external num get d;
|
| + external set d(num v);
|
| +
|
| + /// example comment
|
| + external dynamic get e;
|
| + external set e(dynamic v);
|
| + external factory Y({num d, dynamic e, String a, num b, X c});
|
| +}`);
|
| + expectTranslate(`interface X<A> { a: A; b: num, c: X }
|
| + interface Y<A,B> extends X<A> { d: B; e: any; }`)
|
| + .to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X<A> {
|
| + external A get a;
|
| + external set a(A v);
|
| + external num get b;
|
| + external set b(num v);
|
| + external X get c;
|
| + external set c(X v);
|
| + external factory X({A a, num b, X c});
|
| +}
|
| +
|
| +@anonymous
|
| +@JS()
|
| +abstract class Y<A, B> implements X<A> {
|
| + external B get d;
|
| + external set d(B v);
|
| + external dynamic get e;
|
| + external set e(dynamic v);
|
| + external factory Y({B d, dynamic e, A a, num b, X c});
|
| +}`);
|
| + });
|
| + it('callable', () => {
|
| + expectTranslate('interface X<T> { (a:T):T; Y():T; }').to.equal(`@anonymous
|
| +@JS()
|
| +abstract class X<T> implements Function {
|
| + external T call(T a);
|
| + external T Y();
|
| +}`);
|
| + });
|
| +
|
| + it('supports constructors', () => {
|
| + expectTranslate('class X { constructor() { } }').to.equal(`@JS()
|
| +class X {
|
| + // @Ignore
|
| + X.fakeConstructor$();
|
| + external factory X();
|
| +}`);
|
| + });
|
| + it('supports parameter properties', () => {
|
| + expectTranslate(`
|
| +class X {
|
| + c: number;
|
| + constructor(private _bar: B, public foo: string = "hello", private _goggles: boolean = 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(`
|
| +class X {
|
| + constructor(public foo: string, b: number, private _marbles: boolean = 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(`@anonymous
|
| +@JS()
|
| +abstract class X {}`);
|
| + });
|
| + it('translates interface extends to class implements', () => {
|
| + 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(`@anonymous
|
| +@JS()
|
| +abstract class X {
|
| + external x();
|
| +}`);
|
| + });
|
| +
|
| + it('supports interface properties', () => {
|
| + 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});
|
| +}`);
|
| + });
|
| +});
|
| +
|
| +describe('single call signature interfaces', () => {
|
| + it('should support declaration', () => {
|
| + expectTranslate('interface F { (n: number): boolean; }').to.equal('typedef bool F(num n);');
|
| + });
|
| + it('should support generics', () => {
|
| + expectTranslate('interface F<A, B> { (a: A): B; }').to.equal('typedef B F<A, B>(A a);');
|
| + });
|
| +});
|
| +
|
| +describe('enums', () => {
|
| + it('should support basic enum declaration', () => {
|
| + 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('empty enum', () => {
|
| + expectTranslate('enum Color { }').to.equal(`@JS()
|
| +class Color {}`);
|
| + });
|
| + 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;
|
| +}`);
|
| + });
|
| +});
|
| +
|
| +describe('renames', () => {
|
| + it('should support class renames', () => {
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + interface A { x(); }
|
| +}
|
| +declare module m2 {
|
| + interface A { y(); }
|
| +}
|
| +`).to.equal(`// Module m1
|
| +@anonymous
|
| +@JS()
|
| +abstract class A {
|
| + external x();
|
| +}
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +@anonymous
|
| +@JS()
|
| +abstract class m2_A {
|
| + external y();
|
| +}
|
| +// End module m2`);
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + class A { constructor(x); }
|
| +}
|
| +declare module m2 {
|
| + class A { constructor(y); }
|
| +}`).to.equal(`// Module m1
|
| +@JS("m1.A")
|
| +class A {
|
| + // @Ignore
|
| + A.fakeConstructor$();
|
| + external factory A(x);
|
| +}
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +@JS("m2.A")
|
| +class m2_A {
|
| + // @Ignore
|
| + m2_A.fakeConstructor$();
|
| + external factory m2_A(y);
|
| +}
|
| +// End module m2`);
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + class A { constructor(x:m2.A); }
|
| +}
|
| +declare module m2 {
|
| + class A { constructor(y:m1.A); }
|
| +}
|
| +`).to.equal(`// Module m1
|
| +@JS("m1.A")
|
| +class A {
|
| + // @Ignore
|
| + A.fakeConstructor$();
|
| + external factory A(m2_A x);
|
| +}
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +@JS("m2.A")
|
| +class m2_A {
|
| + // @Ignore
|
| + m2_A.fakeConstructor$();
|
| + external factory m2_A(A y);
|
| +}
|
| +// End module m2`);
|
| +
|
| + });
|
| + it('should support member renames', () => {
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + interface A { x(); }
|
| +}
|
| +declare module m2 {
|
| + export function A(x:m1.A);
|
| +}`).to.equal(`// Module m1
|
| +@anonymous
|
| +@JS()
|
| +abstract class A {
|
| + external x();
|
| +}
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +@JS("m2.A")
|
| +external m2_A(A x);
|
| +// End module m2`);
|
| + });
|
| +
|
| + it('handle class renames in type declarations', () => {
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + interface A { x(); }
|
| +}
|
| +declare module m2 {
|
| + interface A { y(); }
|
| +}
|
| +export function register(x:m2.A);
|
| +`).to.equal(`// Module m1
|
| +@anonymous
|
| +@JS()
|
| +abstract class A {
|
| + external x();
|
| +}
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +@anonymous
|
| +@JS()
|
| +abstract class m2_A {
|
| + external y();
|
| +}
|
| +
|
| +// End module m2
|
| +@JS()
|
| +external register(m2_A x);`);
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + module foo {
|
| + interface A { x(); }
|
| + }
|
| +}
|
| +declare module m2 {
|
| + module foo {
|
| + interface A { y(); }
|
| + }
|
| +}
|
| +declare module m3 {
|
| + module foo {
|
| + interface A { z(); }
|
| + }
|
| +}
|
| +export function register(y:m2.foo.A, z:m3.foo.A);
|
| +`).to.equal(`// Module m1
|
| +
|
| +// Module foo
|
| +@anonymous
|
| +@JS()
|
| +abstract class A {
|
| + external x();
|
| +}
|
| +// End module foo
|
| +
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +
|
| +// Module foo
|
| +@anonymous
|
| +@JS()
|
| +abstract class foo_A {
|
| + external y();
|
| +}
|
| +// End module foo
|
| +
|
| +// End module m2
|
| +
|
| +// Module m3
|
| +
|
| +// Module foo
|
| +@anonymous
|
| +@JS()
|
| +abstract class m3_foo_A {
|
| + external z();
|
| +}
|
| +// End module foo
|
| +
|
| +// End module m3
|
| +@JS()
|
| +external register(foo_A y, m3_foo_A z);`);
|
| +
|
| + expectTranslate(`
|
| +declare module m1 {
|
| + interface A { x(); }
|
| +}
|
| +declare module m2 {
|
| + interface A { y(); }
|
| +}
|
| +export function register(x:m1.A);
|
| + `).to.equal(`// Module m1
|
| +@anonymous
|
| +@JS()
|
| +abstract class A {
|
| + external x();
|
| +}
|
| +// End module m1
|
| +
|
| +// Module m2
|
| +@anonymous
|
| +@JS()
|
| +abstract class m2_A {
|
| + external y();
|
| +}
|
| +
|
| +// End module m2
|
| +@JS()
|
| +external register(A x);`);
|
| + });
|
| +
|
| + describe('type alias', () => {
|
| + it('replace with simple type', () => {
|
| + expectTranslate(`
|
| +type MyNumber = number;
|
| +export function add(x: MyNumber, y: MyNumber): MyNumber;
|
| + `).to.equal(`@JS()
|
| +external num add(num x, num y);`);
|
| + });
|
| + });
|
| +
|
| + it('union types', () => {
|
| + // TODO(jacobr): ideally the draw method should specify that arg el has type
|
| + // HtmlElement instead of dynamic.
|
| + expectTranslate(`
|
| +type listener1 = ()=>boolean;
|
| +type listener2 = (e:string)=>boolean;
|
| +function addEventListener(listener: listener1|listener2);`)
|
| + .to.equal(`import "package:func/func.dart";
|
| +
|
| +@JS()
|
| +external addEventListener(
|
| + Function /*Func0<bool>|Func1<String, bool>*/ listener);`);
|
| +
|
| + expectTranslate('function draw(el: HTMLCanvasElement|HTMLImageElement):void;')
|
| + .to.equal(`import "dart:html";
|
| +
|
| +@JS()
|
| +external void draw(dynamic /*CanvasElement|ImageElement*/ el);`);
|
| + });
|
| +});
|
|
|