empipelines 0.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1 +1,14 @@
1
1
  # EM Pipelines
2
+
3
+ ## TODO
4
+ * Make wiring easier
5
+ * Example apps
6
+ * TerminatorStage should consume message
7
+ * Control flow for AmqpEventSource
8
+ * Transaction ID on each message
9
+ * Evented I/O for IOEventSource
10
+ * Consolidate logger and monitoring
11
+ * Default monitoring implementation
12
+ * Performance testing
13
+ * Make all events composable (e.g. new_on_event = old_on_event o new_handler)
14
+ * Detect insonsistency when handler didnt consume or pass message ahead
data/Rakefile CHANGED
@@ -59,12 +59,23 @@ Cucumber::Rake::Task.new(:all_features) do |t|
59
59
  t.cucumber_opts = "--format pretty"
60
60
  end
61
61
 
62
- desc "Runs specs"
63
- task :specs do
64
- all = FileList['spec/**/*_spec.rb']
62
+ def spec(dir)
63
+ puts "---------- #{dir} tests... ----------"
64
+ all = FileList["#{dir}/**/*_spec.rb"]
65
65
  sh "rspec --color #{all}"
66
66
  end
67
67
 
68
+ desc "Runs unit tests"
69
+ task :unit do
70
+ spec('unit')
71
+ end
72
+
73
+ desc "Run functional tests"
74
+ task :functional do
75
+ spec('functional')
76
+ end
77
+
78
+
68
79
  desc "Resets localhost's rabbitmq"
69
80
  task :reset_rabbitmq do
70
81
  # sh 'rabbitmqctl stop_app; echo 0'
@@ -72,17 +83,7 @@ task :reset_rabbitmq do
72
83
  # sh 'rabbitmqctl start_app'
73
84
  end
74
85
 
75
- desc "Run cucumber tests for finished features"
76
- task :features do
77
-
78
- end
79
-
80
- desc "Run cucumber tests for all features, including work in progress"
81
- task :all_features do
82
-
83
- end
84
-
85
- task :ci => [:specs, :features, :build]
86
+ task :ci => [:unit, :functional, :build]
86
87
 
87
88
  desc "MUST BE RUN (AND PASS!) BEFORE CHECKING IN CODE!"
88
89
  task :pre_checkin => [:reset_rabbitmq, :ci]
data/empipelines.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
  ## Leave these as is they will be modified for you by the rake gemspec task.
6
6
  s.name = 'empipelines'
7
- s.version = '0.2'
8
- s.date = '2011-12-20'
7
+ s.version = '0.2.1'
8
+ s.date = '2011-12-21'
9
9
  s.rubyforge_project = 'empipelines'
10
10
 
11
11
  s.summary = "Simple Event Handling Pipeline Architecture for EventMachine"
@@ -36,23 +36,31 @@ Gem::Specification.new do |s|
36
36
  README.md
37
37
  Rakefile
38
38
  empipelines.gemspec
39
+ functional/consuming_events_from_file_spec.rb
40
+ functional/events.dat
41
+ functional/test_stages.rb
39
42
  lib/empipelines.rb
40
43
  lib/empipelines/amqp_event_source.rb
41
44
  lib/empipelines/batch_event_source.rb
45
+ lib/empipelines/event_handlers.rb
42
46
  lib/empipelines/event_pipeline.rb
47
+ lib/empipelines/io_event_source.rb
43
48
  lib/empipelines/list_event_source.rb
44
49
  lib/empipelines/message.rb
45
50
  lib/empipelines/periodic_event_source.rb
46
51
  lib/empipelines/pipeline.rb
47
- spec/empipelines/amqp_event_source_spec.rb
48
- spec/empipelines/batch_event_source_spec.rb
49
- spec/empipelines/event_pipeline_spec.rb
50
- spec/empipelines/list_event_source_spec.rb
51
- spec/empipelines/message_spec.rb
52
- spec/empipelines/periodic_event_source_spec.rb
53
- spec/empipelines/pipeline_spec.rb
54
- spec/spec_helper.rb
55
- spec/stage_helper.rb
52
+ unit/empipelines/amqp_event_source_spec.rb
53
+ unit/empipelines/batch_event_source_spec.rb
54
+ unit/empipelines/empty_io_event_source.dat
55
+ unit/empipelines/event_pipeline_spec.rb
56
+ unit/empipelines/io_event_source.dat
57
+ unit/empipelines/io_event_source_spec.rb
58
+ unit/empipelines/list_event_source_spec.rb
59
+ unit/empipelines/message_spec.rb
60
+ unit/empipelines/periodic_event_source_spec.rb
61
+ unit/empipelines/pipeline_spec.rb
62
+ unit/spec_helper.rb
63
+ unit/stage_helper.rb
56
64
  ]
57
65
  # = MANIFEST =
58
66
 
@@ -0,0 +1,42 @@
1
+ require 'eventmachine'
2
+ require 'empipelines'
3
+ require File.join(File.dirname(__FILE__), 'test_stages')
4
+
5
+ module TestStages
6
+ describe 'Consumption of events from a file' do
7
+ let(:monitoring) { stub() }
8
+ let(:logger) { stub(:info => nil, :debug => nil) }
9
+ let (:processed) { {} }
10
+ include EmRunner
11
+
12
+ it 'consumes all events from the file' do
13
+ with_em_run do
14
+ pipeline = EmPipelines::Pipeline.new(EM, {:processed => processed}, monitoring, logger)
15
+
16
+ file_name = File.join(File.dirname(__FILE__), 'events.dat')
17
+ source = EmPipelines::IOEventSource.new(EM, file_name)
18
+
19
+ stages = [PassthroughStage, PassthroughStage, PassthroughStage, ConsumeStage]
20
+ event_pipeline = EmPipelines::EventPipeline.new(source, pipeline.for(stages), monitoring)
21
+
22
+ source.on_finished do |messages|
23
+ EM.stop
24
+ messages.should have(10).items
25
+ messages[0][:payload].should ==("event #0")
26
+ messages[1][:payload].should ==("event #1")
27
+ messages[2][:payload].should ==("event #2")
28
+ messages[3][:payload].should ==("event #3")
29
+ messages[4][:payload].should ==("event #4")
30
+ messages[5][:payload].should ==("event #5")
31
+ messages[6][:payload].should ==("event #6")
32
+ messages[7][:payload].should ==("event #7")
33
+ messages[8][:payload].should ==("event #8")
34
+ messages[9][:payload].should ==("event #9")
35
+ messages.each { |m| m.state.should ==(:consumed) }
36
+ end
37
+
38
+ event_pipeline.start!
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,10 @@
1
+ event #0
2
+ event #1
3
+ event #2
4
+ event #3
5
+ event #4
6
+ event #5
7
+ event #6
8
+ event #7
9
+ event #8
10
+ event #9
@@ -0,0 +1,67 @@
1
+ module TestStages
2
+ module EmRunner
3
+ def with_em_run(&test_body)
4
+ EM.run do
5
+ EM.add_timer(10) do
6
+ EM.stop
7
+ raise "################### Test timed-out! ################### "
8
+ end
9
+
10
+ test_body.call
11
+ end
12
+ end
13
+ end
14
+
15
+ module SomeStage
16
+ @@last_id = 0
17
+ def initialize
18
+ @id = "module ##{(@@last_id)}"
19
+ @@last_id += 1
20
+ end
21
+
22
+ def call(message, &callback)
23
+ processed[self.class] = message
24
+ process(message, callback)
25
+ end
26
+ end
27
+
28
+ class PassthroughStage
29
+ include SomeStage
30
+
31
+ def process(message, callback)
32
+ callback.call(message)
33
+ end
34
+ end
35
+
36
+ class ShouldNotBeReachedStage
37
+ include SomeStage
38
+
39
+ def process(message, callback)
40
+ raise "should not be reached but got #{message}!"
41
+ end
42
+ end
43
+
44
+ class ConsumeStage
45
+ include SomeStage
46
+
47
+ def process(message, callback)
48
+ message.consumed!
49
+ end
50
+ end
51
+
52
+ class RejectStage
53
+ include SomeStage
54
+
55
+ def process(message, callback)
56
+ message.rejected!
57
+ end
58
+ end
59
+
60
+ class BrokenMessageStage
61
+ include SomeStage
62
+
63
+ def process(message, callback)
64
+ message.broken!
65
+ end
66
+ end
67
+ end
@@ -2,8 +2,8 @@ require 'json'
2
2
 
3
3
  module EmPipelines
4
4
  class AmqpEventSource
5
- def initialize(queue, event_name)
6
- @queue, @event_name = queue, event_name
5
+ def initialize(em, queue, event_name)
6
+ @em, @queue, @event_name = em, queue, event_name
7
7
  end
8
8
 
9
9
  def on_event(&handler)
@@ -13,10 +13,11 @@ module EmPipelines
13
13
  def start!
14
14
  @queue.subscribe do |header, json_payload|
15
15
  message = Message.new ({
16
- :header => header,
17
- :payload => JSON.parse(json_payload),
18
- :event => @event_name,
19
- :started_at => Time.now.to_i
16
+ :header => header,
17
+ :origin => @queue.name,
18
+ :payload => JSON.parse(json_payload),
19
+ :event => @event_name,
20
+ :started_at => Time.now.to_i
20
21
  })
21
22
  @handler.call(message)
22
23
  end
@@ -1,15 +1,11 @@
1
+ require 'empipelines/event_handlers'
2
+
1
3
  module EmPipelines
2
4
  class BatchEventSource
3
- def initialize(em, events)
4
- @em, @events = em, events
5
- end
6
-
7
- def on_event(&handler)
8
- @handler = handler
9
- end
10
-
11
- def on_batch_finished(&batch_finished_handler)
12
- @batch_finished_handler = batch_finished_handler
5
+ include EventHandlers
6
+
7
+ def initialize(em, list_name, events)
8
+ @em, @list_name, @events = em, list_name,events
13
9
  end
14
10
 
15
11
  def start!
@@ -22,13 +18,16 @@ module EmPipelines
22
18
  end
23
19
 
24
20
  @events.each do |e|
25
- message = Message.new({:payload => e})
21
+ message = Message.new({
22
+ :payload => e,
23
+ :origin => @list_name
24
+ })
26
25
 
27
26
  message.on_rejected_broken(message_finished)
28
27
  message.on_rejected(message_finished)
29
28
  message.on_consumed(message_finished)
30
29
 
31
- @handler.call(message)
30
+ event_handler.call(message)
32
31
  end
33
32
  end
34
33
 
@@ -36,8 +35,8 @@ module EmPipelines
36
35
  def check_if_finished
37
36
  finished = (@finalised.size == @events.size)
38
37
 
39
- if finished and @batch_finished_handler
40
- @em.next_tick { @batch_finished_handler.call(@finalised) }
38
+ if finished and finished_handler
39
+ @em.next_tick { finished_handler.call(@finalised) }
41
40
  end
42
41
  end
43
42
  end
@@ -0,0 +1,20 @@
1
+ module EmPipelines
2
+ module EventHandlers
3
+ def on_event(event_handler=nil, &block)
4
+ @event_handler = block_given? ? block : event_handler
5
+ end
6
+
7
+ def on_finished(batch_finished_handler=nil, &block)
8
+ @finished_handler = block_given? ? block : batch_finished_handler
9
+ end
10
+
11
+ protected
12
+ def finished_handler
13
+ @finished_handler
14
+ end
15
+
16
+ def event_handler
17
+ @event_handler
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require 'empipelines/event_handlers'
2
+
3
+ module EmPipelines
4
+ class IOEventSource
5
+ include EventHandlers
6
+
7
+ def initialize(em, file_path)
8
+ raise "File #{file_path} does not exist!" unless File.exists?(file_path)
9
+ @em, @file_path = em, file_path
10
+ end
11
+
12
+ def start!
13
+ #TODO: this sucks hard, move to evented I/O
14
+ events = IO.readlines(@file_path).map { |e| e.strip }
15
+
16
+ wrapped_handler = BatchEventSource.new(@em, @file_path, events)
17
+ wrapped_handler.on_event(event_handler)
18
+ wrapped_handler.on_finished(finished_handler)
19
+ wrapped_handler.start!
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,7 @@
1
1
  module EmPipelines
2
2
  class Message
3
+ attr_reader :state
4
+
3
5
  def initialize(base_hash={})
4
6
  hash!(base_hash)
5
7
  created!
@@ -1,7 +1,10 @@
1
1
  module EmPipelines
2
2
  class PeriodicEventSource
3
- def initialize(em, interval_in_secs, &event_sourcing_code)
4
- @em, @interval_in_secs, @event_sourcing_code = em, interval_in_secs, event_sourcing_code
3
+ def initialize(em, name, interval_in_secs, &event_sourcing_code)
4
+ @em = em
5
+ @name = name
6
+ @interval_in_secs = interval_in_secs
7
+ @event_sourcing_code = event_sourcing_code
5
8
  end
6
9
 
7
10
  def start!
@@ -18,7 +21,8 @@ module EmPipelines
18
21
 
19
22
  def tick!
20
23
  event = @event_sourcing_code.call
21
- @handler.call(event) if event
24
+
25
+ @handler.call(Message.new(:payload => event, :origin => @name)) if event
22
26
  end
23
27
  end
24
28
  end
@@ -6,8 +6,8 @@ module EmPipelines
6
6
  end
7
7
  end
8
8
 
9
- def initialize(spawner, context, monitoring, logger)
10
- @spawner = spawner
9
+ def initialize(em, context, monitoring, logger)
10
+ @em = em
11
11
  @logger = logger
12
12
  @context = context
13
13
  @monitoring = monitoring
@@ -20,7 +20,7 @@ module EmPipelines
20
20
  logger = @logger
21
21
 
22
22
  first_stage_process = stages.reverse.reduce(TerminatorStage) do |current_head, next_stage|
23
- @spawner.spawn do |input|
23
+ @em.spawn do |input|
24
24
  begin
25
25
  logger.debug "#{next_stage.class}#notify with #{input}}"
26
26
  next_stage.call(input) do |output|
data/lib/empipelines.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  module EmPipelines
2
- VERSION = '0.2'
2
+ VERSION = '0.2.1'
3
3
  end
4
4
 
5
+ require 'empipelines/event_handlers'
5
6
  require 'empipelines/amqp_event_source'
6
7
  require 'empipelines/batch_event_source'
8
+ require 'empipelines/io_event_source'
7
9
  require 'empipelines/event_pipeline'
8
10
  require 'empipelines/list_event_source'
9
11
  require 'empipelines/message'
@@ -2,6 +2,7 @@ require 'empipelines/amqp_event_source'
2
2
 
3
3
  module EmPipelines
4
4
  class StubQueue
5
+ attr_accessor :name
5
6
  def subscribe(&code)
6
7
  @code = code
7
8
  end
@@ -12,21 +13,25 @@ module EmPipelines
12
13
  end
13
14
 
14
15
  describe AmqpEventSource do
15
- it "adds payload, time and event type to message and sends to listener" do
16
+ let (:em) { mock('eventmachine') }
17
+
18
+ it 'wraps each AMQP message and send to listeners' do
16
19
  json_payload = '{"key":"value"}'
17
20
  queue = StubQueue.new
21
+ queue.name = "this.is.some.queue"
18
22
  event_type = "NuclearWar"
19
23
  header = stub('header')
20
24
 
21
25
  received_messages = []
22
26
 
23
- amqp_source = AmqpEventSource.new(queue, event_type)
27
+ amqp_source = AmqpEventSource.new(em, queue, event_type)
24
28
  amqp_source.on_event { |e| received_messages << e }
25
29
  amqp_source.start!
26
30
 
27
31
  queue.publish(header, json_payload)
28
32
 
29
33
  received_messages.size.should eql(1)
34
+ received_messages.first[:origin].should ==(queue.name)
30
35
  received_messages.first[:header].should ==(header)
31
36
  received_messages.first[:payload].should ==({:key => "value"})
32
37
  received_messages.first[:event].should ==(event_type)
@@ -9,9 +9,11 @@ module EmPipelines
9
9
  em
10
10
  end
11
11
 
12
+ let (:list_name) { "list of stuff" }
13
+
12
14
  it "sends each element on the list as a payload to the listener" do
13
15
  events = [1,2,3,4,5,6,7,8,9,10]
14
- source = BatchEventSource.new(em, events)
16
+ source = BatchEventSource.new(em, list_name, events)
15
17
 
16
18
  received = []
17
19
  source.on_event do |e|
@@ -21,15 +23,16 @@ module EmPipelines
21
23
  source.start!
22
24
 
23
25
  received.map{ |i| i[:payload] }.should ==(events)
26
+ received.each{ |i| i[:origin].should == list_name }
24
27
  end
25
28
 
26
29
  it "calls the batch finished callback when all items were processed" do
27
30
  events = [1,2,3,4,5,6,7,8,9,10]
28
- source = BatchEventSource.new(em, events)
31
+ source = BatchEventSource.new(em, list_name, events)
29
32
 
30
33
  has_finished = []
31
34
 
32
- source.on_batch_finished do |messages|
35
+ source.on_finished do |messages|
33
36
  has_finished << messages
34
37
  end
35
38
 
@@ -42,11 +45,11 @@ module EmPipelines
42
45
  has_finished.first.map{ |i| i[:payload] }.should ==(events)
43
46
  end
44
47
 
45
- it "finishes straight away if there are no events to process" do
46
- source = BatchEventSource.new(em, [])
48
+ it "finishes immediately if there are no events to process" do
49
+ source = BatchEventSource.new(em, list_name, [])
47
50
 
48
51
  has_finished = []
49
- source.on_batch_finished do |messages|
52
+ source.on_finished do |messages|
50
53
  has_finished << true
51
54
  end
52
55
 
@@ -59,11 +62,11 @@ module EmPipelines
59
62
  has_finished.first.should be_true
60
63
  end
61
64
 
62
- it "does not call the batch finished callback if not all of the items were processed" do
65
+ it "only calls the finished handler if all events were processed" do
63
66
  events = [1,2,3,4,5,6,7,8,9,10]
64
- source = BatchEventSource.new(em, events)
67
+ source = BatchEventSource.new(em, list_name, events)
65
68
 
66
- source.on_batch_finished do |messages|
69
+ source.on_finished do |messages|
67
70
  raise "should not be called"
68
71
  end
69
72
 
File without changes
@@ -0,0 +1,3 @@
1
+ 1
2
+ 2
3
+ 3
@@ -0,0 +1,87 @@
1
+ require 'empipelines/io_event_source'
2
+
3
+ module EmPipelines
4
+ describe IOEventSource do
5
+ let(:events_file) { File.join(File.dirname(__FILE__), 'io_event_source.dat')}
6
+ let(:empty_file) { File.join(File.dirname(__FILE__), 'empty_io_event_source.dat')}
7
+ let(:inexistent_file) { File.join(File.dirname(__FILE__), 'not_really_son.dat')}
8
+ let (:em) do
9
+ em = mock('eventmachine')
10
+ em.stub(:next_tick).and_yield
11
+ em
12
+ end
13
+
14
+ it 'verifies file existance' do
15
+ lambda{ IOEventSource.new(em, inexistent_file) }.should raise_error
16
+ end
17
+
18
+ it 'sends each line in the file as a message to listeners' do
19
+ source = IOEventSource.new(em, events_file)
20
+
21
+ received = []
22
+ source.on_event do |e|
23
+ received << e
24
+ end
25
+
26
+ source.start!
27
+
28
+ received.map{ |i| i[:payload].to_i }.should ==([1,2,3])
29
+ received.each{ |i| i[:origin].should == events_file }
30
+ end
31
+
32
+
33
+ it 'calls the finished callback when all messages were processed' do
34
+ source = IOEventSource.new(em, events_file)
35
+
36
+ has_finished = []
37
+
38
+ source.on_finished do |messages|
39
+ has_finished << messages
40
+ end
41
+
42
+ source.on_event do |e|
43
+ e.consumed!
44
+ end
45
+
46
+ source.start!
47
+
48
+ has_finished.first.map{ |i| i[:payload].to_i }.should ==([1,2,3])
49
+ end
50
+
51
+ it 'finishes immediately if there are no events to process' do
52
+ source = IOEventSource.new(em, empty_file)
53
+
54
+ has_finished = []
55
+ source.on_finished do |messages|
56
+ has_finished << true
57
+ end
58
+
59
+ source.on_event do |e|
60
+ raise 'should not be called!'
61
+ end
62
+
63
+ source.start!
64
+
65
+ has_finished.first.should be_true
66
+ end
67
+
68
+ it 'only calls the finished handler if all events were processed' do
69
+ source = IOEventSource.new(em, events_file)
70
+
71
+ source.on_finished do |messages|
72
+ raise "should not be called"
73
+ end
74
+
75
+ count = 0
76
+ source.on_event do |e|
77
+ e.consumed! if (count=+1) > 1
78
+ end
79
+
80
+ source.start!
81
+ end
82
+
83
+ it 'can read really long files' do
84
+ pending('current implementation is terribly naive')
85
+ end
86
+ end
87
+ end
File without changes
@@ -0,0 +1,31 @@
1
+ require 'empipelines/periodic_event_source'
2
+
3
+ module EmPipelines
4
+ describe PeriodicEventSource do
5
+ it 'schedules itself with eventmachine' do
6
+ em = stub('eventmachine')
7
+ em.should_receive(:add_periodic_timer).with(5)
8
+ PeriodicEventSource.new(em, 'a name', 5){ 'something cool!' }.start!
9
+ end
10
+
11
+ it 'sends the result of the periodic action to the handler' do
12
+ name = 'some name'
13
+ event = {:this => :is, :some => 'event'}
14
+ received_messages = []
15
+
16
+ source = PeriodicEventSource.new(stub('eventmachine'), name, 666){ event }
17
+ source.on_event { |msg| received_messages << msg}
18
+ source.tick!
19
+
20
+ received_messages.should have(1).item
21
+ received_messages[0][:payload].should eql(event)
22
+ received_messages[0][:origin].should eql(name)
23
+ end
24
+
25
+ it 'doesnt o anything if no event was generated' do
26
+ source = PeriodicEventSource.new(stub('eventmachine'), 'a name', 666){ nil }
27
+ source.on_event { |m| raise 'should not be called' }
28
+ source.tick!
29
+ end
30
+ end
31
+ end
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: empipelines
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-12-20 00:00:00.000000000Z
13
+ date: 2011-12-21 00:00:00.000000000Z
14
14
  dependencies: []
15
15
  description: Simple Event Handling Pipeline Architecture for EventMachine
16
16
  email: pcalcado+empipelines@gmail.com
@@ -24,23 +24,31 @@ files:
24
24
  - README.md
25
25
  - Rakefile
26
26
  - empipelines.gemspec
27
+ - functional/consuming_events_from_file_spec.rb
28
+ - functional/events.dat
29
+ - functional/test_stages.rb
27
30
  - lib/empipelines.rb
28
31
  - lib/empipelines/amqp_event_source.rb
29
32
  - lib/empipelines/batch_event_source.rb
33
+ - lib/empipelines/event_handlers.rb
30
34
  - lib/empipelines/event_pipeline.rb
35
+ - lib/empipelines/io_event_source.rb
31
36
  - lib/empipelines/list_event_source.rb
32
37
  - lib/empipelines/message.rb
33
38
  - lib/empipelines/periodic_event_source.rb
34
39
  - lib/empipelines/pipeline.rb
35
- - spec/empipelines/amqp_event_source_spec.rb
36
- - spec/empipelines/batch_event_source_spec.rb
37
- - spec/empipelines/event_pipeline_spec.rb
38
- - spec/empipelines/list_event_source_spec.rb
39
- - spec/empipelines/message_spec.rb
40
- - spec/empipelines/periodic_event_source_spec.rb
41
- - spec/empipelines/pipeline_spec.rb
42
- - spec/spec_helper.rb
43
- - spec/stage_helper.rb
40
+ - unit/empipelines/amqp_event_source_spec.rb
41
+ - unit/empipelines/batch_event_source_spec.rb
42
+ - unit/empipelines/empty_io_event_source.dat
43
+ - unit/empipelines/event_pipeline_spec.rb
44
+ - unit/empipelines/io_event_source.dat
45
+ - unit/empipelines/io_event_source_spec.rb
46
+ - unit/empipelines/list_event_source_spec.rb
47
+ - unit/empipelines/message_spec.rb
48
+ - unit/empipelines/periodic_event_source_spec.rb
49
+ - unit/empipelines/pipeline_spec.rb
50
+ - unit/spec_helper.rb
51
+ - unit/stage_helper.rb
44
52
  homepage: http://github.com/pcalcado/empipelines
45
53
  licenses: []
46
54
  post_install_message:
@@ -56,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
64
  version: '0'
57
65
  segments:
58
66
  - 0
59
- hash: 4504897307794021270
67
+ hash: -3827854829014823938
60
68
  required_rubygems_version: !ruby/object:Gem::Requirement
61
69
  none: false
62
70
  requirements:
@@ -1,28 +0,0 @@
1
- require 'empipelines/periodic_event_source'
2
-
3
- module EmPipelines
4
- describe PeriodicEventSource do
5
- it 'schedules itself with eventmachine' do
6
- em = stub('eventmachine')
7
- em.should_receive(:add_periodic_timer).with(5)
8
- PeriodicEventSource.new(em, 5){ "something cool!" }.start!
9
- end
10
-
11
- it 'sends the result of the periodic action to the handler' do
12
- expected_message = { :something => "goes here" }
13
- received_messages = []
14
-
15
- source = PeriodicEventSource.new(stub('eventmachine'), 666){ expected_message }
16
- source.on_event { |msg| received_messages << msg}
17
- source.tick!
18
-
19
- received_messages.should eql([expected_message])
20
- end
21
-
22
- it 'doesnt o anything if no event was generated' do
23
- source = PeriodicEventSource.new(stub('eventmachine'), 666){ nil }
24
- source.on_event { |m| raise "should not be called" }
25
- source.tick!
26
- end
27
- end
28
- end