1 | mockery = require 'mockery'
|
2 | expect = require 'expect.js'
|
3 |
|
4 | describe 'worker', ->
|
5 |
|
6 | reflex = ((cb) -> cb()).toString()
|
7 |
|
8 | slow_reflex = ((cb) ->
|
9 | setTimeout cb, 10
|
10 | ).toString()
|
11 |
|
12 | cluster_mock =
|
13 | isMaster: false
|
14 | isWorker: true
|
15 |
|
16 | handlers = {}
|
17 |
|
18 | process_mock = (send_handler) ->
|
19 | on: (ev, handler) ->
|
20 | handlers[ev] = handler
|
21 | send: send_handler
|
22 |
|
23 | worker = null
|
24 |
|
25 | before ->
|
26 | mockery.enable useCleanCache: true, warnOnReplace: false
|
27 | mockery.registerAllowable '../src/worker.coffee', true
|
28 | mockery.registerMock 'cluster', cluster_mock
|
29 | worker = require '../src/worker.coffee'
|
30 |
|
31 | it 'should fail unless cluster.isWorker', ->
|
32 | cluster_mock.isWorker = false
|
33 | expect(-> worker()).to.throwError()
|
34 | cluster_mock.isWorker = true
|
35 |
|
36 | it 'should run the work function', (done) ->
|
37 | worker(process_mock -> undefined)
|
38 |
|
39 | run_tester = (what) ->
|
40 | expect(what).to.eql 'hello world'
|
41 | done()
|
42 |
|
43 | handlers['message'] {
|
44 | id: 'blah'
|
45 | data: [run_tester]
|
46 | work: ((rt, cb) ->
|
47 | rt 'hello world'
|
48 | cb()
|
49 | ).toString()
|
50 | }
|
51 |
|
52 | it 'should call back with the task id', (done) ->
|
53 | id = 'fizzbuzzwhatup'
|
54 |
|
55 | worker(process_mock (msg) ->
|
56 | if msg.type is 'result'
|
57 | expect(msg.contents.id).to.eql id
|
58 | done()
|
59 | )
|
60 |
|
61 | handlers['message'] {
|
62 | id: id
|
63 | data: []
|
64 | work: reflex
|
65 | }
|
66 |
|
67 | it 'should notify the master when its function queue is empty', (done) ->
|
68 | result_count = 0
|
69 | id = 'blah'
|
70 |
|
71 | worker(process_mock (msg) ->
|
72 | if msg.type is 'empty'
|
73 | expect(result_count).to.eql 4
|
74 | done()
|
75 |
|
76 | if msg.type is 'result'
|
77 | result_count++
|
78 | )
|
79 |
|
80 | for i in [1..4]
|
81 | handlers['message'] {
|
82 | id: id
|
83 | data: []
|
84 | work: slow_reflex
|
85 | }
|
86 |
|
87 | it 'should pass data in/out of work function correctly', (done) ->
|
88 | id = 'foo'
|
89 |
|
90 | data = ['foo', 'bar', {quux: {a: 1, b: null, c: false, d: true}}]
|
91 |
|
92 | worker(process_mock (msg) ->
|
93 | if msg.type is 'result'
|
94 | expect(msg.contents.callback_params).to.eql [null, data.reverse()]
|
95 | done()
|
96 | )
|
97 |
|
98 | handlers['message'] {
|
99 | id: id
|
100 | data: data
|
101 | work: ((data..., cb) ->
|
102 | cb null, data.reverse()
|
103 | ).toString()
|
104 | }
|
105 |
|
106 | it 'should pass work function errors to master', (done) ->
|
107 | id = 'foo'
|
108 |
|
109 | data = ['foo', 'bar', {quux: {a: 1, b: null, c: false, d: true}}]
|
110 |
|
111 | worker(process_mock (msg) ->
|
112 | if msg.type is 'exception'
|
113 | expect(msg.contents.is_error).to.be true
|
114 | expect(msg.contents.error.type).to.eql 'Error'
|
115 | expect(msg.contents.error.parameters.name).to.eql 'Error'
|
116 | expect(msg.contents.error.parameters.message).to.eql 'this is a great error'
|
117 | done()
|
118 | )
|
119 |
|
120 | handlers['message'] {
|
121 | id: id
|
122 | data: data
|
123 | work: ((data..., cb) ->
|
124 | throw new Error 'this is a great error'
|
125 | ).toString()
|
126 | }
|
127 |
|
128 | it 'should pass work function non-error exceptions to master', (done) ->
|
129 | id = 'foo'
|
130 |
|
131 | data = ['foo', 'bar', {quux: {a: 1, b: null, c: false, d: true}}]
|
132 |
|
133 | worker(process_mock (msg) ->
|
134 | if msg.type is 'exception'
|
135 | expect(msg.contents.is_error).to.be false
|
136 | expect(msg.contents.exception).to.eql 'some stupid non-error'
|
137 | done()
|
138 | )
|
139 |
|
140 | handlers['message'] {
|
141 | id: id
|
142 | data: data
|
143 | work: ((data..., cb) ->
|
144 |
|
145 | throw (do -> 'some stupid non-error')
|
146 | ).toString()
|
147 | }
|
148 |
|
149 | after ->
|
150 | mockery.disable() |
\ | No newline at end of file |