New tests and bug fixes for patch and mux
This commit is contained in:
parent
d1b3ffdf81
commit
f22e228cc0
|
@ -42,16 +42,17 @@ Mux.prototype.updateStream = function (pid, unclampedPatch) {
|
|||
deltaAggregate: deltaAggregate };
|
||||
};
|
||||
|
||||
function computePatches(oldMux, newMux, updateStreamResult) {
|
||||
function computeEvents(oldMux, newMux, updateStreamResult) {
|
||||
var actingPid = updateStreamResult.pid;
|
||||
var delta = updateStreamResult.delta;
|
||||
var deltaAggregate = updateStreamResult.deltaAggregate;
|
||||
var oldRoutingTable = oldMux.routingTable;
|
||||
var newRoutingTable = newMux.routingTable;
|
||||
var affectedPids = computeAffectedPids(oldRoutingTable, delta).remove("meta");
|
||||
var affectedPids = computeAffectedPids(oldRoutingTable, delta).add(actingPid).remove("meta");
|
||||
return {
|
||||
eventMap: Immutable.Map().withMutations(function (result) {
|
||||
affectedPids.forEach(function (pid) {
|
||||
var patchForPid;
|
||||
if (pid === actingPid) {
|
||||
var part1 = new Patch.Patch(Patch.biasedIntersection(newRoutingTable, delta.added),
|
||||
Patch.biasedIntersection(oldRoutingTable, delta.removed));
|
||||
|
@ -59,9 +60,12 @@ function computePatches(oldMux, newMux, updateStreamResult) {
|
|||
newMux.interestsOf(pid)),
|
||||
Patch.biasedIntersection(deltaAggregate.removed,
|
||||
oldMux.interestsOf(pid)));
|
||||
results.set(pid, part1.unsafeUnion(part2));
|
||||
patchForPid = part1.unsafeUnion(part2);
|
||||
} else {
|
||||
result.set(pid, updateStreamResult.deltaAggregate.viewFrom(oldMux.interestsOf(pid)));
|
||||
patchForPid = updateStreamResult.deltaAggregate.viewFrom(oldMux.interestsOf(pid));
|
||||
}
|
||||
if (patchForPid.isNonEmpty()) {
|
||||
result.set(pid, patchForPid);
|
||||
}
|
||||
});
|
||||
}),
|
||||
|
@ -97,5 +101,5 @@ Mux.prototype.interestsOf = function (pid) {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module.exports.Mux = Mux;
|
||||
module.exports.computePatches = computePatches;
|
||||
module.exports.computeEvents = computeEvents;
|
||||
module.exports.computeAffectedPids = computeAffectedPids;
|
||||
|
|
|
@ -63,6 +63,11 @@ function unpub(p, metaLevel) {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Patch.prototype.equals = function (other) {
|
||||
if (!(other instanceof Patch)) return false;
|
||||
return Immutable.is(this.added, other.added) && Immutable.is(this.removed, other.removed);
|
||||
};
|
||||
|
||||
Patch.prototype.isEmpty = function () {
|
||||
return this.added === Route.emptyTrie && this.removed === Route.emptyTrie;
|
||||
};
|
||||
|
|
|
@ -656,7 +656,12 @@ function trieStep(m, key) {
|
|||
if (is_emptyTrie(m)) return emptyTrie;
|
||||
if (m instanceof $WildcardSequence) return (is_keyClose(key) ? m.trie : m);
|
||||
if (m instanceof $Success) return emptyTrie;
|
||||
return rlookupWild(m, key) || rlookup(m, __);
|
||||
var result = rlookupWild(m, key);
|
||||
if (result) return result;
|
||||
var wildEdge = rlookup(m, __);
|
||||
if (is_keyOpen(key)) return rwildseq(wildEdge);
|
||||
if (is_keyClose(key)) return (wildEdge instanceof $WildcardSequence) ? wildEdge.trie : emptyTrie;
|
||||
return wildEdge;
|
||||
}
|
||||
|
||||
function relabel(m, f) {
|
||||
|
@ -1025,7 +1030,7 @@ function prettyTrie(m, initialIndent) {
|
|||
|
||||
module.exports.__ = __;
|
||||
module.exports.SOA = SOA;
|
||||
module.exports.EOA = SOA;
|
||||
module.exports.EOA = EOA;
|
||||
module.exports.$Capture = $Capture;
|
||||
module.exports.$Special = $Special;
|
||||
module.exports._$ = _$;
|
||||
|
@ -1050,3 +1055,11 @@ module.exports.trieKeys = trieKeys;
|
|||
module.exports.trieKeysToObjects = trieKeysToObjects;
|
||||
module.exports.projectObjects = projectObjects;
|
||||
module.exports.prettyTrie = prettyTrie;
|
||||
|
||||
// For testing
|
||||
module.exports._testing = {
|
||||
rsuccess: rsuccess,
|
||||
rseq: rseq,
|
||||
rwild: rwild,
|
||||
rwildseq: rwildseq
|
||||
};
|
||||
|
|
|
@ -19,14 +19,14 @@ function checkPrettyPatch(p, expectedAdded, expectedRemoved) {
|
|||
'>>>>>>>>\n'));
|
||||
}
|
||||
|
||||
describe('mux stream', function () {
|
||||
function getM() {
|
||||
var m = new Mux.Mux();
|
||||
expect(m.addStream(Patch.assert(1).andThen(Patch.assert(2))).pid).to.equal(0);
|
||||
expect(m.addStream(Patch.assert(3).andThen(Patch.assert(2))).pid).to.equal(1);
|
||||
return m;
|
||||
}
|
||||
function getM() {
|
||||
var m = new Mux.Mux();
|
||||
expect(m.addStream(Patch.assert(1).andThen(Patch.assert(2))).pid).to.equal(0);
|
||||
expect(m.addStream(Patch.assert(3).andThen(Patch.assert(2))).pid).to.equal(1);
|
||||
return m;
|
||||
}
|
||||
|
||||
describe('mux stream', function () {
|
||||
describe('addition', function () {
|
||||
it('should union interests appropriately', function () {
|
||||
var m = getM();
|
||||
|
@ -75,5 +75,183 @@ describe('mux stream', function () {
|
|||
[' 3 >{[1]}']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removal', function () {
|
||||
it('should remove streams properly', function () {
|
||||
var m = getM();
|
||||
var updateStreamResult = m.removeStream(1);
|
||||
expect(updateStreamResult.pid).to.equal(1);
|
||||
checkPrettyPatch(updateStreamResult.delta,
|
||||
['::: nothing'],
|
||||
[' 2 >{[1]}',
|
||||
' 3 >{[1]}']);
|
||||
checkPrettyTrie(m.routingTable, [' 1 >{[0]}',
|
||||
' 2 >{[0]}']);
|
||||
checkPrettyTrie(m.interestsOf(0), [' 1 >{[0]}',
|
||||
' 2 >{[0]}']);
|
||||
checkPrettyTrie(m.interestsOf(1), ['::: nothing']);
|
||||
checkPrettyPatch(updateStreamResult.deltaAggregate,
|
||||
['::: nothing'],
|
||||
[' 3 >{[1]}']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('computeEvents', function () {
|
||||
describe('for new assertions and existing specific interest', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.sub(1));
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.addStream(Patch.assert(1).andThen(Patch.assert(2)));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield just the assertion of interest', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(0).strip().equals(Patch.assert(1))).to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for removed assertions', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.sub([__]));
|
||||
var newM = oldM.shallowCopy();
|
||||
newM.addStream(Patch.assert([1]).andThen(Patch.assert([2])));
|
||||
var updateStreamResult = newM.updateStream(1, Patch.retract([1]));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield just the specific retraction', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(0).strip().equals(Patch.retract([1]))).to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for new assertions and existing general interest', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.sub([__]));
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.addStream(Patch.assert([1]).andThen(Patch.assert([2])));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield both new assertions', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(0).strip().equals(Patch.assert([1]).andThen(Patch.assert([2]))))
|
||||
.to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
})
|
||||
|
||||
describe('for new specific interest and existing assertion', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.assert(1).andThen(Patch.assert(2)));
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.addStream(Patch.sub(1));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield just the assertion of interest', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(1).strip().equals(Patch.assert(1))).to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for new general interest and existing assertion', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.assert([1]).andThen(Patch.assert([2])));
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.addStream(Patch.sub([__]));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield just the assertion of interest', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(1).strip().equals(Patch.assert([1]).andThen(Patch.assert([2]))))
|
||||
.to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for removed general interest', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.assert([1]).andThen(Patch.assert([2])));
|
||||
oldM.addStream(Patch.sub([__]));
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.updateStream(1, Patch.unsub([__]));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield both retractions', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(1).strip().equals(Patch.retract([1]).andThen(Patch.retract([2]))))
|
||||
.to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for removed specific interest', function () {
|
||||
it('should yield three appropriate events for three intercessions', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
oldM.addStream(Patch.assert([1]).andThen(Patch.assert([2])));
|
||||
oldM.addStream(Patch.sub([__]));
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.updateStream(1, Patch.unsub([1]));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(1).strip().equals(Patch.retract([1]))).to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
|
||||
oldM = newM;
|
||||
newM = oldM.shallowCopy();
|
||||
events = Mux.computeEvents(oldM, newM, newM.updateStream(1, Patch.unsub([2])));
|
||||
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(1).strip().equals(Patch.retract([2])))
|
||||
.to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
|
||||
oldM = newM;
|
||||
newM = oldM.shallowCopy();
|
||||
events = Mux.computeEvents(oldM, newM, newM.updateStream(0, Patch.assert([3])));
|
||||
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(1).strip().equals(Patch.assert([3]))).to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for new meta assertion', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.addStream(Patch.assert(Patch.atMeta(1)).andThen(Patch.assert(2)));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should yield no local events and one meta event', function () {
|
||||
expect(events.eventMap.size).to.be(0);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.metaEvents.get(0).strip().equals(Patch.assert(1))).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('for adding supply and demand simultaneously', function () {
|
||||
var oldM = new Mux.Mux();
|
||||
var newM = oldM.shallowCopy();
|
||||
var updateStreamResult = newM.addStream(Patch.assert(1).andThen(Patch.sub(1)));
|
||||
var events = Mux.computeEvents(oldM, newM, updateStreamResult);
|
||||
|
||||
it('should send a patch back', function () {
|
||||
expect(events.eventMap.size).to.be(1);
|
||||
expect(events.metaEvents.size).to.be(1);
|
||||
expect(events.eventMap.get(0).strip().equals(Patch.assert(1))).to.be(true);
|
||||
expect(events.metaEvents.get(0).equals(Patch.emptyPatch)).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -408,3 +408,11 @@ describe("Projection with no captures", function () {
|
|||
[' "X" ★ >{["A"]}']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('trieStep', function () {
|
||||
it('should expand wildcard when given SOA', function () {
|
||||
expect(Immutable.is(r.trieStep(r.compilePattern(true, r.__), r.SOA),
|
||||
r._testing.rwildseq(r._testing.rseq(r.EOA, r._testing.rsuccess(true)))))
|
||||
.to.be(true);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue