UNPKG

msgflo

Version:

Polyglot FBP runtime based on message queues

133 lines (116 loc) 4.66 kB
chai = require 'chai' EventEmitter = require('events').EventEmitter websocket = require 'websocket' fbp = require 'fbp' participants = require './fixtures/participants' Runtime = require('../src/runtime').Runtime class MockUi extends EventEmitter constructor: -> @connection = null @client = new websocket.client() @client.on 'connect', (connection) => @connection = connection @connection.on 'error', (error) => throw error @connection.on 'close', (error) => @emit 'disconnected' @connection.on 'message', (message) => @handleMessage message @emit 'connected', connection connect: (port) -> @client.connect "ws://localhost:#{port}/", "noflo" disconnect: -> @connection.close() if @connection @emit 'disconnected' send: (protocol, command, payload) -> msg = protocol: protocol command: command payload: payload || {} @sendMsg msg sendMsg: (msg) -> @connection.sendUTF JSON.stringify msg handleMessage: (message) -> if not message.type == 'utf8' throw new Error "Received non-UTF8 message: " + message d = JSON.parse message.utf8Data @emit 'message', d, d.protocol, d.command, d.payload describe 'FBP runtime protocol', () -> runtime = null ui = new MockUi options = broker: 'direct://broker111' port: 3333 host: 'localhost' before (done) -> runtime = new Runtime options runtime.start (err, url) -> chai.expect(err).to.be.a 'null' ui.once 'connected', () -> done() ui.connect options.port after (done) -> ui.once 'disconnected', () -> runtime.stop () -> runtime = null done() ui.disconnect() describe 'runtime info', -> info = null it 'should be returned on getruntime', (done) -> ui.send "runtime", "getruntime" ui.once 'message', (d, protocol, command, payload) -> info = payload chai.expect(info).to.be.an 'object' done() it 'type should be "msgflo"', -> chai.expect(info.type).to.equal "msgflo" it 'protocol version should be "0.4"', -> chai.expect(info.version).to.be.a "string" chai.expect(info.version).to.equal "0.4" describe 'capabilities"', -> it 'should be an array', -> chai.expect(info.capabilities).to.be.an "array" it 'should include "protocol:component"', -> chai.expect(info.capabilities).to.include "protocol:component" it 'should include "protocol:graph"', -> chai.expect(info.capabilities).to.include "protocol:graph" it 'should include "protocol:network"', -> chai.expect(info.capabilities).to.include "protocol:network" it 'should include "component:getsource"', -> chai.expect(info.capabilities).to.include "component:getsource" describe 'participant queues already connected', -> # TODO: move IIP sending into Participant class? sendGraphIIPs = (part, graph) -> processIsParticipant = (name) -> process = graph.processes[name] return name == part.definition.id processes = Object.keys(graph.processes).filter processIsParticipant iips = graph.connections.filter (c) -> return c.data? and c.tgt.process in processes for iip in iips part.send iip.tgt.port, iip.data it 'should show as connected edges', (done) -> graph = fbp.parse " 'world' -> NAME say(Hello) OUT -> DROP sink(DevNullSink) " source = participants.Hello options.broker, 'say' sink = participants.DevNullSink options.broker, 'sink' source.connectGraphEdges graph sink.connectGraphEdges graph sink.start (err) -> chai.expect(err).to.be.a 'null' source.start (err) -> chai.expect(err).to.be.a 'null' ui.send 'component', 'getsource', { name: 'default/main' } ui.on 'message', (d, protocol, command, payload) -> chai.expect(payload).to.be.an 'object' chai.expect(payload).to.include.keys ['name', 'code', 'language'] chai.expect(payload.language).to.equal 'json' graph = JSON.parse payload.code chai.expect(graph).to.include.keys ['connections', 'processes'] chai.expect(graph.connections).to.have.length 1 conn = graph.connections[0] chai.expect(conn.src.process).to.contain 'say' chai.expect(conn.src.port).to.equal 'out' chai.expect(conn.tgt.process).to.contain 'sink' chai.expect(conn.tgt.port).to.equal 'drop' done() # TODO: automatically represent multiple participants of same class as subgraph