Skip to content

Commit

Permalink
CollectTree component (a simpler CollectGroups)
Browse files Browse the repository at this point in the history
  • Loading branch information
bergie committed Mar 9, 2014
1 parent 4a84585 commit aa26d0b
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 0 deletions.
2 changes: 2 additions & 0 deletions component.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"components/SendByGroup.coffee",
"components/CollectGroups.coffee",
"components/CollectObject.coffee",
"components/CollectTree.coffee",
"components/FirstGroup.coffee",
"components/MapGroup.coffee",
"components/MergeGroups.coffee",
Expand All @@ -48,6 +49,7 @@
"SendByGroup": "components/SendByGroup.coffee",
"CollectGroups": "components/CollectGroups.coffee",
"CollectObject": "components/CollectObject.coffee",
"CollectTree": "components/CollectTree.coffee",
"FirstGroup": "components/FirstGroup.coffee",
"MapGroup": "components/MapGroup.coffee",
"MergeGroups": "components/MergeGroups.coffee",
Expand Down
51 changes: 51 additions & 0 deletions components/CollectTree.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
noflo = require 'noflo'

class CollectTree extends noflo.Component
description: 'Collect grouped packets into a simple tree structure
and send on disconnect'

constructor: ->
@data = null
@groups = []
@inPorts =
in: new noflo.Port 'all'
@outPorts =
out: new noflo.Port 'all'
error: new noflo.Port 'object'

@inPorts.in.on 'connect', =>
@data = {}
@inPorts.in.on 'begingroup', (group) =>
@groups.push group
@inPorts.in.on 'data', (data) =>
return unless @groups.length
d = @data
for g, idx in @groups
if idx < @groups.length - 1
d[g] = {} unless d[g]
d = d[g]
continue
unless d[g]
d[g] = data
return
unless Array.isArray d[g]
d[g] = [d[g]]
d[g].push data
@inPorts.in.on 'endgroup', =>
@groups.pop()
@inPorts.in.on 'disconnect', =>
@groups = []
if Object.keys(@data).length
@outPorts.out.send @data
@outPorts.out.disconnect()
@data = null
return
@data = null
err = new Error 'No tree information was collected'
if @outPorts.error.isAttached()
@outPorts.error.send err
@outPorts.error.disconnect()
return
throw err

exports.getComponent = -> new CollectTree
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"SendByGroup": "components/SendByGroup.coffee",
"CollectGroups": "./components/CollectGroups.coffee",
"CollectObject": "components/CollectObject.coffee",
"CollectTree": "components/CollectTree.coffee",
"FirstGroup": "./components/FirstGroup.coffee",
"MapGroup": "./components/MapGroup.coffee",
"MergeGroups": "./components/MergeGroups.coffee",
Expand Down
133 changes: 133 additions & 0 deletions spec/CollectTree.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
noflo = require 'noflo'

unless noflo.isBrowser()
chai = require 'chai' unless chai
CollectTree = require '../components/CollectTree.coffee'
else
CollectTree = require 'noflo-groups/components/CollectTree.js'

describe 'CollectTree component', ->
c = null
ins = null
out = null
err = null

beforeEach ->
c = CollectTree.getComponent()
c.inPorts.in.attach noflo.internalSocket.createSocket()
c.outPorts.out.attach noflo.internalSocket.createSocket()
c.outPorts.error.attach noflo.internalSocket.createSocket()
ins = c.inPorts.in
out = c.outPorts.out
err = c.outPorts.error

describe 'without any groups provided', ->
it 'should send an error and no data', (done) ->
out.on 'data', (data) ->
chai.expect(true).to.equal false

err.on 'data', (data) ->
chai.expect(data).to.be.an 'object'
chai.expect(c.data).to.equal null
chai.expect(c.groups.length).to.equal 0
done()

ins.send 'foo'
ins.send 'bar'
ins.disconnect()

describe 'with a single-level group', ->
it 'should send out an object matching the one packet', (done) ->
out.on 'data', (data) ->
chai.expect(data).to.eql
foo: 'bar'
out.on 'disconnect', ->
done()

ins.beginGroup 'foo'
ins.send 'bar'
ins.endGroup()
ins.disconnect()
it 'should send out an object matching the two packets', (done) ->
out.on 'data', (data) ->
chai.expect(data).to.eql
foo: ['bar', 'baz']
out.on 'disconnect', ->
done()

ins.beginGroup 'foo'
ins.send 'bar'
ins.send 'baz'
ins.endGroup()
ins.disconnect()
it 'should send out an object matching the two packets despite group level change', (done) ->
out.on 'data', (data) ->
chai.expect(data).to.eql
foo: ['bar', 'baz']
out.on 'disconnect', ->
done()

ins.beginGroup 'foo'
ins.send 'bar'
ins.endGroup()
ins.beginGroup 'foo'
ins.send 'baz'
ins.endGroup()
ins.disconnect()

describe 'with a multi-level group', ->
it 'should send out an object matching the one packet', (done) ->
out.on 'data', (data) ->
chai.expect(data).to.eql
baz:
foo: 'bar'
out.on 'disconnect', ->
done()

ins.beginGroup 'baz'
ins.beginGroup 'foo'
ins.send 'bar'
ins.endGroup()
ins.endGroup()
ins.disconnect()
it 'should send out an object matching the three packets', (done) ->
out.on 'data', (data) ->
chai.expect(data).to.eql
baz: [
foo: 'bar'
'ping'
]
hello: 'world'
out.on 'disconnect', ->
done()

ins.beginGroup 'baz'
ins.beginGroup 'foo'
ins.send 'bar'
ins.endGroup()
ins.send 'ping'
ins.endGroup()
ins.beginGroup 'hello'
ins.send 'world'
ins.endGroup()
ins.disconnect()
it 'should send out an object matching the two packets despite endgroups', (done) ->
out.on 'data', (data) ->
chai.expect(data).to.eql
baz:
foo: 'bar'
hello: 'world'
out.on 'disconnect', ->
done()

ins.beginGroup 'baz'
ins.beginGroup 'foo'
ins.send 'bar'
ins.endGroup()
ins.endGroup()
ins.beginGroup 'baz'
ins.beginGroup 'hello'
ins.send 'world'
ins.endGroup()
ins.endGroup()
ins.disconnect()
1 change: 1 addition & 0 deletions spec/runner.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<script src="../node_modules/mocha/mocha.js"></script>
<script>mocha.setup('bdd');</script>
<script src="./CollectGroups.js"></script>
<script src="./CollectTree.js"></script>
<script src="./ReadGroup.js"></script>
<script>
if (window.mochaPhantomJS) {
Expand Down

0 comments on commit aa26d0b

Please sign in to comment.