onstomp 1.0.0pre1

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 (80) hide show
  1. data/.autotest +2 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +2 -0
  4. data/.yardopts +5 -0
  5. data/CHANGELOG.md +4 -0
  6. data/DeveloperNarrative.md +15 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.md +221 -0
  9. data/README.md +73 -0
  10. data/Rakefile +6 -0
  11. data/UserNarrative.md +8 -0
  12. data/examples/basic.rb +40 -0
  13. data/examples/events.rb +72 -0
  14. data/lib/onstomp/client.rb +152 -0
  15. data/lib/onstomp/components/frame.rb +108 -0
  16. data/lib/onstomp/components/frame_headers.rb +212 -0
  17. data/lib/onstomp/components/nil_processor.rb +20 -0
  18. data/lib/onstomp/components/scopes/header_scope.rb +25 -0
  19. data/lib/onstomp/components/scopes/receipt_scope.rb +25 -0
  20. data/lib/onstomp/components/scopes/transaction_scope.rb +191 -0
  21. data/lib/onstomp/components/scopes.rb +45 -0
  22. data/lib/onstomp/components/subscription.rb +30 -0
  23. data/lib/onstomp/components/threaded_processor.rb +62 -0
  24. data/lib/onstomp/components/uri.rb +30 -0
  25. data/lib/onstomp/components.rb +13 -0
  26. data/lib/onstomp/connections/base.rb +208 -0
  27. data/lib/onstomp/connections/heartbeating.rb +82 -0
  28. data/lib/onstomp/connections/serializers/stomp_1.rb +166 -0
  29. data/lib/onstomp/connections/serializers/stomp_1_0.rb +41 -0
  30. data/lib/onstomp/connections/serializers/stomp_1_1.rb +134 -0
  31. data/lib/onstomp/connections/serializers.rb +9 -0
  32. data/lib/onstomp/connections/stomp_1.rb +69 -0
  33. data/lib/onstomp/connections/stomp_1_0.rb +28 -0
  34. data/lib/onstomp/connections/stomp_1_1.rb +65 -0
  35. data/lib/onstomp/connections.rb +119 -0
  36. data/lib/onstomp/interfaces/client_configurable.rb +55 -0
  37. data/lib/onstomp/interfaces/client_events.rb +168 -0
  38. data/lib/onstomp/interfaces/connection_events.rb +62 -0
  39. data/lib/onstomp/interfaces/event_manager.rb +69 -0
  40. data/lib/onstomp/interfaces/frame_methods.rb +190 -0
  41. data/lib/onstomp/interfaces/receipt_manager.rb +33 -0
  42. data/lib/onstomp/interfaces/subscription_manager.rb +48 -0
  43. data/lib/onstomp/interfaces/uri_configurable.rb +106 -0
  44. data/lib/onstomp/interfaces.rb +14 -0
  45. data/lib/onstomp/version.rb +13 -0
  46. data/lib/onstomp.rb +147 -0
  47. data/onstomp.gemspec +29 -0
  48. data/spec/onstomp/client_spec.rb +265 -0
  49. data/spec/onstomp/components/frame_headers_spec.rb +163 -0
  50. data/spec/onstomp/components/frame_spec.rb +144 -0
  51. data/spec/onstomp/components/nil_processor_spec.rb +32 -0
  52. data/spec/onstomp/components/scopes/header_scope_spec.rb +27 -0
  53. data/spec/onstomp/components/scopes/receipt_scope_spec.rb +33 -0
  54. data/spec/onstomp/components/scopes/transaction_scope_spec.rb +227 -0
  55. data/spec/onstomp/components/scopes_spec.rb +63 -0
  56. data/spec/onstomp/components/subscription_spec.rb +58 -0
  57. data/spec/onstomp/components/threaded_processor_spec.rb +92 -0
  58. data/spec/onstomp/components/uri_spec.rb +33 -0
  59. data/spec/onstomp/connections/base_spec.rb +349 -0
  60. data/spec/onstomp/connections/heartbeating_spec.rb +132 -0
  61. data/spec/onstomp/connections/serializers/stomp_1_0_spec.rb +50 -0
  62. data/spec/onstomp/connections/serializers/stomp_1_1_spec.rb +99 -0
  63. data/spec/onstomp/connections/serializers/stomp_1_spec.rb +104 -0
  64. data/spec/onstomp/connections/stomp_1_0_spec.rb +54 -0
  65. data/spec/onstomp/connections/stomp_1_1_spec.rb +137 -0
  66. data/spec/onstomp/connections/stomp_1_spec.rb +113 -0
  67. data/spec/onstomp/connections_spec.rb +135 -0
  68. data/spec/onstomp/interfaces/client_events_spec.rb +108 -0
  69. data/spec/onstomp/interfaces/connection_events_spec.rb +55 -0
  70. data/spec/onstomp/interfaces/event_manager_spec.rb +72 -0
  71. data/spec/onstomp/interfaces/frame_methods_spec.rb +109 -0
  72. data/spec/onstomp/interfaces/receipt_manager_spec.rb +53 -0
  73. data/spec/onstomp/interfaces/subscription_manager_spec.rb +64 -0
  74. data/spec/onstomp_spec.rb +15 -0
  75. data/spec/spec_helper.rb +12 -0
  76. data/spec/support/custom_argument_matchers.rb +51 -0
  77. data/spec/support/frame_matchers.rb +88 -0
  78. data/spec/support/shared_frame_method_examples.rb +116 -0
  79. data/yard_extensions.rb +32 -0
  80. metadata +219 -0
@@ -0,0 +1,55 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ module OnStomp::Interfaces
5
+ describe ConnectionEvents do
6
+ let(:client) { mock('client') }
7
+ let(:eventable) {
8
+ mock('eventable', :client => client).tap do |m|
9
+ m.extend ConnectionEvents
10
+ end
11
+ }
12
+
13
+ describe "connection event methods" do
14
+ it "should provide a 'on_established' event" do
15
+ triggered = false
16
+ eventable.on_established { triggered = true }
17
+ eventable.trigger_connection_event :established
18
+ triggered.should be_true
19
+ end
20
+ it "should provide a 'on_closed' event" do
21
+ triggered = false
22
+ eventable.on_closed { triggered = true }
23
+ eventable.trigger_connection_event :closed
24
+ triggered.should be_true
25
+ end
26
+ it "should provide a 'on_died' event" do
27
+ triggered = false
28
+ eventable.on_died { triggered = true }
29
+ eventable.trigger_connection_event :died
30
+ triggered.should be_true
31
+ end
32
+ it "should provide a 'on_terminated' event" do
33
+ triggered = false
34
+ eventable.on_terminated { triggered = true }
35
+ eventable.trigger_connection_event :terminated
36
+ triggered.should be_true
37
+ end
38
+ end
39
+
40
+ describe ".install_bindings_from_client" do
41
+ let(:callback1) { mock('callback1') }
42
+ let(:callback2) { mock('callback2') }
43
+ let(:callback3) { mock('callback3') }
44
+
45
+ it "should bind events from the hash and trigger connected" do
46
+ eventable.should_receive(:bind_event).with(:ev1, callback3)
47
+ eventable.should_receive(:bind_event).with(:ev1, callback2)
48
+ eventable.should_receive(:bind_event).with(:ev2, callback1)
49
+ eventable.should_receive(:trigger_connection_event).with(:established)
50
+ eventable.install_bindings_from_client :ev1 => [callback3, callback2],
51
+ :ev2 => [callback1]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,72 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ module OnStomp::Interfaces
5
+ describe EventManager do
6
+ let(:eventable) {
7
+ mock('eventable').tap do |m|
8
+ m.extend EventManager
9
+ end
10
+ }
11
+ describe ".bind_event / .trigger_event" do
12
+ it "should bind a proc and call it when the event is triggered" do
13
+ triggered = nil
14
+ eventable.bind_event(:some_event_name,
15
+ lambda { |a1, a2| triggered = [a1, a2] })
16
+ eventable.trigger_event :some_event_name, 3, 'test'
17
+ triggered.should == [3, 'test']
18
+ end
19
+ end
20
+
21
+ describe ".event_callbacks" do
22
+ it "should provide an empty array for an unbound event" do
23
+ eventable.event_callbacks[:foo_bar_bazz].should == []
24
+ end
25
+ end
26
+
27
+ describe "::create_event_method(s)" do
28
+ before(:each) do
29
+ class TestEventManager
30
+ include EventManager
31
+ create_event_method :foo_event1
32
+ create_event_methods :foo_event2
33
+ create_event_methods :foo_event3, :before, :during, :after
34
+ end
35
+ end
36
+ let(:test_eventable) {
37
+ TestEventManager.new
38
+ }
39
+
40
+ it "should have a 'foo_event' method" do
41
+ triggered = false
42
+ test_eventable.foo_event1 { triggered = true }
43
+ test_eventable.trigger_event :foo_event1, 'arg'
44
+ triggered.should be_true
45
+ end
46
+ it "should have a 'on_foo_event2' method" do
47
+ triggered = false
48
+ test_eventable.on_foo_event2 { triggered = true }
49
+ test_eventable.trigger_event :on_foo_event2, 'arg'
50
+ triggered.should be_true
51
+ end
52
+ it "should have a 'before_foo_event3' method" do
53
+ triggered = false
54
+ test_eventable.before_foo_event3 { triggered = true }
55
+ test_eventable.trigger_event :before_foo_event3, 'arg'
56
+ triggered.should be_true
57
+ end
58
+ it "should have a 'during_foo_event3' method" do
59
+ triggered = false
60
+ test_eventable.during_foo_event3 { triggered = true }
61
+ test_eventable.trigger_event :during_foo_event3, 'arg'
62
+ triggered.should be_true
63
+ end
64
+ it "should have a 'after_foo_event3' method" do
65
+ triggered = false
66
+ test_eventable.after_foo_event3 { triggered = true }
67
+ test_eventable.trigger_event :after_foo_event3, 'arg'
68
+ triggered.should be_true
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,109 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ module OnStomp::Interfaces
5
+ describe FrameMethods do
6
+ let(:connection) {
7
+ mock('connection')
8
+ }
9
+ let(:framer) {
10
+ mock('framer', :connection => connection).tap do |m|
11
+ m.extend FrameMethods
12
+ end
13
+ }
14
+ let(:headers) {
15
+ { :header1 => 'value 1' }
16
+ }
17
+ let(:frame) {
18
+ mock('frame')
19
+ }
20
+ let(:callback) {
21
+ lambda { }
22
+ }
23
+
24
+ describe ".send" do
25
+ it "should transmit the result of connection.send_frame and callbacks" do
26
+ connection.should_receive(:send_frame).with('/queue/test', 'frame body', headers).and_return(frame)
27
+ framer.should_receive(:transmit).with(frame, { :receipt => callback })
28
+ framer.send('/queue/test', 'frame body', headers, &callback)
29
+ end
30
+ it "should be aliased as .puts" do
31
+ connection.should_receive(:send_frame).with('/queue/test', 'frame body', headers).and_return(frame)
32
+ framer.should_receive(:transmit).with(frame, { :receipt => callback })
33
+ framer.puts('/queue/test', 'frame body', headers, &callback)
34
+ end
35
+ end
36
+
37
+ describe ".subscribe" do
38
+ it "should transmit the result of connection.subscribe_frame and callbacks" do
39
+ connection.should_receive(:subscribe_frame).with('/queue/test2', headers).and_return(frame)
40
+ framer.should_receive(:transmit).with(frame, { :subscribe => callback })
41
+ framer.subscribe('/queue/test2', headers, &callback)
42
+ end
43
+ end
44
+
45
+ describe ".unsubscribe" do
46
+ it "should transmit the result of connection.unsubscribe_frame" do
47
+ connection.should_receive(:unsubscribe_frame).with('frame_or_id', headers).and_return(frame)
48
+ framer.should_receive(:transmit).with(frame)
49
+ framer.unsubscribe('frame_or_id', headers)
50
+ end
51
+ end
52
+
53
+ describe ".begin" do
54
+ it "should transmit the result of connection.begin_frame" do
55
+ connection.should_receive(:begin_frame).with('tx_id', headers).and_return(frame)
56
+ framer.should_receive(:transmit).with(frame)
57
+ framer.begin('tx_id', headers)
58
+ end
59
+ end
60
+
61
+ describe ".abort" do
62
+ it "should transmit the result of connection.abort_frame" do
63
+ connection.should_receive(:abort_frame).with('tx_id', headers).and_return(frame)
64
+ framer.should_receive(:transmit).with(frame)
65
+ framer.abort('tx_id', headers)
66
+ end
67
+ end
68
+
69
+ describe ".commit" do
70
+ it "should transmit the result of connection.commit_frame" do
71
+ connection.should_receive(:commit_frame).with('tx_id', headers).and_return(frame)
72
+ framer.should_receive(:transmit).with(frame)
73
+ framer.commit('tx_id', headers)
74
+ end
75
+ end
76
+
77
+ describe ".disconnect" do
78
+ it "should transmit the result of connection.disconnect_frame" do
79
+ connection.should_receive(:disconnect_frame).with(headers).and_return(frame)
80
+ framer.should_receive(:transmit).with(frame)
81
+ framer.disconnect(headers)
82
+ end
83
+ end
84
+
85
+ describe ".ack" do
86
+ it "should transmit the result of connection.ack_frame" do
87
+ connection.should_receive(:ack_frame).with('arg1', headers, :arg2).and_return(frame)
88
+ framer.should_receive(:transmit).with(frame)
89
+ framer.ack('arg1', headers, :arg2)
90
+ end
91
+ end
92
+
93
+ describe ".nack" do
94
+ it "should transmit the result of connection.nack_frame" do
95
+ connection.should_receive(:nack_frame).with('arg1', headers, :arg2).and_return(frame)
96
+ framer.should_receive(:transmit).with(frame)
97
+ framer.nack('arg1', headers, :arg2)
98
+ end
99
+ end
100
+
101
+ describe ".beat" do
102
+ it "should transmit the result of connection.heartbeat_frame" do
103
+ connection.should_receive(:heartbeat_frame).and_return(frame)
104
+ framer.should_receive(:transmit).with(frame)
105
+ framer.beat
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,53 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ module OnStomp::Interfaces
5
+ describe ReceiptManager do
6
+ let(:client) {
7
+ mock('mock client').tap do |m|
8
+ m.extend ClientEvents
9
+ m.extend ReceiptManager
10
+ end
11
+ }
12
+ let(:frame) {
13
+ OnStomp::Components::Frame.new('COMMAND', :receipt => 'r-1234')
14
+ }
15
+ let(:receipt_frame) {
16
+ OnStomp::Components::Frame.new('RECEIPT', :'receipt-id' => 'r-1234')
17
+ }
18
+ before(:each) do
19
+ client.__send__(:configure_receipt_management)
20
+ end
21
+ after(:each) do
22
+ client.__send__(:clear_receipts)
23
+ end
24
+
25
+ describe "adding receipt callbacks" do
26
+ it "should add a callback and invoke it upon receiving its RECEIPT" do
27
+ triggered = false
28
+ client.__send__ :add_receipt, frame, lambda { |r| triggered = true }
29
+ client.trigger_after_receiving receipt_frame
30
+ triggered.should be_true
31
+ end
32
+ it "should create a receipt header if one does not exist" do
33
+ frame.headers.delete :receipt
34
+ triggered = false
35
+ client.__send__ :add_receipt, frame, lambda { |r| triggered = true }
36
+ frame[:receipt].should_not be_nil
37
+ frame[:receipt].should_not be_empty
38
+ receipt_frame[:'receipt-id'] = frame[:receipt]
39
+ client.trigger_after_receiving receipt_frame
40
+ triggered.should be_true
41
+ end
42
+ end
43
+
44
+ describe "receipted DISCONNECT" do
45
+ it "should close the client upon receiving a RECEIPT for a DISCONNECT" do
46
+ frame.command = 'DISCONNECT'
47
+ client.trigger_before_transmitting frame
48
+ client.should_receive(:close)
49
+ client.trigger_after_receiving receipt_frame
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,64 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ module OnStomp::Interfaces
5
+ describe SubscriptionManager do
6
+ let(:client) {
7
+ mock('client').tap do |m|
8
+ m.extend ClientEvents
9
+ m.extend SubscriptionManager
10
+ end
11
+ }
12
+ let(:message_frame) {
13
+ OnStomp::Components::Frame.new('MESSAGE', :subscription => 's-1234',
14
+ :destination => '/queue/test')
15
+ }
16
+ let(:subscribe_frame) {
17
+ OnStomp::Components::Frame.new('SUBSCRIBE', :id => 's-1234',
18
+ :destination => '/queue/test')
19
+ }
20
+ let(:unsubscribe_frame) {
21
+ OnStomp::Components::Frame.new('UNSUBSCRIBE', :id => 's-1234')
22
+ }
23
+ let(:subscribed_frames) { [] }
24
+ let(:callback) {
25
+ lambda { |m| subscribed_frames << m }
26
+ }
27
+
28
+ before(:each) do
29
+ client.__send__(:configure_subscription_management)
30
+ end
31
+ after(:each) do
32
+ client.__send__(:clear_subscriptions)
33
+ end
34
+
35
+ describe "adding subscription callbacks" do
36
+ it "should add a callback and invoke it upon receiving matching MESSAGE" do
37
+ client.__send__ :add_subscription, subscribe_frame, callback
38
+ client.subscriptions.map { |s| [s.id, s.callback] }.should ==
39
+ [ ['s-1234', callback] ]
40
+ client.trigger_after_receiving message_frame
41
+ client.trigger_after_receiving message_frame
42
+ subscribed_frames.should == [message_frame, message_frame]
43
+ end
44
+ it "should invoke the callback if there is no subscription header but destinations match" do
45
+ message_frame.headers.delete :subscription
46
+ client.__send__ :add_subscription, subscribe_frame, callback
47
+ client.trigger_after_receiving message_frame
48
+ client.trigger_after_receiving message_frame
49
+ subscribed_frames.should == [message_frame, message_frame]
50
+ end
51
+ end
52
+
53
+ describe "unsubscribing" do
54
+ it "should not invoke the callback after UNSUBSCRIBE has been processed" do
55
+ client.__send__ :add_subscription, subscribe_frame, callback
56
+ client.trigger_after_receiving message_frame
57
+ client.trigger_after_receiving unsubscribe_frame
58
+ client.trigger_after_receiving message_frame
59
+ subscribed_frames.should == [message_frame]
60
+ client.subscriptions.should be_empty
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe OnStomp do
5
+ describe ".connect / .open" do
6
+ let(:client) { mock('client') }
7
+ let(:client_uri) { mock('uri') }
8
+ let(:client_options) { mock('options') }
9
+ it "should create a new client and connect it" do
10
+ OnStomp::Client.should_receive(:new).with(client_uri, client_options).and_return(client)
11
+ client.should_receive(:connect)
12
+ OnStomp.open(client_uri, client_options).should == client
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Dir[File.expand_path('support', File.dirname(__FILE__)) + "/**/*.rb"].each { |f| require f }
3
+
4
+ begin
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter "/spec/"
8
+ end
9
+ rescue LoadError
10
+ end
11
+
12
+ require 'onstomp'
@@ -0,0 +1,51 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module RSpec
3
+ module Mocks
4
+ module ArgumentMatchers
5
+ def an_onstomp_frame(command=false, header_arr=false, body=false)
6
+ OnStompFrameMatcher.new(command, header_arr, body).tap do |m|
7
+ m.match_command = command != false
8
+ m.match_headers = header_arr != false
9
+ m.match_body = body != false
10
+ end
11
+ end
12
+
13
+ class OnStompFrameMatcher
14
+ attr_accessor :match_command, :match_body, :match_headers
15
+
16
+ def initialize(com, header_arr, body)
17
+ @match_command = @match_body = @match_headers = true
18
+ @expected = OnStomp::Components::Frame.new(com, {}, body)
19
+ header_arr = [header_arr] if header_arr.is_a?(Hash)
20
+ header_arr.each do |h|
21
+ @expected.headers.merge!(h)
22
+ end if header_arr.is_a?(Array)
23
+ end
24
+
25
+ def ==(actual)
26
+ actual.is_a?(@expected.class) && matches_command(actual) &&
27
+ matches_headers(actual) && matches_body(actual)
28
+ end
29
+
30
+ def matches_command actual
31
+ !match_command || actual.command == @expected.command
32
+ end
33
+
34
+ def matches_body actual
35
+ !match_body || actual.body == @expected.body
36
+ end
37
+
38
+ def matches_headers actual
39
+ !match_headers || @expected.headers.to_hash.keys.all? { |k| @expected[k] == actual[k] }
40
+ end
41
+
42
+ def description
43
+ frame_desc = match_command ? "#{@expected.command} frame" : "Any frame"
44
+ header_desc = match_headers ? " with headers #{@expected.headers.to_hash.inspect}" : ''
45
+ body_desc = match_body ? " and body '#{@expected.body}'" : ''
46
+ [frame_desc, header_desc, body_desc].join
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ # -*- encoding: utf-8 -*-
2
+ RSpec::Matchers.define :have_header_named do |header_name|
3
+ match do |actual|
4
+ actual.headers.set? header_name
5
+ end
6
+ end
7
+
8
+ RSpec::Matchers.define :have_headers do |expected_hash|
9
+ match do |actual|
10
+ expected_hash.inject(true) do |matched, (k,v)|
11
+ matched && actual[k] == v
12
+ end
13
+ end
14
+ end
15
+
16
+ RSpec::Matchers.define :be_a_header_scope do |headers|
17
+ match do |actual|
18
+ actual.is_a?(OnStomp::Components::Scopes::HeaderScope) &&
19
+ actual.headers == headers
20
+ end
21
+ end
22
+
23
+ RSpec::Matchers.define :be_a_receipt_scope do |callback|
24
+ match do |actual|
25
+ actual.is_a?(OnStomp::Components::Scopes::ReceiptScope) &&
26
+ actual.callback == callback
27
+ end
28
+ end
29
+
30
+ RSpec::Matchers.define :be_a_transaction_scope do |tx_id|
31
+ match do |actual|
32
+ $stdout.puts "Checking transaction? #{tx_id.inspect}"
33
+ type_check = actual.is_a?(OnStomp::Components::Scopes::TransactionScope)
34
+ tx_id ? type_check && actual.transaction == tx_id : type_check
35
+ end
36
+ end
37
+
38
+ RSpec::Matchers.define :be_an_onstomp_frame do |com, head, body|
39
+ match do |actual|
40
+ checked = actual.is_a?(OnStomp::Components::Frame)
41
+ checked &&= actual.command == com
42
+ checked &&= head.inject(checked) do |matched, (k,v)|
43
+ matched && actual[k] == v
44
+ end
45
+ checked &&= actual.body == body
46
+ end
47
+ end
48
+
49
+ RSpec::Matchers.define :be_an_encoded_onstomp_frame do |com, head, body, enc|
50
+ match do |actual|
51
+ if RUBY_VERSION >= '1.9'
52
+ enc_check = actual.body.encoding.name == enc
53
+ body.force_encoding(enc)
54
+ else
55
+ enc_check = true
56
+ end
57
+ enc_check && actual.should(be_an_onstomp_frame(com, head, body))
58
+ end
59
+ end
60
+
61
+ RSpec::Matchers.define :have_transaction_header do |expected|
62
+ have_frame_header :transaction, expected
63
+ end
64
+
65
+ RSpec::Matchers.define :have_command do |expected|
66
+ match do |actual|
67
+ actual.command.should == expected
68
+ end
69
+ end
70
+
71
+ RSpec::Matchers.define :have_body_encoding do |expected|
72
+ if RUBY_VERSION >= "1.9"
73
+ match do |actual|
74
+ actual.body.encoding.name.should == expected
75
+ end
76
+ else
77
+ match do |actual|
78
+ true.should be_true
79
+ end
80
+ end
81
+ end
82
+
83
+ RSpec::Matchers.define :have_body do |expected, expected_no_encoding, encoding|
84
+ e_expected = (RUBY_VERSION >= '1.9') ? expected.encode(encoding) : expected_no_encoding
85
+ match do |actual|
86
+ actual.body.should == e_expected
87
+ end
88
+ end
@@ -0,0 +1,116 @@
1
+ shared_examples_for "frame method interfaces" do
2
+ let(:shared_frame_method_headers) {
3
+ { :header1 => 'value 1' }
4
+ }
5
+ let(:shared_frame_methods_transmit_callbacks) {
6
+ Hash.new
7
+ }
8
+
9
+ before(:each) do
10
+ if frame_method_interface.respond_to?(:connection)
11
+ frame_method_interface.stub(
12
+ :connection => OnStomp::Connections::Stomp_1_1.new(mock('io'), client)
13
+ )
14
+ end
15
+ end
16
+
17
+ describe ".send" do
18
+ it "should transmit the result of connection.send_frame and callbacks" do
19
+ frame_method_interface.should_receive(:transmit).
20
+ with(an_onstomp_frame('SEND',
21
+ [shared_frame_method_headers, {:destination => '/queue/test'}],
22
+ 'message body'), an_instance_of(Hash))
23
+ frame_method_interface.send('/queue/test', 'message body', shared_frame_method_headers)
24
+ end
25
+ it "should be aliased as .puts" do
26
+ frame_method_interface.should_receive(:transmit).
27
+ with(an_onstomp_frame('SEND',
28
+ [shared_frame_method_headers, {:destination => '/queue/test'}],
29
+ 'message body'), an_instance_of(Hash))
30
+ frame_method_interface.puts('/queue/test', 'message body', shared_frame_method_headers)
31
+ end
32
+ end
33
+
34
+ describe ".subscribe" do
35
+ it "should transmit the result of connection.subscribe_frame and callbacks" do
36
+ frame_method_interface.should_receive(:transmit).
37
+ with(an_onstomp_frame('SUBSCRIBE',
38
+ [shared_frame_method_headers, {:destination => '/queue/test'}]),
39
+ an_instance_of(Hash))
40
+ frame_method_interface.subscribe('/queue/test', shared_frame_method_headers)
41
+ end
42
+ end
43
+
44
+ describe ".unsubscribe" do
45
+ it "should transmit the result of connection.unsubscribe_frame" do
46
+ frame_method_interface.should_receive(:transmit).
47
+ with(an_onstomp_frame('UNSUBSCRIBE',
48
+ [shared_frame_method_headers, {:id => 's-1234'}]))
49
+ frame_method_interface.unsubscribe('s-1234', shared_frame_method_headers)
50
+ end
51
+ end
52
+
53
+ describe ".begin" do
54
+ it "should transmit the result of connection.begin_frame" do
55
+ frame_method_interface.should_receive(:transmit).
56
+ with(an_onstomp_frame('BEGIN',
57
+ [shared_frame_method_headers, {:transaction => 't-1234'}]))
58
+ frame_method_interface.begin('t-1234', shared_frame_method_headers)
59
+ end
60
+ end
61
+
62
+ describe ".abort" do
63
+ it "should transmit the result of connection.abort_frame" do
64
+ frame_method_interface.should_receive(:transmit).
65
+ with(an_onstomp_frame('ABORT',
66
+ [shared_frame_method_headers, {:transaction => 't-1234'}]))
67
+ frame_method_interface.abort('t-1234', shared_frame_method_headers)
68
+ end
69
+ end
70
+
71
+ describe ".commit" do
72
+ it "should transmit the result of connection.commit_frame" do
73
+ frame_method_interface.should_receive(:transmit).
74
+ with(an_onstomp_frame('COMMIT',
75
+ [shared_frame_method_headers, {:transaction => 't-1234'}]))
76
+ frame_method_interface.commit('t-1234', shared_frame_method_headers)
77
+ end
78
+ end
79
+
80
+ describe ".disconnect" do
81
+ it "should transmit the result of connection.disconnect_frame" do
82
+ frame_method_interface.should_receive(:transmit).
83
+ with(an_onstomp_frame('DISCONNECT',
84
+ [shared_frame_method_headers]))
85
+ frame_method_interface.disconnect(shared_frame_method_headers)
86
+ end
87
+ end
88
+
89
+ describe ".ack" do
90
+ it "should transmit the result of connection.ack_frame" do
91
+ frame_method_interface.should_receive(:transmit).
92
+ with(an_onstomp_frame('ACK',
93
+ [shared_frame_method_headers, {:'message-id' => 'm-1234',
94
+ :subscription => 's-5678'}]))
95
+ frame_method_interface.ack('m-1234', 's-5678', shared_frame_method_headers)
96
+ end
97
+ end
98
+
99
+ describe ".nack" do
100
+ it "should transmit the result of connection.nack_frame" do
101
+ frame_method_interface.should_receive(:transmit).
102
+ with(an_onstomp_frame('NACK',
103
+ [shared_frame_method_headers, {:'message-id' => 'm-1234',
104
+ :subscription => 's-5678'}]))
105
+ frame_method_interface.nack('m-1234', 's-5678', shared_frame_method_headers)
106
+ end
107
+ end
108
+
109
+ describe ".beat" do
110
+ it "should transmit the result of connection.heartbeat_frame" do
111
+ frame_method_interface.should_receive(:transmit).
112
+ with(an_onstomp_frame(nil))
113
+ frame_method_interface.beat
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,32 @@
1
+ class ConfigurableAttributeHandler < YARD::Handlers::Ruby::AttributeHandler
2
+ handles method_call(:attr_configurable_str)
3
+ handles method_call(:attr_configurable_client_beats)
4
+ handles method_call(:attr_configurable_protocols)
5
+ namespace_only
6
+
7
+ def process
8
+ name = statement.parameters.first.jump(:symbol, :ident).source
9
+ namespace.attributes[scope][name] ||= SymbolHash[:read => nil, :write => nil]
10
+ namespace.attributes[scope][name][:read] = YARD::CodeObjects::MethodObject.new(namespace, name)
11
+ namespace.attributes[scope][name][:write] = YARD::CodeObjects::MethodObject.new(namespace, "#{name}=")
12
+ register namespace.attributes[scope][name][:read]
13
+ register namespace.attributes[scope][name][:write]
14
+ end
15
+ end
16
+
17
+ class EventMethodsHandler < YARD::Handlers::Ruby::MethodHandler
18
+ handles method_call(:create_event_methods)
19
+ namespace_only
20
+
21
+ def process
22
+ base_name = statement.parameters.first.jump(:symbol, :ident).source[1..-1]
23
+ statement.parameters[1..-1].each do |pref_sexp|
24
+ if pref_sexp
25
+ pref = pref_sexp.jump(:symbol, :ident).source[1..-1]
26
+ name = "#{pref}_#{base_name}"
27
+ object = YARD::CodeObjects::MethodObject.new(namespace, name)
28
+ register object
29
+ end
30
+ end
31
+ end
32
+ end