batsir 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/.document +5 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +22 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +79 -0
  7. data/Rakefile +55 -0
  8. data/VERSION +1 -0
  9. data/batsir.gemspec +104 -0
  10. data/batsir.png +0 -0
  11. data/lib/batsir.rb +73 -0
  12. data/lib/batsir/acceptors/acceptor.rb +45 -0
  13. data/lib/batsir/acceptors/amqp_acceptor.rb +19 -0
  14. data/lib/batsir/amqp.rb +45 -0
  15. data/lib/batsir/chain.rb +33 -0
  16. data/lib/batsir/config.rb +34 -0
  17. data/lib/batsir/dsl/dsl_mappings.rb +96 -0
  18. data/lib/batsir/filter.rb +12 -0
  19. data/lib/batsir/filter_queue.rb +30 -0
  20. data/lib/batsir/logo.rb +36 -0
  21. data/lib/batsir/notifiers/amqp_notifier.rb +16 -0
  22. data/lib/batsir/notifiers/notifier.rb +39 -0
  23. data/lib/batsir/registry.rb +15 -0
  24. data/lib/batsir/stage.rb +94 -0
  25. data/lib/batsir/stage_worker.rb +86 -0
  26. data/lib/batsir/transformers/field_transformer.rb +40 -0
  27. data/lib/batsir/transformers/json_input_transformer.rb +9 -0
  28. data/lib/batsir/transformers/json_output_transformer.rb +9 -0
  29. data/lib/batsir/transformers/transformer.rb +15 -0
  30. data/spec/batsir/acceptors/acceptor_spec.rb +136 -0
  31. data/spec/batsir/acceptors/amqp_acceptor_spec.rb +169 -0
  32. data/spec/batsir/chain_spec.rb +31 -0
  33. data/spec/batsir/dsl/chain_mapping_spec.rb +117 -0
  34. data/spec/batsir/dsl/stage_mapping_spec.rb +435 -0
  35. data/spec/batsir/filter_queue_spec.rb +74 -0
  36. data/spec/batsir/filter_spec.rb +12 -0
  37. data/spec/batsir/notifiers/amqp_notifier_spec.rb +117 -0
  38. data/spec/batsir/notifiers/notifier_spec.rb +73 -0
  39. data/spec/batsir/stage_spec.rb +678 -0
  40. data/spec/batsir/stage_worker_spec.rb +128 -0
  41. data/spec/batsir/support/bunny_mocks.rb +62 -0
  42. data/spec/batsir/support/mock_filters.rb +43 -0
  43. data/spec/batsir/transformers/field_transformer_spec.rb +73 -0
  44. data/spec/batsir/transformers/json_input_transformer_spec.rb +22 -0
  45. data/spec/batsir/transformers/json_output_transformer_spec.rb +18 -0
  46. data/spec/batsir/transformers/transformer_spec.rb +22 -0
  47. data/spec/spec_helper.rb +22 -0
  48. metadata +220 -0
@@ -0,0 +1,74 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+
3
+ describe Batsir::FilterQueue do
4
+ it "should be possible to add a filter to a queue" do
5
+ queue = Batsir::FilterQueue.new
6
+ queue.add("Filter")
7
+ queue.should include "Filter"
8
+ end
9
+
10
+ it "should not return nil as last operation when no acceptors or notifiers are added" do
11
+ queue = Batsir::FilterQueue.new
12
+
13
+ queue.add("AnotherFilter")
14
+ ops = []
15
+ queue.each do |op|
16
+ ops << op
17
+ end
18
+ ops.last.should_not be_nil
19
+ end
20
+
21
+ it "should be possible to add a notifier" do
22
+ queue = Batsir::FilterQueue.new
23
+ notifier = "Notifier"
24
+ queue.add_notifier(notifier)
25
+ queue.should include notifier
26
+ end
27
+
28
+ it "should be possible to add multiple notifiers" do
29
+ queue = Batsir::FilterQueue.new
30
+ ops = []
31
+ 3.times do |index|
32
+ ops << "Notifier #{index}"
33
+ queue.add_notifier("Notifier #{index}")
34
+ end
35
+
36
+ ops.each {|op| queue.should include op}
37
+ end
38
+
39
+ it "should return notifiers as the last operations" do
40
+ queue = Batsir::FilterQueue.new
41
+ notifier = "Notifier"
42
+
43
+ queue.add("SomeFilter")
44
+ queue.add_notifier(notifier)
45
+ queue.add("AnotherFilter")
46
+
47
+ ops = []
48
+ queue.each do |op|
49
+ ops << op
50
+ end
51
+ ops.last.should == notifier
52
+ end
53
+
54
+ it "should respond true to #empty? when no operations are added" do
55
+ queue = Batsir::FilterQueue.new
56
+ queue.should be_empty
57
+ end
58
+
59
+ it "should not be empty when a notification operation is added" do
60
+ queue = Batsir::FilterQueue.new
61
+ operation = "Notifier"
62
+
63
+ queue.add_notifier(operation)
64
+
65
+ queue.should_not be_empty
66
+ end
67
+
68
+ it "should not be empty when a regular operation is added" do
69
+ queue = Batsir::FilterQueue.new
70
+
71
+ queue.add("SomeFilter")
72
+ queue.should_not be_empty
73
+ end
74
+ end
@@ -0,0 +1,12 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+
3
+ describe Batsir::Filter do
4
+ it "should be possible to create an filter" do
5
+ filter = Batsir::Filter.new
6
+ filter.should_not be_nil
7
+ end
8
+
9
+ it "should have an #execute method" do
10
+ Batsir::Filter.instance_methods.map{|im| im.to_s}.should include "execute"
11
+ end
12
+ end
@@ -0,0 +1,117 @@
1
+ require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
+
3
+ describe Batsir::Notifiers::AMQPNotifier do
4
+ let(:notifier_class){
5
+ Batsir::Notifiers::AMQPNotifier
6
+ }
7
+
8
+ context "With respect to setting options" do
9
+ it "should be a Batsir::Notifiers::Notifier" do
10
+ notifier_class.ancestors.should include Batsir::Notifiers::Notifier
11
+ end
12
+
13
+ it "should be possible to set the queue on which to listen" do
14
+ notifier = notifier_class.new(:queue => :queue)
15
+ notifier.queue.should == :queue
16
+ end
17
+
18
+ it "should be possible to set the host of the amqp broker" do
19
+ notifier = notifier_class.new(:host => 'localhost')
20
+ notifier.host.should == 'localhost'
21
+ end
22
+
23
+ it "should be possible to set the port of the amqp broker" do
24
+ notifier = notifier_class.new(:port => 1234)
25
+ notifier.port.should == 1234
26
+ end
27
+
28
+ it "should be possible to set the username with which to connect to the broker" do
29
+ notifier = notifier_class.new(:username => 'some_user')
30
+ notifier.username.should == 'some_user'
31
+ end
32
+
33
+ it "should be possible to set the password with which to connect to the broker" do
34
+ notifier = notifier_class.new(:password => 'password')
35
+ notifier.password.should == 'password'
36
+ end
37
+
38
+ it "should be possible to set the vhost to use on the broker" do
39
+ notifier = notifier_class.new(:vhost => '/blah')
40
+ notifier.vhost.should == '/blah'
41
+ end
42
+
43
+ it "should be possible to set the exchange to use on the broker" do
44
+ notifier = notifier_class.new(:exchange => 'amq.direct')
45
+ notifier.exchange.should == 'amq.direct'
46
+ end
47
+
48
+ it "should default to amqp://guest:guest@localhost:5672/ with direct exchange on vhost ''" do
49
+ notifier = notifier_class.new(:queue => :somequeue)
50
+ notifier.queue.should == :somequeue
51
+ notifier.host.should == 'localhost'
52
+ notifier.port.should == 5672
53
+ notifier.username.should == 'guest'
54
+ notifier.password.should == 'guest'
55
+ notifier.vhost.should == '/'
56
+ notifier.exchange.should == 'amq.direct'
57
+ end
58
+ end
59
+
60
+ context "With respect to notifying" do
61
+ def new_notifier(options = {})
62
+ notifier_class.new(options)
63
+ end
64
+
65
+ it "should connect to the configured host" do
66
+ notifier = new_notifier(:host => 'somehost')
67
+ notifier.execute({})
68
+ instance = Bunny.instance
69
+ instance.options[:host].should == 'somehost'
70
+ end
71
+
72
+ it "should connect to the configured port" do
73
+ notifier = new_notifier(:port => 1234)
74
+ notifier.execute({})
75
+ instance = Bunny.instance
76
+ instance.options[:port].should == 1234
77
+ end
78
+
79
+ it "should connect with the configured username" do
80
+ notifier = new_notifier(:username => 'user')
81
+ notifier.execute({})
82
+ instance = Bunny.instance
83
+ instance.options[:user].should == 'user'
84
+ end
85
+
86
+ it "should connect with the configured password" do
87
+ notifier = new_notifier(:password => 'pass')
88
+ notifier.execute({})
89
+ instance = Bunny.instance
90
+ instance.options[:pass].should == 'pass'
91
+ end
92
+
93
+ it "should connect to the configured vhost" do
94
+ notifier = new_notifier(:vhost => '/vhost')
95
+ notifier.execute({})
96
+ instance = Bunny.instance
97
+ instance.options[:vhost].should == '/vhost'
98
+ end
99
+
100
+ it "should declare the configured exchange" do
101
+ notifier = new_notifier(:exchange => 'some_exchange')
102
+ notifier.execute({})
103
+ instance = Bunny.instance
104
+ instance.exchange.name.should == 'some_exchange'
105
+ end
106
+
107
+ it "should bind the configured exchange to the queue and publish the message with the queue set as routing key" do
108
+ notifier = new_notifier(:exchange => 'some_exchange', :queue => :queue)
109
+ notifier.execute({})
110
+ instance = Bunny.instance
111
+ instance.exchange.name.should == 'some_exchange'
112
+ instance.exchange.message.should == {}
113
+ instance.exchange.key.should == :queue
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,73 @@
1
+ require File.join( File.dirname(__FILE__), "..", "..", "spec_helper" )
2
+
3
+ describe Batsir::Notifiers::Notifier do
4
+ let( :notifier_class ) do
5
+ Batsir::Notifiers::Notifier
6
+ end
7
+
8
+ it "should have a transformer_queue" do
9
+ notifier = notifier_class.new
10
+ notifier.transformer_queue.should_not be_nil
11
+ end
12
+
13
+ it "should initially have an empty transformer_queue" do
14
+ notifier = notifier_class.new
15
+ notifier.transformer_queue.should_not be_nil
16
+ notifier.transformer_queue.should be_empty
17
+ end
18
+
19
+ it "should be possible to add a transformer to the transformer_queue" do
20
+ transformer = :transformer
21
+
22
+ notifier = notifier_class.new
23
+ notifier.add_transformer transformer
24
+
25
+ notifier.transformer_queue.should_not be_empty
26
+ notifier.transformer_queue.size.should == 1
27
+ notifier.transformer_queue.first.should == :transformer
28
+ end
29
+
30
+ it "should be possible to add a transformer multiple times" do
31
+ transformer = :transformer
32
+
33
+ notifier = notifier_class.new
34
+ notifier.add_transformer transformer
35
+ notifier.add_transformer transformer
36
+
37
+ notifier.transformer_queue.should_not be_empty
38
+ notifier.transformer_queue.size.should == 2
39
+ end
40
+
41
+ it "should create a FieldTransformer when the 'fields' option is given during initialization" do
42
+ fields = {:foo => :bar}
43
+ notifier = notifier_class.new(:fields => fields)
44
+ notifier.transformer_queue.should_not be_empty
45
+ notifier.transformer_queue.first.class.should == Batsir::Transformers::FieldTransformer
46
+ notifier.transformer_queue.first.fields.should == fields
47
+ end
48
+
49
+ it "should call #transform when #notify is called" do
50
+ notifier = notifier_class.new
51
+ notifier.should_receive(:transform).with({})
52
+ notifier.notify({})
53
+ end
54
+
55
+ it "should call #transform on all transformers when #transform is called" do
56
+ class MockTransformer < Batsir::Transformers::Transformer
57
+ end
58
+
59
+ notifier = notifier_class.new
60
+ transformer = MockTransformer.new
61
+ notifier.add_transformer transformer
62
+ notifier.transformer_queue.size.should == 1
63
+
64
+ transformer.should_receive(:transform).with({})
65
+ notifier.notify({})
66
+ end
67
+
68
+ it "should call #execute when #notify is called" do
69
+ notifier = notifier_class.new
70
+ notifier.should_receive(:execute)
71
+ notifier.notify({})
72
+ end
73
+ end
@@ -0,0 +1,678 @@
1
+ require File.join( File.dirname(__FILE__), "..", "spec_helper" )
2
+
3
+ describe Batsir::Stage do
4
+ def create_stage(options = {})
5
+ defaults = {
6
+ :name => "Test Stage",
7
+ :chain => Batsir::Chain.new
8
+ }
9
+ Batsir::Stage.new(defaults.merge(options))
10
+ end
11
+
12
+ before :all do
13
+ class StubFilter < Batsir::Filter
14
+ end
15
+
16
+ class AnotherFilter < Batsir::Filter
17
+ end
18
+
19
+ @object_type = "SomeResource"
20
+ end
21
+
22
+ it "should be a Celluloid Actor" do
23
+ Batsir::Stage.ancestors.should include Celluloid
24
+ end
25
+
26
+ it "should be possible to name the stage" do
27
+ stage = Batsir::Stage.new
28
+ name = "StageName"
29
+ stage.name = name
30
+ stage.name.should == name
31
+ end
32
+
33
+ it "should be possible to set the name in the constructor" do
34
+ name = "StageName"
35
+ stage = Batsir::Stage.new(:name => name)
36
+ stage.name.should == name
37
+ end
38
+
39
+ it "should be possible to set the aggregator chain to which the stage belongs" do
40
+ chain = "Chain"
41
+ stage = Batsir::Stage.new(:chain => chain)
42
+ stage.chain.should == chain
43
+ end
44
+
45
+ context "With respect to filters" do
46
+ it "should not be possible to set the filters" do
47
+ stage = Batsir::Stage.new
48
+ lambda { stage.filters = {} }.should raise_error(NoMethodError)
49
+ end
50
+
51
+ it "should store filters using filter declarations" do
52
+ filter = "Filter"
53
+ stage = Batsir::Stage.new
54
+ stage.add_filter(filter)
55
+ stage.filter_declarations.should_not be_nil
56
+ stage.filter_declarations.size.should == 1
57
+ declaration = stage.filter_declarations.first
58
+ declaration.filter.should == filter
59
+ declaration.options.should == {}
60
+ end
61
+
62
+ it "should return an empty array when the #filters method is called without any declared filters" do
63
+ stage = Batsir::Stage.new
64
+ stage.filters.should_not be_nil
65
+ stage.filters.should == []
66
+ end
67
+
68
+ it "should return all filters when the #filters method is called" do
69
+ filter1 = "Filter"
70
+ filter2 = "Filter2"
71
+ filter3 = "Filter"
72
+ stage = Batsir::Stage.new
73
+ stage.add_filter(filter1)
74
+ stage.add_filter(filter2)
75
+ stage.add_filter(filter3)
76
+
77
+ stage.filters.should_not be_nil
78
+ stage.filters.size.should == 3
79
+ stage.filters[0].should == filter1
80
+ stage.filters[1].should == filter2
81
+ stage.filters[2].should == filter3
82
+ end
83
+
84
+ it "should add a filter to its filters" do
85
+ filter = "Filter"
86
+ stage = Batsir::Stage.new
87
+ stage.add_filter(filter)
88
+ stage.filters.should_not be_nil
89
+ stage.filters.should include filter
90
+ end
91
+
92
+ it "should be possible to have multiple filters of the same class but with different options" do
93
+ stage = Batsir::Stage.new
94
+ stage.add_filter(:filter)
95
+ stage.add_filter(:filter, :foo => :bar)
96
+
97
+ stage.filters.should include :filter
98
+ stage.filters.size.should == 2
99
+ end
100
+
101
+ it "should be possible to add filters with on options hash" do
102
+ filter = :filter
103
+ options = {:foo => :bar}
104
+
105
+ stage = Batsir::Stage.new
106
+ stage.add_filter(filter, options)
107
+
108
+ stage.filters.should_not be_nil
109
+ stage.filters.should_not be_empty
110
+ stage.filters.should include filter
111
+ stage.filter_declarations.first.options.should == options
112
+ end
113
+
114
+ it "should be possible to add multiple filters with option hashes" do
115
+ filter1 = :filter1
116
+ filter2 = :filter2
117
+ options1 = {:foo1 => :bar1}
118
+ options2 = {:foo2 => :bar2}
119
+
120
+ stage = Batsir::Stage.new
121
+ stage.add_filter(filter1, options1)
122
+ stage.add_filter(filter2, options2)
123
+
124
+ stage.filters.should include filter1
125
+ stage.filters.should include filter2
126
+ stage.filter_declarations[0].options.should == options1
127
+ stage.filter_declarations[1].options.should == options2
128
+ end
129
+
130
+ it "should add empty options hashes to filters when no option hash is given" do
131
+ filter = :filter
132
+
133
+ stage = Batsir::Stage.new
134
+ stage.add_filter(filter)
135
+
136
+ stage.filters.should_not be_nil
137
+ stage.filters.should_not be_empty
138
+ stage.filters.should include filter
139
+ stage.filter_declarations.first.options.should == {}
140
+ end
141
+
142
+ it "should be possible to add a filter more than once" do
143
+ filter = :filter
144
+ stage = Batsir::Stage.new
145
+ stage.add_filter(filter)
146
+ stage.add_filter(filter)
147
+ stage.filters.should_not be_nil
148
+ stage.filters.should_not be_empty
149
+ stage.filters.size.should == 2
150
+ end
151
+
152
+ it "should be possible to add filter with different options and respect the order" do
153
+ filter = :filter
154
+ other_filter = :other_filter
155
+
156
+ stage = Batsir::Stage.new
157
+ stage.add_filter(filter)
158
+ stage.add_filter(other_filter)
159
+ stage.add_filter(filter, :foo => :bar)
160
+ stage.filters.size.should == 3
161
+ end
162
+ end
163
+
164
+ context "With respect to acceptors" do
165
+ it "should initially have an empty list of acceptors" do
166
+ stage = Batsir::Stage.new
167
+ stage.acceptors.should_not be_nil
168
+ stage.acceptors.should be_empty
169
+ end
170
+
171
+ it "should not be possible to set the acceptors" do
172
+ stage = Batsir::Stage.new
173
+ lambda { stage.acceptors = {} }.should raise_error(NoMethodError)
174
+ end
175
+
176
+ it "should be possible to add new acceptors" do
177
+ stage = Batsir::Stage.new
178
+ stage.add_acceptor(:acceptor)
179
+ stage.acceptors.should_not be_nil
180
+ stage.acceptors.should_not be_empty
181
+ stage.acceptors.keys.should include :acceptor
182
+ end
183
+
184
+ it "should store a set of different options for each acceptor" do
185
+ stage = Batsir::Stage.new
186
+ stage.add_acceptor(:acceptor)
187
+ stage.acceptors[:acceptor].should be_a Set
188
+ end
189
+
190
+ it "should be possible to have multiple acceptors of the same class but with different options" do
191
+ stage = Batsir::Stage.new
192
+ stage.add_acceptor(:acceptor_class)
193
+ stage.add_acceptor(:acceptor_class, :foo => :bar)
194
+
195
+ stage.acceptors.should_not be_nil
196
+ stage.acceptors.should_not be_empty
197
+ stage.acceptors.keys.should include :acceptor_class
198
+ stage.acceptors[:acceptor_class].size.should == 2
199
+ end
200
+
201
+ it "should be possible to add an acceptor with an options hash" do
202
+ stage = Batsir::Stage.new
203
+ options = {:foo => :bar}
204
+ stage.add_acceptor(:acceptor, options)
205
+
206
+ stage.acceptors.should_not be_nil
207
+ stage.acceptors.should_not be_empty
208
+ stage.acceptors.keys.should include :acceptor
209
+ stage.acceptors[:acceptor].first.should == options
210
+ end
211
+
212
+ it "should add an empty options hash for added acceptors without options" do
213
+ stage = Batsir::Stage.new
214
+ stage.add_acceptor(:acceptor)
215
+
216
+ stage.acceptors.should_not be_nil
217
+ stage.acceptors.should_not be_empty
218
+ stage.acceptors.keys.should include :acceptor
219
+ stage.acceptors[:acceptor].first.should == {}
220
+ end
221
+
222
+ it "should initially have an empty list of cancellators" do
223
+ stage = Batsir::Stage.new
224
+ stage.cancellators.should_not be_nil
225
+ stage.cancellators.should be_empty
226
+ end
227
+
228
+ context "with respect to acceptor transformers" do
229
+ it "should have an empty acceptor transformers queue by default" do
230
+ stage = Batsir::Stage.new
231
+
232
+ stage.acceptor_transformers.should_not be_nil
233
+ stage.acceptor_transformers.should be_empty
234
+ end
235
+
236
+ it "should be possible to add a transformer to the acceptors" do
237
+ stage = Batsir::Stage.new
238
+
239
+ transformer = :transformer
240
+
241
+ stage.add_acceptor_transformer(transformer)
242
+ stage.acceptor_transformers.should_not be_empty
243
+
244
+ stage.acceptor_transformers.first.transformer.should == transformer
245
+ end
246
+
247
+ it "should add an empty options hash by default" do
248
+ stage = Batsir::Stage.new
249
+
250
+ transformer = :transformer
251
+ stage.add_acceptor_transformer(transformer)
252
+ stage.acceptor_transformers.should_not be_empty
253
+
254
+ stage.acceptor_transformers.first.options.should == {}
255
+ end
256
+
257
+ it "should be possible to add options to a transformer" do
258
+ stage = Batsir::Stage.new
259
+
260
+ transformer = :transformer
261
+ options = {:foo => :bar}
262
+
263
+ stage.add_acceptor_transformer(transformer, options)
264
+ stage.acceptor_transformers.should_not be_empty
265
+
266
+ stage.acceptor_transformers.first.transformer.should == transformer
267
+ stage.acceptor_transformers.first.options.should == options
268
+ end
269
+
270
+ it "should be possible to add multiple transformers" do
271
+ stage = Batsir::Stage.new
272
+
273
+ transformer1 = :transformer1
274
+ transformer2 = :transformer2
275
+
276
+ stage.add_acceptor_transformer(transformer1)
277
+ stage.add_acceptor_transformer(transformer2)
278
+ stage.acceptor_transformers.should_not be_empty
279
+ stage.acceptor_transformers.size.should == 2
280
+
281
+ transformers = stage.acceptor_transformers.map{|td| td.transformer}
282
+ transformers.should include transformer1
283
+ transformers.should include transformer2
284
+ end
285
+
286
+ it "should keep the transformers in the order of declaration" do
287
+ stage = Batsir::Stage.new
288
+
289
+ transformer1 = :transformer1
290
+ transformer2 = :transformer2
291
+
292
+ stage.add_acceptor_transformer(transformer1)
293
+ stage.add_acceptor_transformer(transformer2)
294
+ stage.acceptor_transformers.should_not be_empty
295
+ stage.acceptor_transformers.size.should == 2
296
+
297
+ stage.acceptor_transformers.first.transformer.should == transformer1
298
+ stage.acceptor_transformers.last.transformer.should == transformer2
299
+ end
300
+
301
+ it "should be possible to add a transformer more than once" do
302
+ stage = Batsir::Stage.new
303
+
304
+ transformer = :transformer
305
+
306
+ stage.add_acceptor_transformer(transformer)
307
+ stage.add_acceptor_transformer(transformer)
308
+ stage.acceptor_transformers.should_not be_empty
309
+ stage.acceptor_transformers.size.should == 2
310
+
311
+ stage.acceptor_transformers.first.transformer.should == transformer
312
+ stage.acceptor_transformers.last.transformer.should == transformer
313
+ end
314
+ end
315
+
316
+ end
317
+
318
+ context "With respect to notifiers" do
319
+ it "should initially have an empty notifiers queue" do
320
+ stage = Batsir::Stage.new
321
+ stage.notifiers.should_not be_nil
322
+ stage.notifiers.should be_empty
323
+ end
324
+
325
+ it "should not be possible to set the notifiers" do
326
+ stage = Batsir::Stage.new
327
+ lambda { stage.notifiers = {} }.should raise_error(NoMethodError)
328
+ end
329
+
330
+ it "should be possible to add new notifiers" do
331
+ stage = Batsir::Stage.new
332
+
333
+ stage.add_notifier(:notifier)
334
+ stage.notifiers.should_not be_nil
335
+ stage.notifiers.should_not be_empty
336
+ stage.notifiers.keys.should include :notifier
337
+ end
338
+
339
+ it "should store a set of different options for each notifier" do
340
+ stage = Batsir::Stage.new
341
+ stage.add_notifier(:notifier)
342
+ stage.notifiers[:notifier].should be_a Set
343
+ end
344
+
345
+ it "should be possible to have multiple notifiers of the same class but with different options" do
346
+ stage = Batsir::Stage.new
347
+ stage.add_notifier(:notifier_class)
348
+ stage.add_notifier(:notifier_class, :foo => :bar)
349
+
350
+ stage.notifiers.should_not be_nil
351
+ stage.notifiers.keys.should include :notifier_class
352
+ stage.notifiers[:notifier_class].size.should == 2
353
+ end
354
+
355
+ it "should be possible to set a notifier with an options hash" do
356
+ stage = Batsir::Stage.new
357
+
358
+ options = {:foo => :bar}
359
+
360
+ stage.add_notifier(:notifier, options)
361
+ stage.notifiers.should_not be_nil
362
+ stage.notifiers.should_not be_empty
363
+ stage.notifiers.keys.should include :notifier
364
+ stage.notifiers[:notifier].first.should == options
365
+ end
366
+
367
+ it "should add an empty options hash for added notifiers without options" do
368
+ stage = Batsir::Stage.new
369
+
370
+ stage.add_notifier(:notifier)
371
+ stage.notifiers.should_not be_nil
372
+ stage.notifiers.should_not be_empty
373
+ stage.notifiers.keys.should include :notifier
374
+ stage.notifiers[:notifier].first.should == {}
375
+ end
376
+
377
+ context "with respect to notifier transformers" do
378
+ it "should have an empty notifier transformers queue by default" do
379
+ stage = Batsir::Stage.new
380
+
381
+ stage.notifier_transformers.should_not be_nil
382
+ stage.notifier_transformers.should be_empty
383
+ end
384
+
385
+ it "should be possible to add a transformer to the notifiers" do
386
+ stage = Batsir::Stage.new
387
+
388
+ transformer = :transformer
389
+
390
+ stage.add_notifier_transformer(transformer)
391
+ stage.notifier_transformers.should_not be_empty
392
+
393
+ stage.notifier_transformers.first.transformer.should == transformer
394
+ end
395
+
396
+ it "should add an empty options hash by default" do
397
+ stage = Batsir::Stage.new
398
+
399
+ transformer = :transformer
400
+ stage.add_notifier_transformer(transformer)
401
+ stage.notifier_transformers.should_not be_empty
402
+
403
+ stage.notifier_transformers.first.options.should == {}
404
+ end
405
+
406
+ it "should be possible to add options to a transformer" do
407
+ stage = Batsir::Stage.new
408
+
409
+ transformer = :transformer
410
+ options = {:foo => :bar}
411
+
412
+ stage.add_notifier_transformer(transformer, options)
413
+ stage.notifier_transformers.should_not be_empty
414
+
415
+ stage.notifier_transformers.first.transformer.should == transformer
416
+ stage.notifier_transformers.first.options.should == options
417
+ end
418
+
419
+ it "should be possible to add multiple transformers" do
420
+ stage = Batsir::Stage.new
421
+
422
+ transformer1 = :transformer1
423
+ transformer2 = :transformer2
424
+
425
+ stage.add_notifier_transformer(transformer1)
426
+ stage.add_notifier_transformer(transformer2)
427
+ stage.notifier_transformers.should_not be_empty
428
+ stage.notifier_transformers.size.should == 2
429
+
430
+ transformers = stage.notifier_transformers.map{|td| td.transformer}
431
+ transformers.should include transformer1
432
+ transformers.should include transformer2
433
+ end
434
+
435
+ it "should keep the transformers in the order of declaration" do
436
+ stage = Batsir::Stage.new
437
+
438
+ transformer1 = :transformer1
439
+ transformer2 = :transformer2
440
+
441
+ stage.add_notifier_transformer(transformer1)
442
+ stage.add_notifier_transformer(transformer2)
443
+ stage.notifier_transformers.should_not be_empty
444
+ stage.notifier_transformers.size.should == 2
445
+
446
+ stage.notifier_transformers.first.transformer.should == transformer1
447
+ stage.notifier_transformers.last.transformer.should == transformer2
448
+ end
449
+
450
+ it "should be possible to add a transformer more than once" do
451
+ stage = Batsir::Stage.new
452
+
453
+ transformer = :transformer
454
+
455
+ stage.add_notifier_transformer(transformer)
456
+ stage.add_notifier_transformer(transformer)
457
+ stage.notifier_transformers.should_not be_empty
458
+ stage.notifier_transformers.size.should == 2
459
+
460
+ stage.notifier_transformers.first.transformer.should == transformer
461
+ stage.notifier_transformers.last.transformer.should == transformer
462
+ end
463
+ end
464
+ end
465
+
466
+ context "with respect to compiling the stage" do
467
+ before :all do
468
+ @stage_name = "Stage 1"
469
+
470
+ stage = Batsir::Stage.new(:name => @stage_name)
471
+
472
+ stage.add_notifier_transformer(Batsir::Transformers::Transformer)
473
+ stage.add_notifier(Batsir::Notifiers::Notifier)
474
+ stage.add_filter(Batsir::Filter)
475
+ stage.add_filter(Batsir::Filter)
476
+
477
+ @created_class = eval( stage.compile )
478
+ end
479
+
480
+ it "should create a class named after the stage name" do
481
+ @created_class.to_s.should == "Stage1Worker"
482
+ end
483
+
484
+ it "should create a Batsir::StageWorker class" do
485
+ @created_class.ancestors.should include Batsir::StageWorker
486
+ end
487
+
488
+ it "should create a class that includes Sidekiq::Worker" do
489
+ @created_class.ancestors.should include Sidekiq::Worker
490
+ end
491
+
492
+ it "should create a worker class named after the stage name" do
493
+ @created_class.stage_name.should == @stage_name
494
+ end
495
+
496
+ it "should add the notifier during compilation" do
497
+ instance = @created_class.new
498
+ instance.filter_queue.notifiers.should_not be_nil
499
+ instance.filter_queue.notifiers.should_not be_empty
500
+ instance.filter_queue.notifiers.size.should == 1
501
+ instance.filter_queue.notifiers.first.should be_a Batsir::Notifiers::Notifier
502
+ end
503
+
504
+ it "should add a transformer to the notifier during compilation" do
505
+ instance = @created_class.new
506
+
507
+ instance.filter_queue.notifiers.first.transformer_queue.should_not be_empty
508
+ instance.filter_queue.notifiers.first.transformer_queue.first.should be_a Batsir::Transformers::Transformer
509
+ end
510
+
511
+ it "should add a JSONOutputTransformer by default when no transformers are defined" do
512
+ stage = Batsir::Stage.new(:name => "SomeName")
513
+
514
+ stage.add_notifier(Batsir::Notifiers::Notifier)
515
+
516
+ created_class = eval( stage.compile )
517
+ instance = created_class.new
518
+
519
+ instance.filter_queue.notifiers.should_not be_nil
520
+ instance.filter_queue.notifiers.should_not be_empty
521
+ instance.filter_queue.notifiers.first.transformer_queue.should_not be_empty
522
+ instance.filter_queue.notifiers.first.transformer_queue.first.should be_a Batsir::Transformers::JSONOutputTransformer
523
+ end
524
+
525
+ it "should initialize a class local filter queue" do
526
+ @created_class.filter_queue.should_not be_nil
527
+ @created_class.filter_queue.should_not be_empty
528
+ end
529
+
530
+ it "should have intitialized the filters" do
531
+ @created_class.filter_queue.map{|filter| filter.class.to_s}.should include "Batsir::Filter"
532
+ end
533
+
534
+ it "should be possible to add a filter multiple times" do
535
+ @created_class.filter_queue.select{ |filter| filter.class == Batsir::Filter }.size.should == 2
536
+ end
537
+
538
+ it "should use the class local filter queue once an instance is initialized" do
539
+ instance = @created_class.new
540
+ instance.filter_queue.should == @created_class.filter_queue
541
+ end
542
+
543
+ it "should initialize all filters in the filter queue" do
544
+ @created_class.filter_queue.each do |filter|
545
+ filter.should_not be_a Class
546
+ end
547
+ end
548
+ end
549
+
550
+ context "with respect to starting the stage" do
551
+ before :all do
552
+ class MockAcceptor < Batsir::Acceptors::Acceptor
553
+
554
+ def foo=(bar)
555
+ end
556
+
557
+ def stage_name=(name)
558
+ @@stage_name = name
559
+ end
560
+
561
+ def self.stage_name
562
+ @@stage_name
563
+ end
564
+
565
+ def start
566
+ @@start_count ||= 0
567
+ @@start_count += 1
568
+ end
569
+
570
+ def add_transformer(transformer)
571
+ @@added_transformers ||= []
572
+ @@added_transformers << transformer
573
+ end
574
+
575
+ def self.added_transformers
576
+ @@added_transformers ||= []
577
+ end
578
+
579
+ def self.start_count
580
+ @@start_count ||= 0
581
+ end
582
+
583
+ def self.reset
584
+ @@start_count = 0
585
+ @@stage_name = nil
586
+ @@added_transformers = []
587
+ end
588
+
589
+ end
590
+
591
+ class Celluloid::ActorProxy
592
+ def start!
593
+ Celluloid::Actor.call @mailbox, :start
594
+ end
595
+ end
596
+ end
597
+
598
+ before :each do
599
+ MockAcceptor.reset
600
+ end
601
+
602
+ it "should set the stage name on acceptors when they are started" do
603
+ stage = create_stage
604
+ stage.add_acceptor MockAcceptor
605
+ stage.add_acceptor MockAcceptor, :foo => :bar
606
+
607
+ stage.start
608
+ MockAcceptor.stage_name.should == stage.name
609
+ end
610
+
611
+ it "should initially have an empty list of running acceptors" do
612
+ stage = create_stage
613
+ stage.add_acceptor MockAcceptor
614
+
615
+ stage.running_acceptors.should_not be_nil
616
+ stage.running_acceptors.should be_empty
617
+ end
618
+
619
+ it "should keep track of running acceptors" do
620
+ stage = create_stage
621
+ stage.add_acceptor MockAcceptor
622
+
623
+ stage.start
624
+ stage.running_acceptors.size.should == 1
625
+ end
626
+
627
+ it "should add a cancellator to each acceptor" do
628
+ stage = create_stage
629
+ stage.add_acceptor MockAcceptor
630
+
631
+ stage.start
632
+ stage.running_acceptors.first.cancellator.should_not be_nil
633
+ end
634
+
635
+ it "should add cancellators to the stage list of cancellators" do
636
+ stage = create_stage
637
+ stage.add_acceptor MockAcceptor
638
+ stage.add_acceptor MockAcceptor, :foo => :bar
639
+
640
+ stage.start
641
+ stage.cancellators.size.should == 2
642
+ end
643
+
644
+ it "should start all acceptors" do
645
+ stage = create_stage
646
+ stage.add_acceptor MockAcceptor
647
+ stage.add_acceptor MockAcceptor, :foo => :bar
648
+
649
+ MockAcceptor.start_count.should == 0
650
+
651
+ stage.start
652
+ sleep(0.01)
653
+
654
+ MockAcceptor.start_count.should == 2
655
+ end
656
+
657
+ it "should add a Batsir::Transformers::JSONInputTransformer to acceptors when no transformers are defined" do
658
+ stage = create_stage
659
+ stage.add_acceptor MockAcceptor
660
+
661
+ stage.start
662
+
663
+ MockAcceptor.added_transformers.size.should == 1
664
+ MockAcceptor.added_transformers.first.should be_a Batsir::Transformers::JSONInputTransformer
665
+ end
666
+
667
+ it "should add defined transformers to the acceptors" do
668
+ stage = create_stage
669
+ stage.add_acceptor_transformer Batsir::Transformers::Transformer
670
+ stage.add_acceptor MockAcceptor
671
+
672
+ stage.start
673
+
674
+ MockAcceptor.added_transformers.size.should == 1
675
+ MockAcceptor.added_transformers.first.should be_a Batsir::Transformers::Transformer
676
+ end
677
+ end
678
+ end