UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

400 lines (397 loc) 12.7 kB
var chai, noflo; if (typeof process !== 'undefined' && process.execPath && process.execPath.match(/node|iojs/)) { if (!chai) { chai = require('chai'); } noflo = require('../src/lib/NoFlo.coffee'); } else { noflo = require('noflo'); } describe('Inport Port', function() { describe('with default options', function() { var p; p = new noflo.InPort; it('should be of datatype "all"', function() { return chai.expect(p.getDataType()).to.equal('all'); }); it('should not be required', function() { return chai.expect(p.isRequired()).to.equal(false); }); it('should not be addressable', function() { return chai.expect(p.isAddressable()).to.equal(false); }); return it('should not be buffered', function() { return chai.expect(p.isBuffered()).to.equal(false); }); }); describe('with custom type', function() { var p; p = new noflo.InPort({ datatype: 'string', type: 'text/url' }); return it('should retain the type', function() { chai.expect(p.getDataType()).to.equal('string'); return chai.expect(p.options.type).to.equal('text/url'); }); }); describe('without attached sockets', function() { var p; p = new noflo.InPort; it('should not be attached', function() { chai.expect(p.isAttached()).to.equal(false); return chai.expect(p.listAttached()).to.eql([]); }); it('should allow attaching', function() { return chai.expect(p.canAttach()).to.equal(true); }); it('should not be connected initially', function() { return chai.expect(p.isConnected()).to.equal(false); }); return it('should not contain a socket initially', function() { return chai.expect(p.sockets.length).to.equal(0); }); }); describe('with processing function called with port as context', function() { return it('should set context to port itself', function(done) { var p, s; s = new noflo.internalSocket.InternalSocket; p = new noflo.InPort; p.on('data', function(packet, component) { chai.expect(this).to.equal(p); chai.expect(packet).to.equal('some-data'); return done(); }); p.attach(s); return s.send('some-data'); }); }); describe('with default value', function() { var p, s; p = s = null; beforeEach(function() { p = new noflo.InPort({ "default": 'default-value' }); s = new noflo.internalSocket.InternalSocket; return p.attach(s); }); it('should send the default value as a packet, though on next tick after initialization', function(done) { p.on('data', function(data) { chai.expect(data).to.equal('default-value'); return done(); }); return s.send(); }); return it('should send the default value before IIP', function(done) { var received; received = ['default-value', 'some-iip']; p.on('data', function(data) { chai.expect(data).to.equal(received.shift()); if (received.length === 0) { return done(); } }); return setTimeout(function() { s.send(); return s.send('some-iip'); }, 0); }); }); describe('with options stored in port', function() { return it('should store all provided options in port, whether we expect it or not', function() { var name, option, options, p, results; options = { datatype: 'string', type: 'http://schema.org/Person', description: 'Person', required: true, weNeverExpectThis: 'butWeStoreItAnyway' }; p = new noflo.InPort(options); results = []; for (name in options) { option = options[name]; results.push(chai.expect(p.options[name]).to.equal(option)); } return results; }); }); describe('with data type information', function() { var f, right, wrong; right = 'all string number int object array'.split(' '); wrong = 'not valie data types'.split(' '); f = function(datatype) { return new noflo.InPort({ datatype: datatype }); }; right.forEach(function(r) { return it("should accept a '" + r + "' data type", (function(_this) { return function() { return chai.expect(function() { return f(r); }).to.not["throw"](); }; })(this)); }); return wrong.forEach(function(w) { return it("should NOT accept a '" + w + "' data type", (function(_this) { return function() { return chai.expect(function() { return f(w); }).to["throw"](); }; })(this)); }); }); describe('with TYPE (i.e. ontology) information', function() { var f; f = function(type) { return new noflo.InPort({ type: type }); }; return it('should be a URL or MIME', function() { chai.expect(function() { return f('http://schema.org/Person'); }).to.not["throw"](); chai.expect(function() { return f('text/javascript'); }).to.not["throw"](); return chai.expect(function() { return f('neither-a-url-nor-mime'); }).to["throw"](); }); }); describe('with buffering', function() { it('should buffer incoming packets until `receive()`d', function(done) { var expectedData, expectedEvents, p, s; expectedEvents = ['connect', 'data', 'data', 'disconnect', 'connect', 'data', 'disconnect']; expectedData = ['buffered-data-1', 'buffered-data-2', 'buffered-data-3']; p = new noflo.InPort({ buffered: true }, function(eventName) { var expectedEvent, packet; expectedEvent = expectedEvents.shift(); chai.expect(eventName).to.equal(expectedEvent); packet = p.receive(); chai.expect(packet).to.be.an('object'); chai.expect(packet.event).to.equal(expectedEvent); if (packet.event === 'data') { chai.expect(packet.payload).to.equal(expectedData.shift()); } if (expectedEvents.length === 0) { return done(); } }); s = new noflo.internalSocket.InternalSocket; p.attach(s); s.send('buffered-data-1'); s.send('buffered-data-2'); s.disconnect(); s.send('buffered-data-3'); return s.disconnect(); }); it('should be able to tell the number of contained data packets', function() { var p, s; p = new noflo.InPort({ buffered: true }); s = new noflo.internalSocket.InternalSocket; p.attach(s); s.send('buffered-data-1'); s.beginGroup('foo'); s.send('buffered-data-2'); s.endGroup(); s.disconnect(); s.send('buffered-data-3'); s.disconnect(); return chai.expect(p.contains()).to.equal(3); }); it('should return undefined when buffer is empty', function() { var p; p = new noflo.InPort({ buffered: true }); return chai.expect(p.receive()).to.be.undefined; }); return it('shouldn\'t expose the receive method without buffering', function() { var p, s; p = new noflo.InPort({ buffered: false }); s = new noflo.internalSocket.InternalSocket; p.attach(s); p.once('data', function(data) { chai.expect(data).to.equal('data'); chai.expect(function() { return p.receive(); }).to["throw"](); return chai.expect(function() { return p.contains(); }).to["throw"](); }); return s.send('data'); }); }); describe('with accepted enumerated values', function() { it('should accept certain values', function(done) { var p, s; p = new noflo.InPort({ values: 'noflo is awesome'.split(' ') }); s = new noflo.internalSocket.InternalSocket; p.attach(s); p.on('data', function(data) { chai.expect(data).to.equal('awesome'); return done(); }); return s.send('awesome'); }); return it('should throw an error if value is not accepted', function() { var p, s; p = new noflo.InPort({ values: 'noflo is awesome'.split(' ') }); s = new noflo.internalSocket.InternalSocket; p.attach(s); p.on('data', function() { return chai.expect(true).to.be.equal(false); }); return chai.expect(function() { return s.send('terrific'); }).to["throw"]; }); }); describe('with processing shorthand', function() { it('should create a port with a callback', function() { var ps, s; s = new noflo.internalSocket.InternalSocket; ps = { outPorts: new noflo.OutPorts({ out: new noflo.OutPort }), inPorts: new noflo.InPorts }; ps.inPorts.add('in', function(event, payload) { if (event !== 'data') { return; } return chai.expect(payload).to.equal('some-data'); }); chai.assert(ps.inPorts["in"] instanceof noflo.InPort); ps.inPorts["in"].attach(s); return s.send('some-data'); }); return it('should also accept metadata (i.e. options) when provided', function(done) { var expectedEvents, ps, s; s = new noflo.internalSocket.InternalSocket; expectedEvents = ['connect', 'data', 'disconnect']; ps = { outPorts: new noflo.OutPorts({ out: new noflo.OutPort }), inPorts: new noflo.InPorts }; ps.inPorts.add('in', { datatype: 'string', required: true }, function(event, payload) { chai.expect(event).to.equal(expectedEvents.shift()); if (event !== 'data') { return; } chai.expect(payload).to.equal('some-data'); return done(); }); ps.inPorts["in"].attach(s); chai.expect(ps.inPorts["in"].listAttached()).to.eql([0]); s.send('some-data'); return s.disconnect(); }); }); return describe('with IP handle callback option', function() { it('should pass IP objects to handler', function(done) { var ps, s; s = new noflo.internalSocket.InternalSocket; ps = { outPorts: new noflo.OutPorts({ out: new noflo.OutPort }), inPorts: new noflo.InPorts }; ps.inPorts.add('in', { datatype: 'string', required: true, handle: function(ip) { chai.expect(ip).to.be.an('object'); if (ip.type !== 'data') { return; } chai.expect(ip.data).to.equal('some-data'); return done(); } }); ps.inPorts["in"].attach(s); chai.expect(ps.inPorts["in"].listAttached()).to.eql([0]); return s.send(new noflo.IP('data', 'some-data')); }); it('should translate legacy events to IP objects', function(done) { var expectedEvents, ps, s; s = new noflo.internalSocket.InternalSocket; expectedEvents = ['openBracket', 'data', 'closeBracket']; ps = { outPorts: new noflo.OutPorts({ out: new noflo.OutPort }), inPorts: new noflo.InPorts }; ps.inPorts.add('in', { datatype: 'string', required: true, handle: function(ip) { chai.expect(ip).to.be.an('object'); chai.expect(ip.type).to.equal(expectedEvents.shift()); if (ip.type === 'data') { chai.expect(ip.data).to.equal('some-data'); } if (ip.type === 'closeBracket') { return done(); } } }); ps.inPorts["in"].attach(s); chai.expect(ps.inPorts["in"].listAttached()).to.eql([0]); s.beginGroup('foo'); s.send('some-data'); s.endGroup(); return s.disconnect(); }); return it('should translate IP objects to legacy events', function(done) { var expectedEvents, ps, s; s = new noflo.internalSocket.InternalSocket; expectedEvents = ['connect', 'data', 'disconnect']; ps = { outPorts: new noflo.OutPorts({ out: new noflo.OutPort }), inPorts: new noflo.InPorts }; ps.inPorts.add('in', { datatype: 'string', required: true }, function(event, payload) { chai.expect(event).to.equal(expectedEvents.shift()); if (event !== 'data') { return; } chai.expect(payload).to.equal('some-data'); return done(); }); ps.inPorts["in"].attach(s); chai.expect(ps.inPorts["in"].listAttached()).to.eql([0]); return s.post(new noflo.IP('data', 'some-data')); }); }); });