Skip to content
Browse files

CollectTree component (a simpler CollectGroups)

  • Loading branch information...
1 parent 4a84585 commit aa26d0b6370a175acfe6408a5dd3a05ba3126d74 @bergie bergie committed Mar 9, 2014
Showing with 188 additions and 0 deletions.
  1. +2 −0 component.json
  2. +51 −0 components/CollectTree.coffee
  3. +1 −0 package.json
  4. +133 −0 spec/CollectTree.coffee
  5. +1 −0 spec/runner.html
View
2 component.json
@@ -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",
@@ -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",
View
51 components/CollectTree.coffee
@@ -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
View
1 package.json
@@ -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",
View
133 spec/CollectTree.coffee
@@ -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()
View
1 spec/runner.html
@@ -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) {

0 comments on commit aa26d0b

Please sign in to comment.
Something went wrong with that request. Please try again.