5952d7a067
R=ricow@google.com, sigmund@google.com Review URL: https://codereview.chromium.org//218273002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@34569 260f80e4-7a28-3924-810f-c04153c831b5
182 lines
4.7 KiB
Dart
182 lines
4.7 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.
|
|
|
|
library MintMakerTest;
|
|
import 'dart:async';
|
|
import 'dart:isolate';
|
|
import 'package:unittest/unittest.dart';
|
|
import "remote_unittest_helper.dart";
|
|
|
|
class Mint {
|
|
Map<SendPort, Purse> _registry;
|
|
SendPort port;
|
|
|
|
Mint() : _registry = new Map<SendPort, Purse>() {
|
|
ReceivePort mintPort = new ReceivePort();
|
|
port = mintPort.sendPort;
|
|
serveMint(mintPort);
|
|
}
|
|
|
|
void serveMint(ReceivePort port) {
|
|
port.listen((message) {
|
|
int balance = message[0];
|
|
Purse purse = createPurse(balance);
|
|
message[1].send(purse.port);
|
|
});
|
|
}
|
|
|
|
Purse createPurse(int balance) {
|
|
Purse purse = new Purse(this, balance);
|
|
_registry[purse.port] = purse;
|
|
return purse;
|
|
}
|
|
|
|
Purse lookupPurse(SendPort port) {
|
|
return _registry[port];
|
|
}
|
|
}
|
|
|
|
|
|
class MintWrapper {
|
|
SendPort _mint;
|
|
MintWrapper(SendPort this._mint) {}
|
|
|
|
void createPurse(int balance, handlePurse(PurseWrapper purse)) {
|
|
ReceivePort reply = new ReceivePort();
|
|
reply.first.then((SendPort purse) {
|
|
handlePurse(new PurseWrapper(purse));
|
|
});
|
|
_mint.send([balance, reply.sendPort]);
|
|
}
|
|
|
|
}
|
|
|
|
class Purse {
|
|
Mint mint;
|
|
int balance;
|
|
SendPort port;
|
|
|
|
Purse(this.mint, this.balance) {
|
|
ReceivePort recipient = new ReceivePort();
|
|
port = recipient.sendPort;
|
|
servePurse(recipient);
|
|
}
|
|
|
|
void servePurse(ReceivePort recipient) {
|
|
recipient.listen((message) {
|
|
String command = message[0];
|
|
if (command == "balance") {
|
|
SendPort replyTo = message.last;
|
|
replyTo.send(queryBalance());
|
|
} else if (command == "deposit") {
|
|
Purse source = mint.lookupPurse(message[2]);
|
|
deposit(message[1], source);
|
|
} else if (command == "sprout") {
|
|
SendPort replyTo = message.last;
|
|
Purse result = sproutPurse();
|
|
replyTo.send(result.port);
|
|
} else {
|
|
// TODO: Send an exception back.
|
|
throw UnsupportedError("Unsupported commend: $command");
|
|
}
|
|
});
|
|
}
|
|
|
|
int queryBalance() { return balance; }
|
|
|
|
Purse sproutPurse() { return mint.createPurse(0); }
|
|
|
|
void deposit(int amount, Purse source) {
|
|
// TODO: Throw an exception if the source purse doesn't hold
|
|
// enough dough.
|
|
balance += amount;
|
|
source.balance -= amount;
|
|
}
|
|
}
|
|
|
|
|
|
class PurseWrapper {
|
|
SendPort _purse;
|
|
|
|
PurseWrapper(this._purse) {}
|
|
|
|
void _sendReceive(message, replyHandler(reply)) {
|
|
ReceivePort reply = new ReceivePort();
|
|
_purse.send([message, reply.sendPort]);
|
|
reply.first.then(replyHandler);
|
|
}
|
|
|
|
void queryBalance(handleBalance(int balance)) {
|
|
_sendReceive("balance", handleBalance);
|
|
}
|
|
|
|
void sproutPurse(handleSprouted(PurseWrapper sprouted)) {
|
|
_sendReceive("sprout", (SendPort sprouted) {
|
|
handleSprouted(new PurseWrapper(sprouted));
|
|
});
|
|
}
|
|
|
|
void deposit(PurseWrapper source, int amount) {
|
|
_purse.send([ "deposit", amount, source._purse ]);
|
|
}
|
|
}
|
|
|
|
mintMakerWrapper(SendPort replyPort) {
|
|
ReceivePort receiver = new ReceivePort();
|
|
replyPort.send(receiver.sendPort);
|
|
receiver.listen((SendPort replyTo) {
|
|
Mint mint = new Mint();
|
|
replyTo.send(mint.port);
|
|
});
|
|
}
|
|
|
|
class MintMakerWrapper {
|
|
final SendPort _port;
|
|
|
|
static Future<MintMakerWrapper> create() {
|
|
ReceivePort reply = new ReceivePort();
|
|
return Isolate.spawn(mintMakerWrapper, reply.sendPort).then((_) =>
|
|
reply.first.then((port) => new MintMakerWrapper._(port)));
|
|
}
|
|
|
|
MintMakerWrapper._(this._port);
|
|
|
|
void makeMint(handleMint(MintWrapper mint)) {
|
|
ReceivePort reply = new ReceivePort();
|
|
reply.first.then((SendPort mint) { handleMint(new MintWrapper(mint)); });
|
|
_port.send(reply.sendPort);
|
|
}
|
|
}
|
|
|
|
_checkBalance(PurseWrapper wrapper, expected) {
|
|
wrapper.queryBalance(expectAsync((int balance) {
|
|
expect(balance, equals(expected));
|
|
}));
|
|
}
|
|
|
|
void main([args, port]) {
|
|
if (testRemote(main, port)) return;
|
|
test("creating purse, deposit, and query balance", () {
|
|
MintMakerWrapper.create().then(expectAsync((mintMaker) {
|
|
mintMaker.makeMint(expectAsync((MintWrapper mint) {
|
|
mint.createPurse(100, expectAsync((PurseWrapper purse) {
|
|
_checkBalance(purse, 100);
|
|
purse.sproutPurse(expectAsync((PurseWrapper sprouted) {
|
|
_checkBalance(sprouted, 0);
|
|
_checkBalance(purse, 100);
|
|
|
|
sprouted.deposit(purse, 5);
|
|
_checkBalance(sprouted, 0 + 5);
|
|
_checkBalance(purse, 100 - 5);
|
|
|
|
sprouted.deposit(purse, 42);
|
|
_checkBalance(sprouted, 0 + 5 + 42);
|
|
_checkBalance(purse, 100 - 5 - 42);
|
|
}));
|
|
}));
|
|
}));
|
|
}));
|
|
});
|
|
}
|