OLD | NEW |
1 /// <reference path="../typings/mocha/mocha.d.ts"/> | 1 /// <reference path="../typings/mocha/mocha.d.ts"/> |
2 import {expectTranslate, expectErroneousCode} from './test_support'; | 2 import {expectErroneousCode, expectTranslate} from './test_support'; |
3 | 3 |
4 describe('variables', () => { | 4 describe('variables', () => { |
5 it('should print variable declaration with initializer', | 5 it('should print variable declaration with initializer', () => { |
6 () => { expectTranslate('var a:number = 1;').to.equal('num a = 1;'); }); | 6 expectTranslate('var a:number = 1;').to.equal(`@JS() |
| 7 external num get a; |
| 8 @JS() |
| 9 external set a(num v);`); |
| 10 }); |
7 it('should print variable declaration', () => { | 11 it('should print variable declaration', () => { |
8 expectTranslate('var a:number;').to.equal('num a;'); | 12 expectTranslate('var a:number;').to.equal(`@JS() |
9 expectTranslate('var a;').to.equal('var a;'); | 13 external num get a; |
10 expectTranslate('var a:any;').to.equal('dynamic a;'); | 14 @JS() |
| 15 external set a(num v);`); |
| 16 expectTranslate('var a;').to.equal(`@JS() |
| 17 external get a; |
| 18 @JS() |
| 19 external set a(v);`); |
| 20 expectTranslate('var a:any;').to.equal(`@JS() |
| 21 external dynamic get a; |
| 22 @JS() |
| 23 external set a(dynamic v);`); |
11 }); | 24 }); |
12 it('should transpile variable declaration lists', () => { | 25 it('should transpile variable declaration lists', () => { |
13 expectTranslate('var a: A;').to.equal('A a;'); | 26 expectTranslate('var a: A;').to.equal(`@JS() |
14 expectTranslate('var a, b;').to.equal('var a, b;'); | 27 external A get a; |
| 28 @JS() |
| 29 external set a(A v);`); |
| 30 expectTranslate('var a, b;').to.equal(`@JS() |
| 31 external get a; |
| 32 @JS() |
| 33 external set a(v); |
| 34 @JS() |
| 35 external get b; |
| 36 @JS() |
| 37 external set b(v);`); |
15 }); | 38 }); |
16 it('should transpile variable declaration lists with initializers', () => { | 39 it('should transpile variable declaration lists with initializers', () => { |
17 expectTranslate('var a = 0;').to.equal('var a = 0;'); | 40 expectTranslate('var a = 0;').to.equal(`@JS() |
18 expectTranslate('var a, b = 0;').to.equal('var a, b = 0;'); | 41 external get a; |
19 expectTranslate('var a = 1, b = 0;').to.equal('var a = 1, b = 0;'); | 42 @JS() |
| 43 external set a(v);`); |
| 44 expectTranslate('var a, b = 0;').to.equal(`@JS() |
| 45 external get a; |
| 46 @JS() |
| 47 external set a(v); |
| 48 @JS() |
| 49 external get b; |
| 50 @JS() |
| 51 external set b(v);`); |
| 52 expectTranslate('var a = 1, b = 0;').to.equal(`@JS() |
| 53 external get a; |
| 54 @JS() |
| 55 external set a(v); |
| 56 @JS() |
| 57 external get b; |
| 58 @JS() |
| 59 external set b(v);`); |
20 }); | 60 }); |
21 it('does not support vardecls containing more than one type (implicit or expli
cit)', () => { | 61 it('support vardecls containing more than one type (implicit or explicit)', ()
=> { |
22 let msg = 'Variables in a declaration list of more than one variable cannot
by typed'; | 62 expectTranslate('var a: A, untyped;').to.equal(`@JS() |
23 expectErroneousCode('var a: A, untyped;').to.throw(msg); | 63 external A get a; |
24 expectErroneousCode('var untyped, b: B;').to.throw(msg); | 64 @JS() |
25 expectErroneousCode('var n: number, s: string;').to.throw(msg); | 65 external set a(A v); |
26 expectErroneousCode('var untyped, n: number, s: string;').to.throw(msg); | 66 @JS() |
| 67 external get untyped; |
| 68 @JS() |
| 69 external set untyped(v);`); |
| 70 expectTranslate('var untyped, b: B;').to.equal(`@JS() |
| 71 external get untyped; |
| 72 @JS() |
| 73 external set untyped(v); |
| 74 @JS() |
| 75 external B get b; |
| 76 @JS() |
| 77 external set b(B v);`); |
| 78 expectTranslate('var n: number, s: string;').to.equal(`@JS() |
| 79 external num get n; |
| 80 @JS() |
| 81 external set n(num v); |
| 82 @JS() |
| 83 external String get s; |
| 84 @JS() |
| 85 external set s(String v);`); |
| 86 expectTranslate('var untyped, n: number, s: string;').to.equal(`@JS() |
| 87 external get untyped; |
| 88 @JS() |
| 89 external set untyped(v); |
| 90 @JS() |
| 91 external num get n; |
| 92 @JS() |
| 93 external set n(num v); |
| 94 @JS() |
| 95 external String get s; |
| 96 @JS() |
| 97 external set s(String v);`); |
27 }); | 98 }); |
28 | 99 |
29 it('supports const', () => { | 100 it('supports const', () => { |
30 // NB: const X = CONST_EXPR(1); is translated as deep-const, see tests in fa
cade_converter_test. | 101 // Arbitrary expressions essentially translate const ==> final |
31 // Arbitrary expressions translate const ==> final... | 102 // but Dart doesn't allow external fields so we use getters instead. |
32 expectTranslate('const A = 1 + 2;').to.equal('final A = 1 + 2;'); | 103 expectTranslate('const A = 1 + 2;').to.equal(`@JS() |
| 104 external get A;`); |
33 // ... but literals are special cased to be deep const. | 105 // ... but literals are special cased to be deep const. |
34 expectTranslate('const A = 1, B = 2;').to.equal('const A = 1, B = 2;'); | 106 expectTranslate('const A = 1, B = 2;').to.equal(`@JS() |
35 expectTranslate('const A: number = 1;').to.equal('const num A = 1;'); | 107 external get A; |
| 108 @JS() |
| 109 external get B;`); |
| 110 expectTranslate('const A: number = 1;').to.equal(`@JS() |
| 111 external num get A;`); |
36 }); | 112 }); |
37 }); | 113 }); |
38 | 114 |
39 describe('classes', () => { | 115 describe('classes', () => { |
40 it('should translate classes', () => { expectTranslate('class X {}').to.equal(
'class X {}'); }); | 116 it('should translate classes', () => { |
41 it('should support extends', | 117 expectTranslate('class X {}').to.equal(`@JS() |
42 () => { expectTranslate('class X extends Y {}').to.equal('class X extends Y
{}'); }); | 118 class X { |
43 it('should support implements', () => { | 119 // @Ignore |
44 expectTranslate('class X implements Y, Z {}').to.equal('class X implements Y
, Z {}'); | 120 X.fakeConstructor$(); |
| 121 }`); |
| 122 }); |
| 123 it('should support extends', () => { |
| 124 expectTranslate('class X extends Y {}').to.equal(`@JS() |
| 125 class X extends Y { |
| 126 // @Ignore |
| 127 X.fakeConstructor$() : super.fakeConstructor$(); |
| 128 }`); |
45 }); | 129 }); |
46 it('should support implements', () => { | 130 it('should support implements', () => { |
47 expectTranslate('class X extends Y implements Z {}') | 131 expectTranslate('class X implements Y, Z {}').to.equal(`@JS() |
48 .to.equal('class X extends Y implements Z {}'); | 132 class X implements Y, Z { |
| 133 // @Ignore |
| 134 X.fakeConstructor$(); |
| 135 }`); |
49 }); | 136 }); |
50 it('should support abstract', | 137 it('should support implements', () => { |
51 () => { expectTranslate('abstract class X {}').to.equal('abstract class X {
}'); }); | 138 expectTranslate('class X extends Y implements Z {}').to.equal(`@JS() |
| 139 class X extends Y implements Z { |
| 140 // @Ignore |
| 141 X.fakeConstructor$() : super.fakeConstructor$(); |
| 142 }`); |
| 143 }); |
| 144 it('should support abstract', () => { |
| 145 expectTranslate('abstract class X {}').to.equal(`@JS() |
| 146 abstract class X { |
| 147 // @Ignore |
| 148 X.fakeConstructor$(); |
| 149 }`); |
| 150 }); |
52 | 151 |
53 describe('members', () => { | 152 describe('members', () => { |
54 it('supports empty declarations', | 153 it('supports empty declarations', () => { |
55 () => { expectTranslate('class X { ; }').to.equal('class X {}'); }); | 154 expectTranslate('class X { ; }').to.equal(`@JS() |
| 155 class X { |
| 156 // @Ignore |
| 157 X.fakeConstructor$(); |
| 158 }`); |
| 159 }); |
56 it('supports fields', () => { | 160 it('supports fields', () => { |
57 expectTranslate('class X { x: number; y: string; }').to.equal(`class X { | 161 expectTranslate('class X { x: number; y: string; }').to.equal(`@JS() |
58 num x; | 162 class X { |
59 String y; | 163 // @Ignore |
| 164 X.fakeConstructor$(); |
| 165 external num get x; |
| 166 external set x(num v); |
| 167 external String get y; |
| 168 external set y(String v); |
60 }`); | 169 }`); |
61 expectTranslate('class X { x; }').to.equal(`class X { | 170 expectTranslate('class X { x; }').to.equal(`@JS() |
62 var x; | 171 class X { |
| 172 // @Ignore |
| 173 X.fakeConstructor$(); |
| 174 external get x; |
| 175 external set x(v); |
63 }`); | 176 }`); |
64 }); | 177 }); |
65 it('supports function typed fields', () => { | 178 it('supports function typed fields', () => { |
66 expectTranslate( | 179 expectTranslate( |
67 'interface FnDef {(y: number): string;}\n' + | 180 'interface FnDef {(y: number): string;}\n' + |
68 'class X { x: FnDef; }') | 181 'class X { x: FnDef; }') |
69 .to.equal(`typedef String FnDef(num y); | 182 .to.equal(`typedef String FnDef(num y); |
70 | 183 |
| 184 @JS() |
71 class X { | 185 class X { |
72 FnDef x; | 186 // @Ignore |
| 187 X.fakeConstructor$(); |
| 188 external FnDef get x; |
| 189 external set x(FnDef v); |
73 }`); | 190 }`); |
74 }); | 191 }); |
75 it('supports field initializers', () => { | 192 it('supports field initializers', () => { |
76 expectTranslate('class X { x: number = 42; }').to.equal(`class X { | 193 expectTranslate('class X { x: number = 42; }').to.equal(`@JS() |
77 num x = 42; | 194 class X { |
| 195 // @Ignore |
| 196 X.fakeConstructor$(); |
| 197 external num get x; |
| 198 external set x(num v); |
78 }`); | 199 }`); |
79 }); | 200 }); |
80 // TODO(martinprobst): Re-enable once Angular is migrated to TS. | 201 // TODO(martinprobst): Re-enable once Angular is migrated to TS. |
81 it('supports visibility modifiers', () => { | 202 it('supports visibility modifiers', () => { |
82 expectTranslate('class X { private _x; x; }').to.equal(`class X { | 203 expectTranslate('class X { private _x; x; }').to.equal(`@JS() |
83 var _x; | 204 class X { |
84 var x; | 205 // @Ignore |
| 206 X.fakeConstructor$(); |
| 207 external get JS$_x; |
| 208 external set JS$_x(v); |
| 209 external get x; |
| 210 external set x(v); |
85 }`); | 211 }`); |
86 expectErroneousCode('class X { private x; }') | 212 expectTranslate('class X { private x; }').to.equal(`@JS() |
87 .to.throw('private members must be prefixed with "_"'); | 213 class X { |
88 expectErroneousCode('class X { constructor (private x) {} }') | 214 // @Ignore |
89 .to.throw('private members must be prefixed with "_"'); | 215 X.fakeConstructor$(); |
90 expectErroneousCode('class X { _x; }') | 216 external get x; |
91 .to.throw('public members must not be prefixed with "_"'); | 217 external set x(v); |
| 218 }`); |
| 219 expectTranslate('class X { constructor (private x) {} }').to.equal(`@JS() |
| 220 class X { |
| 221 // @Ignore |
| 222 X.fakeConstructor$(); |
| 223 external get x; |
| 224 external set x(v); |
| 225 external factory X(x); |
| 226 }`); |
| 227 expectTranslate('class X { _x; }').to.equal(`@JS() |
| 228 class X { |
| 229 // @Ignore |
| 230 X.fakeConstructor$(); |
| 231 external get JS$_x; |
| 232 external set JS$_x(v); |
| 233 }`); |
92 }); | 234 }); |
93 it('does not support protected', () => { | 235 it('allow protected', () => { |
94 expectErroneousCode('class X { protected x; }') | 236 expectTranslate('class X { protected x; }').to.equal(`@JS() |
95 .to.throw('protected declarations are unsupported'); | 237 class X { |
| 238 // @Ignore |
| 239 X.fakeConstructor$(); |
| 240 external get x; |
| 241 external set x(v); |
| 242 }`); |
96 }); | 243 }); |
97 it('supports static fields', () => { | 244 it('supports static fields', () => { |
98 expectTranslate('class X { static x: number = 42; }').to.equal(`class X { | 245 expectTranslate('class X { static x: number = 42; }').to.equal(`@JS() |
99 static num x = 42; | 246 class X { |
| 247 // @Ignore |
| 248 X.fakeConstructor$(); |
| 249 external static num get x; |
| 250 external static set x(num v); |
100 }`); | 251 }`); |
101 }); | 252 }); |
102 it('supports methods', () => { | 253 it('supports methods', () => { |
103 expectTranslate('class X { x() { return 42; } }').to.equal(`class X { | 254 expectTranslate('class X { x() { return 42; } }').to.equal(`@JS() |
104 x() { | 255 class X { |
105 return 42; | 256 // @Ignore |
106 } | 257 X.fakeConstructor$(); |
| 258 external x(); |
107 }`); | 259 }`); |
108 }); | 260 }); |
109 it('supports abstract methods', () => { | 261 it('supports abstract methods', () => { |
110 expectTranslate('abstract class X { abstract x(); }').to.equal(`abstract c
lass X { | 262 expectTranslate('abstract class X { abstract x(); }').to.equal(`@JS() |
111 x(); | 263 abstract class X { |
| 264 // @Ignore |
| 265 X.fakeConstructor$(); |
| 266 external x(); |
112 }`); | 267 }`); |
113 }); | 268 }); |
114 it('supports method return types', () => { | 269 it('supports method return types', () => { |
115 expectTranslate('class X { x(): number { return 42; } }').to.equal(`class
X { | 270 expectTranslate('class X { x(): number { return 42; } }').to.equal(`@JS() |
116 num x() { | 271 class X { |
117 return 42; | 272 // @Ignore |
118 } | 273 X.fakeConstructor$(); |
| 274 external num x(); |
119 }`); | 275 }`); |
120 }); | 276 }); |
121 it('supports method params', () => { | 277 it('supports method params', () => { |
122 expectTranslate('class X { x(a, b) { return 42; } }').to.equal(`class X { | 278 expectTranslate('class X { x(a, b) { return 42; } }').to.equal(`@JS() |
123 x(a, b) { | 279 class X { |
124 return 42; | 280 // @Ignore |
125 } | 281 X.fakeConstructor$(); |
| 282 external x(a, b); |
126 }`); | 283 }`); |
127 }); | 284 }); |
128 it('supports method return types', () => { | 285 it('supports method return types', () => { |
129 expectTranslate('class X { x( a : number, b : string ) { return 42; } }').
to.equal(`class X { | 286 expectTranslate('class X { x( a : number, b : string ) { return 42; } }').
to.equal(`@JS() |
130 x(num a, String b) { | 287 class X { |
131 return 42; | 288 // @Ignore |
132 } | 289 X.fakeConstructor$(); |
| 290 external x(num a, String b); |
133 }`); | 291 }`); |
134 }); | 292 }); |
135 it('supports get methods', () => { | 293 it('supports get methods', () => { |
136 expectTranslate('class X { get y(): number {} }').to.equal(`class X { | 294 expectTranslate('class X { get y(): number {} }').to.equal(`@JS() |
137 num get y {} | 295 class X { |
| 296 // @Ignore |
| 297 X.fakeConstructor$(); |
| 298 external num get y; |
138 }`); | 299 }`); |
139 expectTranslate('class X { static get Y(): number {} }').to.equal(`class X
{ | 300 expectTranslate('class X { static get Y(): number {} }').to.equal(`@JS() |
140 static num get Y {} | 301 class X { |
| 302 // @Ignore |
| 303 X.fakeConstructor$(); |
| 304 external static num get Y; |
141 }`); | 305 }`); |
142 }); | 306 }); |
143 it('supports set methods', () => { | 307 it('supports set methods', () => { |
144 expectTranslate('class X { set y(n: number) {} }').to.equal(`class X { | 308 expectTranslate('class X { set y(n: number) {} }').to.equal(`@JS() |
145 set y(num n) {} | 309 class X { |
| 310 // @Ignore |
| 311 X.fakeConstructor$(); |
| 312 external set y(num n); |
146 }`); | 313 }`); |
147 expectTranslate('class X { static get Y(): number {} }').to.equal(`class X
{ | 314 expectTranslate('class X { static get Y(): number {} }').to.equal(`@JS() |
148 static num get Y {} | 315 class X { |
| 316 // @Ignore |
| 317 X.fakeConstructor$(); |
| 318 external static num get Y; |
149 }`); | 319 }`); |
150 }); | 320 }); |
151 it('supports constructors', () => { | 321 it('supports constructors', () => { |
152 expectTranslate('class X { constructor() {} }').to.equal(`class X { | 322 expectTranslate('class X { constructor() {} }').to.equal(`@JS() |
153 X() {} | 323 class X { |
| 324 // @Ignore |
| 325 X.fakeConstructor$(); |
| 326 external factory X(); |
154 }`); | 327 }`); |
155 }); | 328 }); |
156 it('supports parameter properties', () => { | 329 it('supports parameter properties', () => { |
157 expectTranslate( | 330 expectTranslate( |
158 'class X { c: number; \n' + | 331 'class X { c: number; \n' + |
159 ' constructor(private _bar: B, ' + | 332 ' constructor(private _bar: B, ' + |
160 'public foo: string = "hello", ' + | 333 'public foo: string = "hello", ' + |
161 'private _goggles: boolean = true) {} }') | 334 'private _goggles: boolean = true) {} }') |
162 .to.equal(`class X { | 335 .to.equal(`@JS() |
163 B _bar; | 336 class X { |
164 String foo; | 337 // @Ignore |
165 bool _goggles; | 338 X.fakeConstructor$(); |
166 num c; | 339 external B get JS$_bar; |
167 X(this._bar, [this.foo = "hello", this._goggles = true]) {} | 340 external set JS$_bar(B v); |
| 341 external String get foo; |
| 342 external set foo(String v); |
| 343 external bool get JS$_goggles; |
| 344 external set JS$_goggles(bool v); |
| 345 external num get c; |
| 346 external set c(num v); |
| 347 external factory X(B JS$_bar, [String foo, bool JS$_goggles]); |
168 }`); | 348 }`); |
169 expectTranslate( | 349 expectTranslate( |
170 '@CONST class X { ' + | 350 '@CONST class X { ' + |
171 'constructor(public foo: string, b: number, private _marbles: boolean
= true) {} }') | 351 'constructor(public foo: string, b: number, private _marbles: boolean
= true) {} }') |
172 .to.equal(`class X { | 352 .to.equal(`@JS() |
173 final String foo; | 353 class X { |
174 final bool _marbles; | 354 // @Ignore |
175 const X(this.foo, num b, [this._marbles = true]); | 355 X.fakeConstructor$(); |
| 356 external String get foo; |
| 357 external set foo(String v); |
| 358 external bool get JS$_marbles; |
| 359 external set JS$_marbles(bool v); |
| 360 external factory X(String foo, num b, [bool JS$_marbles]); |
176 }`); | 361 }`); |
177 }); | 362 }); |
178 }); | 363 }); |
179 }); | 364 }); |
180 | 365 |
181 describe('interfaces', () => { | 366 describe('interfaces', () => { |
182 it('translates interfaces to abstract classes', | 367 it('translates interfaces to abstract classes', () => { |
183 () => { expectTranslate('interface X {}').to.equal('abstract class X {}');
}); | 368 expectTranslate('interface X {}').to.equal(`@anonymous |
| 369 @JS() |
| 370 abstract class X {}`); |
| 371 }); |
184 it('translates interface extends to class implements', () => { | 372 it('translates interface extends to class implements', () => { |
185 expectTranslate('interface X extends Y, Z {}').to.equal('abstract class X im
plements Y, Z {}'); | 373 expectTranslate('interface X extends Y, Z {}').to.equal(`@anonymous |
| 374 @JS() |
| 375 abstract class X implements Y, Z {}`); |
186 }); | 376 }); |
187 it('supports abstract methods', () => { | 377 it('supports abstract methods', () => { |
188 expectTranslate('interface X { x(); }').to.equal(`abstract class X { | 378 expectTranslate('interface X { x(); }').to.equal(`@anonymous |
189 x(); | 379 @JS() |
| 380 abstract class X { |
| 381 external x(); |
190 }`); | 382 }`); |
191 }); | 383 }); |
192 it('supports interface properties', () => { | 384 it('supports interface properties', () => { |
193 expectTranslate('interface X { x: string; y; }').to.equal(`abstract class X
{ | 385 expectTranslate('interface X { x: string; y; }').to.equal(`@anonymous |
194 String x; | 386 @JS() |
195 var y; | 387 abstract class X { |
| 388 external String get x; |
| 389 external set x(String v); |
| 390 external get y; |
| 391 external set y(v); |
| 392 external factory X({String x, y}); |
196 }`); | 393 }`); |
197 }); | 394 }); |
198 }); | 395 }); |
199 | 396 |
200 describe('single call signature interfaces', () => { | 397 describe('single call signature interfaces', () => { |
201 it('should support declaration', () => { | 398 it('should support declaration', () => { |
202 expectTranslate('interface F { (n: number): boolean; }').to.equal('typedef b
ool F(num n);'); | 399 expectTranslate('interface F { (n: number): boolean; }').to.equal('typedef b
ool F(num n);'); |
203 }); | 400 }); |
204 it('should support generics', () => { | 401 it('should support generics', () => { |
205 expectTranslate('interface F<A, B> { (a: A): B; }').to.equal('typedef B F<A,
B>(A a);'); | 402 expectTranslate('interface F<A, B> { (a: A): B; }').to.equal('typedef B F<A,
B>(A a);'); |
206 }); | 403 }); |
207 }); | 404 }); |
208 | 405 |
209 describe('enums', () => { | 406 describe('enums', () => { |
210 it('should support basic enum declaration', () => { | 407 it('should support basic enum declaration', () => { |
211 expectTranslate('enum Color { Red, Green, Blue }').to.equal('enum Color { Re
d, Green, Blue }'); | 408 expectTranslate('enum Color { Red, Green, Blue }').to.equal(`@JS() |
| 409 class Color { |
| 410 external static num get Red; |
| 411 external static num get Green; |
| 412 external static num get Blue; |
| 413 }`); |
212 }); | 414 }); |
213 it('does not support empty enum', | 415 it('allow empty enum', () => { |
214 () => { expectErroneousCode('enum Empty {}').to.throw('empty enums are not
supported'); }); | 416 expectTranslate('enum Empty {}').to.equal(`@JS() |
215 it('does not support enum with initializer', () => { | 417 class Empty {}`); |
216 expectErroneousCode('enum Color { Red = 1, Green, Blue = 4 }') | |
217 .to.throw('enum initializers are not supported'); | |
218 }); | 418 }); |
219 it('should support switch over enum', () => { | 419 it('enum with initializer', () => { |
220 expectTranslate('switch(c) { case Color.Red: break; default: break; }').to.e
qual(`switch (c) { | 420 expectTranslate('enum Color { Red = 1, Green, Blue = 4 }').to.equal(`@JS() |
221 case Color.Red: | 421 class Color { |
222 break; | 422 external static num get Red; |
223 default: | 423 external static num get Green; |
224 break; | 424 external static num get Blue; |
225 }`); | 425 }`); |
226 }); | 426 }); |
| 427 it('should ingore switch', () => { |
| 428 expectTranslate('switch(c) { case Color.Red: break; default: break; }').to.e
qual(''); |
| 429 }); |
227 it('does not support const enum', () => { | 430 it('does not support const enum', () => { |
228 expectErroneousCode('const enum Color { Red }').to.throw('const enums are no
t supported'); | 431 expectErroneousCode('const enum Color { Red }').to.throw('const enums are no
t supported'); |
229 }); | 432 }); |
230 }); | 433 }); |
OLD | NEW |