OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 library MirrorsTest; |
| 6 |
| 7 import 'dart:mirrors'; |
| 8 |
| 9 import '../../light_unittest.dart'; |
| 10 |
| 11 bool isDart2js = false; // TODO(ahe): Remove this field. |
| 12 |
| 13 var topLevelField; |
| 14 u(a, b, c) => {"a": a, "b": b, "c": c}; |
| 15 _v(a, b) => a + b; |
| 16 |
| 17 class Class<T> { |
| 18 Class() { this.field = "default value"; } |
| 19 Class.withInitialValue(this.field); |
| 20 var field; |
| 21 |
| 22 Class.generative(this.field); |
| 23 Class.redirecting(y) : this.generative(y*2); |
| 24 factory Class.faktory(y) => new Class.withInitialValue(y*3); |
| 25 factory Class.redirectingFactory(y) = Class.faktory; |
| 26 |
| 27 m(a, b, c) => {"a": a, "b": b, "c": c}; |
| 28 _n(a, b) => a + b; |
| 29 noSuchMethod(invocation) => "DNU"; |
| 30 |
| 31 static var staticField; |
| 32 static s(a, b, c) => {"a": a, "b": b, "c": c}; |
| 33 static _t(a, b) => a + b; |
| 34 } |
| 35 |
| 36 typedef Typedef(); |
| 37 |
| 38 testInvoke(mirrors) { |
| 39 var instance = new Class(); |
| 40 var instMirror = reflect(instance); |
| 41 |
| 42 expect(instMirror.invoke(#m, ['A', 'B', instance]).reflectee, |
| 43 equals({"a": 'A', "b":'B', "c": instance})); |
| 44 expect(instMirror.invoke(#notDefined, []).reflectee, |
| 45 equals("DNU")); |
| 46 expect(instMirror.invoke(#m, []).reflectee, |
| 47 equals("DNU")); // Wrong arity. |
| 48 |
| 49 var classMirror = instMirror.type; |
| 50 expect(classMirror.invoke(#s, ['A', 'B', instance]).reflectee, |
| 51 equals({"a": 'A', "b":'B', "c": instance})); |
| 52 expect(() => classMirror.invoke(#notDefined, []).reflectee, |
| 53 throws); |
| 54 expect(() => classMirror.invoke(#s, []).reflectee, |
| 55 throws); // Wrong arity. |
| 56 |
| 57 var libMirror = classMirror.owner; |
| 58 expect(libMirror.invoke(#u, ['A', 'B', instance]).reflectee, |
| 59 equals({"a": 'A', "b":'B', "c": instance})); |
| 60 expect(() => libMirror.invoke(#notDefined, []).reflectee, |
| 61 throws); |
| 62 expect(() => libMirror.invoke(#u, []).reflectee, |
| 63 throws); // Wrong arity. |
| 64 } |
| 65 |
| 66 /// In dart2js, lists, numbers, and other objects are treated special |
| 67 /// and their methods are invoked through a techique called interceptors. |
| 68 testIntercepted(mirrors) { |
| 69 var instance = 1; |
| 70 var instMirror = reflect(instance); |
| 71 |
| 72 expect(instMirror.invoke(#toString, []).reflectee, |
| 73 equals('1')); |
| 74 |
| 75 instance = []; |
| 76 instMirror = reflect(instance); |
| 77 instMirror.setField(#length, 44); |
| 78 var resultMirror = instMirror.getField(#length); |
| 79 expect(resultMirror.reflectee, equals(44)); |
| 80 expect(instance.length, equals(44)); |
| 81 |
| 82 expect(instMirror.invoke(#toString, []).reflectee, |
| 83 equals('[null, null, null, null, null, null, null, null, null, null,' |
| 84 ' null, null, null, null, null, null, null, null, null, null,' |
| 85 ' null, null, null, null, null, null, null, null, null, null,' |
| 86 ' null, null, null, null, null, null, null, null, null, null,' |
| 87 ' null, null, null, null]')); |
| 88 } |
| 89 |
| 90 testFieldAccess(mirrors) { |
| 91 var instance = new Class(); |
| 92 |
| 93 var libMirror = mirrors.findLibrary(#MirrorsTest); |
| 94 var classMirror = libMirror.declarations[#Class]; |
| 95 var instMirror = reflect(instance); |
| 96 var fieldMirror = classMirror.declarations[#field]; |
| 97 var future; |
| 98 |
| 99 expect(fieldMirror is VariableMirror, isTrue); |
| 100 expect(fieldMirror.type, equals(mirrors.dynamicType)); |
| 101 |
| 102 libMirror.setField(#topLevelField, [91]); |
| 103 expect(libMirror.getField(#topLevelField).reflectee, |
| 104 equals([91])); |
| 105 expect(topLevelField, equals([91])); |
| 106 } |
| 107 |
| 108 testClosureMirrors(mirrors) { |
| 109 // TODO(ahe): Test optional parameters (named or not). |
| 110 var closure = (x, y, z) { return x + y + z; }; |
| 111 |
| 112 var mirror = reflect(closure); |
| 113 expect(mirror is ClosureMirror, equals(true)); |
| 114 |
| 115 var funcMirror = mirror.function; |
| 116 expect(funcMirror is MethodMirror, equals(true)); |
| 117 expect(funcMirror.parameters.length, equals(3)); |
| 118 |
| 119 expect(mirror.apply([7, 8, 9]).reflectee, equals(24)); |
| 120 } |
| 121 |
| 122 testInvokeConstructor(mirrors) { |
| 123 var classMirror = reflectClass(Class); |
| 124 |
| 125 var instanceMirror = classMirror.newInstance(const Symbol(''),[]); |
| 126 expect(instanceMirror.reflectee is Class, equals(true)); |
| 127 expect(instanceMirror.reflectee.field, equals("default value")); |
| 128 |
| 129 instanceMirror = classMirror.newInstance(#withInitialValue, |
| 130 [45]); |
| 131 expect(instanceMirror.reflectee is Class, equals(true)); |
| 132 expect(instanceMirror.reflectee.field, equals(45)); |
| 133 |
| 134 |
| 135 instanceMirror = classMirror.newInstance(#generative, |
| 136 [7]); |
| 137 expect(instanceMirror.reflectee is Class, equals(true)); |
| 138 expect(instanceMirror.reflectee.field, equals(7)); |
| 139 |
| 140 instanceMirror = classMirror.newInstance(#redirecting, |
| 141 [8]); |
| 142 expect(instanceMirror.reflectee is Class, equals(true)); |
| 143 expect(instanceMirror.reflectee.field, equals(16)); |
| 144 |
| 145 instanceMirror = classMirror.newInstance(#faktory, |
| 146 [9]); |
| 147 expect(instanceMirror.reflectee is Class, equals(true)); |
| 148 expect(instanceMirror.reflectee.field, equals(27)); |
| 149 |
| 150 instanceMirror = classMirror.newInstance(#redirectingFactory, |
| 151 [10]); |
| 152 expect(instanceMirror.reflectee is Class, equals(true)); |
| 153 expect(instanceMirror.reflectee.field, equals(30)); |
| 154 } |
| 155 |
| 156 testReflectClass(mirrors) { |
| 157 var classMirror = reflectClass(Class); |
| 158 expect(classMirror is ClassMirror, equals(true)); |
| 159 var symbolClassMirror = reflectClass(Symbol); |
| 160 var symbolMirror = symbolClassMirror.newInstance(const Symbol(''), |
| 161 ['withInitialValue']); |
| 162 var objectMirror = classMirror.newInstance(symbolMirror.reflectee,[1234]); |
| 163 expect(objectMirror.reflectee is Class, equals(true)); |
| 164 expect(objectMirror.reflectee.field, equals(1234)); |
| 165 } |
| 166 |
| 167 testNames(mirrors) { |
| 168 var libMirror = mirrors.findLibrary(#MirrorsTest); |
| 169 var classMirror = libMirror.declarations[#Class]; |
| 170 var typedefMirror = libMirror.declarations[#Typedef]; |
| 171 var methodMirror = libMirror.declarations[#testNames]; |
| 172 var variableMirror = classMirror.declarations[#field]; |
| 173 |
| 174 expect(libMirror.simpleName, equals(#MirrorsTest)); |
| 175 expect(libMirror.qualifiedName, equals(#MirrorsTest)); |
| 176 |
| 177 expect(classMirror.simpleName, equals(#Class)); |
| 178 expect(classMirror.qualifiedName, equals(#MirrorsTest.Class)); |
| 179 |
| 180 TypeVariableMirror typeVariable = classMirror.typeVariables.single; |
| 181 expect(typeVariable.simpleName, equals(#T)); |
| 182 expect(typeVariable.qualifiedName, |
| 183 equals(const Symbol('MirrorsTest.Class.T'))); |
| 184 |
| 185 if (!isDart2js) { // TODO(ahe): Implement this in dart2js. |
| 186 expect(typedefMirror.simpleName, equals(#Typedef)); |
| 187 expect(typedefMirror.qualifiedName, |
| 188 equals(const Symbol('MirrorsTest.Typedef'))); |
| 189 |
| 190 var typedefMirrorDeNovo = reflectType(Typedef); |
| 191 expect(typedefMirrorDeNovo.simpleName, equals(#Typedef)); |
| 192 expect(typedefMirrorDeNovo.qualifiedName, |
| 193 equals(const Symbol('MirrorsTest.Typedef'))); |
| 194 } |
| 195 |
| 196 expect(methodMirror.simpleName, equals(#testNames)); |
| 197 expect(methodMirror.qualifiedName, |
| 198 equals(const Symbol('MirrorsTest.testNames'))); |
| 199 |
| 200 expect(variableMirror.simpleName, equals(#field)); |
| 201 expect(variableMirror.qualifiedName, |
| 202 equals(const Symbol('MirrorsTest.Class.field'))); |
| 203 } |
| 204 |
| 205 testLibraryUri(var value, bool check(Uri)) { |
| 206 var valueMirror = reflect(value); |
| 207 ClassMirror valueClass = valueMirror.type; |
| 208 LibraryMirror valueLibrary = valueClass.owner; |
| 209 Uri uri = valueLibrary.uri; |
| 210 if (uri.scheme != "https" || |
| 211 uri.host != "dartlang.org" || |
| 212 uri.path != "/dart2js-stripped-uri") { |
| 213 expect(check(uri), isTrue); |
| 214 } |
| 215 } |
| 216 |
| 217 main() { |
| 218 var mirrors = currentMirrorSystem(); |
| 219 test("Test reflective method invocation", () { testInvoke(mirrors); }); |
| 220 test('Test intercepted objects', () { testIntercepted(mirrors); }); |
| 221 test("Test field access", () { testFieldAccess(mirrors); }); |
| 222 test("Test closure mirrors", () { testClosureMirrors(mirrors); }); |
| 223 test("Test invoke constructor", () { testInvokeConstructor(mirrors); }); |
| 224 test("Test current library uri", () { |
| 225 testLibraryUri(new Class(), |
| 226 // TODO(floitsch): change this to "/mirrors_test.dart" when |
| 227 // dart2js_mirrors_test.dart has been removed. |
| 228 (Uri uri) => uri.path.endsWith('mirrors_test.dart')); |
| 229 }); |
| 230 test("Test dart library uri", () { |
| 231 testLibraryUri("test", |
| 232 (Uri uri) { |
| 233 if (uri == Uri.parse('dart:core')) return true; |
| 234 // TODO(floitsch): do we want to fake the interceptors to |
| 235 // be in dart:core? |
| 236 return (uri == Uri.parse('dart:_interceptors')); |
| 237 }); |
| 238 }); |
| 239 test("Test simple and qualifiedName", () { testNames(mirrors); }); |
| 240 test("Test reflect type", () { testReflectClass(mirrors); }); |
| 241 } |
OLD | NEW |