7ca5ad46ce
Mark tests that contain errors about using a class as a mixin to use language version 2.19 where that's not an error. This may not fix all of the tests because it's the language version of the library where the class is declared that matters, not where the class is used as a mixin. But most tests have all of their declarations in the same library, so this should fix most. Change-Id: I910439ebd2f10f731418dc588b7e4619a0841c16 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/285923 Reviewed-by: Jake Macdonald <jakemac@google.com> Commit-Queue: Jake Macdonald <jakemac@google.com>
517 lines
13 KiB
Dart
517 lines
13 KiB
Dart
// Copyright (c) 2012, 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.
|
|
|
|
// TODO(51557): Decide if the mixins being applied in this test should be
|
|
// "mixin", "mixin class" or the test should be left at 2.19.
|
|
// @dart=2.19
|
|
|
|
// VMOptions=--no-enable-fast-object-copy
|
|
// VMOptions=--enable-fast-object-copy
|
|
|
|
// Dart test program for testing serialization of messages.
|
|
// VMOptions=--enable_type_checks --enable_asserts
|
|
|
|
library MessageTest;
|
|
|
|
import 'dart:async';
|
|
import 'dart:collection';
|
|
import 'dart:io';
|
|
import 'dart:isolate';
|
|
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'package:expect/expect.dart';
|
|
import 'dart:typed_data';
|
|
|
|
void echoMain(msg) {
|
|
SendPort replyTo = msg[0];
|
|
SendPort pong = msg[1];
|
|
ReceivePort port = new ReceivePort();
|
|
replyTo.send(port.sendPort);
|
|
port.listen((msg) {
|
|
if (msg == "halt") {
|
|
port.close();
|
|
} else {
|
|
pong.send(msg);
|
|
}
|
|
});
|
|
}
|
|
|
|
class A {
|
|
var field = 499;
|
|
|
|
A();
|
|
A.named(this.field);
|
|
}
|
|
|
|
class B extends A {
|
|
final field2;
|
|
B() : field2 = 99;
|
|
B.named(this.field2, x) : super.named(x);
|
|
}
|
|
|
|
class C extends B {
|
|
var field = 33;
|
|
|
|
get superField => super.field;
|
|
get superField2 => super.field2;
|
|
}
|
|
|
|
class M {
|
|
get field2 => 11;
|
|
}
|
|
|
|
class D extends C with M {
|
|
var gee = 123;
|
|
}
|
|
|
|
class E {
|
|
// Make sure E.fun is not removed by the tree shaker, as this test verifies
|
|
// that an object with a tear-off in E.fun cannot be sent.
|
|
@pragma("vm:entry-point")
|
|
Function fun;
|
|
|
|
E(this.fun);
|
|
|
|
static fooFun() => 499;
|
|
instanceFun() => 1234;
|
|
}
|
|
|
|
barFun() => 42;
|
|
|
|
class F {
|
|
final field = "field";
|
|
const F();
|
|
}
|
|
|
|
class G {
|
|
final field;
|
|
const G(this.field);
|
|
}
|
|
|
|
class Value {
|
|
final val;
|
|
Value(this.val);
|
|
|
|
operator ==(other) {
|
|
if (other is! Value) return false;
|
|
return other.val == val;
|
|
}
|
|
|
|
get hashCode => val;
|
|
}
|
|
|
|
void runTests(SendPort ping, Queue checks) {
|
|
ping.send("abc");
|
|
checks.add((x) => Expect.equals("abc", x));
|
|
|
|
ping.send([1, 2]);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is List);
|
|
Expect.listEquals([1, 2], x);
|
|
// Make sure the list is mutable.
|
|
x[0] = 0;
|
|
Expect.equals(0, x[0]);
|
|
// List must be extendable.
|
|
x.add(3);
|
|
Expect.equals(3, x[2]);
|
|
});
|
|
|
|
var fixed = List.filled(2, 0);
|
|
fixed[0] = 0;
|
|
fixed[1] = 1;
|
|
ping.send(fixed);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is List);
|
|
Expect.listEquals([0, 1], x);
|
|
// List must be mutable.
|
|
x[0] = 3;
|
|
Expect.equals(3, x[0]);
|
|
// List must be fixed length.
|
|
Expect.throws(() {
|
|
x.add(5);
|
|
});
|
|
});
|
|
|
|
List cyclic = [];
|
|
cyclic.add(cyclic);
|
|
ping.send(cyclic);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is List);
|
|
Expect.equals(1, x.length);
|
|
Expect.identical(x, x[0]);
|
|
// List must be mutable.
|
|
x[0] = 55;
|
|
Expect.equals(55, x[0]);
|
|
// List must be extendable.
|
|
x.add(42);
|
|
Expect.equals(42, x[1]);
|
|
});
|
|
|
|
var cyclic2 = List<Object?>.filled(1, null);
|
|
cyclic2[0] = cyclic2;
|
|
ping.send(cyclic2);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is List);
|
|
Expect.equals(1, x.length);
|
|
Expect.identical(x, x[0]);
|
|
// List must be mutable.
|
|
x[0] = 55;
|
|
Expect.equals(55, x[0]);
|
|
// List must be fixed.
|
|
Expect.throws(() => x.add(42));
|
|
});
|
|
|
|
List constList = const [1, 2];
|
|
ping.send(constList);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is List);
|
|
Expect.listEquals([1, 2], x);
|
|
// Make sure the list is immutable.
|
|
Expect.throws(() => x[0] = 0); // //# constList: ok
|
|
// List must not be extendable.
|
|
Expect.throws(() => x.add(3));
|
|
Expect.identical(x, constList); // //# constList_identical: ok
|
|
});
|
|
|
|
Uint8List uint8 = new Uint8List(2);
|
|
uint8[0] = 0;
|
|
uint8[1] = 1;
|
|
ping.send(uint8);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is Uint8List);
|
|
Expect.equals(2, x.length);
|
|
Expect.equals(0, x[0]);
|
|
Expect.equals(1, x[1]);
|
|
});
|
|
|
|
Uint16List uint16 = new Uint16List(2);
|
|
uint16[0] = 0;
|
|
uint16[1] = 1;
|
|
ByteBuffer byteBuffer = uint16.buffer;
|
|
ping.send(byteBuffer); // //# byteBuffer: ok
|
|
checks.add( // //# byteBuffer: ok
|
|
(x) {
|
|
Expect.isTrue(x is ByteBuffer);
|
|
Uint16List uint16View = new Uint16List.view(x);
|
|
Expect.equals(2, uint16View.length);
|
|
Expect.equals(0, uint16View[0]);
|
|
Expect.equals(1, uint16View[1]);
|
|
}
|
|
) // //# byteBuffer: ok
|
|
;
|
|
|
|
Int32x4List list32x4 = new Int32x4List(2);
|
|
list32x4[0] = new Int32x4(1, 2, 3, 4);
|
|
list32x4[1] = new Int32x4(5, 6, 7, 8);
|
|
ping.send(list32x4);
|
|
checks.add(
|
|
(x) {
|
|
Expect.isTrue(x is Int32x4List);
|
|
Expect.equals(2, x.length);
|
|
Int32x4 entry1 = x[0];
|
|
Int32x4 entry2 = x[1];
|
|
Expect.equals(1, entry1.x);
|
|
Expect.equals(2, entry1.y);
|
|
Expect.equals(3, entry1.z);
|
|
Expect.equals(4, entry1.w);
|
|
Expect.equals(5, entry2.x);
|
|
Expect.equals(6, entry2.y);
|
|
Expect.equals(7, entry2.z);
|
|
Expect.equals(8, entry2.w);
|
|
});
|
|
|
|
Float32x4List flist32x4 = new Float32x4List(2);
|
|
flist32x4[0] = new Float32x4(1.5, 2.5, 3.5, 4.5);
|
|
flist32x4[1] = new Float32x4(5.5, 6.5, 7.5, 8.5);
|
|
ping.send(flist32x4);
|
|
checks.add(
|
|
(x) {
|
|
Expect.isTrue(x is Float32x4List);
|
|
Expect.equals(2, x.length);
|
|
Float32x4 entry1 = x[0];
|
|
Float32x4 entry2 = x[1];
|
|
Expect.equals(1.5, entry1.x);
|
|
Expect.equals(2.5, entry1.y);
|
|
Expect.equals(3.5, entry1.z);
|
|
Expect.equals(4.5, entry1.w);
|
|
Expect.equals(5.5, entry2.x);
|
|
Expect.equals(6.5, entry2.y);
|
|
Expect.equals(7.5, entry2.z);
|
|
Expect.equals(8.5, entry2.w);
|
|
});
|
|
|
|
Float64x2List flist64x2 = new Float64x2List(2);
|
|
flist64x2[0] = new Float64x2(1.5, 2.5);
|
|
flist64x2[1] = new Float64x2(5.5, 6.5);
|
|
ping.send(flist64x2);
|
|
checks.add(
|
|
(x) {
|
|
Expect.isTrue(x is Float64x2List);
|
|
Expect.equals(2, x.length);
|
|
Float64x2 entry1 = x[0];
|
|
Float64x2 entry2 = x[1];
|
|
Expect.equals(1.5, entry1.x);
|
|
Expect.equals(2.5, entry1.y);
|
|
Expect.equals(5.5, entry2.x);
|
|
Expect.equals(6.5, entry2.y);
|
|
});
|
|
|
|
ping.send({"foo": 499, "bar": 32});
|
|
checks.add((x) {
|
|
Expect.isTrue(x is LinkedHashMap);
|
|
Expect.listEquals(["foo", "bar"], x.keys.toList());
|
|
Expect.listEquals([499, 32], x.values.toList());
|
|
Expect.equals(499, x["foo"]);
|
|
Expect.equals(32, x["bar"]);
|
|
// Must be mutable.
|
|
x["foo"] = 22;
|
|
Expect.equals(22, x["foo"]);
|
|
// Must be extendable.
|
|
x["gee"] = 499;
|
|
Expect.equals(499, x["gee"]);
|
|
});
|
|
|
|
Map<String, int> mapWithRemovedKey = {"foo": 499, "bar": 32};
|
|
mapWithRemovedKey.remove("foo");
|
|
ping.send(mapWithRemovedKey);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is LinkedHashMap);
|
|
Expect.listEquals(["bar"], x.keys.toList());
|
|
Expect.listEquals([32], x.values.toList());
|
|
Expect.equals(32, x["bar"]);
|
|
});
|
|
|
|
// Test map where a key does not define ==/hashCode.
|
|
Map<A, int> mapWithIdentityKey = new Map<A, int>();
|
|
mapWithIdentityKey[new A()] = 499;
|
|
ping.send(mapWithIdentityKey);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is LinkedHashMap);
|
|
int value = x.values.first;
|
|
Expect.equals(499, value);
|
|
A key = x.keys.first;
|
|
Expect.equals(499, x[key]);
|
|
});
|
|
|
|
ping.send({0: 499, 1: 32});
|
|
checks.add((x) {
|
|
Expect.isTrue(x is LinkedHashMap);
|
|
Expect.listEquals([0, 1], x.keys.toList());
|
|
Expect.listEquals([499, 32], x.values.toList());
|
|
// Must be mutable.
|
|
x[0] = 22;
|
|
Expect.equals(22, x[0]);
|
|
// Must be extendable.
|
|
x[123] = 499;
|
|
Expect.equals(499, x[123]);
|
|
});
|
|
|
|
Map cyclicMap = {};
|
|
cyclicMap["cycle"] = cyclicMap;
|
|
ping.send(cyclicMap);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is LinkedHashMap);
|
|
Expect.identical(x, x["cycle"]);
|
|
// Must be mutable.
|
|
x["cycle"] = 22;
|
|
Expect.equals(22, x["cycle"]);
|
|
// Must be extendable.
|
|
x["gee"] = 499;
|
|
Expect.equals(499, x["gee"]);
|
|
});
|
|
|
|
Map constMap = const {'foo': 499};
|
|
ping.send(constMap);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is Map);
|
|
print(x.length);
|
|
Expect.equals(1, x.length);
|
|
Expect.equals(499, x['foo']);
|
|
Expect.identical(constMap, x); // //# constMap: ok
|
|
Expect.throws(() => constMap['bar'] = 42);
|
|
});
|
|
|
|
ping.send(new A());
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.equals(499, x.field);
|
|
});
|
|
|
|
ping.send(new A.named(42));
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.equals(42, x.field);
|
|
});
|
|
|
|
ping.send(new B());
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.isTrue(x is B);
|
|
Expect.equals(499, x.field);
|
|
Expect.equals(99, x.field2);
|
|
Expect.throws(() => x.field2 = 22);
|
|
});
|
|
|
|
ping.send(new B.named(1, 2));
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.isTrue(x is B);
|
|
Expect.equals(2, x.field);
|
|
Expect.equals(1, x.field2);
|
|
Expect.throws(() => x.field2 = 22);
|
|
});
|
|
|
|
ping.send(new C());
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.isTrue(x is B);
|
|
Expect.isTrue(x is C);
|
|
Expect.equals(33, x.field);
|
|
Expect.equals(99, x.field2);
|
|
Expect.equals(499, x.superField);
|
|
Expect.throws(() => x.field2 = 22);
|
|
});
|
|
|
|
ping.send(new D());
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.isTrue(x is B);
|
|
Expect.isTrue(x is C);
|
|
Expect.isTrue(x is D);
|
|
Expect.isTrue(x is M);
|
|
Expect.equals(33, x.field);
|
|
Expect.equals(11, x.field2);
|
|
Expect.equals(499, x.superField);
|
|
Expect.equals(99, x.superField2);
|
|
Expect.throws(() => x.field2 = 22);
|
|
});
|
|
|
|
D cyclicD = new D();
|
|
ping.send(cyclicD);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is A);
|
|
Expect.isTrue(x is B);
|
|
Expect.isTrue(x is C);
|
|
Expect.isTrue(x is D);
|
|
Expect.isTrue(x is M);
|
|
Expect.equals(11, x.field2);
|
|
Expect.equals(499, x.superField);
|
|
Expect.equals(99, x.superField2);
|
|
Expect.throws(() => x.field2 = 22);
|
|
});
|
|
|
|
ping.send(new E(E.fooFun)); // //# fun: ok
|
|
checks.add((x) { // //# fun: continued
|
|
Expect.equals(E.fooFun, x.fun); // //# fun: continued
|
|
Expect.equals(499, x.fun()); // //# fun: continued
|
|
}); // //# fun: continued
|
|
|
|
ping.send(new E(barFun)); // //# fun: continued
|
|
checks.add((x) { // //# fun: continued
|
|
Expect.equals(barFun, x.fun); // //# fun: continued
|
|
Expect.equals(42, x.fun()); // //# fun: continued
|
|
}); // //# fun: continued
|
|
|
|
ping.send(new E(new E(E.fooFun).instanceFun));
|
|
checks.add((x) {
|
|
Expect.equals(1234, (x as E).fun());
|
|
});
|
|
|
|
F nonConstF = new F();
|
|
ping.send(nonConstF);
|
|
checks.add((x) {
|
|
Expect.equals("field", x.field);
|
|
Expect.isFalse(identical(nonConstF, x));
|
|
});
|
|
|
|
const F constF = const F();
|
|
ping.send(constF);
|
|
checks.add((x) {
|
|
Expect.equals("field", x.field);
|
|
Expect.identical(constF, x); // //# constInstance: ok
|
|
});
|
|
|
|
G g1 = new G(nonConstF);
|
|
G g2 = new G(constF);
|
|
G g3 = const G(constF);
|
|
ping.send(g1);
|
|
ping.send(g2);
|
|
ping.send(g3);
|
|
|
|
checks.add((x) {
|
|
// g1.
|
|
Expect.isTrue(x is G);
|
|
Expect.isFalse(identical(g1, x));
|
|
F f = x.field;
|
|
Expect.equals("field", f.field);
|
|
Expect.isFalse(identical(nonConstF, f));
|
|
});
|
|
checks.add((x) {
|
|
// g2.
|
|
Expect.isTrue(x is G);
|
|
Expect.isFalse(identical(g1, x));
|
|
F f = x.field;
|
|
Expect.equals("field", f.field);
|
|
Expect.identical(constF, f); // //# constInstance: continued
|
|
});
|
|
checks.add((x) {
|
|
// g3.
|
|
Expect.isTrue(x is G);
|
|
Expect.identical(g3, x); // //# constInstance: continued
|
|
F f = x.field;
|
|
Expect.equals("field", f.field);
|
|
Expect.identical(constF, f); // //# constInstance: continued
|
|
});
|
|
|
|
// Make sure objects in a map are serialized and deserialized in the correct
|
|
// order.
|
|
Map m = new Map();
|
|
Value val1 = new Value(1);
|
|
Value val2 = new Value(2);
|
|
m[val1] = val2;
|
|
m[val2] = val1;
|
|
// Possible bug we want to catch:
|
|
// serializer runs through keys first, and then the values:
|
|
// - id1 = val1, id2 = val2, ref[id2], ref[id1]
|
|
// deserializer runs through the keys and values in order:
|
|
// - val1; // id1.
|
|
// - ref[id2]; // boom. Wasn't deserialized yet.
|
|
ping.send(m);
|
|
checks.add((x) {
|
|
Expect.isTrue(x is Map);
|
|
Expect.equals(2, x.length);
|
|
Expect.equals(val2, x[val1]);
|
|
Expect.equals(val1, x[val2]);
|
|
Expect.identical(x.keys.elementAt(0), x.values.elementAt(1));
|
|
Expect.identical(x.keys.elementAt(1), x.values.elementAt(0));
|
|
});
|
|
}
|
|
|
|
void main() {
|
|
asyncStart();
|
|
Queue checks = new Queue();
|
|
ReceivePort testPort = new ReceivePort();
|
|
Completer completer = new Completer();
|
|
|
|
testPort.listen((msg) {
|
|
Function check = checks.removeFirst();
|
|
check(msg);
|
|
if (checks.isEmpty) {
|
|
completer.complete();
|
|
testPort.close();
|
|
}
|
|
});
|
|
|
|
ReceivePort initialReplyPort = new ReceivePort();
|
|
Isolate
|
|
.spawn(echoMain, [initialReplyPort.sendPort, testPort.sendPort])
|
|
.then((_) => initialReplyPort.first)
|
|
.then((_ping) {
|
|
SendPort ping = _ping;
|
|
runTests(ping, checks);
|
|
Expect.isTrue(checks.length > 0);
|
|
completer.future.then((_) => ping.send("halt")).then((_) => asyncEnd());
|
|
});
|
|
}
|