rpd
Version:
RPD is a minimal framework for building Node-Based User Interfaces, powered by Reactive Programming
240 lines (182 loc) • 10.4 kB
JavaScript
describe('building: network', function() {
describe('projecting patches', function() {
it('outlet could be defined as patch output', function() {
withNewPatch(function(patch, updateSpy) {
var node = patch.addNode('spec/empty');
var outlet = node.addOutlet('spec/any', 'foo');
patch.outputs([ outlet ]);
expect(updateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/set-outputs',
outputs: jasmine.arrayContaining([ outlet ]) }));
});
});
it('inlet could be defined as patch output', function() {
withNewPatch(function(patch, updateSpy) {
var node = patch.addNode('spec/empty');
var inlet = node.addInlet('spec/any', 'foo');
patch.inputs([ inlet ]);
expect(updateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/set-inputs',
inputs: jasmine.arrayContaining([ inlet ]) }));
});
});
it('both outlets and inlets could be defined together', function() {
withNewPatch(function(patch, updateSpy) {
var node = patch.addNode('spec/empty');
var inletOne = node.addInlet('spec/any', 'foo');
var inletTwo = node.addInlet('spec/any', 'foo');
var outletOne = node.addOutlet('spec/any', 'foo');
var outletTwo = node.addOutlet('spec/any', 'foo');
patch.inputs([ inletOne, inletTwo ]);
patch.outputs([ outletOne, outletTwo ]);
expect(updateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/set-inputs',
inputs: jasmine.arrayContaining([ inletOne, inletTwo ]) }));
expect(updateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/set-outputs',
outputs: jasmine.arrayContaining([ outletOne, outletTwo ]) }));
});
});
it('inner patch could not be projected when no inputs or outputs were specified', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
var rootNode = rootPatch.addNode('spec/empty');
withNewPatch('inner', function(innerPatch, innerUpdateSpy) {
innerPatch.project(rootNode);
expect(innerUpdateSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/project' }));
expect(rootUpdateSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/refer' }));
});
});
});
it('inner patch could be projected when empty inputs and outputs sets were specified', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
var rootNode = rootPatch.addNode('spec/empty');
withNewPatch('inner', function(innerPatch, innerUpdateSpy) {
innerPatch.inputs([ ]);
innerPatch.outputs([ ]);
innerPatch.project(rootNode);
expect(innerUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/project',
node: rootNode,
target: rootPatch }));
expect(rootUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/refer',
node: rootNode,
target: innerPatch }));
});
});
});
it('inner patch could be projected when both inputs and outputs were specified', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
var rootNode = rootPatch.addNode('spec/empty');
withNewPatch('inner', function(innerPatch, innerUpdateSpy) {
var innerNodeOne = innerPatch.addNode('spec/empty');
var inputOne = innerNodeOne.addInlet('spec/any', 'foo');
var outputOne = innerNodeOne.addOutlet('spec/any', 'foo');
var outputTwo = innerNodeOne.addOutlet('spec/any', 'foo');
var innerNodeTwo = innerPatch.addNode('spec/empty');
var outputThree = innerNodeTwo.addOutlet('spec/any', 'foo');
innerPatch.inputs([ inputOne ]);
innerPatch.outputs([ outputOne, outputTwo, outputThree ]);
innerPatch.project(rootNode);
expect(innerUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/project',
node: rootNode,
target: rootPatch }));
expect(rootUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/refer',
node: rootNode,
target: innerPatch }));
});
});
});
it('patches are opened by default', function() {
var networkUpdateSpy = jasmine.createSpy('network-update');
Rpd.events.onValue(networkUpdateSpy);
var patch = Rpd.addPatch();
expect(networkUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/open',
patch: patch }));
Rpd.events.offValue(networkUpdateSpy);
});
it('may pass parent patch to an opened one', function() {
var networkUpdateSpy = jasmine.createSpy('network-update');
Rpd.events.onValue(networkUpdateSpy);
var parent = Rpd.addPatch('parent');
var patch = Rpd.addPatch('child', null, parent);
expect(networkUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/open',
patch: patch,
parent: parent }));
Rpd.events.offValue(networkUpdateSpy);
});
it('patch can be already closed when added', function() {
var networkUpdateSpy = jasmine.createSpy('network-update');
Rpd.events.onValue(networkUpdateSpy);
var patch = Rpd.addClosedPatch('patch');
expect(networkUpdateSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/open' }));
/* expect(networkUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/close',
patch: patch })); */
Rpd.events.offValue(networkUpdateSpy);
});
it('closing a patch fires corresponding event', function() {
var networkUpdateSpy = jasmine.createSpy('network-update');
Rpd.events.onValue(networkUpdateSpy);
var patch = Rpd.addPatch('patch').close();
expect(networkUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/close',
patch: patch }));
Rpd.events.offValue(networkUpdateSpy);
});
it('properly passes events between several patches', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
withNewPatch('inner', function(innerPatch, innerUpdateSpy) {
innerNode = innerPatch.addNode('spec/empty');
expect(innerUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/add-node',
patch: innerPatch,
node: innerNode }));
var rootNode = rootPatch.addNode('spec/empty');
expect(rootUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/add-node',
patch: rootPatch,
node: rootNode }));
});
});
});
it('informs when patch was opened', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
expect(rootUpdateSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/open' }));
rootPatch.open();
expect(rootUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/open',
patch: rootPatch }));
});
});
it('parent patch could be passed to the opening event', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
withNewPatch('inner', function(innerPatch, innerUpdateSpy) {
innerPatch.open(rootPatch);
expect(innerUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/open',
patch: innerPatch,
parent: rootPatch }));
});
});
});
it('informs when patch was closed', function() {
withNewPatch('root', function(rootPatch, rootUpdateSpy) {
expect(rootUpdateSpy).not.toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/close' }));
rootPatch.close();
expect(rootUpdateSpy).toHaveBeenCalledWith(
jasmine.objectContaining({ type: 'patch/close',
patch: rootPatch }));
});
});
});
});