queue-bus 0.5.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 (49) hide show
  1. data/.gitignore +5 -0
  2. data/.rbenv-version +1 -0
  3. data/.rspec +1 -0
  4. data/.rvmrc +2 -0
  5. data/Gemfile +6 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.mdown +264 -0
  8. data/Rakefile +1 -0
  9. data/lib/queue-bus.rb +62 -0
  10. data/lib/queue_bus/adapters/base.rb +41 -0
  11. data/lib/queue_bus/adapters/data.rb +65 -0
  12. data/lib/queue_bus/application.rb +121 -0
  13. data/lib/queue_bus/config.rb +98 -0
  14. data/lib/queue_bus/dispatch.rb +61 -0
  15. data/lib/queue_bus/dispatchers.rb +26 -0
  16. data/lib/queue_bus/driver.rb +31 -0
  17. data/lib/queue_bus/heartbeat.rb +109 -0
  18. data/lib/queue_bus/local.rb +38 -0
  19. data/lib/queue_bus/matcher.rb +81 -0
  20. data/lib/queue_bus/publisher.rb +23 -0
  21. data/lib/queue_bus/publishing.rb +80 -0
  22. data/lib/queue_bus/rider.rb +28 -0
  23. data/lib/queue_bus/subscriber.rb +65 -0
  24. data/lib/queue_bus/subscription.rb +55 -0
  25. data/lib/queue_bus/subscription_list.rb +53 -0
  26. data/lib/queue_bus/task_manager.rb +52 -0
  27. data/lib/queue_bus/util.rb +87 -0
  28. data/lib/queue_bus/version.rb +3 -0
  29. data/lib/queue_bus/worker.rb +14 -0
  30. data/lib/tasks/resquebus.rake +2 -0
  31. data/queue-bus.gemspec +32 -0
  32. data/spec/adapter/publish_at_spec.rb +48 -0
  33. data/spec/adapter/support.rb +15 -0
  34. data/spec/adapter_spec.rb +14 -0
  35. data/spec/application_spec.rb +152 -0
  36. data/spec/config_spec.rb +83 -0
  37. data/spec/dispatch_spec.rb +76 -0
  38. data/spec/driver_spec.rb +100 -0
  39. data/spec/heartbeat_spec.rb +44 -0
  40. data/spec/integration_spec.rb +53 -0
  41. data/spec/matcher_spec.rb +143 -0
  42. data/spec/publish_spec.rb +95 -0
  43. data/spec/publisher_spec.rb +7 -0
  44. data/spec/rider_spec.rb +39 -0
  45. data/spec/spec_helper.rb +69 -0
  46. data/spec/subscriber_spec.rb +268 -0
  47. data/spec/subscription_list_spec.rb +43 -0
  48. data/spec/subscription_spec.rb +53 -0
  49. metadata +192 -0
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Driver do
5
+ before(:each) do
6
+ Application.new("app1").subscribe(test_list(test_sub("event1"), test_sub("event2"), test_sub("event3")))
7
+ Application.new("app2").subscribe(test_list(test_sub("event2","other"), test_sub("event4", "more")))
8
+ Application.new("app3").subscribe(test_list(test_sub("event[45]"), test_sub("event5"), test_sub("event6")))
9
+ Timecop.freeze
10
+ end
11
+ after(:each) do
12
+ Timecop.return
13
+ end
14
+
15
+ let(:bus_attrs) { {"bus_driven_at" => Time.now.to_i, "bus_rider_class_name"=>"::QueueBus::Rider"} }
16
+
17
+ describe ".subscription_matches" do
18
+ it "return empty array when none" do
19
+ Driver.subscription_matches("bus_event_type" => "else").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
20
+ Driver.subscription_matches("bus_event_type" => "event").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should == []
21
+ end
22
+ it "should return a match" do
23
+ Driver.subscription_matches("bus_event_type" => "event1").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app1", "event1", "default", "::QueueBus::Rider"]]
24
+ Driver.subscription_matches("bus_event_type" => "event6").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app3", "event6", "default", "::QueueBus::Rider"]]
25
+ end
26
+ it "should match multiple apps" do
27
+ Driver.subscription_matches("bus_event_type" => "event2").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app1", "event2", "default", "::QueueBus::Rider"], ["app2", "event2", "other", "::QueueBus::Rider"]]
28
+ end
29
+ it "should match multiple apps with patterns" do
30
+ Driver.subscription_matches("bus_event_type" => "event4").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app3", "event[45]", "default", "::QueueBus::Rider"], ["app2", "event4", "more", "::QueueBus::Rider"]]
31
+ end
32
+ it "should match multiple events in same app" do
33
+ Driver.subscription_matches("bus_event_type" => "event5").collect{|s| [s.app_key, s.key, s.queue_name, s.class_name]}.should =~ [["app3", "event[45]", "default", "::QueueBus::Rider"], ["app3", "event5", "default", "::QueueBus::Rider"]]
34
+ end
35
+ end
36
+
37
+ describe ".perform" do
38
+ let(:attributes) { {"x" => "y"} }
39
+
40
+ before(:each) do
41
+ QueueBus.redis { |redis| redis.smembers("queues") }.should == []
42
+ QueueBus.redis { |redis| redis.lpop("queue:app1_default") }.should be_nil
43
+ QueueBus.redis { |redis| redis.lpop("queue:app2_default") }.should be_nil
44
+ QueueBus.redis { |redis| redis.lpop("queue:app3_default") }.should be_nil
45
+ end
46
+
47
+ it "should do nothing when empty" do
48
+ Driver.perform(attributes.merge("bus_event_type" => "else"))
49
+ QueueBus.redis { |redis| redis.smembers("queues") }.should == []
50
+ end
51
+
52
+ it "should queue up the riders in redis" do
53
+ QueueBus.redis { |redis| redis.lpop("queue:app1_default") }.should be_nil
54
+ Driver.perform(attributes.merge("bus_event_type" => "event1"))
55
+ QueueBus.redis { |redis| redis.smembers("queues") }.should =~ ["default"]
56
+
57
+ hash = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
58
+ hash["class"].should == "::QueueBus::Rider"
59
+ hash["args"].should == [ {"bus_rider_app_key"=>"app1", "x" => "y", "bus_event_type" => "event1", "bus_rider_sub_key"=>"event1", "bus_rider_queue" => "default"}.merge(bus_attrs) ]
60
+ end
61
+
62
+ it "should queue up to multiple" do
63
+ Driver.perform(attributes.merge("bus_event_type" => "event4"))
64
+ QueueBus.redis { |redis| redis.smembers("queues") }.should =~ ["default", "more"]
65
+
66
+ hash = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:more") })
67
+ hash["class"].should == "::QueueBus::Rider"
68
+ hash["args"].should == [ {"bus_rider_app_key"=>"app2", "x" => "y", "bus_event_type" => "event4", "bus_rider_sub_key"=>"event4", "bus_rider_queue" => "more"}.merge(bus_attrs) ]
69
+
70
+ hash = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
71
+ hash["class"].should == "::QueueBus::Rider"
72
+ hash["args"].should == [ {"bus_rider_app_key"=>"app3", "x" => "y", "bus_event_type" => "event4", "bus_rider_sub_key"=>"event[45]", "bus_rider_queue" => "default"}.merge(bus_attrs) ]
73
+ end
74
+
75
+ it "should queue up to the same" do
76
+ Driver.perform(attributes.merge("bus_event_type" => "event5"))
77
+ QueueBus.redis { |redis| redis.smembers("queues") }.should =~ ["default"]
78
+
79
+ QueueBus.redis { |redis| redis.llen("queue:default") }.should == 2
80
+
81
+ pop1 = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
82
+ pop2 = JSON.parse(QueueBus.redis { |redis| redis.lpop("queue:default") })
83
+
84
+ if pop1["args"][0]["bus_rider_sub_key"] == "event5"
85
+ hash1 = pop1
86
+ hash2 = pop2
87
+ else
88
+ hash1 = pop2
89
+ hash2 = pop1
90
+ end
91
+
92
+ hash1["class"].should == "::QueueBus::Rider"
93
+ hash1["args"][0].should == {"bus_rider_app_key"=>"app3", "x" => "y", "bus_event_type" => "event5", "bus_rider_sub_key"=>"event5", "bus_rider_queue" => "default"}.merge(bus_attrs)
94
+
95
+ hash2["class"].should == "::QueueBus::Rider"
96
+ hash2["args"][0].should == {"bus_rider_app_key"=>"app3", "x" => "y", "bus_event_type" => "event5", "bus_rider_sub_key"=>"event[45]", "bus_rider_queue" => "default"}.merge(bus_attrs)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Heartbeat do
5
+ def now_attributes
6
+ {
7
+ "epoch_seconds" => (Time.now.to_i / 60) * 60, # rounded
8
+ "epoch_minutes" => Time.now.to_i / 60,
9
+ "epoch_hours" => Time.now.to_i / (60*60),
10
+ "epoch_days" => Time.now.to_i / (60*60*24),
11
+ "minute" => Time.now.min,
12
+ "hour" => Time.now.hour,
13
+ "day" => Time.now.day,
14
+ "month" => Time.now.month,
15
+ "year" => Time.now.year,
16
+ "yday" => Time.now.yday,
17
+ "wday" => Time.now.wday
18
+ }
19
+ end
20
+
21
+ it "should publish the current time once" do
22
+ Timecop.freeze "12/12/2013 12:01:19" do
23
+ QueueBus.should_receive(:publish).with("heartbeat_minutes", now_attributes)
24
+ Heartbeat.perform
25
+ end
26
+
27
+ Timecop.freeze "12/12/2013 12:01:40" do
28
+ Heartbeat.perform
29
+ end
30
+ end
31
+
32
+ it "should publish a minute later" do
33
+ Timecop.freeze "12/12/2013 12:01:19" do
34
+ QueueBus.should_receive(:publish).with("heartbeat_minutes", now_attributes)
35
+ Heartbeat.perform
36
+ end
37
+
38
+ Timecop.freeze "12/12/2013 12:02:01" do
39
+ QueueBus.should_receive(:publish).with("heartbeat_minutes", now_attributes)
40
+ Heartbeat.perform
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe "Integration" do
5
+ it "should round trip attributes" do
6
+ write1 = Subscription.new("default", "key1", "MyClass1", {"bus_event_type" => "event_one"})
7
+ write2 = Subscription.new("else_ok", "key2", "MyClass2", {"bus_event_type" => /^[ab]here/}) #regex
8
+
9
+ write1.matches?("bus_event_type" => "event_one").should == true
10
+ write1.matches?("bus_event_type" => "event_one1").should == false
11
+ write1.matches?("bus_event_type" => "aevent_one").should == false
12
+
13
+ write2.matches?("bus_event_type" => "ahere").should == true
14
+ write2.matches?("bus_event_type" => "bhere").should == true
15
+ write2.matches?("bus_event_type" => "qhere").should == false
16
+ write2.matches?("bus_event_type" => "abhere").should == false
17
+ write2.matches?("bus_event_type" => "[ab]here").should == false
18
+
19
+ write = SubscriptionList.new
20
+ write.add(write1)
21
+ write.add(write2)
22
+
23
+ app = Application.new("test")
24
+ app.subscribe(write)
25
+
26
+ reset_test_adapter # reset to make sure we read from redis
27
+ app = Application.new("test")
28
+ read = app.send(:subscriptions)
29
+
30
+ read.size.should == 2
31
+ read1 = read.key("key1")
32
+ read2 = read.key("key2")
33
+ read1.should_not be_nil
34
+ read2.should_not be_nil
35
+
36
+ read1.queue_name.should == "default"
37
+ read1.class_name.should == "MyClass1"
38
+ read2.queue_name.should == "else_ok"
39
+ read2.class_name.should == "MyClass2"
40
+
41
+ read1.matches?("bus_event_type" => "event_one").should == true
42
+ read1.matches?("bus_event_type" => "event_one1").should == false
43
+ read1.matches?("bus_event_type" => "aevent_one").should == false
44
+
45
+ read2.matches?("bus_event_type" => "ahere").should == true
46
+ read2.matches?("bus_event_type" => "bhere").should == true
47
+ read2.matches?("bus_event_type" => "qhere").should == false
48
+ read2.matches?("bus_event_type" => "abhere").should == false
49
+ read2.matches?("bus_event_type" => "[ab]here").should == false
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Matcher do
5
+ it "should already return false on empty filters" do
6
+ matcher = Matcher.new({})
7
+ matcher.matches?({}).should == false
8
+ matcher.matches?(nil).should == false
9
+ matcher.matches?("name" => "val").should == false
10
+ end
11
+
12
+ it "should not crash if nil inputs" do
13
+ matcher = Matcher.new("name" => "val")
14
+ matcher.matches?(nil).should == false
15
+ end
16
+
17
+ it "string filter to/from redis" do
18
+ matcher = Matcher.new("name" => "val")
19
+ matcher.matches?("name" => "val").should == true
20
+ matcher.matches?("name" => " val").should == false
21
+ matcher.matches?("name" => "zval").should == false
22
+ end
23
+
24
+ it "regex filter" do
25
+ matcher = Matcher.new("name" => /^[cb]a+t/)
26
+ matcher.matches?("name" => "cat").should == true
27
+ matcher.matches?("name" => "bat").should == true
28
+ matcher.matches?("name" => "caaaaat").should == true
29
+ matcher.matches?("name" => "ct").should == false
30
+ matcher.matches?("name" => "bcat").should == false
31
+ end
32
+
33
+ it "present filter" do
34
+ matcher = Matcher.new("name" => :present)
35
+ matcher.matches?("name" => "").should == false
36
+ matcher.matches?("name" => "cat").should == true
37
+ matcher.matches?("name" => "bear").should == true
38
+ matcher.matches?("other" => "bear").should == false
39
+ end
40
+
41
+ it "blank filter" do
42
+ matcher = Matcher.new("name" => :blank)
43
+ matcher.matches?("name" => nil).should == true
44
+ matcher.matches?("other" => "bear").should == true
45
+ matcher.matches?("name" => "").should == true
46
+ matcher.matches?("name" => " ").should == true
47
+ matcher.matches?("name" => "bear").should == false
48
+ matcher.matches?("name" => " s ").should == false
49
+ end
50
+
51
+ it "nil filter" do
52
+ matcher = Matcher.new("name" => :nil)
53
+ matcher.matches?("name" => nil).should == true
54
+ matcher.matches?("other" => "bear").should == true
55
+ matcher.matches?("name" => "").should == false
56
+ matcher.matches?("name" => " ").should == false
57
+ matcher.matches?("name" => "bear").should == false
58
+ end
59
+
60
+ it "key filter" do
61
+ matcher = Matcher.new("name" => :key)
62
+ matcher.matches?("name" => nil).should == true
63
+ matcher.matches?("other" => "bear").should == false
64
+ matcher.matches?("name" => "").should == true
65
+ matcher.matches?("name" => " ").should == true
66
+ matcher.matches?("name" => "bear").should == true
67
+ end
68
+
69
+ it "empty filter" do
70
+ matcher = Matcher.new("name" => :empty)
71
+ matcher.matches?("name" => nil).should == false
72
+ matcher.matches?("other" => "bear").should == false
73
+ matcher.matches?("name" => "").should == true
74
+ matcher.matches?("name" => " ").should == false
75
+ matcher.matches?("name" => "bear").should == false
76
+ matcher.matches?("name" => " s ").should == false
77
+ end
78
+
79
+ it "value filter" do
80
+ matcher = Matcher.new("name" => :value)
81
+ matcher.matches?("name" => nil).should == false
82
+ matcher.matches?("other" => "bear").should == false
83
+ matcher.matches?("name" => "").should == true
84
+ matcher.matches?("name" => " ").should == true
85
+ matcher.matches?("name" => "bear").should == true
86
+ matcher.matches?("name" => " s ").should == true
87
+ end
88
+
89
+ it "multiple filters" do
90
+ matcher = Matcher.new("name" => /^[cb]a+t/, "state" => "sleeping")
91
+ matcher.matches?("state" => "sleeping", "name" => "cat").should == true
92
+ matcher.matches?("state" => "awake", "name" => "cat").should == false
93
+ matcher.matches?("state" => "sleeping", "name" => "bat").should == true
94
+ matcher.matches?("state" => "sleeping", "name" => "bear").should == false
95
+ matcher.matches?("state" => "awake", "name" => "bear").should == false
96
+ end
97
+
98
+ it "regex should go back and forth into redis" do
99
+ matcher = Matcher.new("name" => /^[cb]a+t/)
100
+ matcher.matches?("name" => "cat").should == true
101
+ matcher.matches?("name" => "bat").should == true
102
+ matcher.matches?("name" => "caaaaat").should == true
103
+ matcher.matches?("name" => "ct").should == false
104
+ matcher.matches?("name" => "bcat").should == false
105
+
106
+ QueueBus.redis { |redis| redis.set("temp1", QueueBus::Util.encode(matcher.to_redis) ) }
107
+ redis = QueueBus.redis { |redis| redis.get("temp1") }
108
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
109
+ matcher.matches?("name" => "cat").should == true
110
+ matcher.matches?("name" => "bat").should == true
111
+ matcher.matches?("name" => "caaaaat").should == true
112
+ matcher.matches?("name" => "ct").should == false
113
+ matcher.matches?("name" => "bcat").should == false
114
+
115
+ QueueBus.redis { |redis| redis.set("temp2", QueueBus::Util.encode(matcher.to_redis) ) }
116
+ redis = QueueBus.redis { |redis| redis.get("temp2") }
117
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
118
+ matcher.matches?("name" => "cat").should == true
119
+ matcher.matches?("name" => "bat").should == true
120
+ matcher.matches?("name" => "caaaaat").should == true
121
+ matcher.matches?("name" => "ct").should == false
122
+ matcher.matches?("name" => "bcat").should == false
123
+ end
124
+
125
+ it "special value should go back and forth into redis" do
126
+ matcher = Matcher.new("name" => :blank)
127
+ matcher.matches?("name" => "cat").should == false
128
+ matcher.matches?("name" => "").should == true
129
+
130
+ QueueBus.redis { |redis| redis.set("temp1", QueueBus::Util.encode(matcher.to_redis) ) }
131
+ redis= QueueBus.redis { |redis| redis.get("temp1") }
132
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
133
+ matcher.matches?("name" => "cat").should == false
134
+ matcher.matches?("name" => "").should == true
135
+
136
+ QueueBus.redis { |redis| redis.set("temp2", QueueBus::Util.encode(matcher.to_redis) ) }
137
+ redis= QueueBus.redis { |redis| redis.get("temp2") }
138
+ matcher = Matcher.new(QueueBus::Util.decode(redis))
139
+ matcher.matches?("name" => "cat").should == false
140
+ matcher.matches?("name" => "").should == true
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Publishing an event" do
4
+
5
+ before(:each) do
6
+ Timecop.freeze
7
+ QueueBus.stub(:generate_uuid).and_return("idfhlkj")
8
+ end
9
+ after(:each) do
10
+ Timecop.return
11
+ end
12
+ let(:bus_attrs) { {"bus_published_at" => Time.now.to_i,
13
+ "bus_id"=>"#{Time.now.to_i}-idfhlkj",
14
+ "bus_app_hostname" => `hostname 2>&1`.strip.sub(/.local/,'')} }
15
+
16
+ it "should add it to Redis" do
17
+ hash = {:one => 1, "two" => "here", "id" => 12 }
18
+ event_name = "event_name"
19
+
20
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
21
+ val.should == nil
22
+
23
+ QueueBus.publish(event_name, hash)
24
+
25
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
26
+ hash = JSON.parse(val)
27
+ hash["class"].should == "QueueBus::Driver"
28
+ hash["args"].should == [ {"bus_event_type" => event_name, "two"=>"here", "one"=>1, "id" => 12}.merge(bus_attrs) ]
29
+
30
+ end
31
+
32
+ it "should use the id if given" do
33
+ hash = {:one => 1, "two" => "here", "bus_id" => "app-given" }
34
+ event_name = "event_name"
35
+
36
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
37
+ val.should == nil
38
+
39
+ QueueBus.publish(event_name, hash)
40
+
41
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
42
+ hash = JSON.parse(val)
43
+ hash["class"].should == "QueueBus::Driver"
44
+ hash["args"].should == [ {"bus_event_type" => event_name, "two"=>"here", "one"=>1}.merge(bus_attrs).merge("bus_id" => 'app-given') ]
45
+ end
46
+
47
+ it "should add metadata via callback" do
48
+ myval = 0
49
+ QueueBus.before_publish = lambda { |att|
50
+ att["mine"] = 4
51
+ myval += 1
52
+ }
53
+
54
+ hash = {:one => 1, "two" => "here", "bus_id" => "app-given" }
55
+ event_name = "event_name"
56
+
57
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
58
+ val.should == nil
59
+
60
+ QueueBus.publish(event_name, hash)
61
+
62
+
63
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
64
+ hash = JSON.parse(val)
65
+ att = hash["args"].first
66
+ att["mine"].should == 4
67
+ myval.should == 1
68
+ end
69
+
70
+ it "should set the timezone and locale if available" do
71
+ defined?(I18n).should be_nil
72
+ Time.respond_to?(:zone).should eq(false)
73
+
74
+ stub_const("I18n", Class.new)
75
+ I18n.stub(:locale).and_return("jp")
76
+
77
+ Time.stub(:zone).and_return(double('zone', :name => "EST"))
78
+
79
+ hash = {:one => 1, "two" => "here", "bus_id" => "app-given" }
80
+ event_name = "event_name"
81
+
82
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
83
+ val.should == nil
84
+
85
+ QueueBus.publish(event_name, hash)
86
+
87
+ val = QueueBus.redis { |redis| redis.lpop("queue:bus_incoming") }
88
+ hash = JSON.parse(val)
89
+ hash["class"].should == "QueueBus::Driver"
90
+ att = hash["args"].first
91
+ att["bus_locale"].should == "jp"
92
+ att["bus_timezone"].should == "EST"
93
+ end
94
+
95
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Publisher do
5
+ it "should call publish as expected"
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module QueueBus
4
+ describe Rider do
5
+ it "should call execute" do
6
+ QueueBus.should_receive(:dispatcher_execute)
7
+ Rider.perform("bus_rider_app_key" => "app", "bus_rider_sub_key" => "sub", "ok" => true, "bus_event_type" => "event_name")
8
+ end
9
+
10
+ it "should change the value" do
11
+ QueueBus.dispatch("r1") do
12
+ subscribe "event_name" do |attributes|
13
+ Runner1.run(attributes)
14
+ end
15
+ end
16
+ Runner1.value.should == 0
17
+ Rider.perform("bus_locale" => "en", "bus_timezone" => "PST", "bus_rider_app_key" => "r1", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
18
+ Rider.perform("bus_rider_app_key" => "other", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
19
+ Runner1.value.should == 1
20
+ end
21
+
22
+ it "should set the timezone and locale if present" do
23
+ QueueBus.dispatch("r1") do
24
+ subscribe "event_name" do |attributes|
25
+ Runner1.run(attributes)
26
+ end
27
+ end
28
+
29
+ defined?(I18n).should be_nil
30
+ Time.respond_to?(:zone).should eq(false)
31
+
32
+ stub_const("I18n", Class.new)
33
+ I18n.should_receive(:locale=).with("en")
34
+ Time.should_receive(:zone=).with("PST")
35
+
36
+ Rider.perform("bus_locale" => "en", "bus_timezone" => "PST", "bus_rider_app_key" => "r1", "bus_rider_sub_key" => "event_name", "ok" => true, "bus_event_type" => "event_name")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,69 @@
1
+ require 'timecop'
2
+ require 'queue-bus'
3
+ require 'adapter/support'
4
+
5
+ reset_test_adapter
6
+
7
+ module QueueBus
8
+ class Runner
9
+ def self.value
10
+ @value ||= 0
11
+ end
12
+
13
+ def self.attributes
14
+ @attributes
15
+ end
16
+
17
+ def self.run(attrs)
18
+ @value ||= 0
19
+ @value += 1
20
+ @attributes = attrs
21
+ end
22
+
23
+ def self.reset
24
+ @value = nil
25
+ @attributes = nil
26
+ end
27
+ end
28
+
29
+ class Runner1 < Runner
30
+ end
31
+
32
+ class Runner2 < Runner
33
+ end
34
+ end
35
+
36
+ def test_sub(event_name, queue="default")
37
+ matcher = {"bus_event_type" => event_name}
38
+ QueueBus::Subscription.new(queue, event_name, "::QueueBus::Rider", matcher, nil)
39
+ end
40
+
41
+ def test_list(*args)
42
+ out = QueueBus::SubscriptionList.new
43
+ args.each do |sub|
44
+ out.add(sub)
45
+ end
46
+ out
47
+ end
48
+
49
+ RSpec.configure do |config|
50
+ config.mock_with :rspec do |c|
51
+ c.syntax = :should
52
+ end
53
+ config.expect_with :rspec do |c|
54
+ c.syntax = :should
55
+ end
56
+
57
+ config.before(:each) do
58
+ reset_test_adapter
59
+ end
60
+ config.after(:each) do
61
+ begin
62
+ QueueBus.redis { |redis| redis.flushall }
63
+ rescue
64
+ end
65
+ QueueBus.send(:reset)
66
+ QueueBus::Runner1.reset
67
+ QueueBus::Runner2.reset
68
+ end
69
+ end