dart-sdk/tests/lib/mirrors/proxy_type_test.dart
Ryan Macnak 081e2acf29 [test] Update copied mirrors tests for Dart 3.
Bug: https://github.com/dart-lang/sdk/issues/40045
Change-Id: Ic0f62843d61b613e61f434b72b9553dd1e6897af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132441
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2020-01-23 18:09:37 +00:00

84 lines
2.1 KiB
Dart

// 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.
library test.proxy_type;
import 'dart:mirrors';
import 'package:expect/expect.dart';
// This test is much longer that is strictly necessary to test
// InstanceMirror.type in the face of a reflectee overriding runtimeType, but
// shows a case where one might have legimate reason to override runtimeType.
// See section 2.2 in Mark Miller's Robust Composition: Towards a Unified
// Approach to Access Control and Concurrency Control.
class Alice {
Bob bob = new Bob();
Carol carol = new Carol();
sayFooUnattenuated() {
bob.foo(carol);
}
sayFooAttenuated() {
bool enabled = true;
bool gate() => enabled;
bob.foo(new CarolCaretaker(carol, gate));
enabled = false; // Attenuate a capability
}
sayBar() {
bob.bar();
}
}
class Bob {
Carol? savedCarol;
foo(Carol carol) {
savedCarol = carol; // Store a capability
carol.foo();
}
bar() {
savedCarol!.foo();
}
}
class Carol {
foo() => 'c';
}
typedef bool Gate();
class CarolCaretaker implements Carol {
final Carol _carol;
final Gate _gate;
CarolCaretaker(this._carol, this._gate);
foo() {
if (!_gate()) throw new NoSuchMethodError(this, #foo, [], {});
return _carol.foo();
}
Type get runtimeType => Carol;
}
main() {
Alice alice1 = new Alice();
alice1.sayFooUnattenuated();
alice1.sayBar(); // Bob still has authority to use Carol
Alice alice2 = new Alice();
alice2.sayFooAttenuated();
Expect.throwsNoSuchMethodError(() => alice2.sayBar(),
'Authority should have been attenuated');
// At the base level, a caretaker for a Carol masquerades as a Carol.
CarolCaretaker caretaker = new CarolCaretaker(new Carol(), () => true);
Expect.isTrue(caretaker is Carol);
Expect.equals(Carol, caretaker.runtimeType);
// At the reflective level, the caretaker is distinguishable.
Expect.equals(reflectClass(CarolCaretaker), reflect(caretaker).type);
}