UNPKG

30.2 kBtext/coffeescriptView Raw
1if typeof process isnt 'undefined' and process.execPath and process.execPath.indexOf('node') isnt -1
2 chai = require 'chai' unless chai
3 parser = require '../lib/index'
4 parser.validateSchema = true # validate schema for every test on node.js. Don't have tv4 in the browser build
5else
6 parser = require 'fbp'
7
8describe 'FBP parser', ->
9 it 'should provide a parse method', ->
10 chai.expect(parser.parse).to.be.a 'function'
11 describe 'with simple FBP string', ->
12 fbpData = "'somefile' -> SOURCE Read(ReadFile)"
13 graphData = null
14 it 'should produce a graph JSON object', ->
15 graphData = parser.parse fbpData, caseSensitive:true
16 chai.expect(graphData).to.be.an 'object'
17 chai.expect(graphData.caseSensitive).to.equal true
18 describe 'the generated graph', ->
19 it 'should contain one node', ->
20 chai.expect(graphData.processes).to.eql
21 Read:
22 component: 'ReadFile'
23 it 'should contain an IIP', ->
24 chai.expect(graphData.connections).to.be.an 'array'
25 chai.expect(graphData.connections.length).to.equal 1
26 chai.expect(graphData.connections[0]).to.eql
27 data: 'somefile'
28 tgt:
29 process: 'Read'
30 port: 'SOURCE'
31
32 describe 'with three-statement FBP string', ->
33 fbpData = """
34 'somefile.txt' -> SOURCE Read(ReadFile) OUT -> IN Display(Output)
35 """
36 graphData = null
37 it 'should produce a graph JSON object', ->
38 graphData = parser.parse fbpData, caseSensitive:true
39 chai.expect(graphData).to.be.an 'object'
40 describe 'the generated graph', ->
41 it 'should contain two nodes', ->
42 chai.expect(graphData.processes).to.eql
43 Read:
44 component: 'ReadFile'
45 Display:
46 component: 'Output'
47 it 'should contain an edge and an IIP', ->
48 chai.expect(graphData.connections).to.be.an 'array'
49 chai.expect(graphData.connections.length).to.equal 2
50 it 'should contain no exports', ->
51 chai.expect(graphData.exports).to.be.an 'undefined'
52 chai.expect(graphData.inports).to.eql {}
53 chai.expect(graphData.outports).to.eql {}
54
55 describe 'with three-statement FBP string without instantiation', ->
56 it 'should not fail', ->
57 fbpData = """
58 'db' -> KEY SetDb(Set)
59 SplitDb(Split) OUT -> VALUE SetDb CONTEXT -> IN MergeContext(Merge)
60 """
61 graphData = parser.parse fbpData, caseSensitive:true
62 chai.expect(graphData.connections).to.have.length 3
63
64 describe 'with no spaces around arrows', ->
65 it 'should not fail', ->
66 fbpData = """
67 a(A)->b(B) ->c(C)-> d(D)->e(E)
68 """
69 graphData = parser.parse fbpData, caseSensitive:true
70 chai.expect(graphData.connections).to.have.length 4
71
72 describe 'with anonymous nodes in an FBP string', ->
73 fbpData = """
74 (A) OUT -> IN (B) OUT -> IN (B)
75 """
76 graphData = null
77 it 'should produce a graph JSON object', ->
78 graphData = parser.parse fbpData, caseSensitive:true
79 chai.expect(graphData).to.be.an 'object'
80 describe 'the generated graph', ->
81 it 'should contain three nodes with unique names', ->
82 chai.expect(graphData.processes).to.eql
83 _A_1:
84 component: 'A'
85 _B_1:
86 component: 'B'
87 _B_2:
88 component: 'B'
89 it 'should contain two edges', ->
90 chai.expect(graphData.connections).to.eql [
91 { src: { process: '_A_1', port: 'OUT' }, tgt: { process: '_B_1', port: 'IN' } }
92 { src: { process: '_B_1', port: 'OUT' }, tgt: { process: '_B_2', port: 'IN' } }
93 ]
94 it 'should contain no exports', ->
95 chai.expect(graphData.exports).to.be.an 'undefined'
96 chai.expect(graphData.inports).to.eql {}
97 chai.expect(graphData.outports).to.eql {}
98
99 describe 'with default inport', ->
100 fbpData = """
101 (A) OUT -> (B)
102 """
103 graphData = null
104 it 'should produce a graph JSON object', ->
105 graphData = parser.parse fbpData, caseSensitive:true
106 chai.expect(graphData).to.be.an 'object'
107 describe 'the generated graph', ->
108 it 'should default port name to "IN"', ->
109 chai.expect(graphData.connections).to.eql [
110 { src: { process: '_A_1', port: 'OUT' }, tgt: { process: '_B_1', port: 'IN' } }
111 ]
112 it 'should contain no exports', ->
113 chai.expect(graphData.exports).to.be.an 'undefined'
114 chai.expect(graphData.inports).to.eql {}
115 chai.expect(graphData.outports).to.eql {}
116
117 describe 'with default outport', ->
118 fbpData = """
119 (A) -> IN (B)
120 """
121 graphData = null
122 it 'should produce a graph JSON object', ->
123 graphData = parser.parse fbpData, caseSensitive:true
124 chai.expect(graphData).to.be.an 'object'
125 describe 'the generated graph', ->
126 it 'should default port name to "OUT"', ->
127 chai.expect(graphData.connections).to.eql [
128 { src: { process: '_A_1', port: 'OUT' }, tgt: { process: '_B_1', port: 'IN' } }
129 ]
130 it 'should contain no exports', ->
131 chai.expect(graphData.exports).to.be.an 'undefined'
132 chai.expect(graphData.inports).to.eql {}
133 chai.expect(graphData.outports).to.eql {}
134
135 describe 'with default ports', ->
136 fbpData = """
137 (A) -> (B) -> (C)
138 """
139 graphData = null
140 it 'should produce a graph JSON object', ->
141 graphData = parser.parse fbpData, caseSensitive:true
142 chai.expect(graphData).to.be.an 'object'
143 describe 'the generated graph', ->
144 it 'should correctly use default ports', ->
145 chai.expect(graphData.connections).to.eql [
146 { src: { process: '_A_1', port: 'OUT' }, tgt: { process: '_B_1', port: 'IN' } }
147 { src: { process: '_B_1', port: 'OUT' }, tgt: { process: '_C_1', port: 'IN' } }
148 ]
149 it 'should contain no exports', ->
150 chai.expect(graphData.exports).to.be.an 'undefined'
151 chai.expect(graphData.inports).to.eql {}
152 chai.expect(graphData.outports).to.eql {}
153
154 describe 'with a more complex FBP string', ->
155 fbpData = """
156 '8003' -> LISTEN WebServer(HTTP/Server) REQUEST -> IN Profiler(HTTP/Profiler) OUT -> IN Authentication(HTTP/BasicAuth)
157 Authentication() OUT -> IN GreetUser(HelloController) OUT[0] -> IN[0] WriteResponse(HTTP/WriteResponse) OUT -> IN Send(HTTP/SendResponse)
158 'hello.jade' -> SOURCE ReadTemplate(ReadFile) OUT -> TEMPLATE Render(Template)
159 GreetUser() DATA -> OPTIONS Render() OUT -> STRING WriteResponse()
160 """
161 graphData = null
162 it 'should produce a graph JSON object', ->
163 graphData = parser.parse fbpData, caseSensitive:true
164 chai.expect(graphData).to.be.an 'object'
165 describe 'the generated graph', ->
166 it 'should contain eight nodes', ->
167 chai.expect(graphData.processes).to.be.an 'object'
168 chai.expect(graphData.processes).to.have.keys [
169 'WebServer'
170 'Profiler'
171 'Authentication'
172 'GreetUser'
173 'WriteResponse'
174 'Send'
175 'ReadTemplate'
176 'Render'
177 ]
178 it 'should contain ten edges and IIPs', ->
179 chai.expect(graphData.connections).to.be.an 'array'
180 chai.expect(graphData.connections.length).to.equal 10
181 it 'should contain no exports', ->
182 chai.expect(graphData.exports).to.be.an 'undefined'
183
184 describe 'with multiple arrayport connections on same line', ->
185 fbpData = """
186 'test 1' -> IN[0] Mux(mux) OUT[0] -> IN Display(console)
187 'test 2' -> IN[1] Mux OUT[1] -> IN Display
188 """
189 graphData = null
190 it 'should produce a graph JSON object', ->
191 graphData = parser.parse fbpData, caseSensitive: true
192 chai.expect(graphData).to.be.an 'object'
193 chai.expect(graphData.processes).to.be.an 'object'
194 chai.expect(graphData.connections).to.be.an 'array'
195 describe 'the generated graph', ->
196 it 'should contain two nodes', ->
197 chai.expect(graphData.processes).to.have.keys [
198 'Mux'
199 'Display'
200 ]
201 it 'should contain two IIPs', ->
202 iips = graphData.connections.filter (conn) -> conn.data
203 chai.expect(iips.length).to.equal 2
204 chai.expect(iips[0].data).to.eql 'test 1'
205 chai.expect(iips[0].tgt).to.eql
206 process: 'Mux'
207 port: 'IN'
208 index: 0
209 chai.expect(iips[1].data).to.eql 'test 2'
210 chai.expect(iips[1].tgt).to.eql
211 process: 'Mux'
212 port: 'IN'
213 index: 1
214 it 'should contain two regular connections', ->
215 connections = graphData.connections.filter (conn) -> conn.src
216 chai.expect(connections.length).to.equal 2
217 chai.expect(connections[0].src).to.eql
218 process: 'Mux'
219 port: 'OUT'
220 index: 0
221 chai.expect(connections[0].tgt).to.eql
222 process: 'Display'
223 port: 'IN'
224 chai.expect(connections[1].src).to.eql
225 process: 'Mux'
226 port: 'OUT'
227 index: 1
228 chai.expect(connections[1].tgt).to.eql
229 process: 'Display'
230 port: 'IN'
231 it 'should contain no exports', ->
232 chai.expect(graphData.exports).to.be.an 'undefined'
233
234 describe 'with FBP string containing an IIP with whitespace', ->
235 fbpData = """
236 'foo Bar BAZ' -> IN Display(Output)
237 """
238 graphData = null
239 it 'should produce a graph JSON object', ->
240 graphData = parser.parse fbpData, caseSensitive:true
241 chai.expect(graphData).to.be.an 'object'
242 describe 'the generated graph', ->
243 it 'should contain a node', ->
244 chai.expect(graphData.processes).to.eql
245 Display:
246 component: 'Output'
247 it 'should contain an IIP', ->
248 chai.expect(graphData.connections).to.be.an 'array'
249 chai.expect(graphData.connections.length).to.equal 1
250 chai.expect(graphData.connections[0].data).to.equal 'foo Bar BAZ'
251 it 'should contain no exports', ->
252 chai.expect(graphData.exports).to.be.an 'undefined'
253 chai.expect(graphData.inports).to.eql {}
254 chai.expect(graphData.outports).to.eql {}
255
256 describe 'with FBP string containing an empty IIP string', ->
257 fbpData = """
258 '' -> IN Display(Output)
259 """
260 graphData = null
261 it 'should produce a graph JSON object', ->
262 graphData = parser.parse fbpData, caseSensitive:true
263 chai.expect(graphData).to.be.an 'object'
264 describe 'the generated graph', ->
265 it 'should contain a node', ->
266 chai.expect(graphData.processes).to.eql
267 Display:
268 component: 'Output'
269 it 'should contain an IIP', ->
270 chai.expect(graphData.connections).to.be.an 'array'
271 chai.expect(graphData.connections.length).to.equal 1
272 chai.expect(graphData.connections[0].data).to.equal ''
273 it 'should contain no exports', ->
274 chai.expect(graphData.exports).to.be.an 'undefined'
275 chai.expect(graphData.inports).to.eql {}
276 chai.expect(graphData.outports).to.eql {}
277
278 describe 'with FBP string containing a JSON IIP string', ->
279 fbpData = """
280 { "string": "s", "number": 123, "array": [1,2,3], "object": {}} -> IN Display(Output)
281 """
282 graphData = null
283 it 'should produce a graph JSON object', ->
284 graphData = parser.parse fbpData, caseSensitive:true
285 chai.expect(graphData).to.be.an 'object'
286 describe 'the generated graph', ->
287 it 'should contain a node', ->
288 chai.expect(graphData.processes).to.eql
289 Display:
290 component: 'Output'
291 it 'should contain an IIP', ->
292 chai.expect(graphData.connections).to.be.an 'array'
293 chai.expect(graphData.connections.length).to.equal 1
294 chai.expect(graphData.connections[0].data).to.deep.equal { "string": "s", "number": 123, "array": [1,2,3], "object": {}}
295 it 'should contain no exports', ->
296 chai.expect(graphData.exports).to.be.an 'undefined'
297 chai.expect(graphData.inports).to.eql {}
298 chai.expect(graphData.outports).to.eql {}
299
300 describe 'with FBP string containing comments', ->
301 fbpData = """
302 # Do stuff
303 'foo bar' -> IN Display(Output) # Here we show the string
304 """
305 graphData = null
306 it 'should produce a graph JSON object', ->
307 graphData = parser.parse fbpData, caseSensitive:true
308 chai.expect(graphData).to.be.an 'object'
309 describe 'the generated graph', ->
310 it 'should contain a node', ->
311 chai.expect(graphData.processes).to.eql
312 Display:
313 component: 'Output'
314 it 'should contain an IIP', ->
315 chai.expect(graphData.connections).to.be.an 'array'
316 chai.expect(graphData.connections.length).to.equal 1
317 chai.expect(graphData.connections[0].data).to.equal 'foo bar'
318 it 'should contain no exports', ->
319 chai.expect(graphData.exports).to.be.an 'undefined'
320 chai.expect(graphData.inports).to.eql {}
321 chai.expect(graphData.outports).to.eql {}
322
323 describe 'with FBP string containing URL as IIP', ->
324 fbpData = """
325 'http://localhost:5984/default' -> URL Conn(couchdb/OpenDatabase)
326 """
327 graphData = null
328 it 'should produce a graph JSON object', ->
329 graphData = parser.parse fbpData, caseSensitive:true
330 chai.expect(graphData).to.be.an 'object'
331 describe 'the generated graph', ->
332 it 'should contain a node', ->
333 chai.expect(graphData.processes).to.eql
334 Conn:
335 component: 'couchdb/OpenDatabase'
336 it 'should contain an IIP', ->
337 chai.expect(graphData.connections).to.be.an 'array'
338 chai.expect(graphData.connections.length).to.equal 1
339 chai.expect(graphData.connections[0].data).to.equal 'http://localhost:5984/default'
340 it 'should contain no exports', ->
341 chai.expect(graphData.exports).to.be.an 'undefined'
342 chai.expect(graphData.inports).to.eql {}
343 chai.expect(graphData.outports).to.eql {}
344
345 describe 'with FBP string containing RegExp as IIP', ->
346 fbpData = """
347 '_id=(\d+\.\d+\.\d*)=http://iks-project.eu/%deliverable/$1' -> REGEXP MapDeliverableUri(MapPropertyValue)
348 'path=/_(?!(includes|layouts)' -> REGEXP MapDeliverableUri(MapPropertyValue)
349 '@type=deliverable' -> PROPERTY SetDeliverableProps(SetProperty)
350 '#foo' -> SELECTOR Get(dom/GetElement)
351 'Hi, {{ name }}' -> TEMPLATE Get
352 """
353 graphData = null
354 it 'should produce a graph JSON object', ->
355 graphData = parser.parse fbpData, caseSensitive:true
356 chai.expect(graphData).to.be.an 'object'
357 describe 'the generated graph', ->
358 it 'should contain two nodes', ->
359 chai.expect(graphData.processes).to.eql
360 MapDeliverableUri:
361 component: 'MapPropertyValue'
362 SetDeliverableProps:
363 component: 'SetProperty'
364 Get:
365 component: 'dom/GetElement'
366 it 'should contain IIPs', ->
367 chai.expect(graphData.connections).to.be.an 'array'
368 chai.expect(graphData.connections.length).to.equal 5
369 chai.expect(graphData.connections[0].data).to.be.a 'string'
370 it 'should contain no exports', ->
371 chai.expect(graphData.exports).to.be.an 'undefined'
372 chai.expect(graphData.inports).to.eql {}
373 chai.expect(graphData.outports).to.eql {}
374
375 describe 'with FBP string with inports and outports', ->
376 fbpData = """
377 INPORT=Read.IN:FILENAME
378 INPORT=Display.OPTIONS:OPTIONS
379 OUTPORT=Display.OUT:OUT
380 Read(ReadFile) OUT -> IN Display(Output)
381 """
382 graphData = null
383 it 'should produce a graph JSON object', ->
384 graphData = parser.parse fbpData, caseSensitive:true
385 chai.expect(graphData).to.be.an 'object'
386 describe 'the generated graph', ->
387 it 'should contain two nodes', ->
388 chai.expect(graphData.processes).to.eql
389 Read:
390 component: 'ReadFile'
391 Display:
392 component: 'Output'
393 it 'should contain no legacy exports', ->
394 chai.expect(graphData.exports).to.be.an 'undefined'
395 it 'should contain a single connection', ->
396 chai.expect(graphData.connections).to.be.an 'array'
397 chai.expect(graphData.connections.length).to.equal 1
398 chai.expect(graphData.connections[0]).to.eql
399 src:
400 process: 'Read'
401 port: 'OUT'
402 tgt:
403 process: 'Display'
404 port: 'IN'
405 it 'should contain two inports', ->
406 chai.expect(graphData.inports).to.be.an 'object'
407 chai.expect(graphData.inports.FILENAME).to.eql
408 process: 'Read'
409 port: 'IN'
410 chai.expect(graphData.inports.OPTIONS).to.eql
411 process: 'Display'
412 port: 'OPTIONS'
413 it 'should contain an outport', ->
414 chai.expect(graphData.outports).to.be.an 'object'
415 chai.expect(graphData.outports.OUT).to.eql
416 process: 'Display'
417 port: 'OUT'
418
419 describe 'with FBP string with legacy EXPORTs', ->
420 fbpData = """
421 EXPORT=Read.IN:FILENAME
422 Read(ReadFile) OUT -> IN Display(Output)
423 """
424 graphData = null
425 it 'should fail', ->
426 chai.expect(->
427 graphData = parser.parse fbpData, caseSensitive:true
428 ).to.throw Error
429
430 describe 'with FBP string containing node metadata', ->
431 fbpData = """
432 Read(ReadFile) OUT -> IN Display(Output:foo=bar)
433
434 # And we drop the rest
435 Display OUT -> IN Drop(Drop:foo=baz,baz=/foo/bar)
436 """
437 graphData = null
438 it 'should produce a graph JSON object', ->
439 graphData = parser.parse fbpData, caseSensitive:true
440 chai.expect(graphData).to.be.an 'object'
441 it 'should contain nodes with named routes', ->
442 chai.expect(graphData.processes).to.eql
443 Read:
444 component: 'ReadFile'
445 Display:
446 component: 'Output'
447 metadata:
448 foo: 'bar'
449 Drop:
450 component: 'Drop'
451 metadata:
452 foo: 'baz'
453 baz: '/foo/bar'
454 it 'should contain two edges', ->
455 chai.expect(graphData.connections).to.be.an 'array'
456 chai.expect(graphData.connections.length).to.equal 2
457 it 'should contain no exports', ->
458 chai.expect(graphData.exports).to.be.an 'undefined'
459 chai.expect(graphData.inports).to.eql {}
460 chai.expect(graphData.outports).to.eql {}
461
462 describe 'with FBP string containing node x/y metadata', ->
463 fbpData = """
464 Read(ReadFile) OUT -> IN Display(Output:foo=bar,x=17,y=42)
465 """
466 graphData = null
467 it 'should produce a graph JSON object', ->
468 graphData = parser.parse fbpData, caseSensitive:true
469 chai.expect(graphData).to.be.an 'object'
470 it 'should contain nodes with numerical x/y metadata', ->
471 chai.expect(graphData.processes).to.eql
472 Read:
473 component: 'ReadFile'
474 Display:
475 component: 'Output'
476 metadata:
477 foo: 'bar'
478 x: 17
479 y: 42
480
481 describe 'with an invalid FBP string', ->
482 fbpData = """
483 'foo' --> Display(Output)
484 """
485 it 'should fail with an Exception', ->
486 chai.expect(-> parser.parse fbpData, caseSensitive:true).to.throw Error
487
488 describe 'with a component that contains dashes in name', ->
489 fbpData = "'somefile' -> SOURCE Read(my-cool-component/ReadFile)"
490 graphData = null
491 it 'should produce a graph JSON object', ->
492 graphData = parser.parse fbpData, caseSensitive:true
493 chai.expect(graphData).to.be.an 'object'
494 describe 'the generated graph', ->
495 it 'should contain one node', ->
496 chai.expect(graphData.processes).to.eql
497 Read:
498 component: 'my-cool-component/ReadFile'
499 it 'should contain an IIP', ->
500 chai.expect(graphData.connections).to.be.an 'array'
501 chai.expect(graphData.connections.length).to.equal 1
502
503 describe 'with commas to separate statements', ->
504 fbpData = "'Hello' -> IN Foo(Component), 'World' -> IN Bar(OtherComponent), Foo OUT -> DATA Bar"
505 graphData = null
506 it 'should produce a graph JSON object', ->
507 graphData = parser.parse fbpData, caseSensitive:true
508 chai.expect(graphData).to.be.an 'object'
509 describe 'the generated graph', ->
510 it 'should contain two nodes', ->
511 chai.expect(graphData.processes).to.eql
512 Foo:
513 component: 'Component'
514 Bar:
515 component: 'OtherComponent'
516 it 'should contain two IIPs and one edge', ->
517 chai.expect(graphData.connections).to.eql [
518 data: 'Hello'
519 tgt:
520 process: 'Foo'
521 port: 'IN'
522 ,
523 data: 'World'
524 tgt:
525 process: 'Bar'
526 port: 'IN'
527 ,
528 src:
529 process: 'Foo'
530 port: 'OUT'
531 tgt:
532 process: 'Bar'
533 port: 'DATA'
534
535 ]
536
537 describe 'with underscores and numbers in ports, nodes, and components', ->
538 fbpData = "'Hello 09' -> IN_2 Foo_Node_42(Component_15)"
539 graphData = null
540 it 'should produce a graph JSON object', ->
541 graphData = parser.parse fbpData, caseSensitive:true
542 chai.expect(graphData).to.be.an 'object'
543 describe 'the generated graph', ->
544 it 'should contain one node', ->
545 chai.expect(graphData.processes).to.eql
546 Foo_Node_42:
547 component: 'Component_15'
548 it 'should contain an IIP', ->
549 chai.expect(graphData.connections).to.be.an 'array'
550 chai.expect(graphData.connections.length).to.equal 1
551 chai.expect(graphData.connections[0]).to.eql
552 data: 'Hello 09'
553 tgt:
554 process: 'Foo_Node_42'
555 port: 'IN_2'
556
557 describe 'with dashes and numbers in nodes, and components', ->
558 fbpData = "'Hello 09' -> IN_2 Foo-Node-42(Component-15)"
559 graphData = null
560 it 'should produce a graph JSON object', ->
561 graphData = parser.parse fbpData, caseSensitive:true
562 chai.expect(graphData).to.be.an 'object'
563 describe 'the generated graph', ->
564 it 'should contain one node', ->
565 chai.expect(graphData.processes).to.eql
566 'Foo-Node-42':
567 component: 'Component-15'
568 it 'should contain an IIP', ->
569 chai.expect(graphData.connections).to.be.an 'array'
570 chai.expect(graphData.connections.length).to.equal 1
571 chai.expect(graphData.connections[0]).to.eql
572 data: 'Hello 09'
573 tgt:
574 process: 'Foo-Node-42'
575 port: 'IN_2'
576
577 describe 'with FBP string containing port indexes', ->
578 fbpData = """
579 Read(ReadFile) OUT[1] -> IN Display(Output:foo=bar)
580
581 # And we drop the rest
582 Display OUT -> IN[0] Drop(Drop:foo=baz,baz=/foo/bar)
583 """
584 graphData = null
585 it 'should produce a graph JSON object', ->
586 graphData = parser.parse fbpData, caseSensitive:true
587 chai.expect(graphData).to.be.an 'object'
588 it 'should contain nodes with named routes', ->
589 chai.expect(graphData.processes).to.eql
590 Read:
591 component: 'ReadFile'
592 Display:
593 component: 'Output'
594 metadata:
595 foo: 'bar'
596 Drop:
597 component: 'Drop'
598 metadata:
599 foo: 'baz'
600 baz: '/foo/bar'
601 it 'should contain two edges', ->
602 chai.expect(graphData.connections).to.be.an 'array'
603 chai.expect(graphData.connections).to.eql [
604 src:
605 process: 'Read'
606 port: 'OUT'
607 index: 1
608 tgt:
609 process: 'Display'
610 port: 'IN'
611 ,
612 src:
613 process: 'Display'
614 port: 'OUT'
615 tgt:
616 process: 'Drop'
617 port: 'IN'
618 index: 0
619 ]
620 it 'should contain no exports', ->
621 chai.expect(graphData.exports).to.be.an 'undefined'
622 chai.expect(graphData.inports).to.eql {}
623 chai.expect(graphData.outports).to.eql {}
624
625 describe 'with case-sensitive FBP string', ->
626 fbpData = "'Hello' -> in Foo(Component), 'World' -> inPut Bar(OtherComponent), Foo outPut -> data Bar"
627 graphData = null
628 it 'should produce a graph JSON object', ->
629 graphData = parser.parse fbpData, caseSensitive:true
630 chai.expect(graphData).to.be.an 'object'
631 describe 'the generated graph', ->
632 it 'should contain two nodes', ->
633 chai.expect(graphData.processes).to.eql
634 Foo:
635 component: 'Component'
636 Bar:
637 component: 'OtherComponent'
638 it 'should contain two IIPs and one edge', ->
639 chai.expect(graphData.connections).to.eql [
640 data: 'Hello'
641 tgt:
642 process: 'Foo'
643 port: 'in'
644 ,
645 data: 'World'
646 tgt:
647 process: 'Bar'
648 port: 'inPut'
649 ,
650 src:
651 process: 'Foo'
652 port: 'outPut'
653 tgt:
654 process: 'Bar'
655 port: 'data'
656
657 ]
658
659 describe 'should convert port names to lowercase by default', ->
660 fbpData = """
661 INPORT=Read.IN:FILENAME
662 INPORT=Display.OPTIONS:OPTIONS
663 OUTPORT=Display.OUT:OUT
664 Read(ReadFile) OUT -> IN Display(Output)
665
666 ReadIndexed(ReadFile) OUT[1] -> IN DisplayIndexed(Output:foo=bar)
667 DisplayIndexed OUT -> IN[0] Drop(Drop:foo=baz,baz=/foo/bar)
668 """
669 graphData = null
670
671 beforeEach ->
672 graphData = parser.parse fbpData
673
674 it 'should produce a graph JSON object', ->
675 chai.expect(graphData).to.be.an 'object'
676 chai.expect(graphData.caseSensitive).to.equal false
677
678 it 'should contain connections', ->
679 chai.expect(graphData.connections).to.be.an 'array'
680 chai.expect(graphData.connections.length).to.equal 3
681 chai.expect(graphData.connections).to.eql [
682 src:
683 process: 'Read'
684 port: 'out'
685 tgt:
686 process: 'Display'
687 port: 'in'
688 ,
689 src:
690 process: 'ReadIndexed'
691 port: 'out'
692 index: 1
693 tgt:
694 process: 'DisplayIndexed'
695 port: 'in'
696 ,
697 src:
698 process: 'DisplayIndexed'
699 port: 'out'
700 tgt:
701 process: 'Drop'
702 port: 'in'
703 index: 0
704 ]
705
706 it 'should contain two inports', ->
707 chai.expect(graphData.inports).to.be.an 'object'
708 chai.expect(graphData.inports.filename).to.eql
709 process: 'Read'
710 port: 'in'
711 chai.expect(graphData.inports.options).to.eql
712 process: 'Display'
713 port: 'options'
714
715 it 'should contain an outport', ->
716 chai.expect(graphData.outports).to.be.an 'object'
717 chai.expect(graphData.outports.out).to.eql
718 process: 'Display'
719 port: 'out'
720
721 describe 'with FBP string with source node that doesn\'t have a component defined', ->
722 fbpData = """
723 instanceMissingComponentName OUT -> (core/Output)
724 """
725 graphData = null
726 it 'should fail', ->
727 chai.expect(->
728 graphData = parser.parse fbpData, caseSensitive:true
729 ).to.throw Error, 'Edge to "_core_Output_1" port "IN" is connected to an undefined source node "instanceMissingComponentName"'
730 describe 'with FBP string with IIP sent to node that doesn\'t have a component defined', ->
731 fbpData = """
732 'localhost' -> IN instanceMissingComponentName
733 """
734 graphData = null
735 it 'should fail', ->
736 chai.expect(->
737 graphData = parser.parse fbpData, caseSensitive:true
738 ).to.throw Error, 'IIP containing "localhost" is connected to an undefined target node "instanceMissingComponentName"'
739 describe 'with FBP string with target node that doesn\'t have a component defined', ->
740 fbpData = """
741 a(A)->b(B) ->c(C)-> d(D)->e
742 """
743 graphData = null
744 it 'should fail', ->
745 chai.expect(->
746 graphData = parser.parse fbpData, caseSensitive:true
747 ).to.throw Error, 'Edge from "d" port "OUT" is connected to an undefined target node "e"'
748 describe 'with FBP string with exported inport pointing to non-existing node', ->
749 fbpData = """
750 INPORT=noexist.IN:broken
751 INPORT=exist.IN:works
752 exist(foo/Bar)
753 """
754 graphData = null
755 it 'should fail', ->
756 chai.expect(->
757 graphData = parser.parse fbpData, caseSensitive:true
758 ).to.throw Error, 'Inport "broken" is connected to an undefined target node "noexist"'
759 describe 'with FBP string with exported outport pointing to non-existing node', ->
760 fbpData = """
761 INPORT=exist.IN:works
762 OUTPORT=noexist.OUT:broken
763 exist(foo/Bar)
764 """
765 graphData = null
766 it 'should fail', ->
767 chai.expect(->
768 graphData = parser.parse fbpData, caseSensitive:true
769 ).to.throw Error, 'Outport "broken" is connected to an undefined source node "noexist"'
770 describe 'with FBP string containing a runtime annotation', ->
771 fbpData = """
772 # @runtime foo
773 'somefile' -> SOURCE Read(ReadFile)
774 """
775 graphData = null
776 it 'should produce a graph JSON object', ->
777 graphData = parser.parse fbpData, caseSensitive:true
778 chai.expect(graphData).to.be.an 'object'
779 chai.expect(graphData.caseSensitive).to.equal true
780 it 'should contain the runtime type property', ->
781 chai.expect(graphData.properties.environment.type).to.equal 'foo'
782 describe 'with FBP string containing a name annotation', ->
783 fbpData = """
784 # @name ReadSomefile
785 'somefile' -> SOURCE Read(ReadFile)
786 """
787 graphData = null
788 it 'should produce a graph JSON object', ->
789 graphData = parser.parse fbpData, caseSensitive:true
790 chai.expect(graphData).to.be.an 'object'
791 chai.expect(graphData.caseSensitive).to.equal true
792 it 'should contain the name', ->
793 chai.expect(graphData.properties.name).to.equal 'ReadSomefile'
794 describe 'with FBP string containing two annotations', ->
795 fbpData = """
796 # @runtime foo
797 # @name ReadSomefile
798 'somefile' -> SOURCE Read(ReadFile)
799 """
800 graphData = null
801 it 'should produce a graph JSON object', ->
802 graphData = parser.parse fbpData, caseSensitive:true
803 chai.expect(graphData).to.be.an 'object'
804 chai.expect(graphData.caseSensitive).to.equal true
805 it 'should contain the runtime type property', ->
806 chai.expect(graphData.properties.environment.type).to.equal 'foo'
807 it 'should contain the name', ->
808 chai.expect(graphData.properties.name).to.equal 'ReadSomefile'