Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 var assert = chai.assert; | 5 var assert = chai.assert; |
| 6 | 6 |
| 7 suite('generic', () => { | 7 suite('generic', () => { |
| 8 "use strict"; | 8 "use strict"; |
| 9 | 9 |
| 10 let generic = dart.generic; | 10 let generic = dart.generic; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 suite('instanceOf', () => { | 85 suite('instanceOf', () => { |
| 86 "use strict"; | 86 "use strict"; |
| 87 | 87 |
| 88 let expect = assert.equal; | 88 let expect = assert.equal; |
| 89 let isGroundType = dart.isGroundType; | 89 let isGroundType = dart.isGroundType; |
| 90 let generic = dart.generic; | 90 let generic = dart.generic; |
| 91 let intIsNonNullable = false; | 91 let intIsNonNullable = false; |
| 92 let cast = dart.as; | 92 let cast = dart.as; |
| 93 let instanceOf = dart.is; | 93 let instanceOf = dart.is; |
| 94 let runtimeType = dart.realRuntimeType; | 94 let runtimeType = dart.realRuntimeType; |
| 95 let setRuntimeType = dart.setRuntimeType; | |
| 96 let functionType = dart.functionType; | 95 let functionType = dart.functionType; |
| 97 let typedef = dart.typedef; | 96 let typedef = dart.typedef; |
| 98 | 97 |
| 99 let Object = core.Object; | 98 let Object = core.Object; |
| 100 let String = core.String; | 99 let String = core.String; |
| 101 let dynamic = dart.dynamic; | 100 let dynamic = dart.dynamic; |
| 102 let List = core.List; | 101 let List = core.List; |
| 103 let Map = core.Map; | 102 let Map = core.Map; |
| 104 let Map$ = core.Map$; | 103 let Map$ = core.Map$; |
| 105 let int = core.int; | 104 let int = core.int; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 118 | 117 |
| 119 let Func2 = typedef('Func2', () => functionType(dynamic, [dynamic, dynamic])); | 118 let Func2 = typedef('Func2', () => functionType(dynamic, [dynamic, dynamic])); |
| 120 let Foo = typedef('Foo', () => functionType(B, [B, String])); | 119 let Foo = typedef('Foo', () => functionType(B, [B, String])); |
| 121 | 120 |
| 122 let FuncG$ = generic((T, U) => typedef('FuncG', () => functionType(T, [T, U])) ) | 121 let FuncG$ = generic((T, U) => typedef('FuncG', () => functionType(T, [T, U])) ) |
| 123 let FuncG = FuncG$(); | 122 let FuncG = FuncG$(); |
| 124 | 123 |
| 125 // TODO(vsm): Revisit when we encode types on functions properly. | 124 // TODO(vsm): Revisit when we encode types on functions properly. |
| 126 // A bar1(C c, String s) => null; | 125 // A bar1(C c, String s) => null; |
| 127 function bar1(c, s) { return null; } | 126 function bar1(c, s) { return null; } |
| 128 setRuntimeType(bar1, functionType(A, [C, String])); | 127 dart.fn(bar1, A, [C, String]); |
| 129 | 128 |
| 130 // bar2(B b, String s) => null; | 129 // bar2(B b, String s) => null; |
| 131 function bar2(b, s) { return null; } | 130 function bar2(b, s) { return null; } |
| 132 setRuntimeType(bar2, functionType(dynamic, [B, String])); | 131 dart.fn(bar2, dynamic, [B, String]); |
| 133 | 132 |
| 134 // B bar3(B b, Object o) => null; | 133 // B bar3(B b, Object o) => null; |
| 135 function bar3(b, o) { return null; } | 134 function bar3(b, o) { return null; } |
| 136 setRuntimeType(bar3, functionType(B, [B, Object])); | 135 dart.fn(bar3, B, [B, Object]); |
| 137 | 136 |
| 138 // B bar4(B b, o) => null; | 137 // B bar4(B b, o) => null; |
| 139 function bar4(b, o) { return null; } | 138 function bar4(b, o) { return null; } |
| 140 setRuntimeType(bar4, functionType(B, [B, dynamic])); | 139 dart.fn(bar4, B, [B, dynamic]); |
| 141 | 140 |
| 142 // C bar5(A a, Object o) => null; | 141 // C bar5(A a, Object o) => null; |
| 143 function bar5(a, o) { return null; } | 142 function bar5(a, o) { return null; } |
| 144 setRuntimeType(bar5, functionType(C, [A, Object])); | 143 dart.fn(bar5, C, [A, Object]); |
| 145 | 144 |
| 146 // B bar6(B b, String s, String o) => null; | 145 // B bar6(B b, String s, String o) => null; |
| 147 function bar6(b, s, o) { return null; } | 146 function bar6(b, s, o) { return null; } |
| 148 setRuntimeType(bar6, functionType(B, [B, String, String])); | 147 dart.fn(bar6, B, [B, String, String]); |
| 149 | 148 |
| 150 // B bar7(B b, String s, [Object o]) => null; | 149 // B bar7(B b, String s, [Object o]) => null; |
| 151 function bar7(b, s, o) { return null; } | 150 function bar7(b, s, o) { return null; } |
| 152 setRuntimeType(bar7, functionType(B, [B, String], [Object])); | 151 dart.fn(bar7, B, [B, String], [Object]); |
| 153 | 152 |
| 154 // B bar8(B b, String s, {Object p}) => null; | 153 // B bar8(B b, String s, {Object p}) => null; |
| 155 function bar8(b, s, o) { return null; } | 154 function bar8(b, s, o) { return null; } |
| 156 setRuntimeType(bar8, functionType(B, [B, String], {p: Object})); | 155 dart.fn(bar8, B, [B, String], {p: Object}); |
| 156 | |
| 157 let cls1 = dart.fn((c, s) => { return null; }, A, [C, String]); | |
| 158 | |
| 159 let cls2 = dart.fn((b, s) => { return null; }, dynamic, [B, String]); | |
| 160 | |
| 161 let cls3 = dart.fn((b, o) => { return null; }, B, [B, Object]); | |
| 162 | |
| 163 let cls4 = dart.fn((b, o) => { return null; }, B, [B, dynamic]); | |
| 164 | |
| 165 let cls5 = dart.fn((a, o) => { return null; }, C, [A, Object]); | |
| 166 | |
| 167 let cls6 = dart.fn((b, s, o) => { return null; }, B, [B, String, String]); | |
| 168 | |
| 169 let cls7 = dart.fn((b, s, o) => { return null; }, B, [B, String], [Object]); | |
| 170 | |
| 171 let cls8 = dart.fn((b, s, o) => { return null; }, B, [B, String], {p: Object}) ; | |
|
Jennifer Messerly
2015/05/19 22:49:48
long line
Leaf
2015/05/19 23:24:07
Done.
| |
| 157 | 172 |
| 158 function checkType(x, type, expectedTrue) { | 173 function checkType(x, type, expectedTrue) { |
| 159 if (expectedTrue === undefined) expectedTrue = true; | 174 if (expectedTrue === undefined) expectedTrue = true; |
| 160 expect(instanceOf(x, type), expectedTrue); | 175 expect(instanceOf(x, type), expectedTrue); |
| 161 } | 176 } |
| 162 | 177 |
| 163 test('int', () => { | 178 test('int', () => { |
| 164 expect(isGroundType(int), true); | 179 expect(isGroundType(int), true); |
| 165 expect(isGroundType(runtimeType(5)), true); | 180 expect(isGroundType(runtimeType(5)), true); |
| 166 | 181 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 checkType(s1, c.SetMixin$(int), false); | 339 checkType(s1, c.SetMixin$(int), false); |
| 325 }); | 340 }); |
| 326 | 341 |
| 327 test('Functions', () => { | 342 test('Functions', () => { |
| 328 // - return type: Dart is bivariant. We're covariant. | 343 // - return type: Dart is bivariant. We're covariant. |
| 329 // - param types: Dart is bivariant. We're contravariant. | 344 // - param types: Dart is bivariant. We're contravariant. |
| 330 expect(isGroundType(Func2), true); | 345 expect(isGroundType(Func2), true); |
| 331 expect(isGroundType(Foo), false); | 346 expect(isGroundType(Foo), false); |
| 332 expect(isGroundType(functionType(B, [B, String])), false); | 347 expect(isGroundType(functionType(B, [B, String])), false); |
| 333 checkType(bar1, Foo, false); | 348 checkType(bar1, Foo, false); |
| 349 checkType(cls1, Foo, false); | |
| 334 checkType(bar1, functionType(B, [B, String]), false); | 350 checkType(bar1, functionType(B, [B, String]), false); |
| 351 checkType(cls1, functionType(B, [B, String]), false); | |
| 335 checkType(bar2, Foo, false); | 352 checkType(bar2, Foo, false); |
| 353 checkType(cls2, Foo, false); | |
| 336 checkType(bar2, functionType(B, [B, String]), false); | 354 checkType(bar2, functionType(B, [B, String]), false); |
| 355 checkType(cls2, functionType(B, [B, String]), false); | |
| 337 checkType(bar3, Foo); | 356 checkType(bar3, Foo); |
| 357 checkType(cls3, Foo); | |
| 338 checkType(bar3, functionType(B, [B, String])); | 358 checkType(bar3, functionType(B, [B, String])); |
| 359 checkType(cls3, functionType(B, [B, String])); | |
| 339 checkType(bar4, Foo, false); | 360 checkType(bar4, Foo, false); |
| 361 checkType(cls4, Foo, false); | |
| 340 // TODO(vsm): Revisit. bar4 is (B, *) -> B. Perhaps it should be treated a s top for a reified object. | 362 // TODO(vsm): Revisit. bar4 is (B, *) -> B. Perhaps it should be treated a s top for a reified object. |
| 341 checkType(bar4, functionType(B, [B, String]), false); | 363 checkType(bar4, functionType(B, [B, String]), false); |
| 364 checkType(cls4, functionType(B, [B, String]), false); | |
| 342 checkType(bar5, Foo); | 365 checkType(bar5, Foo); |
| 366 checkType(cls5, Foo); | |
| 343 checkType(bar5, functionType(B, [B, String])); | 367 checkType(bar5, functionType(B, [B, String])); |
| 368 checkType(cls5, functionType(B, [B, String])); | |
| 344 checkType(bar6, Foo, false); | 369 checkType(bar6, Foo, false); |
| 370 checkType(cls6, Foo, false); | |
| 345 checkType(bar6, functionType(B, [B, String]), false); | 371 checkType(bar6, functionType(B, [B, String]), false); |
| 372 checkType(cls6, functionType(B, [B, String]), false); | |
| 346 checkType(bar7, Foo); | 373 checkType(bar7, Foo); |
| 374 checkType(cls7, Foo); | |
| 347 checkType(bar7, functionType(B, [B, String])); | 375 checkType(bar7, functionType(B, [B, String])); |
| 376 checkType(cls7, functionType(B, [B, String])); | |
| 348 checkType(bar7, runtimeType(bar6)); | 377 checkType(bar7, runtimeType(bar6)); |
| 378 checkType(cls7, runtimeType(bar6)); | |
| 349 checkType(bar8, Foo); | 379 checkType(bar8, Foo); |
| 380 checkType(cls8, Foo); | |
| 350 checkType(bar8, functionType(B, [B, String])); | 381 checkType(bar8, functionType(B, [B, String])); |
| 382 checkType(cls8, functionType(B, [B, String])); | |
| 351 checkType(bar8, runtimeType(bar6), false); | 383 checkType(bar8, runtimeType(bar6), false); |
| 384 checkType(cls8, runtimeType(bar6), false); | |
| 352 checkType(bar7, runtimeType(bar8), false); | 385 checkType(bar7, runtimeType(bar8), false); |
| 386 checkType(cls7, runtimeType(bar8), false); | |
| 353 checkType(bar8, runtimeType(bar7), false); | 387 checkType(bar8, runtimeType(bar7), false); |
| 388 checkType(cls8, runtimeType(bar7), false); | |
| 354 | 389 |
| 355 // Parameterized typedefs | 390 // Parameterized typedefs |
| 356 expect(isGroundType(FuncG), true); | 391 expect(isGroundType(FuncG), true); |
| 357 expect(isGroundType(FuncG$(B, String)), false); | 392 expect(isGroundType(FuncG$(B, String)), false); |
| 358 checkType(bar1, FuncG$(B, String), false); | 393 checkType(bar1, FuncG$(B, String), false); |
| 394 checkType(cls1, FuncG$(B, String), false); | |
| 359 checkType(bar3, FuncG$(B, String)); | 395 checkType(bar3, FuncG$(B, String)); |
| 396 checkType(cls3, FuncG$(B, String)); | |
| 397 }); | |
| 398 | |
| 399 test('dcall', () => { | |
| 400 function dd2d(x, y) {return x}; | |
| 401 dart.fn(dd2d); | |
| 402 function ii2i(x, y) {return x}; | |
| 403 dart.fn(ii2i, core.int, [core.int, core.int]); | |
| 404 function ii_2i(x, y) {return x}; | |
| 405 dart.fn(ii_2i, core.int, [core.int], [core.int]); | |
| 406 function i_i2i(x, opts) {return x}; | |
| 407 dart.fn(i_i2i, core.int, [core.int], {extra: core.int}); | |
| 408 | |
| 409 assert.equal(dart.dcall(dd2d, 0, 1), 0); | |
| 410 assert.equal(dart.dcall(dd2d, "hello", "world"), "hello"); | |
| 411 assert.throws(() => dart.dcall(dd2d, 0)); | |
| 412 assert.throws(() => dart.dcall(dd2d, 0, 1, 2)); | |
| 413 assert.throws(() => dart.dcall(dd2d, 0, 1, {extra : 3})); | |
| 414 // This should throw but currently doesn't. | |
| 415 // assert.throws(() => dart.dcall(dd2d, 0, {extra:3})); | |
| 416 | |
| 417 assert.equal(dart.dcall(ii2i, 0, 1), 0); | |
| 418 assert.throws(() => dart.dcall(ii2i, "hello", "world")); | |
| 419 assert.throws(() => dart.dcall(ii2i, 0)); | |
| 420 assert.throws(() => dart.dcall(ii2i, 0, 1, 2)); | |
| 421 | |
| 422 assert.equal(dart.dcall(ii_2i, 0, 1), 0); | |
| 423 assert.throws(() => dart.dcall(ii_2i, "hello", "world")); | |
| 424 assert.equal(dart.dcall(ii_2i, 0), 0); | |
| 425 assert.throws(() => dart.dcall(ii_2i, 0, 1, 2)); | |
| 426 | |
| 427 assert.throws(() => dart.dcall(i_i2i, 0, 1)); | |
| 428 assert.throws(() => dart.dcall(i_i2i, "hello", "world")); | |
| 429 assert.equal(dart.dcall(i_i2i, 0), 0); | |
| 430 assert.throws(() => dart.dcall(i_i2i, 0, 1, 2)); | |
| 431 assert.equal(dart.dcall(i_i2i, 0, {extra: 3}), 0); | |
| 432 }); | |
| 433 | |
| 434 test('dsend', () => { | |
| 435 class Tester extends core.Object { | |
| 436 Tester() { | |
| 437 this.f = dart.fn(x => x, core.int, [core.int]); | |
| 438 this.me = this; | |
| 439 } | |
| 440 m(x, y) {return x;} | |
| 441 call(x) {return x;} | |
| 442 static s(x, y) { return x;} | |
| 443 } | |
| 444 dart.setSignature(Tester, { | |
| 445 methods: () => ({ | |
| 446 m: dart.functionType(core.int, [core.int, core.int]), | |
| 447 call: dart.functionType(core.int, [core.int]) | |
| 448 }), | |
| 449 statics: () => ({ | |
| 450 s: dart.functionType(core.String, [core.String]) | |
| 451 }), | |
| 452 names: ['s'] | |
| 453 }) | |
| 454 let o = new Tester(); | |
| 455 | |
| 456 // Method send | |
| 457 assert.equal(dart.dsend(o, 'm', 3, 4), 3); | |
| 458 assert.throws(() => dart.dsend(o, 'm', 3)); | |
| 459 assert.throws(() => dart.dsend(o, 'm', "hello", "world")); | |
| 460 assert.throws(() => dart.dsend(o, 'q', 3)); | |
| 461 | |
| 462 // Method send through a field | |
| 463 assert.equal(dart.dsend(o, 'f', 3), 3); | |
| 464 assert.throws(() => dart.dsend(o, 'f', "hello")); | |
| 465 assert.throws(() => dart.dsend(o, 'f', 3, 4)); | |
| 466 | |
| 467 // Static method call | |
| 468 assert.equal(dart.dcall(Tester.s, "hello"), "hello"); | |
| 469 assert.throws(() => dart.dcall(Tester.s, "hello", "world")); | |
| 470 assert.throws(() => dart.dcall(Tester.s, 0, 1)); | |
| 471 | |
| 472 // Calling an object with a call method | |
| 473 assert.equal(dart.dcall(o, 3), 3); | |
| 474 assert.throws(() => dart.dcall(o, "hello")); | |
| 475 assert.throws(() => dart.dcall(o, 3, 4)); | |
| 476 | |
| 477 // Calling through a field containing an object with a call method | |
| 478 assert.equal(dart.dsend(o, 'me', 3), 3); | |
| 479 assert.throws(() => dart.dsend(o, 'me', "hello")); | |
| 480 assert.throws(() => dart.dsend(o, 'me', 3, 4)); | |
| 481 }); | |
| 482 | |
| 483 test('Types on top level functions', () => { | |
| 484 // Test some generated code | |
| 485 // Test the lazy path | |
| 486 checkType(core.identityHashCode, | |
| 487 dart.functionType(core.int, [core.Object])); | |
| 488 // Test the normal path | |
| 489 checkType(core.identical, | |
| 490 dart.functionType(core.bool, | |
| 491 [core.Object, core.Object])); | |
| 492 | |
| 493 // Hand crafted tests | |
| 494 // All dynamic | |
| 495 function dd2d(x, y) {return x}; | |
| 496 dart.fn(dd2d); | |
| 497 checkType(dd2d, dart.functionType(dart.dynamic, | |
| 498 [dart.dynamic, dart.dynamic])); | |
| 499 | |
| 500 // Set the type eagerly | |
| 501 function ii2i(x, y) {return x}; | |
| 502 dart.fn(ii2i, core.int, [core.int, core.int]); | |
| 503 checkType(ii2i, dart.functionType(core.int, | |
| 504 [core.int, core.int])); | |
| 505 | |
| 506 // Set the type lazily | |
| 507 function ss2s(x, y) {return x}; | |
| 508 var coreString; | |
| 509 dart.fn(ss2s, () => dart.functionType(coreString, | |
| 510 [coreString, coreString])); | |
| 511 coreString = core.String; | |
| 512 checkType(ss2s, dart.functionType(core.String, | |
| 513 [core.String, core.String])); | |
| 514 | |
| 515 // Optional types | |
| 516 function ii_2i(x, y) {return x}; | |
| 517 dart.fn(ii_2i, core.int, [core.int], [core.int]); | |
| 518 checkType(ii_2i, dart.functionType(core.int, [core.int], | |
| 519 [core.int])); | |
| 520 checkType(ii_2i, dart.functionType(core.int, [core.int, | |
| 521 core.int])); | |
| 522 checkType(ii_2i, dart.functionType(core.int, [], [core.int, | |
| 523 core.int]), | |
| 524 false); | |
| 525 checkType(ii_2i, dart.functionType(core.int, [core.int], | |
| 526 {extra: core.int}), false); | |
| 527 | |
| 528 // Named types | |
| 529 function i_i2i(x, opts) {return x}; | |
| 530 dart.fn(i_i2i, core.int, [core.int], {extra: core.int}); | |
| 531 checkType(i_i2i, dart.functionType(core.int, [core.int], | |
| 532 {extra: core.int})); | |
| 533 checkType(i_i2i, dart.functionType(core.int, | |
| 534 [core.int, core.int]), false); | |
| 535 checkType(i_i2i, dart.functionType(core.int, [core.int], {})); | |
| 536 checkType(i_i2i, | |
| 537 dart.functionType(core.int, [], {extra: core.int, | |
| 538 also: core.int}), false); | |
| 539 checkType(i_i2i, | |
| 540 dart.functionType(core.int, [core.int], [core.int]), false); | |
| 541 }); | |
| 542 | |
| 543 test('Method tearoffs', () => { | |
| 544 let c = collection; | |
| 545 // Tear off of an inherited method | |
| 546 let map = new (Map$(core.int, core.String))(); | |
| 547 checkType(dart.tearoff(map, 'toString'), | |
| 548 dart.functionType(String, [])); | |
| 549 checkType(dart.tearoff(map, 'toString'), | |
| 550 dart.functionType(int, []), false); | |
| 551 | |
| 552 // Tear off of a method directly on the object | |
| 553 let smap = new (c.SplayTreeMap$(core.int, core.String))(); | |
| 554 checkType(dart.tearoff(smap, 'forEach'), | |
| 555 dart.functionType(dart.void, | |
| 556 [dart.functionType(dart.void, [core.int, core.String])])); | |
| 557 checkType(dart.tearoff(smap, 'forEach'), | |
| 558 dart.functionType(dart.void, | |
| 559 [dart.functionType(dart.void, | |
| 560 [core.String, core.String])]), false); | |
| 561 | |
| 562 // Tear off of a mixed in method | |
| 563 let mapB = new (c.MapBase$(core.int, core.int))(); | |
| 564 checkType(dart.tearoff(mapB, 'forEach'), | |
| 565 dart.functionType(dart.void, [ | |
| 566 dart.functionType(dart.void, [core.int, core.int])])); | |
| 567 checkType(dart.tearoff(mapB, 'forEach'), | |
| 568 dart.functionType(dart.void, [ | |
| 569 dart.functionType(dart.void, [core.int, core.String])]), | |
| 570 false); | |
| 571 | |
| 572 // Tear off of a method with a symbol name | |
| 573 let listB = new (c.ListBase$(core.int))(); | |
| 574 checkType(dart.tearoff(listB, core.$add), | |
| 575 dart.functionType(dart.void, [core.int])); | |
| 576 checkType(dart.tearoff(listB, core.$add), | |
| 577 dart.functionType(dart.void, [core.String]), false); | |
| 578 | |
| 579 // Tear off of a static method | |
| 580 checkType(c.ListBase.listToString, | |
| 581 dart.functionType(core.String, [core.List])); | |
| 582 checkType(c.ListBase.listToString, | |
| 583 dart.functionType(core.String, [core.String]), false); | |
| 584 | |
| 360 }); | 585 }); |
| 361 | 586 |
| 362 test('Object members', () => { | 587 test('Object members', () => { |
| 363 let nullHash = dart.hashCode(null); | 588 let nullHash = dart.hashCode(null); |
| 364 assert.equal(nullHash, 0); | 589 assert.equal(nullHash, 0); |
| 365 let nullString = dart.toString(null); | 590 let nullString = dart.toString(null); |
| 366 assert.equal(nullString, 'null'); | 591 assert.equal(nullString, 'null'); |
| 367 let nullType = dart.runtimeType(null); | 592 let nullType = dart.runtimeType(null); |
| 368 assert.equal(nullType, core.Null); | 593 assert.equal(nullType, core.Null); |
| 369 | 594 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 | 626 |
| 402 suite('primitives', function() { | 627 suite('primitives', function() { |
| 403 'use strict'; | 628 'use strict'; |
| 404 | 629 |
| 405 test('fixed length list', () => { | 630 test('fixed length list', () => { |
| 406 let list = new core.List(10); | 631 let list = new core.List(10); |
| 407 list[0] = 42; | 632 list[0] = 42; |
| 408 assert.throws(() => list.add(42)); | 633 assert.throws(() => list.add(42)); |
| 409 }); | 634 }); |
| 410 }); | 635 }); |
| OLD | NEW |