Skip to content

Commit

Permalink
Merge 7b9860b into d461a12
Browse files Browse the repository at this point in the history
  • Loading branch information
bergie committed Dec 3, 2017
2 parents d461a12 + 7b9860b commit 550c228
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 9 deletions.
138 changes: 138 additions & 0 deletions spec/ComponentLoader.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@ describe 'ComponentLoader with no external packages installed', ->
# Browser component registry can be synchronous
chai.expect(l.processing, 'should have started processing').to.equal true

describe 'calling listComponents twice simultaneously', ->
it 'should return the same results', (done) ->
loader = new noflo.ComponentLoader root
received = []
loader.listComponents (err, components) ->
return done err if err
received.push components
return unless received.length is 2
chai.expect(received[0]).to.equal received[1]
done()
loader.listComponents (err, components) ->
return done err if err
received.push components
return unless received.length is 2
chai.expect(received[0]).to.equal received[1]
done()

describe 'after listing components', ->
it 'should have the Graph component registered', ->
chai.expect(l.components.Graph).not.to.be.empty
Expand All @@ -103,6 +120,14 @@ describe 'ComponentLoader with no external packages installed', ->
it 'should be able to provide an icon for the Graph', ->
chai.expect(instance.getIcon()).to.be.a 'string'
chai.expect(instance.getIcon()).to.equal 'sitemap'
it 'should be able to load the component with non-ready ComponentLoader', (done) ->
loader = new noflo.ComponentLoader root
loader.load 'Graph', (err, inst) ->
return done err if err
chai.expect(inst).to.be.an 'object'
chai.expect(inst.componentName).to.equal 'Graph'
instance = inst
done()

describe 'loading a subgraph', ->
l = new noflo.ComponentLoader root
Expand Down Expand Up @@ -271,6 +296,18 @@ describe 'ComponentLoader with no external packages installed', ->
chai.expect(src.code).to.not.be.empty
chai.expect(src.language).to.equal 'json'
done()
it 'should be able to get the source for non-ready ComponentLoader', (done) ->
loader = new noflo.ComponentLoader root
loader.getSource 'Graph', (err, component) ->
return done err if err
chai.expect(component).to.be.an 'object'
chai.expect(component.code).to.be.a 'string'
chai.expect(component.code.indexOf('noflo.Component')).to.not.equal -1
chai.expect(component.code.indexOf('exports.getComponent')).to.not.equal -1
chai.expect(component.name).to.equal 'Graph'
chai.expect(component.library).to.equal ''
chai.expect(component.language).to.equal shippingLanguage
done()

describe 'writing sources', ->
describe 'with working code', ->
Expand Down Expand Up @@ -310,6 +347,10 @@ describe 'ComponentLoader with no external packages installed', ->
chai.expect(ip.data).to.equal 'ES5'
done()
ins.send 'ES5'
it 'should be able to set the source for non-ready ComponentLoader', (done) ->
@timeout 10000
loader = new noflo.ComponentLoader root
loader.setSource 'foo', 'RepeatData', workingSource, 'javascript', done
describe 'with ES6', ->
before ->
# PhantomJS doesn't work with ES6
Expand Down Expand Up @@ -534,3 +575,100 @@ describe 'ComponentLoader with a fixture project', ->
l.load 'componentloader/Missing', (err, instance) ->
chai.expect(err).to.be.an 'error'
done()

describe 'ComponentLoader with a fixture project and caching', ->
l = null
fixtureRoot = null
before ->
return @skip() if noflo.isBrowser()
fixtureRoot = path.resolve __dirname, 'fixtures/componentloader'
after (done) ->
return done() if noflo.isBrowser()
manifestPath = path.resolve fixtureRoot, 'fbp.json'
{ unlink } = require 'fs'
unlink manifestPath, done
it 'should be possible to pre-heat the cache file', (done) ->
@timeout 8000
{ exec } = require 'child_process'
exec "node #{path.resolve(__dirname, '../bin/noflo-cache-preheat')}",
cwd: fixtureRoot
, done
it 'should have populated a fbp-manifest file', (done) ->
manifestPath = path.resolve fixtureRoot, 'fbp.json'
{ stat } = require 'fs'
stat manifestPath, (err, stats) ->
return done err if err
chai.expect(stats.isFile()).to.equal true
done()
it 'should be possible to instantiate', ->
l = new noflo.ComponentLoader fixtureRoot,
cache: true
it 'should initially know of no components', ->
chai.expect(l.components).to.be.a 'null'
it 'should not initially be ready', ->
chai.expect(l.ready).to.be.false
it 'should be able to read a list of components', (done) ->
ready = false
l.once 'ready', ->
chai.expect(l.ready).to.equal true
ready = l.ready
l.listComponents (err, components) ->
return done err if err
chai.expect(l.processing).to.equal false
chai.expect(l.components).not.to.be.empty
chai.expect(components).to.equal l.components
chai.expect(l.ready).to.equal true
chai.expect(ready).to.equal true
done()
chai.expect(l.processing).to.equal true
it 'should be able to load a local component', (done) ->
l.load 'componentloader/Output', (err, instance) ->
chai.expect(err).to.be.a 'null'
chai.expect(instance.description).to.equal 'Output stuff'
chai.expect(instance.icon).to.equal 'cloud'
done()
it 'should be able to load a component from a dependency', (done) ->
l.load 'example/Forward', (err, instance) ->
chai.expect(err).to.be.a 'null'
chai.expect(instance.description).to.equal 'Forward stuff'
chai.expect(instance.icon).to.equal 'car'
done()
it 'should be able to load a dynamically registered component from a dependency', (done) ->
l.load 'example/Hello', (err, instance) ->
chai.expect(err).to.be.a 'null'
chai.expect(instance.description).to.equal 'Hello stuff'
chai.expect(instance.icon).to.equal 'bicycle'
done()
it 'should be able to load core Graph component', (done) ->
l.load 'Graph', (err, instance) ->
chai.expect(err).to.be.a 'null'
chai.expect(instance.icon).to.equal 'sitemap'
done()
it 'should fail loading a missing component', (done) ->
l.load 'componentloader/Missing', (err, instance) ->
chai.expect(err).to.be.an 'error'
done()
it 'should fail with missing manifest without discover option', (done) ->
l = new noflo.ComponentLoader fixtureRoot,
cache: true
discover: false
manifest: 'fbp2.json'
l.listComponents (err) ->
chai.expect(err).to.be.an 'error'
done()
it 'should be able to use a custom manifest file', (done) ->
@timeout 8000
manifestPath = path.resolve fixtureRoot, 'fbp2.json'
l = new noflo.ComponentLoader fixtureRoot,
cache: true
discover: true
manifest: 'fbp2.json'
l.listComponents (err, components) ->
return done err if err
chai.expect(l.processing).to.equal false
chai.expect(l.components).not.to.be.empty
done()
it 'should have saved the new manifest', (done) ->
manifestPath = path.resolve fixtureRoot, 'fbp2.json'
{ unlink } = require 'fs'
unlink manifestPath, done
73 changes: 73 additions & 0 deletions spec/Network.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,36 @@ describe 'NoFlo Network', ->
chai.expect(err).to.be.an 'error'
chai.expect(err.message).to.contain 'not found'
done()
describe 'with new edge', ->
before ->
n.loader.components.Split = Split
g.addNode 'A', 'Split'
g.addNode 'B', 'Split'
after ->
g.removeNode 'A'
g.removeNode 'B'
it 'should contain the edge', (done) ->
g.once 'addEdge', ->
setTimeout ->
chai.expect(n.connections).not.to.be.empty
chai.expect(n.connections[0].from).to.eql
process: n.getNode 'A'
port: 'out'
index: undefined
chai.expect(n.connections[0].to).to.eql
process: n.getNode 'B'
port: 'in'
index: undefined
done()
, 10
g.addEdge 'A', 'out', 'B', 'in'
it 'should not contain the edge after removal', (done) ->
g.once 'removeEdge', ->
setTimeout ->
chai.expect(n.connections).to.be.empty
done()
, 10
g.removeEdge 'A', 'out', 'B', 'in'

describe 'with a simple graph', ->
g = null
Expand Down Expand Up @@ -593,3 +623,46 @@ describe 'NoFlo Network', ->
chai.expect(err).to.be.an 'error'
chai.expect(err.message).to.contain 'No process defined for inbound node'
done()
describe 'baseDir setting', ->
it 'should set baseDir based on given graph', ->
g = new noflo.Graph
g.baseDir = root
n = new noflo.Network g
chai.expect(n.baseDir).to.equal root
it 'should fall back to CWD if graph has no baseDir', ->
return @skip() if noflo.isBrowser()
g = new noflo.Graph
n = new noflo.Network g
chai.expect(n.baseDir).to.equal process.cwd()
it 'should set the baseDir for the component loader', ->
g = new noflo.Graph
g.baseDir = root
n = new noflo.Network g
chai.expect(n.baseDir).to.equal root
chai.expect(n.loader.baseDir).to.equal root
describe 'debug setting', ->
n = null
g = null
before (done) ->
g = new noflo.Graph
g.baseDir = root
n = new noflo.Network g
n.loader.listComponents (err, components) ->
return done err if err
n.loader.components.Split = Split
g.addNode 'A', 'Split'
g.addNode 'B', 'Split'
g.addEdge 'A', 'out', 'B', 'in'
n.connect done
it 'should initially have debug enabled', ->
chai.expect(n.getDebug()).to.equal true
it 'should have propagated debug setting to connections', ->
chai.expect(n.connections[0].debug).to.equal n.getDebug()
it 'calling setDebug with same value should be no-op', ->
n.setDebug true
chai.expect(n.getDebug()).to.equal true
chai.expect(n.connections[0].debug).to.equal n.getDebug()
it 'disabling debug should get propagated to connections', ->
n.setDebug false
chai.expect(n.getDebug()).to.equal false
chai.expect(n.connections[0].debug).to.equal n.getDebug()
119 changes: 119 additions & 0 deletions spec/Subgraph.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,122 @@ describe 'NoFlo Graph component', ->
return done err if err
sendNext()
return
describe 'event forwarding on parent network', ->
describe 'with a single level subgraph', ->
graph = null
network = null
before (done) ->
graph = new noflo.Graph 'main'
graph.baseDir = root
network = new noflo.Network graph
network.loader.listComponents (err) ->
return done err if err
network.loader.components.Split = Split
network.loader.components.Merge = SubgraphMerge
sg = new noflo.Graph 'Subgraph'
sg.addNode 'A', 'Split'
sg.addNode 'B', 'Merge'
sg.addEdge 'A', 'out', 'B', 'in'
sg.addInport 'in', 'A', 'in'
sg.addOutport 'out', 'B', 'out'
network.loader.registerGraph 'foo', 'AB', sg, (err) ->
return done err if err
network.connect done
it 'should instantiate the subgraph when node is added', (done) ->
setTimeout ->
chai.expect(network.processes).not.to.be.empty
chai.expect(network.processes.Sub).to.exist
done()
, 10
graph.addNode 'Sub', 'foo/AB'
graph.addNode 'Split', 'Split'
graph.addEdge 'Sub', 'out', 'Split', 'in'
it 'should be possible to start the graph', (done) ->
network.start done
it 'should forward IP events', (done) ->
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'DATA -> IN Sub()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.be.undefined
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'A() OUT -> IN B()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.eql [
'Sub'
]
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'Sub() OUT -> IN Split()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.be.undefined
done()
graph.addInitial 'foo', 'Sub', 'in'
describe 'with two levels of subgraphs', ->
graph = null
network = null
before (done) ->
graph = new noflo.Graph 'main'
graph.baseDir = root
network = new noflo.Network graph
network.loader.listComponents (err) ->
return done err if err
network.loader.components.Split = Split
network.loader.components.Merge = SubgraphMerge
sg = new noflo.Graph 'Subgraph'
sg.addNode 'A', 'Split'
sg.addNode 'B', 'Merge'
sg.addEdge 'A', 'out', 'B', 'in'
sg.addInport 'in', 'A', 'in'
sg.addOutport 'out', 'B', 'out'
sg2 = new noflo.Graph 'Subgraph'
sg2.addNode 'A', 'foo/AB'
sg2.addNode 'B', 'Merge'
sg2.addEdge 'A', 'out', 'B', 'in'
sg2.addInport 'in', 'A', 'in'
sg2.addOutport 'out', 'B', 'out'
network.loader.registerGraph 'foo', 'AB', sg, (err) ->
return done err if err
network.loader.registerGraph 'foo', 'AB2', sg2, (err) ->
return done err if err
network.connect done
it 'should instantiate the subgraphs when node is added', (done) ->
setTimeout ->
chai.expect(network.processes).not.to.be.empty
chai.expect(network.processes.Sub).to.exist
done()
, 100
graph.addNode 'Sub', 'foo/AB2'
graph.addNode 'Split', 'Split'
graph.addEdge 'Sub', 'out', 'Split', 'in'
it 'should be possible to start the graph', (done) ->
network.start done
it 'should forward IP events', (done) ->
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'DATA -> IN Sub()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.be.undefined
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'A() OUT -> IN B()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.eql [
'Sub'
'A'
]
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'A() OUT -> IN B()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.eql [
'Sub'
]
network.once 'ip', (ip) ->
chai.expect(ip.id).to.equal 'Sub() OUT -> IN Split()'
chai.expect(ip.type).to.equal 'data'
chai.expect(ip.data).to.equal 'foo'
chai.expect(ip.subgraph).to.be.undefined
done()
graph.addInitial 'foo', 'Sub', 'in'
2 changes: 1 addition & 1 deletion src/lib/ComponentLoader.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ComponentLoader extends EventEmitter
@libraryIcons = {}
@processing = false
@ready = false
@setMaxListeners 0 if typeof @setMaxListeners is 'function'
@setMaxListeners 0

# Get the library prefix for a given module name. This
# is mostly used for generating valid names for namespaced
Expand Down
2 changes: 0 additions & 2 deletions src/lib/InPort.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ class InPort extends BasePort

if options.process
throw new Error 'InPort process callback is deprecated. Please use Process API'
delete options.process

if options.handle
throw new Error 'InPort handle callback is deprecated. Please use Process API'
delete options.handle

super options

Expand Down
Loading

0 comments on commit 550c228

Please sign in to comment.