blob: 25a3f1a8a3505692ce95b6bc8cad92f409b9a6b8 [file] [log] [blame]
// Copyright (c) 2019, 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.
// Tests getters and setters where one or both is defined
// by an extension.
import "package:expect/expect.dart";
main() {
C c = C();
// v1: C get, C set
expectGet("C.v1", c.v1);
expectSet("C.v1=1", c.v1 = Result("1"));
// v2: C get, E1 get/set, C wins.
expectGet("C.v2", c.v2);
expectSet("E1.v2=2", E1(c).v2 = Result("2"));
// v3: E1 get/set, C set, C wins.
expectGet("E1.v3", E1(c).v3);
expectSet("C.v3=3", c.v3 = Result("3"));
// v4: E1 get/set
expectGet("E1.v4", c.v4);
expectSet("E1.v4=4", c.v4 = Result("4"));
// v5: E1 get, E2 set, neither more specific.
expectGet("E1.v5", E1(c).v5);
expectSet("E2.v5=5", E2(c).v5 = Result("5"));
expectSet("C.v1=C.v1+1", c.v1++);
expectSet("E1.v4=E1.v4+1", c.v4++);
expectSet("C.v1=C.v1+a", c.v1 += "a");
expectSet("C.v1=C.v1-b", c.v1 -= "b");
expectSet("E1.v4=E1.v4-b", c.v4 -= "b");
// Explicit application used by all accesses of read/write operations
expectSet("E1.v1=E1.v1+1", E1(c).v1++);
expectSet("E1.v2=E1.v2+1", E1(c).v2++);
expectSet("E1.v3=E1.v3+1", E1(c).v3++);
// Same using `+= 1` instead of `++`.
expectSet("E1.v1=E1.v1+1", E1(c).v1 += 1);
expectSet("E1.v2=E1.v2+1", E1(c).v2 += 1);
expectSet("E1.v3=E1.v3+1", E1(c).v3 += 1);
// Same fully expanded.
expectSet("E1.v1=E1.v1+1", E1(c).v1 = E1(c).v1 + 1);
expectSet("E1.v2=E1.v2+1", E1(c).v2 = E1(c).v2 + 1);
expectSet("E1.v3=E1.v3+1", E1(c).v3 = E1(c).v3 + 1);
// Cascades work.
expectSet(
"E1.v4=E1.v4+[C.v1=C.v1-[C.v3=a]]",
c
..v3 = Result("a")
..v1 -= Result("[$lastSetter]")
..v4 += Result("[$lastSetter]"));
}
/// Expect the value of [result] to be the [expected] string
expectGet(String expected, Result result) {
Expect.equals(expected, result.value);
}
/// Expect the [lastSetter] value set by evaluating [assignment] to be
/// [expected].
expectSet(String expected, void assignment) {
Expect.equals(expected, lastSetter);
}
/// Last value passed to any of our tested setters.
String? lastSetter = null;
/// A type which supports a `+` operation accepting `int`,
/// so we can test `+=` and `++`.
class Result {
final String value;
Result(this.value);
Result operator +(Object o) => Result("$value+$o");
Result operator -(Object o) => Result("$value-$o");
String toString() => value;
}
/// Target type for extensions.
///
/// Declares [v1] getter and setter, [v2] getter and [v3] setter.
class C {
Result get v1 => Result("C.v1");
void set v1(Result value) {
lastSetter = "C.v1=$value";
}
Result get v2 => Result("C.v2");
void set v3(Result value) {
lastSetter = "C.v3=$value";
}
}
/// Primary extension on [C].
///
/// Declares [v1], [v2] and [v3] getters and setters.
///
/// Declares [v4] getter and setter, and [v5] getter
/// which are supplemented by a setter from the [E2] extension.
extension E1 on C {
// Same basename as C getter and setter.
Result get v1 => Result("E1.v1");
void set v1(Result value) {
lastSetter = "E1.v1=$value";
}
// Same basename as C getter.
Result get v2 => Result("E1.v2");
void set v2(Result value) {
lastSetter = "E1.v2=$value";
}
// Same basename as C setter.
Result get v3 => Result("E1.v3");
void set v3(Result value) {
lastSetter = "E1.v3=$value";
}
// No other declarations with same basename.
Result get v4 => Result("E1.v4");
void set v4(Result value) {
lastSetter = "E1.v4=$value";
}
// Same basename as E2 setter.
Result get v5 => Result("E1.v5");
}
/// A different extension than [E1] on [C].
///
/// Declares [v5] setter.
extension E2 on C {
void set v5(Result value) {
lastSetter = "E2.v5=$value";
}
}