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('dart_runtime generic', function() { | 7 suite('generic', () => { |
|
Jennifer Messerly
2015/04/01 00:32:35
this test had bit rotted
| |
| 8 "use strict"; | 8 "use strict"; |
| 9 | 9 |
| 10 var generic = dart.generic; | 10 let generic = dart.generic; |
| 11 | 11 |
| 12 test('zero arguments is not allowed', function() { | 12 test('zero arguments is not allowed', () => { |
| 13 assert.throws(function() { generic(function(){}); }); | 13 assert.throws(() => { generic(function(){}); }); |
| 14 }); | 14 }); |
| 15 | 15 |
| 16 test('argument count cannot change', function() { | 16 test('argument count cannot change', () => { |
| 17 var SomeType = generic(function(x) {}); | 17 let SomeType = generic(function(x) { return {x: x}; }); |
| 18 assert.throws(function() { SomeType(1,2) }); | 18 assert.throws(() => { SomeType(1,2) }); |
| 19 SomeType(1); | 19 let obj = {}; |
| 20 SomeType(1); | 20 assert.equal(SomeType(obj).x, obj); |
| 21 assert.throws(function() { SomeType() }); | 21 assert.equal(SomeType(obj).x, obj); |
| 22 SomeType(1); | 22 assert.equal(SomeType().x, dart.dynamic); |
| 23 }); | 23 }); |
| 24 | 24 |
| 25 test('undefined is not allowed as an argument', function() { | 25 test('undefined/null are not allowed', () => { |
| 26 var SomeType = generic(function(x) {}); | 26 let SomeType = generic(function(x) {}); |
| 27 assert.throws(function() { SomeType(void 0) }); | 27 assert.throws(() => { SomeType(void 0) }); |
| 28 SomeType(1); | 28 SomeType(1); |
| 29 assert.throws(function() { SomeType(void 0) }); | 29 assert.throws(() => { SomeType(void 0) }); |
| 30 SomeType(1); | 30 SomeType(1); |
| 31 SomeType(null); | 31 assert.throws(() => { SomeType(null) }); |
| 32 }); | 32 }); |
| 33 | 33 |
| 34 test('result is memoized', function() { | 34 test('result is memoized', () => { |
| 35 var t1 = Object.create(null); | 35 let t1 = Object.create(null); |
| 36 var t2 = Object.create(null); | 36 let t2 = Object.create(null); |
| 37 | 37 |
| 38 var count = 0; | 38 let count = 0; |
| 39 var SomeType = generic(function(x, y) { | 39 let SomeType = generic(function(x, y) { |
| 40 count++; | 40 count++; |
| 41 return Object.create(null); | 41 return Object.create(null); |
| 42 }); | 42 }); |
| 43 | 43 |
| 44 var x12 = SomeType(1, 2); | 44 let x12 = SomeType(1, 2); |
| 45 assert.strictEqual(SomeType(1, 2), x12); | 45 assert.strictEqual(SomeType(1, 2), x12); |
| 46 assert.strictEqual(SomeType(1, 2), x12); | 46 assert.strictEqual(SomeType(1, 2), x12); |
| 47 assert.strictEqual(count, 1); | 47 assert.strictEqual(count, 1); |
| 48 var x11 = SomeType(1, 1); | 48 let x11 = SomeType(1, 1); |
| 49 assert.strictEqual(count, 2); | 49 assert.strictEqual(count, 2); |
| 50 assert.strictEqual(SomeType(1, 1), x11); | 50 assert.strictEqual(SomeType(1, 1), x11); |
| 51 assert.strictEqual(count, 2); | 51 assert.strictEqual(count, 2); |
| 52 count = 0; | 52 count = 0; |
| 53 | 53 |
| 54 var t1t2 = SomeType(t1, t2); | 54 let t1t2 = SomeType(t1, t2); |
| 55 assert.strictEqual(count, 1); | 55 assert.strictEqual(count, 1); |
| 56 var t2t1 = SomeType(t2, t1); | 56 let t2t1 = SomeType(t2, t1); |
| 57 assert.strictEqual(count, 2); | 57 assert.strictEqual(count, 2); |
| 58 assert.notStrictEqual(t1t2, t2t1); | 58 assert.notStrictEqual(t1t2, t2t1); |
| 59 assert.strictEqual(SomeType(t1, t2), t1t2); | 59 assert.strictEqual(SomeType(t1, t2), t1t2); |
| 60 assert.strictEqual(SomeType(t2, t1), t2t1); | 60 assert.strictEqual(SomeType(t2, t1), t2t1); |
| 61 assert.strictEqual(SomeType(t1, t2), t1t2); | 61 assert.strictEqual(SomeType(t1, t2), t1t2); |
| 62 count = 0; | 62 count = 0; |
| 63 | 63 |
| 64 var nullKeys = SomeType(null, null); | |
| 65 assert.strictEqual(SomeType(null, null), nullKeys); | |
| 66 assert.strictEqual(count, 1); | |
| 67 count = 0; | |
| 68 | |
| 69 // Nothing has been stored on the object | 64 // Nothing has been stored on the object |
| 70 assert.strictEqual(Object.keys(t1).length, 0); | 65 assert.strictEqual(Object.keys(t1).length, 0); |
| 71 assert.strictEqual(Object.keys(t2).length, 0); | 66 assert.strictEqual(Object.keys(t2).length, 0); |
| 72 }); | 67 }); |
| 73 | 68 |
| 74 test('type constructor is reflectable', function() { | 69 test('type constructor is reflectable', () => { |
| 75 var SomeType = generic(function(x, y) { return Object.create(null); }); | 70 let SomeType = generic(function(x, y) { return Object.create(null); }); |
| 76 var someValue = SomeType('hi', 123); | 71 let someValue = SomeType('hi', 123); |
| 77 assert.deepEqual(someValue[dart.typeSignature], [SomeType, 'hi', 123]); | 72 assert.equal(someValue[dart.originalDeclaration], SomeType); |
| 73 assert.deepEqual(someValue[dart.typeArguments], ['hi', 123]); | |
| 78 }); | 74 }); |
| 79 }); | 75 }); |
| 76 | |
| 77 | |
| 78 suite('instanceOf', () => { | |
| 79 "use strict"; | |
| 80 | |
| 81 let expect = assert.equal; | |
| 82 let isGroundType = dart.isGroundType; | |
| 83 let generic = dart.generic; | |
| 84 let intIsNonNullable = false; | |
| 85 let cast = dart.as; | |
| 86 let instanceOf = dart.is; | |
| 87 let getRuntimeType = dart.getRuntimeType; | |
| 88 | |
| 89 let Object = core.Object; | |
| 90 let String = core.String; | |
| 91 let dynamic = dart.dynamic; | |
| 92 let List = core.List; | |
| 93 let Map = core.Map; | |
| 94 let Map$ = core.Map$; | |
| 95 let int = core.int; | |
| 96 let num = core.num; | |
| 97 let bool = core.bool; | |
| 98 | |
| 99 class A {} | |
| 100 class B extends A {} | |
| 101 class C extends B {} | |
| 102 | |
| 103 let AA$ = generic((T, U) => class AA extends core.Object {}); | |
| 104 let AA = AA$(); | |
| 105 let BB$ = generic((T, U) => class BB extends AA$(U, T) {}); | |
| 106 let BB = BB$(); | |
| 107 class CC extends BB$(String, List) {} | |
| 108 | |
| 109 function checkType(x, type, expectedTrue) { | |
| 110 if (expectedTrue === undefined) expectedTrue = true; | |
| 111 expect(instanceOf(x, type), expectedTrue); | |
| 112 } | |
| 113 | |
| 114 test('int', () => { | |
| 115 expect(isGroundType(int), true); | |
| 116 expect(isGroundType(getRuntimeType(5)), true); | |
| 117 | |
| 118 checkType(5, int); | |
| 119 checkType(5, dynamic); | |
| 120 checkType(5, Object); | |
| 121 checkType(5, num); | |
| 122 | |
| 123 checkType(5, bool, false); | |
| 124 checkType(5, String, false); | |
| 125 | |
| 126 expect(cast(5, int), 5); | |
| 127 if (intIsNonNullable) { | |
| 128 expect(() => cast(null, int), throws); | |
| 129 } else { | |
| 130 expect(cast(null, int), null); | |
| 131 } | |
| 132 }); | |
| 133 | |
| 134 test('dynamic', () => { | |
| 135 expect(isGroundType(dynamic), true); | |
| 136 checkType(new Object(), dynamic); | |
| 137 checkType(null, dynamic); | |
| 138 | |
| 139 expect(cast(null, dynamic), null); | |
| 140 }); | |
| 141 | |
| 142 test('Object', () => { | |
| 143 expect(isGroundType(Object), true); | |
| 144 checkType(new Object(), dynamic); | |
| 145 checkType(null, Object); | |
| 146 | |
| 147 expect(cast(null, Object), null); | |
| 148 }); | |
| 149 | |
| 150 test('String', () => { | |
| 151 expect(isGroundType(String), true); | |
| 152 expect(isGroundType(getRuntimeType("foo")), true); | |
| 153 checkType("foo", String); | |
| 154 checkType("foo", Object); | |
| 155 checkType("foo", dynamic); | |
| 156 | |
| 157 expect(cast(null, String), null); | |
| 158 }); | |
| 159 | |
| 160 test('Map', () => { | |
| 161 let m1 = new (Map$(String, String))(); | |
| 162 let m2 = new (Map$(Object, Object))(); | |
| 163 let m3 = new Map(); | |
| 164 let m4 = new (collection.HashMap$(dart.dynamic, dart.dynamic))(); | |
| 165 let m5 = new collection.LinkedHashMap(); | |
| 166 | |
| 167 expect(isGroundType(Map), true); | |
| 168 expect(isGroundType(getRuntimeType(m1)), false); | |
| 169 expect(isGroundType(Map$(String, String)), false); | |
| 170 expect(isGroundType(getRuntimeType(m2)), true); | |
| 171 expect(isGroundType(Map$(Object, Object)), true); | |
| 172 expect(isGroundType(getRuntimeType(m3)), true); | |
| 173 expect(isGroundType(Map), true); | |
| 174 expect(isGroundType(getRuntimeType(m4)), true); | |
| 175 expect(isGroundType(collection.HashMap$(dynamic, dynamic)), true); | |
| 176 expect(isGroundType(getRuntimeType(m5)), true); | |
| 177 expect(isGroundType(collection.LinkedHashMap), true); | |
| 178 expect(isGroundType(collection.LinkedHashMap), true); | |
| 179 | |
| 180 // Map<T1,T2> <: Map | |
| 181 checkType(m1, Map); | |
| 182 checkType(m1, Object); | |
| 183 | |
| 184 // Instance of self | |
| 185 checkType(m1, getRuntimeType(m1)); | |
| 186 checkType(m1, Map$(String, String)); | |
| 187 | |
| 188 // Covariance on generics | |
| 189 checkType(m1, getRuntimeType(m2)); | |
| 190 checkType(m1, Map$(Object, Object)); | |
| 191 | |
| 192 // No contravariance on generics. | |
| 193 checkType(m2, getRuntimeType(m1), false); | |
| 194 checkType(m2, Map$(String, String), false); | |
| 195 | |
| 196 // null is! Map | |
| 197 checkType(null, Map, false); | |
| 198 | |
| 199 // Raw generic types | |
| 200 checkType(m5, Map); | |
| 201 checkType(m4, Map); | |
| 202 }); | |
| 203 | |
| 204 test('generic and inheritance', () => { | |
| 205 let aaraw = new AA(); | |
| 206 let aarawtype = getRuntimeType(aaraw); | |
| 207 let aadynamic = new (AA$(dynamic, dynamic))(); | |
| 208 let aadynamictype = getRuntimeType(aadynamic); | |
| 209 let aa = new (AA$(String, List))(); | |
| 210 let aatype = getRuntimeType(aa); | |
| 211 let bb = new (BB$(String, List))(); | |
| 212 let bbtype = getRuntimeType(bb); | |
| 213 let cc = new CC(); | |
| 214 let cctype = getRuntimeType(cc); | |
| 215 // We don't allow constructing bad types. | |
| 216 // This was AA<String> in Dart (wrong number of type args). | |
| 217 let aabad = new (AA$(dart.dynamic, dart.dynamic))(); | |
| 218 let aabadtype = getRuntimeType(aabad); | |
| 219 | |
| 220 expect(isGroundType(aatype), false); | |
| 221 expect(isGroundType(AA$(String, List)), false); | |
| 222 expect(isGroundType(bbtype), false); | |
| 223 expect(isGroundType(BB$(String, List)), false); | |
| 224 expect(isGroundType(cctype), true); | |
| 225 expect(isGroundType(CC), true); | |
| 226 checkType(cc, aatype, false); | |
| 227 checkType(cc, AA$(String, List), false); | |
| 228 checkType(cc, bbtype); | |
| 229 checkType(cc, BB$(String, List)); | |
| 230 checkType(aa, cctype, false); | |
| 231 checkType(aa, CC, false); | |
| 232 checkType(aa, bbtype, false); | |
| 233 checkType(aa, BB$(String, List), false); | |
| 234 checkType(bb, cctype, false); | |
| 235 checkType(bb, CC, false); | |
| 236 checkType(aa, aabadtype); | |
| 237 checkType(aa, dynamic); | |
| 238 checkType(aabad, aatype, false); | |
| 239 checkType(aabad, AA$(String, List), false); | |
| 240 checkType(aabad, aarawtype); | |
| 241 checkType(aabad, AA); | |
| 242 checkType(aaraw, aabadtype); | |
| 243 checkType(aaraw, AA$(dart.dynamic, dart.dynamic)); | |
| 244 checkType(aaraw, aadynamictype); | |
| 245 checkType(aaraw, AA$(dynamic, dynamic)); | |
| 246 checkType(aadynamic, aarawtype); | |
| 247 checkType(aadynamic, AA); | |
| 248 }); | |
| 249 | |
| 250 test('void', () => { | |
| 251 //checkType((x) => x, type((void _(x)) {})); | |
| 252 }); | |
| 253 | |
| 254 }); | |
| OLD | NEW |