blob: f7cfb8448f90f79db9ead3dacb10f7f6c1b0dc79 [file] [log] [blame]
// Copyright (c) 2021, 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.
// Test that private names exported via public typedefs allow extension.
import "package:expect/expect.dart";
import "private_name_library.dart";
/// Extend a private class via a public typedef without overriding any methods.
class Derived extends PublicClass {
// Check that super constructor calls work.
Derived() : super();
}
/// Extend a private class via a public typedef overriding methods and
/// properties. The final field `x` is overriden with a getter which returns
/// different values every time it is called.
class AlsoDerived extends AlsoPublicClass {
int backingStore = publicLibrarySentinel;
int get x => backingStore++;
int get y => super.x;
// Check that named super constructors work. Use the private sentinel value
// to allow us to distinguish reads of `x` from `super.x`.
AlsoDerived() : super.named(privateLibrarySentinel);
// Override the instanceMethod to return a distinguishing value.
int instanceMethod() => publicLibrarySentinel;
// Add a non-overriding private method with the same textual name as a private
// name in the super class which returns a distinguishing value.
int _privateInstanceMethod() => publicLibrarySentinel;
}
/// Test that inherited methods work correctly.
void test1() {
PublicClass p = Derived();
Expect.equals(privateLibrarySentinel, p.instanceMethod());
// Calling the inherited private method from the private library should work.
Expect.equals(privateLibrarySentinel, callPrivateInstanceMethod(p));
Expect.equals(privateLibrarySentinel, callInstanceMethod(p));
// Calling the inherited private method from this library should throw.
Expect.throwsNoSuchMethodError(() => (p as dynamic)._privateInstanceMethod());
}
/// Test that overriden methods work correctly.
void test2() {
var p = AlsoDerived();
Expect.equals(publicLibrarySentinel, p.instanceMethod());
// Calling the overriden private method from this library should work.
Expect.equals(publicLibrarySentinel, p._privateInstanceMethod());
// Calling the inherited private method from the private library should work.
Expect.equals(privateLibrarySentinel, callPrivateInstanceMethod(p));
// Calling the overriden private method dynamically from this library should
// work.
Expect.equals(publicLibrarySentinel, (p as dynamic)._privateInstanceMethod());
}
/// Test that inherited properties work correctly
void test3() {
var p = Derived();
// Reading the virtual field should give the private value
Expect.equals(privateLibrarySentinel, p.x);
// Reading the virtual field from the private library should give the private
// value
Expect.equals(privateLibrarySentinel, readInstanceField(p));
}
/// Test that overriden properties work correctly.
void test4() {
var p = AlsoDerived();
// Reading the original virtual field should give the private value.
Expect.equals(privateLibrarySentinel, p.y);
// Reading the overriding getter from this library should give the public
// value and increment it each time it is called.
Expect.equals(publicLibrarySentinel, readInstanceField(p));
// Reading the overriding getter from the original library should give the
// public value and increment it each time it is called.
Expect.equals(publicLibrarySentinel + 1, p.x);
Expect.equals(privateLibrarySentinel, p.y);
Expect.equals(publicLibrarySentinel + 2, readInstanceField(p));
Expect.equals(publicLibrarySentinel + 3, p.x);
}
void main() {
test1();
test2();
test3();
test4();
}