UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

476 lines (460 loc) 15.5 kB
if typeof process isnt 'undefined' and process.execPath and process.execPath.match /node|iojs/ chai = require 'chai' unless chai subgraph = require '../src/components/Graph.coffee' graph = require '../src/lib/Graph.coffee' noflo = require '../src/lib/NoFlo.coffee' path = require 'path' root = path.resolve __dirname, '../' urlPrefix = './' else subgraph = require 'noflo/src/components/Graph.js' graph = require 'noflo/src/lib/Graph.js' noflo = require 'noflo/src/lib/NoFlo.js' root = 'noflo' urlPrefix = '/' describe 'Graph component', -> c = null g = null beforeEach -> c = subgraph.getComponent() g = noflo.internalSocket.createSocket() c.inPorts.graph.attach g class Split extends noflo.Component constructor: -> @inPorts = in: new noflo.Port @outPorts = out: new noflo.ArrayPort @inPorts.in.on 'connect', (data) => @outPorts.out.connect() @inPorts.in.on 'data', (data) => @outPorts.out.send data @inPorts.in.on 'disconnect', => @outPorts.out.disconnect() Split.getComponent = -> new Split SubgraphMerge = -> inst = new noflo.Component inst.inPorts.add 'in', (event, payload, instance) -> method = event method = 'send' if event is 'data' instance.outPorts[method] 'out', payload inst.outPorts.add 'out' inst describe 'initially', -> it 'should be ready', -> chai.expect(c.ready).to.be.true it 'should not contain a network', -> chai.expect(c.network).to.be.null it 'should not have a baseDir', -> chai.expect(c.baseDir).to.be.null it 'should only have the graph inport', -> chai.expect(c.inPorts.ports).to.have.keys ['graph'] chai.expect(c.outPorts.ports).to.be.empty describe 'with JSON graph definition', -> it 'should emit a ready event after network has been loaded', (done) -> @timeout 6000 c.baseDir = root c.once 'ready', -> chai.expect(c.network).not.to.be.null chai.expect(c.ready).to.be.true done() c.once 'network', (network) -> network.loader.components.Split = Split network.loader.registerComponent '', 'Merge', SubgraphMerge chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.start() g.send processes: Split: component: 'Split' Merge: component: 'Merge' it 'should expose available ports', (done) -> @timeout 6000 c.baseDir = root c.once 'ready', -> chai.expect(c.inPorts.ports).to.have.keys [ 'graph' ] chai.expect(c.outPorts.ports).to.be.empty done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send processes: Split: component: 'Split' Merge: component: 'Merge' connections: [ src: process: 'Merge' port: 'out' tgt: process: 'Split' port: 'in' ] it 'should update description from the graph', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> chai.expect(c.network).not.to.be.null chai.expect(c.ready).to.be.true chai.expect(c.description).to.equal 'Hello, World!' done() c.once 'network', (network) -> network.loader.components.Split = Split chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null chai.expect(c.description).to.equal 'Hello, World!' c.start() g.send properties: description: 'Hello, World!' processes: Split: component: 'Split' it 'should expose only exported ports when they exist', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> chai.expect(c.inPorts.ports).to.have.keys [ 'graph' ] chai.expect(c.outPorts.ports).to.have.keys [ 'out' ] done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send exports: [ public: 'out' private: 'split.out' ] processes: Split: component: 'Split' Merge: component: 'Merge' connections: [ src: process: 'Merge' port: 'out' tgt: process: 'Split' port: 'in' ] it 'should be able to run the graph', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> ins = noflo.internalSocket.createSocket() out = noflo.internalSocket.createSocket() c.inPorts['in'].attach ins c.outPorts['out'].attach out out.on 'data', (data) -> chai.expect(data).to.equal 'Foo' done() ins.send 'Foo' c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send exports: [ public: 'in' private: 'merge.in' , public: 'out' private: 'split.out' ] processes: Split: component: 'Split' Merge: component: 'Merge' connections: [ src: process: 'Merge' port: 'out' tgt: process: 'Split' port: 'in' ] describe 'with a Graph instance', -> gr = new graph.Graph 'Hello, world' gr.baseDir = root gr.addNode 'Split', 'Split' gr.addNode 'Merge', 'Merge' gr.addEdge 'Merge', 'out', 'Split', 'in' gr.addInport 'in', 'Merge', 'in' gr.addOutport 'out', 'Split', 'out' it 'should emit a ready event after network has been loaded', (done) -> @timeout 6000 c.once 'ready', -> chai.expect(c.network).not.to.be.null chai.expect(c.ready).to.be.true done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send gr chai.expect(c.ready).to.be.false it 'should expose available ports', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> chai.expect(c.inPorts.ports).to.have.keys [ 'graph' 'in' ] chai.expect(c.outPorts.ports).to.have.keys [ 'out' ] done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send gr it 'should be able to run the graph', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> ins = noflo.internalSocket.createSocket() out = noflo.internalSocket.createSocket() c.inPorts['in'].attach ins c.outPorts['out'].attach out out.on 'data', (data) -> chai.expect(data).to.equal 'Foo' done() ins.send 'Foo' c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send gr describe 'with a FBP file with INPORTs and OUTPORTs', -> file = "#{urlPrefix}spec/fixtures/subgraph.fbp" it 'should emit a ready event after network has been loaded', (done) -> @timeout 6000 c.once 'ready', -> chai.expect(c.network).not.to.be.null chai.expect(c.ready).to.be.true done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send file chai.expect(c.ready).to.be.false it 'should expose available ports', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> chai.expect(c.inPorts.ports).to.have.keys [ 'graph' 'in' ] chai.expect(c.outPorts.ports).to.have.keys [ 'out' ] done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send file it 'should be able to run the graph', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> ins = noflo.internalSocket.createSocket() out = noflo.internalSocket.createSocket() c.inPorts['in'].attach ins c.outPorts['out'].attach out out.on 'connect', -> ins.send 'Foo' out.on 'data', (data) -> chai.expect(data).to.equal 'Foo' ins.disconnect() out.on 'disconnect', -> done() ins.connect() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send file describe 'with a FBP file with legacy EXPORTS', -> file = "#{urlPrefix}spec/fixtures/subgraph_legacy.fbp" it 'should emit a ready event after network has been loaded', (done) -> @timeout 6000 c.once 'ready', -> chai.expect(c.network).not.to.be.null chai.expect(c.ready).to.be.true done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send file chai.expect(c.ready).to.be.false it 'should expose available ports', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> chai.expect(c.inPorts.ports).to.have.keys [ 'graph' 'in' ] chai.expect(c.outPorts.ports).to.have.keys [ 'out' ] done() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send file it 'should have disambiguated the exported ports', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> chai.expect(c.network.graph.exports).to.be.empty chai.expect(c.network.graph.inports).to.be.not.empty chai.expect(c.network.graph.inports.in).to.be.an 'object' chai.expect(c.network.graph.outports).to.be.not.empty chai.expect(c.network.graph.outports.out).to.be.an 'object' done() c.once 'network', -> c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge g.send file it 'should be able to run the graph', (done) -> c.baseDir = root @timeout 6000 c.once 'ready', -> ins = noflo.internalSocket.createSocket() out = noflo.internalSocket.createSocket() c.inPorts['in'].attach ins c.outPorts['out'].attach out out.on 'connect', -> ins.send 'Foo' out.on 'data', (data) -> chai.expect(data).to.equal 'Foo' ins.disconnect() out.on 'disconnect', -> done() ins.connect() c.once 'network', -> chai.expect(c.ready).to.be.false chai.expect(c.network).not.to.be.null c.network.loader.components.Split = Split c.network.loader.components.Merge = SubgraphMerge c.start() g.send file describe 'when a subgraph is used as a component', -> createSplit = -> c = new noflo.Component c.inPorts.add 'in', required: true datatype: 'string' default: 'default-value', (e, data) => switch e when 'connect' then c.outPorts.out.connect() when 'data' then c.outPorts.out.send(data) when 'disconnect' then c.outPorts.out.disconnect() c.outPorts.add 'out' c grDefaults = new noflo.Graph 'Child Graph Using Defaults' grDefaults.addNode 'SplitIn', 'Split' grDefaults.addNode 'SplitOut', 'Split' grDefaults.addInport 'in', 'SplitIn', 'in' grDefaults.addOutport 'out', 'SplitOut', 'out' grDefaults.addEdge 'SplitIn', 'out', 'SplitOut', 'in' grInitials = new noflo.Graph 'Child Graph Using Initials' grInitials.addNode 'SplitIn', 'Split' grInitials.addNode 'SplitOut', 'Split' grInitials.addInport 'in', 'SplitIn', 'in' grInitials.addOutport 'out', 'SplitOut', 'out' grInitials.addInitial 'initial-value', 'SplitIn', 'in' grInitials.addEdge 'SplitIn', 'out', 'SplitOut', 'in' it 'should send defaults', (done) -> @timeout 6000 cl = new noflo.ComponentLoader root cl.listComponents (err, components) -> return done err if err cl.components.Split = createSplit cl.components.Defaults = grDefaults cl.components.Initials = grInitials cl.load 'Defaults', (err, inst) -> o = noflo.internalSocket.createSocket() inst.outPorts.out.attach o o.once 'data', (data) -> chai.expect(data).to.equal 'default-value' done() inst.start() it 'should send initials', (done) -> @timeout 6000 cl = new noflo.ComponentLoader root cl.listComponents (err, components) -> return done err if err cl.components.Split = createSplit cl.components.Defaults = grDefaults cl.components.Initials = grInitials cl.load 'Initials', (err, inst) -> o = noflo.internalSocket.createSocket() inst.outPorts.out.attach o o.once 'data', (data) -> chai.expect(data).to.equal 'initial-value' done() inst.start() it 'should not send defaults when an inport is attached externally', (done) -> @timeout 6000 cl = new noflo.ComponentLoader root cl.listComponents (err, components) -> return done err if err cl.components.Split = createSplit cl.components.Defaults = grDefaults cl.components.Initials = grInitials cl.load 'Defaults', (err, inst) -> i = noflo.internalSocket.createSocket() o = noflo.internalSocket.createSocket() inst.inPorts.in.attach i inst.outPorts.out.attach o o.once 'data', (data) -> chai.expect(data).to.equal 'Foo' done() inst.start() i.send 'Foo'