| Index: tests/isolate/message3_test.dart
|
| diff --git a/tests/isolate/message3_test.dart b/tests/isolate/message3_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a29c8f94a931772a040b62313c68ff09c5504ecc
|
| --- /dev/null
|
| +++ b/tests/isolate/message3_test.dart
|
| @@ -0,0 +1,438 @@
|
| +// 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.
|
| +
|
| +// Dart test program for testing serialization of messages.
|
| +// VMOptions=--enable_type_checks --enable_asserts
|
| +
|
| +library MessageTest;
|
| +import 'dart:async';
|
| +import 'dart:collection';
|
| +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 {
|
| + 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]);
|
| + });
|
| +
|
| + List fixed = new List(2);
|
| + 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]);
|
| + });
|
| +
|
| + List cyclic2 = new List(1);
|
| + 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); /// int32x4: ok
|
| + checks.add( /// int32x4: ok
|
| + (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);
|
| + }
|
| + ) /// int32x4: ok
|
| + ;
|
| +
|
| + 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());
|
| + // Must be mutable.
|
| + x["foo"] = 22;
|
| + Expect.equals(22, x["foo"]);
|
| + // Must be extendable.
|
| + x["gee"] = 499;
|
| + Expect.equals(499, x["gee"]);
|
| + });
|
| +
|
| + 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["gee"] = 499;
|
| + Expect.equals(499, x["gee"]);
|
| + });
|
| +
|
| + 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();
|
| + cyclicD.field = cyclicD;
|
| + 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.identical(x, x.field);
|
| + 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
|
| +
|
| + Expect.throws(() => ping.send(new E(new E(null).instanceFun)));
|
| +
|
| + 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) { // g1.
|
| + 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(g1, 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((SendPort ping) {
|
| + runTests(ping, checks);
|
| + Expect.isTrue(checks.length > 0);
|
| + completer.future
|
| + .then((_) => ping.send("halt"))
|
| + .then((_) => asyncEnd());
|
| + });
|
| +}
|
|
|