syndicate-2017/js/test/test-syndicate.js

171 lines
4.9 KiB
JavaScript

"use strict";
var expect = require('expect.js');
var Immutable = require('immutable');
var Syndicate = require('../src/main.js');
var Dataspace = Syndicate.Dataspace;
var Patch = Syndicate.Patch;
var __ = Syndicate.__;
var _$ = Syndicate._$;
function configurationTrace(bootConfiguration) {
var eventLog = [];
function trace(item) {
eventLog.push(item);
}
var G = new Syndicate.Ground(function () {
bootConfiguration(trace);
});
while (G.step()) {
// do nothing until G becomes inert
}
return eventLog;
}
function traceEvent(trace) {
return function(item) {
trace((item.type === "stateChange") ? item.patch.pretty() : item);
}
}
function attributedTraceEvent(attribution, trace) {
return function(item) {
trace([attribution, (item.type === "stateChange") ? item.patch.pretty() : item]);
}
}
function checkTrace(bootConfiguration, expected) {
expect(configurationTrace(bootConfiguration)).to.eql(expected);
}
describe("configurationTrace", function() {
describe("with an inert configuration", function () {
it("should yield an empty trace", function () {
checkTrace(function (trace) {}, []);
});
});
describe("with a single trace in an inert configuration", function () {
it("should yield that trace", function () {
checkTrace(function (trace) { trace(1) }, [1]);
});
});
describe("with some traced communication", function () {
it("should yield an appropriate trace", function () {
checkTrace(function (trace) {
Dataspace.spawn({
boot: function () { return Syndicate.sub(__); },
handleEvent: traceEvent(trace)
});
Dataspace.send(123);
Dataspace.send(234);
}, ['\n- ::: nothing'+
'\n+ observe<1> ★ {[0]}\n',
Syndicate.message(123),
Syndicate.message(234)]);
});
});
});
describe("nonempty initial routes", function () {
it("should be immediately signalled to the process", function () {
// Specifically, no Syndicate.updateRoutes([]) first.
checkTrace(function (trace) {
Dataspace.spawn({
boot: function () { return Patch.assert(["A", __]); },
handleEvent: function (e) {}
});
Dataspace.spawn({
boot: function () { return Patch.sub(["A", __]); },
handleEvent: traceEvent(trace)
});
}, ['\n- ::: nothing'+
'\n+ <2> "A" ★ {[0]}\n']);
});
});
describe("nested actor with an echoey protocol", function () {
it("shouldn't see an echoed assertion", function () {
checkTrace(function (trace) {
Dataspace.spawn(new Dataspace(function () {
Dataspace.spawn({
boot: function () {
Dataspace.stateChange(Patch.retract("X", 1)); // happens after subs on next line!
return Patch.sub("X", 1).andThen(Patch.assert("X", 1));
},
handleEvent: traceEvent(trace)
});
}));
}, ['\n- ::: nothing'+
'\n+ at-meta<1> "X" {["meta"]}\n',
'\n- at-meta<1> "X" {["meta"]}'+
'\n+ ::: nothing\n']);
})
it("shouldn't see an echoed message", function () {
checkTrace(function (trace) {
Dataspace.spawn(new Dataspace(function () {
Dataspace.spawn({
boot: function () {
Dataspace.send("X", 1); // happens after subs on next line!
return Patch.sub("X", 1);
},
handleEvent: traceEvent(trace)
});
}));
}, [Syndicate.message(Patch.atMeta("X"))]);
});
it("shouldn't see an echoed assertion", function () {
});
});
// describe("actor with nonempty initial routes", function () {
// it("shouldn't see initial empty conversational context", function () {
// checkTrace(function (trace) {
// Dataspace.spawn({
// boot: function () { return [pub(["A", __])] },
// handleEvent: function (e) {
// Dataspace.spawn(new Actor(function () {
// Actor.observeAdvertisers(
// function () { return ["A", __] },
// { presence: "isPresent" },
// function () {
// trace(["isPresent", this.isPresent]);
// });
// }));
// }
// });
// }, [["isPresent", true]]);
// });
// });
describe("broadcast message delivery", function () {
it("should work", function () {
checkTrace(function (trace) {
Dataspace.spawn({
boot: function () { return Patch.sub(["Alice", __]); },
handleEvent: attributedTraceEvent("Alice", trace)
});
Dataspace.spawn({
boot: function () { return Patch.sub(["Bob", __]); },
handleEvent: attributedTraceEvent("Bob", trace)
});
Dataspace.spawn({
boot: function () {
Dataspace.send(["Alice", "For Alice's eyes only"]);
Dataspace.send(["Bob", "Dear Bob, how are you? Kind regards, etc."]);
Dataspace.send([__, "Important announcement!"]);
}
})
}, [["Alice", Syndicate.message(["Alice", "For Alice's eyes only"])],
["Bob", Syndicate.message(["Bob", "Dear Bob, how are you? Kind regards, etc."])],
["Alice", Syndicate.message([__, "Important announcement!"])],
["Bob", Syndicate.message([__, "Important announcement!"])]]);
});
});