Skip to content

Commit 5ea271b

Browse files
lrhncommit-bot@chromium.org
authored andcommitted
Clean up documentation of implicit new/const insertions tests.
Add Expect.allIdentical to complement Expect.allDistinct. Change-Id: I65e4e0005f141434bd8fb47d9c60153f32b293aa Reviewed-on: https://dart-review.googlesource.com/50421 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
1 parent cf93009 commit 5ea271b

File tree

4 files changed

+97
-111
lines changed

4 files changed

+97
-111
lines changed

pkg/expect/lib/expect.dart

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -179,35 +179,31 @@ class Expect {
179179
}
180180

181181
/**
182-
* Checks whether the expected and actual values are *not* identical
183-
* (using `identical`).
184-
*/
185-
static void notIdentical(var unexpected, var actual, [String reason = null]) {
186-
if (!_identical(unexpected, actual)) return;
187-
String msg = _getMessage(reason);
188-
_fail("Expect.notIdentical(expected and actual: <$actual>$msg) fails.");
189-
}
190-
191-
/**
192-
* Checks that no two [objects] are `identical`.
182+
* Finds equivalence classes of objects (by index) wrt. identity.
183+
*
184+
* Returns a list of lists of identical object indices per object.
185+
* That is, `objects[i]` is identical to objects with indices in
186+
* `_findEquivalences(objects)[i]`.
187+
*
188+
* Uses `null` for objects that are only identical to themselves.
193189
*/
194-
static void allDistinct(List<Object> objects, [String reason = null]) {
195-
String msg = _getMessage(reason);
190+
static List<List<int>> _findEquivalences(List<Object> objects) {
196191
var equivalences = new List<List<int>>(objects.length);
197-
bool hasEquivalence = false;
198192
for (int i = 0; i < objects.length; i++) {
199193
if (equivalences[i] != null) continue;
200194
var o = objects[i];
201195
for (int j = i + 1; j < objects.length; j++) {
202196
if (equivalences[j] != null) continue;
203197
if (_identical(o, objects[j])) {
204198
equivalences[j] = (equivalences[i] ??= <int>[i])..add(j);
205-
hasEquivalence = true;
206199
}
207200
}
208201
}
209-
if (!hasEquivalence) return;
210-
var buffer = new StringBuffer("Expect.allDistinct([");
202+
return equivalences;
203+
}
204+
205+
static void _writeEquivalences(
206+
List<Object> objects, List<List<int>> equivalences, StringBuffer buffer) {
211207
var separator = "";
212208
for (int i = 0; i < objects.length; i++) {
213209
buffer.write(separator);
@@ -223,6 +219,47 @@ class Expect {
223219
}
224220
}
225221
}
222+
}
223+
224+
static void allIdentical(Iterable<Object> objects, [String reason]) {
225+
if (objects.length <= 1) return;
226+
String msg = _getMessage(reason);
227+
var equivalences = _findEquivalences(objects);
228+
var first = equivalences[0];
229+
if (first != null && first.length == objects.length) return;
230+
var buffer = new StringBuffer("Expect.allIdentical([");
231+
_writeEquivalences(objects, equivalences, buffer);
232+
buffer..write("]")..write(msg)..write(")");
233+
_fail(buffer.toString());
234+
}
235+
236+
/**
237+
* Checks whether the expected and actual values are *not* identical
238+
* (using `identical`).
239+
*/
240+
static void notIdentical(var unexpected, var actual, [String reason = null]) {
241+
if (!_identical(unexpected, actual)) return;
242+
String msg = _getMessage(reason);
243+
_fail("Expect.notIdentical(expected and actual: <$actual>$msg) fails.");
244+
}
245+
246+
/**
247+
* Checks that no two [objects] are `identical`.
248+
*/
249+
static void allDistinct(List<Object> objects, [String reason = null]) {
250+
String msg = _getMessage(reason);
251+
var equivalences = _findEquivalences(objects);
252+
253+
bool hasEquivalence = false;
254+
for (int i = 0; i < equivalences.length; i++) {
255+
if (equivalences[i] != null) {
256+
hasEquivalence = true;
257+
break;
258+
}
259+
}
260+
if (!hasEquivalence) return;
261+
var buffer = new StringBuffer("Expect.allDistinct([");
262+
_writeEquivalences(objects, equivalences, buffer);
226263
buffer..write("]")..write(msg)..write(")");
227264
_fail(buffer.toString());
228265
}

tests/language_2/implicit_creation/implicit_new_or_const_composite_test.dart

Lines changed: 35 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44

55
import "package:expect/expect.dart";
66

7-
// Tests that const/new-insertion does the right thing for
8-
// composite object creations.
9-
//
10-
// The right thing is that map and list literals are only constant
11-
// if in a constant context.
12-
// Object creation is const if constructor is const and all arguments are const.
7+
// Tests that new-insertion always inserts `new` when not in const context,
8+
// no matter what the arguments are.
9+
// There is (currently) no automatic const insertion in non-const context.
1310
//
1411
// Not testing inference, so all type arguments are explicit.
1512

@@ -34,27 +31,22 @@ main() {
3431
var cd5 = C(d42); // Non-constant context, so `new`.
3532

3633
Expect.identical(cd1, cd2);
37-
Expect.allDistinct([cd1, cd3]);
38-
Expect.allDistinct([cd1, cd4, cd5]);
34+
Expect.allDistinct([cd1, cd3, cd4, cd5]);
3935
}
4036

4137
{
4238
// List inside other constructor
4339
const cl1 = const C(const <int>[37]);
4440
const cl2 = C(clist); // Constant context.
4541
const cl3 = C(const <int>[37]); // Constant context.
46-
const cl4 = C(<int>[37]);
42+
const cl4 = C(<int>[37]); // Constant context.
4743
var cl5 = C(clist); // Non-constant context, so `new`.
4844
var cl6 = C(const <int>[37]); // Non-constant context, so `new`.
4945
var cl7 = C(list); // Non-constant context, so `new`.
5046
var cl8 = C(<int>[37]); // Non-constant context, so `new`.
5147

52-
Expect.identical(cl1, cl2);
53-
Expect.identical(cl1, cl3);
54-
Expect.identical(cl1, cl4);
55-
Expect.allDistinct([cl1, cl5]);
56-
Expect.allDistinct([cl1, cl6]);
57-
Expect.allDistinct([cl1, cl7, cl8]);
48+
Expect.allIdentical([cl1, cl2, cl3, cl4]);
49+
Expect.allDistinct([cl1, cl5, cl6, cl7, cl8]);
5850
}
5951

6052
{
@@ -69,9 +61,7 @@ main() {
6961

7062
Expect.identical(cm1, cm2);
7163
Expect.identical(cm1, cm3);
72-
Expect.allDistinct([cm1, cm4]);
73-
Expect.allDistinct([cm1, cm5]);
74-
Expect.allDistinct([cm1, cm6, cm7]);
64+
Expect.allDistinct([cm1, cm4, cm5, cm6, cm7]);
7565
}
7666

7767
{
@@ -93,22 +83,14 @@ main() {
9383

9484
Expect.identical(n1, n2);
9585
Expect.identical(n1, n3);
96-
Expect.allDistinct([n1, n4]);
97-
Expect.allDistinct([n1, n8]);
98-
Expect.allDistinct([n1, n5, n6, n7, n9, n10, n11, n12, n13, n14]);
86+
Expect.allDistinct([n1, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14]);
9987

100-
Expect.identical(clist, n6.left);
101-
Expect.identical(clist, n10.left);
102-
Expect.identical(clist, n12.left);
103-
Expect.identical(clist, n13.left);
104-
Expect.identical(clist, n14.left);
88+
Expect
89+
.allIdentical([clist, n6.left, n10.left, n12.left, n13.left, n14.left]);
10590
Expect.allDistinct([n5.left, n7.left, n9.left, n11.left]);
10691

107-
Expect.identical(cmap, n5.right);
108-
Expect.identical(cmap, n9.right);
109-
Expect.identical(cmap, n12.right);
110-
Expect.identical(cmap, n13.right);
111-
Expect.identical(cmap, n14.right);
92+
Expect.allIdentical(
93+
[cmap, n5.right, n9.right, n12.right, n13.right, n14.right]);
11294
Expect.allDistinct([n6.right, n7.right, n10.right, n11.right]);
11395

11496
const n20 = const N(const C(42), const <int>[37]);
@@ -124,21 +106,13 @@ main() {
124106
var n30 = N(c42, clist);
125107
var n31 = N(cc42, list);
126108

127-
Expect.identical(n20, n21);
128-
Expect.identical(n20, n22);
129-
Expect.identical(n20, n23);
130-
Expect.identical(n20, n24);
131-
Expect.allDistinct([n20, n25]);
132-
Expect.allDistinct([n20, n26]);
133-
Expect.allDistinct([n20, n27]);
134-
Expect.allDistinct([n28, n29, n30, n31]);
135-
Expect.allDistinct([cc42, n28.left]);
136-
Expect.allDistinct([cc42, n29.left]);
109+
Expect.allIdentical([n20, n21, n22, n23, n24]);
110+
Expect.allDistinct([n20, n25, n26, n27, n28, n29, n30, n31]);
111+
112+
Expect.allDistinct([cc42, n28.left, n29.left]);
137113
Expect.identical(cc42, n30.left);
138114
Expect.identical(cc42, n31.left);
139-
Expect.identical(clist, n29.right);
140-
Expect.identical(clist, n30.right);
141-
Expect.identical(clist, n31.right);
115+
Expect.allIdentical([clist, n29.right, n30.right, n31.right]);
142116
Expect.notIdentical(clist, n28.right);
143117
}
144118

@@ -178,25 +152,13 @@ main() {
178152
var l30 = [c42, clist];
179153
var l31 = [cc42, list];
180154

181-
Expect.identical(l20, l21);
182-
Expect.identical(l20, l22);
183-
Expect.identical(l20, l23);
184-
Expect.identical(l20, l24);
155+
Expect.allIdentical([l20, l21, l22, l23, l24]);
185156
// List literals are never const unless in const context.
186157
Expect.allDistinct([l20, l25, l26, l27, l28, l29, l30, l31]);
187-
Expect.identical(cc42, l25[0]);
188-
Expect.allDistinct([cc42, l26[0]]);
189-
Expect.allDistinct([cc42, l27[0]]);
190-
Expect.allDistinct([cc42, l28[0]]);
191-
Expect.allDistinct([cc42, l29[0]]);
192-
Expect.identical(cc42, l30[0]);
193-
Expect.identical(cc42, l31[0]);
194-
Expect.identical(clist, l25[1]);
195-
Expect.identical(clist, l26[1]);
196-
Expect.identical(clist, l27[1]);
197-
Expect.identical(clist, l29[1]);
198-
Expect.identical(clist, l30[1]);
199-
Expect.identical(clist, l31[1]);
158+
Expect.allIdentical([cc42, l25[0], l30[0], l31[0]]);
159+
Expect.allDistinct([cc42, l26[0], l27[0], l28[0], l29[0]]);
160+
Expect
161+
.allIdentical([clist, l25[1], l26[1], l27[1], l29[1], l30[1], l31[1]]);
200162
Expect.notIdentical(clist, l28[1]);
201163
}
202164

@@ -229,25 +191,23 @@ main() {
229191
var m30 = {c42: clist};
230192
var m31 = {cc42: list};
231193

232-
Expect.identical(m20, m21);
233-
Expect.identical(m20, m22);
234-
Expect.identical(m20, m23);
235-
Expect.identical(m20, m24);
194+
Expect.allIdentical([m20, m21, m22, m23, m24]);
236195
// Map literals are never const unless in const context.
237196
Expect.allDistinct([m20, m25, m26, m27, m28, m29, m30, m31]);
238197
Expect.identical(cc42, m25.keys.first);
239-
Expect.allDistinct([cc42, m26.keys.first]);
240-
Expect.allDistinct([cc42, m27.keys.first]);
241-
Expect.allDistinct([cc42, m28.keys.first]);
242-
Expect.allDistinct([cc42, m29.keys.first]);
198+
Expect.allDistinct(
199+
[cc42, m26.keys.first, m27.keys.first, m28.keys.first, m29.keys.first]);
243200
Expect.identical(cc42, m30.keys.first);
244201
Expect.identical(cc42, m31.keys.first);
245-
Expect.identical(clist, m25.values.first);
246-
Expect.identical(clist, m26.values.first);
247-
Expect.identical(clist, m27.values.first);
248-
Expect.identical(clist, m29.values.first);
249-
Expect.identical(clist, m30.values.first);
250-
Expect.identical(clist, m31.values.first);
202+
Expect.allIdentical([
203+
clist,
204+
m25.values.first,
205+
m26.values.first,
206+
m27.values.first,
207+
m29.values.first,
208+
m30.values.first,
209+
m31.values.first
210+
]);
251211
Expect.notIdentical(clist, m28.values.first);
252212
}
253213
}

tests/language_2/implicit_creation/implicit_new_or_const_generic_test.dart

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import "package:expect/expect.dart";
66

77
import "implicit_new_or_const_generic_test.dart" as prefix;
88

9-
// Test that const constructors with const arguments become const,
10-
// and non-const constructors or const-constructors with non-const arguments
11-
// do not (except in a const context, which is tested elsewhere).
9+
// Test that const constructors with const arguments do not become const
10+
// if not in a const context.
1211

13-
// This test uses a generic class, which requires new syntax.
12+
// This test uses a generic class cosntructor with no prefix,
13+
// which requires new Dart 2 syntax.
1414

1515
main() {
1616
// Various valid object creation expressions.
17-
var x = 42; // non constant variable.
17+
var x = 42; // non constant variable.
1818

1919
// Various valid object creation expressions of a generic constructor.
2020
// (Requires inference to infer `<int>` for the invocations of `D`.)
@@ -24,43 +24,36 @@ main() {
2424
const D(42),
2525
D(x),
2626
D(42),
27-
2827
new D.named(x),
2928
new D.named(42),
3029
const D.named(42),
3130
D.named(x),
3231
D.named(42),
33-
3432
new prefix.D(x),
3533
new prefix.D(42),
3634
const prefix.D(42),
3735
prefix.D(x),
3836
prefix.D(42),
39-
4037
new prefix.D.named(x),
4138
new prefix.D.named(42),
4239
const prefix.D.named(42),
4340
prefix.D.named(x),
4441
prefix.D.named(42),
45-
4642
new D<int>(x),
4743
new D<int>(42),
4844
const D<int>(42),
4945
D<int>(x),
5046
D<int>(42),
51-
5247
new D<int>.named(x),
5348
new D<int>.named(42),
5449
const D<int>.named(42),
5550
D<int>.named(x),
5651
D<int>.named(42),
57-
5852
new prefix.D<int>(x),
5953
new prefix.D<int>(42),
6054
const prefix.D<int>(42),
6155
prefix.D<int>(x),
6256
prefix.D<int>(42),
63-
6457
new prefix.D<int>.named(x),
6558
new prefix.D<int>.named(42),
6659
const prefix.D<int>.named(42),
@@ -92,7 +85,7 @@ class D<T> {
9285
const D.named(this.x);
9386

9487
int get hashCode => x.hashCode;
95-
bool operator==(Object other) => other is D<Object> && x == other.x;
88+
bool operator ==(Object other) => other is D<Object> && x == other.x;
9689
}
9790

9891
class G<T> {
@@ -102,13 +95,10 @@ class G<T> {
10295
var instances = [
10396
new D<T>(null),
10497
D<T>(null),
105-
10698
new D<T>.named(null),
10799
D<T>.named(null),
108-
109100
new prefix.D<T>(null),
110101
prefix.D<T>(null),
111-
112102
new prefix.D<T>.named(null),
113103
prefix.D<T>.named(null),
114104
];

tests/language_2/implicit_creation/implicit_new_or_const_test.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import "package:expect/expect.dart";
66

77
import "implicit_new_or_const_test.dart" as prefix;
88

9-
// Test that const constructors with const arguments become const,
10-
// and non-const constructors or const-constructors with non-const arguments
11-
// do not (except in a const context, which is tested elsewhere).
9+
// Test that const constructors with const arguments do not become const
10+
// if not in a const context.
1211

1312
main() {
1413
// Various valid object creation expressions.

0 commit comments

Comments
 (0)