// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // This test uses the multi-test "ok" feature to create two positive tests from // one file. One of these tests fail on dart2js, but pass on the VM, or vice // versa. // TODO(ahe): When both implementations agree, remove the multi-test parts. library test.mixin_application_test; import 'dart:mirrors'; import 'package:expect/expect.dart'; import 'model.dart'; import 'stringify.dart'; class Mixin { int i = 0; m() {} } class Mixin2 { int i2 = 0; m2() {} } class MixinApplication = C with Mixin; class MixinApplicationA = C with Mixin, Mixin2; class UnusedMixinApplication = C with Mixin; class Subclass extends C with Mixin { f() {} } class Subclass2 extends MixinApplication { g() {} } class SubclassA extends C with Mixin, Mixin2 { fa() {} } class Subclass2A extends MixinApplicationA { ga() {} } membersOf(ClassMirror cm) { var result = new Map(); cm.declarations.forEach((k, v) { if (v is MethodMirror && !v.isConstructor) result[k] = v; if (v is VariableMirror) result[k] = v; }); return result; } constructorsOf(ClassMirror cm) { var result = new Map(); cm.declarations.forEach((k, v) { if (v is MethodMirror && v.isConstructor) result[k] = v; }); return result; } checkClass(Type type, List expectedSuperclasses) { int i = 0; for (ClassMirror? cls = reflectClass(type); cls != null; cls = cls.superclass) { expect(expectedSuperclasses[i++], cls); } Expect.equals(i, expectedSuperclasses.length, '$type'); } expectSame(ClassMirror a, ClassMirror b) { Expect.equals(a, b); expect(stringify(a), b); expect(stringify(b), a); } testMixin() { checkClass(Mixin, [ 'Class(s(Mixin) in s(test.mixin_application_test), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); expect( '{i: Variable(s(i) in s(Mixin)),' ' m: Method(s(m) in s(Mixin))}', membersOf(reflectClass(Mixin))); expect('{Mixin: Method(s(Mixin) in s(Mixin), constructor)}', constructorsOf(reflectClass(Mixin))); } testMixin2() { checkClass(Mixin2, [ 'Class(s(Mixin2) in s(test.mixin_application_test), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); expect( '{i2: Variable(s(i2) in s(Mixin2)),' ' m2: Method(s(m2) in s(Mixin2))}', membersOf(reflectClass(Mixin2))); expect('{Mixin2: Method(s(Mixin2) in s(Mixin2), constructor)}', constructorsOf(reflectClass(Mixin2))); } testMixinApplication() { checkClass(MixinApplication, [ 'Class(s(MixinApplication) in s(test.mixin_application_test), top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); String owner = 'Mixin'; expect( '{i: Variable(s(i) in s($owner)),' ' m: Method(s(m) in s($owner))}', membersOf(reflectClass(MixinApplication))); expect( '{MixinApplication: Method(s(MixinApplication) in s(MixinApplication),' ' constructor)}', constructorsOf(reflectClass(MixinApplication))); expectSame(reflectClass(C), reflectClass(MixinApplication).superclass!); } testMixinApplicationA() { String owner = ' in s(test.mixin_application_test)'; checkClass(MixinApplicationA, [ 'Class(s(MixinApplicationA)' ' in s(test.mixin_application_test), top-level)', 'Class(s(test.model.C with test.mixin_application_test.Mixin)' '$owner, top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); owner = 'Mixin2'; expect( '{i2: Variable(s(i2) in s($owner)),' ' m2: Method(s(m2) in s($owner))}', membersOf(reflectClass(MixinApplicationA))); expect( '{MixinApplicationA: Method(s(MixinApplicationA) in s(MixinApplicationA),' ' constructor)}', constructorsOf(reflectClass(MixinApplicationA))); expect( '{i: Variable(s(i) in s(Mixin)),' ' m: Method(s(m) in s(Mixin))}', membersOf(reflectClass(MixinApplicationA).superclass!)); String name = 'test.model.C with test.mixin_application_test.Mixin'; expect( '{$name:' ' Method(s($name)' ' in s($name), constructor)}', constructorsOf(reflectClass(MixinApplicationA).superclass!)); expectSame( reflectClass(C), reflectClass(MixinApplicationA).superclass!.superclass!); } testUnusedMixinApplication() { checkClass(UnusedMixinApplication, [ 'Class(s(UnusedMixinApplication) in s(test.mixin_application_test),' ' top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); String owner = 'Mixin'; expect( '{i: Variable(s(i) in s($owner)),' ' m: Method(s(m) in s($owner))}', membersOf(reflectClass(UnusedMixinApplication))); expect( '{UnusedMixinApplication: Method(s(UnusedMixinApplication)' ' in s(UnusedMixinApplication), constructor)}', constructorsOf(reflectClass(UnusedMixinApplication))); expectSame(reflectClass(C), reflectClass(UnusedMixinApplication).superclass!); } testSubclass() { String owner = ' in s(test.mixin_application_test)'; checkClass(Subclass, [ 'Class(s(Subclass) in s(test.mixin_application_test), top-level)', 'Class(s(test.model.C with test.mixin_application_test.Mixin)' '$owner, top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); expect('{f: Method(s(f) in s(Subclass))}', membersOf(reflectClass(Subclass))); expect('{Subclass: Method(s(Subclass) in s(Subclass), constructor)}', constructorsOf(reflectClass(Subclass))); expect( '{i: Variable(s(i) in s(Mixin)),' ' m: Method(s(m) in s(Mixin))}', membersOf(reflectClass(Subclass).superclass!)); String name = 'test.model.C with test.mixin_application_test.Mixin'; expect( '{$name:' ' Method(s($name)' ' in s($name), constructor)}', constructorsOf(reflectClass(Subclass).superclass!)); expectSame(reflectClass(C), reflectClass(Subclass).superclass!.superclass!); } testSubclass2() { checkClass(Subclass2, [ 'Class(s(Subclass2) in s(test.mixin_application_test), top-level)', 'Class(s(MixinApplication) in s(test.mixin_application_test), top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); expect( '{g: Method(s(g) in s(Subclass2))}', membersOf(reflectClass(Subclass2))); expect('{Subclass2: Method(s(Subclass2) in s(Subclass2), constructor)}', constructorsOf(reflectClass(Subclass2))); expectSame( reflectClass(MixinApplication), reflectClass(Subclass2).superclass!); } testSubclassA() { String owner = ' in s(test.mixin_application_test)'; checkClass(SubclassA, [ 'Class(s(SubclassA) in s(test.mixin_application_test), top-level)', 'Class(s(test.model.C with test.mixin_application_test.Mixin,' ' test.mixin_application_test.Mixin2)$owner, top-level)', 'Class(s(test.model.C with test.mixin_application_test.Mixin)$owner,' ' top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); expect('{fa: Method(s(fa) in s(SubclassA))}', membersOf(reflectClass(SubclassA))); expect('{SubclassA: Method(s(SubclassA) in s(SubclassA), constructor)}', constructorsOf(reflectClass(SubclassA))); expect( '{i2: Variable(s(i2) in s(Mixin2)),' ' m2: Method(s(m2) in s(Mixin2))}', membersOf(reflectClass(SubclassA).superclass!)); String name = 'test.model.C with test.mixin_application_test.Mixin,' ' test.mixin_application_test.Mixin2'; expect('{$name: Method(s($name) in s($name), constructor)}', constructorsOf(reflectClass(SubclassA).superclass!)); expect( '{i: Variable(s(i) in s(Mixin)),' ' m: Method(s(m) in s(Mixin))}', membersOf(reflectClass(SubclassA).superclass!.superclass!)); name = 'test.model.C with test.mixin_application_test.Mixin'; expect( '{$name:' ' Method(s($name)' ' in s($name), constructor)}', constructorsOf(reflectClass(SubclassA).superclass!.superclass!)); expectSame(reflectClass(C), reflectClass(SubclassA).superclass!.superclass!.superclass!); } testSubclass2A() { String owner = ' in s(test.mixin_application_test)'; checkClass(Subclass2A, [ 'Class(s(Subclass2A) in s(test.mixin_application_test), top-level)', 'Class(s(MixinApplicationA) in s(test.mixin_application_test),' ' top-level)', 'Class(s(test.model.C with test.mixin_application_test.Mixin)$owner,' ' top-level)', 'Class(s(C) in s(test.model), top-level)', 'Class(s(B) in s(test.model), top-level)', 'Class(s(A) in s(test.model), top-level)', 'Class(s(Object) in s(dart.core), top-level)', ]); expect('{ga: Method(s(ga) in s(Subclass2A))}', membersOf(reflectClass(Subclass2A))); expect('{Subclass2A: Method(s(Subclass2A) in s(Subclass2A), constructor)}', constructorsOf(reflectClass(Subclass2A))); expectSame( reflectClass(MixinApplicationA), reflectClass(Subclass2A).superclass!); } main() { testMixin(); testMixin2(); testMixinApplication(); testMixinApplicationA(); testUnusedMixinApplication(); testSubclass(); testSubclass2(); testSubclassA(); testSubclass2A(); }