batsir 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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