Skip to content

Commit

Permalink
#2976. Add equality tests. Part 1. (#3021)
Browse files Browse the repository at this point in the history
Add equality tests. Part 1
  • Loading branch information
sgrekhov authored Dec 19, 2024
1 parent c433852 commit 6d2a3c5
Show file tree
Hide file tree
Showing 12 changed files with 763 additions and 0 deletions.
81 changes: 81 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t01.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if an expression has the form `e1 == e2` or
/// `e1 != e2` and `e2` is a shorthand expression then it has shorthand
/// context from `e1`. Test a class.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C<T> {
String log = "";
T value;
C(this.value);
C.id(this.value);
factory C.f(T t) = C;

static C<int> get staticGetter => C(1);
static C<X> staticMethod<X>(X x) => C<X>(x);
static List<C<String>> instances = [C("one")];

@override
bool operator ==(Object other) {
log = "$this == $other";
if (other is C) {
return value == other.value;
}
return false;
}

@override
String toString() => "C<$T>($value)";
}

main() {
C<int> c1 = C(1);
Expect.isTrue(c1 == .staticGetter);
Expect.equals("C<int>(1) == C<int>(1)", c1.log);
Expect.isFalse(c1 != .staticGetter);
Expect.equals("C<int>(1) == C<int>(1)", c1.log);

C<int> c2 = C(2);
Expect.isFalse(c2 == .staticMethod<String>("two"));
Expect.equals("C<int>(2) == C<String>(two)", c2.log);
Expect.isTrue(c2 != .staticMethod<String>("two"));
Expect.equals("C<int>(2) == C<String>(two)", c2.log);

C<String> c3 = C("one");
Expect.isTrue(c3 == .instances[0]);
Expect.equals("C<String>(one) == C<String>(one)", c3.log);
Expect.isFalse(c3 != .instances[0]);
Expect.equals("C<String>(one) == C<String>(one)", c3.log);

C<int> c4 = C(4);
Expect.isTrue(c4 == .new(4));
Expect.equals("C<int>(4) == C<int>(4)", c4.log);
Expect.isFalse(c4 != .new(4));
Expect.equals("C<int>(4) == C<int>(4)", c4.log);

C<int> c5 = C(5);
Expect.isTrue(c5 == .id(5));
Expect.equals("C<int>(5) == C<int>(5)", c5.log);
Expect.isFalse(c5 != .id(5));
Expect.equals("C<int>(5) == C<int>(5)", c5.log);

C<int> c6 = C(6);
Expect.isTrue(c6 == .f(6));
Expect.equals("C<int>(6) == C<int>(6)", c6.log);
Expect.isFalse(c6 != .f(6));
Expect.equals("C<int>(6) == C<int>(6)", c6.log);
}
65 changes: 65 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t02.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if an expression has the form `e1 == e2` or
/// `e1 != e2` and `e2` is a shorthand expression then it has shorthand
/// context from `e1`. Test a mixin.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C<T> {
String log = "";
T value;
C(this.value);

@override
bool operator ==(Object other) {
log = "$this == $other";
if (other is C) {
return value == other.value;
}
return false;
}

@override
String toString() => "${this.runtimeType}($value)";
}

mixin M<T> on C<T> {
static M<int> get staticGetter => MC(1);
static M<X> staticMethod<X>(X x) => MC<X>(x);
static List<M<String>> instances = [MC("one")];
}

class MC<T> = C<T> with M<T>;

main() {
M<int> m1 = MC(1);
Expect.isTrue(m1 == .staticGetter);
Expect.equals("MC<int>(1) == MC<int>(1)", m1.log);
Expect.isFalse(m1 != .staticGetter);
Expect.equals("MC<int>(1) == MC<int>(1)", m1.log);

M<int> m2 = MC(2);
Expect.isFalse(m2 == .staticMethod<String>("two"));
Expect.equals("MC<int>(2) == MC<String>(two)", m2.log);
Expect.isTrue(m2 != .staticMethod<String>("two"));
Expect.equals("MC<int>(2) == MC<String>(two)", m2.log);

MC<String> m3 = MC("one");
Expect.isTrue(m3 == .instances[0]);
Expect.equals("MC<String>(one) == MC<String>(one)", m3.log);
Expect.isFalse(m3 != .instances[0]);
Expect.equals("MC<String>(one) == MC<String>(one)", m3.log);
}
42 changes: 42 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t03.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if an expression has the form `e1 == e2` or
/// `e1 != e2` and `e2` is a shorthand expression then it has shorthand
/// context from `e1`. Test an enum.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

enum E<T> {
e0(0), e1("1");
final T value;
const E(this.value);

static E<int> get staticGetter => E.e0;
static E staticMethod(int index) => E.values[index];
}

main() {
Expect.isTrue(E.e0 == .e0);
Expect.isFalse(E.e0 != .e1);

Expect.isTrue(E.e0 == .staticGetter);
Expect.isFalse(E.e0 != .staticGetter);

Expect.isFalse(E.e1 == .staticMethod(0));
Expect.isTrue(E.e1 != .staticMethod(0));

Expect.isTrue(E.e0 == .values[0]);
Expect.isFalse(E.e0 != .values[0]);
}
48 changes: 48 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t04.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if an expression has the form `e1 == e2` or
/// `e1 != e2` and `e2` is a shorthand expression then it has shorthand
/// context from `e1`. Test an extension type.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

extension type ET<T>(T value) {
ET.id(this.value);
factory ET.f(T t) = ET;

static ET<int> get staticGetter => ET(1);
static ET<X> staticMethod<X>(X x) => ET<X>(x);
static List<ET<String>> instances = [ET("one")];
}

main() {
Expect.isTrue(ET(1) == .staticGetter);
Expect.isFalse(ET(1) != .staticGetter);

Expect.isFalse(ET<int>(2) == .staticMethod<String>("two"));
Expect.isTrue(ET<int>(2) != .staticMethod<String>("two"));

Expect.isTrue(ET<String>("one") == .instances[0]);
Expect.isFalse(ET<String>("one") != .instances[0]);

Expect.isTrue(ET(4) == .new(4));
Expect.isFalse(ET(4) != .new(4));

Expect.isTrue(ET(5) == .id(5));
Expect.isFalse(ET(5) != .id(5));

Expect.isTrue(ET(6) == .f(6));
Expect.isFalse(ET(6) != .f(6));
}
86 changes: 86 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t05.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if a pattern has the form `== e2` or `!= e2` and
/// `e2` is a shorthand expression, then it has context type from the matched
/// value type of the pattern. Test a class.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C<T> {
final T value;
const C(this.value);
const C.id(this.value);
const factory C.f(T t) = C;

static const C<int> intOne = C(1);

@override
bool operator ==(Object other) {
if (other is C) {
return value == other.value;
}
return false;
}
}

main() {
bool success = false;
void checkSuccess() {
Expect.isTrue(success);
success = false;
}

C<int> c1 = C(1);
if (c1 case == const .new(1)) {
success = true;
}
checkSuccess();

if (c1 case == const .id(1)) {
success = true;
}
checkSuccess();

if (c1 case == const .f(1)) {
success = true;
}
checkSuccess();

if (c1 case == .intOne) {
success = true;
}
checkSuccess();

C<int> c2 = C(2);
if (c2 case != const .new(1)) {
success = true;
}
checkSuccess();

if (c2 case != const .id(1)) {
success = true;
}
checkSuccess();

if (c2 case != const .f(1)) {
success = true;
}
checkSuccess();

if (c2 case != .intOne) {
success = true;
}
checkSuccess();
}
55 changes: 55 additions & 0 deletions LanguageFeatures/Static-access-shorthand/equality_A01_t06.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2024, 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.

/// @assertion If an expression has the form `e1 == e2` or `e1 != e2`, or a
/// pattern has the form `== e2` or `!= e2`, where the static type of `e1`, or
/// the matched value type of the pattern, is S1, and e2 is precisely a
/// `<staticMemberShorthand>` expression, then assign the type S1 as the
/// shorthand context of the `<staticMemberShorthandHead>` of e2 before
/// inferring its static type the same way as above.
///
/// @description Checks that if a pattern has the form `== e2` or `!= e2` and
/// `e2` is a shorthand expression, then it has context type from the matched
/// value type of the pattern. Test a mixin.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=enum-shorthands

import '../../Utils/expect.dart';

class C<T> {
final T value;
const C(this.value);

@override
bool operator ==(Object other) {
if (other is C) {
return value == other.value;
}
return false;
}
}

mixin M<T> on C<T> {
static const M<int> intOne = MC<int>(1);
}

class MC<T> extends C<T> with M<T> {
const MC(T t) : super(t);
}

main() {
bool success = false;
M<int> m = MC(1);
if (m case == .intOne) {
success = true;
}
Expect.isTrue(success);

success = false;
if (m case != .intOne) {
success = true;
}
Expect.isFalse(success);
}
Loading

0 comments on commit 6d2a3c5

Please sign in to comment.