rpd
Version:
RPD is a minimal framework for building Node-Based User Interfaces, powered by Reactive Programming
227 lines (167 loc) • 8.14 kB
JavaScript
describe('registration: node renderer', function() {
it('could be defined as an empty object', function() {
expect(function() {
Rpd.noderenderer('spec/empty', 'spec', {});
}).not.toThrow();
});
describe('transferring with the events', function() {
var addNodeSpy, processSpy;
var patch;
beforeEach(function() {
addNodeSpy = jasmine.createSpy('add-node');
processSpy = jasmine.createSpy('process');
Rpd.nodetype('spec/foo', {
process: function() {}
});
Rpd.renderer('spec', function(patch) {
return function(target, conf) {
return {
'patch/add-node': addNodeSpy,
'node/process': processSpy
}
}
});
patch = Rpd.addPatch().render('spec', {});
});
it('even if it\'s an empty object, passed with node adding and processing event', function() {
var renderer = {};
Rpd.noderenderer('spec/foo', 'spec', renderer);
var node = patch.addNode('spec/foo');
var inlet = node.addInlet('spec/any', 'a');
inlet.receive('a');
expect(addNodeSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: renderer
}));
expect(processSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: renderer
}));
});
it('the normal update stream should not set this field to an update event', function() {
var patchEventsSpy = jasmine.createSpy('patch-events');
patch.events.onValue(patchEventsSpy);
var node = patch.addNode('spec/foo');
var nodeEventsSpy = jasmine.createSpy('node-events');
node.events.onValue(nodeEventsSpy);
var renderer = {};
Rpd.noderenderer('spec/foo', 'spec', renderer);
var inlet = node.addInlet('spec/any', 'a');
inlet.receive('a');
expect(patchEventsSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/add-node', render: renderer }));
expect(patchEventsSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'node/process', render: renderer }));
expect(nodeEventsSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'node/process', render: renderer }));
});
it('one could define render-first function which is passed with node adding event', function() {
var renderFirst = function() {};
var renderer = { first: renderFirst };
Rpd.noderenderer('spec/foo', 'spec', renderer);
var node = patch.addNode('spec/foo');
var inlet = node.addInlet('spec/any', 'a');
inlet.receive('a');
expect(addNodeSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: { first: renderFirst }
}));
});
it('one could define render-always function which is passed both with node adding event and node processing events', function() {
var renderAlways = function() {};
var renderer = { always: renderAlways };
Rpd.noderenderer('spec/foo', 'spec', renderer);
var node = patch.addNode('spec/foo');
var inlet = node.addInlet('spec/any', 'a');
inlet.receive('a');
expect(addNodeSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
type: 'patch/add-node',
render: { always: renderAlways }
}));
expect(processSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: { always: renderAlways }
}));
});
it('one could define both render-first and render-always functions which are passed with node adding and node processing events', function() {
var renderFirst = function() {},
renderAlways = function() {};
var renderer = { first: renderFirst,
always: renderAlways };
Rpd.noderenderer('spec/foo', 'spec', renderer);
var node = patch.addNode('spec/foo');
var inlet = node.addInlet('spec/any', 'a');
inlet.receive('a');
expect(addNodeSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: { first: renderFirst,
always: renderAlways }
}));
expect(processSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: jasmine.objectContaining({ always: renderAlways })
}));
});
it('one could define a single function which is executed on every node creation, gets node instance and returns the renderer for that node', function() {
var renderers = {};
var rendererGenSpy = jasmine.createSpy('renderer-generator')
.and.callFake(function(node) {
return (renderers[node.id] = {
first: function() { },
always: function() { },
});
});
Rpd.noderenderer('spec/foo', 'spec', rendererGenSpy);
var nodeOne = patch.addNode('spec/foo');
nodeOne.addInlet('spec/any', 'a').receive('a');
expect(rendererGenSpy).toHaveBeenCalledOnce();
expect(rendererGenSpy).toHaveBeenCalledWith(nodeOne);
expect(addNodeSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: renderers[nodeOne.id]
}));
expect(processSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: renderers[nodeOne.id]
}));
var nodeTwo = patch.addNode('spec/foo');
nodeTwo.addInlet('spec/any', 'a').receive('b');
expect(rendererGenSpy).toHaveBeenCalledTwice();
expect(rendererGenSpy).toHaveBeenCalledWith(nodeTwo);
expect(addNodeSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: renderers[nodeTwo.id]
}));
expect(processSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
render: renderers[nodeTwo.id]
}));
});
it('not passes this renderer if current renderer is different from the registered one', function() {
var renderFirst = function() {},
renderAlways = function() {};
var renderer = { first: renderFirst,
always: renderAlways };
Rpd.noderenderer('spec/foo', 'sp_c', renderer);
var node = patch.addNode('spec/foo');
var inlet = node.addInlet('spec/any', 'a');
inlet.receive('a');
expect(addNodeSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({
render: jasmine.objectContaining({ first: renderFirst })
}));
expect(addNodeSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({
render: jasmine.objectContaining({ always: renderAlways })
}));
expect(processSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({
render: jasmine.objectContaining({ always: renderAlways })
}));
});
});
// TODO: test using ASCII-Renderer
xit('calls `first` method of renderer with node body and incoming configuration stream', function() {});
xit('calls `always` method of renderer with node body', function() {});
});