queue-bus 0.5.0

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