converse 1.0.25 → 1.0.26

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.
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ .idea
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
@@ -5,6 +5,13 @@
5
5
  <orderEntry type="inheritedJdk" />
6
6
  <orderEntry type="sourceFolder" forTests="false" />
7
7
  <orderEntry type="library" scope="PROVIDED" name="bundler (v1.1.5, RVM: ruby-1.9.3-p194) [gem]" level="application" />
8
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.1.3, RVM: ruby-1.9.3-p194) [gem]" level="application" />
9
+ <orderEntry type="library" scope="PROVIDED" name="json (v1.7.5, RVM: ruby-1.9.3-p194) [gem]" level="application" />
10
+ <orderEntry type="library" scope="PROVIDED" name="mysql2 (v0.3.12b2, RVM: ruby-1.9.3-p194) [gem]" level="application" />
11
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v2.12.0, RVM: ruby-1.9.3-p194) [gem]" level="application" />
12
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v2.12.0, RVM: ruby-1.9.3-p194) [gem]" level="application" />
13
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v2.12.0, RVM: ruby-1.9.3-p194) [gem]" level="application" />
14
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v2.12.0, RVM: ruby-1.9.3-p194) [gem]" level="application" />
8
15
  </component>
9
16
  </module>
10
17
 
data/README.md CHANGED
@@ -24,6 +24,11 @@ the provider. The application specifies its API through a set of methods that as
24
24
 
25
25
  Brokers can be chained for multiple translation / technology bridging.
26
26
 
27
+ Brokers and conversations supplied with the gem: HTML, REST, MySQL
28
+ Brokers and conversations planned for future release: MCollective, Redis, ActiveMQ
29
+
30
+ This gem is sponsored by Hetzner (Pty) Ltd - http://hetzner.co.za
31
+
27
32
  ## Installation
28
33
 
29
34
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :default => :spec
@@ -14,4 +14,8 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "converse"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Converse::VERSION
17
+
18
+ gem.add_dependency "json"
19
+ gem.add_dependency "mysql2"
20
+ gem.add_development_dependency "rspec"
17
21
  end
@@ -8,5 +8,4 @@ require "converse/comms/mysql/mysql_conversation.rb"
8
8
  require "converse/comms/simple_logger.rb"
9
9
 
10
10
  module Converse
11
- # Your code goes here...
12
11
  end
@@ -1,6 +1,5 @@
1
1
  require 'net/http'
2
2
  require "converse/comms/conversation"
3
- require "json"
4
3
 
5
4
  module Converse
6
5
  class HTMLConversation < Conversation
@@ -1,5 +1,6 @@
1
1
  require 'cgi'
2
2
  require "converse/interaction"
3
+ require "json"
3
4
 
4
5
  module Converse
5
6
  class RESTInteraction < Interaction
@@ -55,7 +56,8 @@ module Converse
55
56
  def is_json
56
57
  begin
57
58
  JSON.parse(@validation)
58
- rescue TypeError
59
+ true
60
+ rescue ::Exception
59
61
  raise ArgumentError, "#{@validation} is not in JSON format"
60
62
  end
61
63
  end
@@ -1,3 +1,3 @@
1
1
  module Converse
2
- VERSION = "1.0.25"
2
+ VERSION = "1.0.26"
3
3
  end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+ require "api"
3
+
4
+ module Converse
5
+ describe API do
6
+ context "when constructed with a broker" do
7
+ it "should remember the broker" do
8
+ @broker = "broker"
9
+ @iut = API.new(@broker)
10
+ @iut.broker.should == @broker
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+ require "broker"
3
+
4
+ module Converse
5
+ describe Broker do
6
+ before :each do
7
+ @iut = Broker.new
8
+ end
9
+
10
+ context "when constructed" do
11
+ it "should facilitate memory of a domain language indicator" do
12
+ @iut.domain_language = "hosting"
13
+ @iut.domain_language.should == "hosting"
14
+ end
15
+ end
16
+
17
+ context "serving as an abstract base class" do
18
+ it "should do have a method open_topic that takes concern and action and does nothing" do
19
+ result = @iut.open_topic("concern", "action")
20
+ result.nil?.should == true
21
+ end
22
+
23
+ it "should do have a method broker_conversation that takes a topic and does nothing" do
24
+ result = @iut.broker_conversation("topic")
25
+ result.nil?.should == true
26
+ end
27
+
28
+ it "should do have a method translate_response that takes a response and transparently returns it" do
29
+ result = @iut.translate_response("response")
30
+ result.should == "response"
31
+ end
32
+ end
33
+
34
+ context "when facilitating a discussion" do
35
+ it "should open the topic and broker the conversation" do
36
+ class BrokerInterceptor < Broker
37
+ attr_accessor :topic_opened
38
+ attr_accessor :conversation_brokered
39
+
40
+ def open_topic(concern, action)
41
+ @topic_opened = true
42
+ end
43
+
44
+ def broker_conversation(topic)
45
+ @conversation_brokered = true
46
+ end
47
+ end
48
+
49
+ @iut = BrokerInterceptor.new
50
+ @iut.discuss("concern", "action")
51
+ @iut.topic_opened.should == true
52
+ @iut.conversation_brokered.should == true
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,61 @@
1
+ require "spec_helper"
2
+ require "comms/conversation"
3
+
4
+ module Converse
5
+ describe Conversation do
6
+ class TestSubscriber
7
+ attr_accessor :data
8
+
9
+ def notify(message)
10
+ @data = message
11
+ end
12
+ end
13
+
14
+ before :each do
15
+ @iut = Conversation.new("http://somewhere.com:8081/something?parama=valuea")
16
+ end
17
+
18
+ context "when constructed with a URI" do
19
+ it "should remember the URI and extract the host, port and path from the URI" do
20
+ @iut.uri.should == "http://somewhere.com:8081/something?parama=valuea"
21
+ @iut.host.should == "somewhere.com"
22
+ @iut.port.should == 8081
23
+ @iut.path.should == "/something"
24
+ end
25
+
26
+ it "should have no subscribers" do
27
+ @iut.subscribers.size.should == 0
28
+ end
29
+ end
30
+
31
+ context "as an abstract base class" do
32
+ it "should raise an error on ask" do
33
+ expect {@iut.ask}.to raise_error NotImplementedError
34
+ end
35
+
36
+ it "should raise an error on say" do
37
+ expect {@iut.say}.to raise_error NotImplementedError
38
+ end
39
+ end
40
+
41
+ context "when managing subscribers" do
42
+ it "should append the subscriber to the list of subscribers" do
43
+ @iut.subscribe(TestSubscriber.new)
44
+ @iut.subscribe(TestSubscriber.new)
45
+ @iut.subscribers.size.should == 2
46
+ end
47
+
48
+ it "should notify all subscribers when requested to do so" do
49
+ a = TestSubscriber.new
50
+ b = TestSubscriber.new
51
+ @iut.subscribe(a)
52
+ @iut.subscribe(b)
53
+ a.data.nil?.should == true
54
+ b.data.nil?.should == true
55
+ @iut.notify_subscribers("somedata")
56
+ a.data.should == "somedata"
57
+ b.data.should == "somedata"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,197 @@
1
+ require "spec_helper"
2
+ require "comms/html/html_conversation"
3
+
4
+ module Converse
5
+ describe HTMLConversation do
6
+ class TestSubscriber
7
+ attr_accessor :data
8
+
9
+ def notify(message)
10
+ @data = message
11
+ end
12
+ end
13
+
14
+ class TestRequest
15
+ attr_accessor :body
16
+ attr_accessor :account
17
+ attr_accessor :password
18
+
19
+ def initialize
20
+ @body = "body"
21
+ basic_auth("account", "password")
22
+ end
23
+
24
+ def basic_auth(account, password)
25
+ @account = account
26
+ @password = password
27
+ end
28
+ end
29
+
30
+ class TestResponse
31
+ attr_accessor :body
32
+
33
+ def initialize
34
+ @body = "response body"
35
+ end
36
+ end
37
+
38
+ before :each do
39
+ @mock_connection = []
40
+ @iut = HTMLConversation.new("http://somewhere.com:9876")
41
+ @iut.username = "user"
42
+ @iut.password = "password"
43
+ @iut.use_ssl = false
44
+ @subscriber = TestSubscriber.new
45
+ end
46
+
47
+ context "on construction" do
48
+ it "should remember username, password, SSL should be forced to false" do
49
+ @iut.username.should == "user"
50
+ @iut.password.should == "password"
51
+ @iut.use_ssl.should == false
52
+ end
53
+
54
+ it "should configure port to 80 if not provided" do
55
+ @iut = HTMLConversation.new("http://somewhere.com")
56
+ @iut.port.should == 80
57
+ end
58
+ end
59
+
60
+ context "when configured" do
61
+ it "should remember username, password, port and ssl" do
62
+ @iut.username = "user2"
63
+ @iut.password = "password2"
64
+ @iut.use_ssl = true
65
+ @iut.port = 443
66
+ @iut.username.should == "user2"
67
+ @iut.password.should == "password2"
68
+ @iut.use_ssl.should == true
69
+ @iut.port.should == 443
70
+ end
71
+ end
72
+
73
+ context "when processing message notification" do
74
+ it "should notify subscribers of requests when asked to" do
75
+ @iut.subscribe(@subscriber)
76
+ @iut.request = TestRequest.new
77
+ @iut.populate_request("http://somewhere.com/something", "request data")
78
+ @subscriber.should_receive(:notify).with("HTTP=>\nrequest\nrequest data\n")
79
+ @iut.notify_subscribers_of_request("request")
80
+ end
81
+
82
+ it "should notify subscribers of responses" do
83
+ @iut.subscribe(@subscriber)
84
+ @iut.response = TestRequest.new
85
+ @subscriber.should_receive(:notify).with("<=HTTP\nbody\n")
86
+ @iut.notify_subscribers_of_response
87
+ end
88
+ end
89
+
90
+ context "when asked to populate request data" do
91
+ it "should set the request body to the data if there is data" do
92
+ @iut.request = TestRequest.new
93
+ @iut.populate_request("http://somewhere.com/something", "request data")
94
+ @iut.request.body.should == "request data"
95
+ end
96
+
97
+ it "should not change the request body if no data is provided" do
98
+ @iut.request = TestRequest.new
99
+ @iut.populate_request("http://somewhere.com/something", nil)
100
+ @iut.request.body.should == "body"
101
+
102
+ @iut.request.body = nil
103
+ @iut.populate_request("http://somewhere.com/something", nil)
104
+ @iut.request.body.nil?.should == true
105
+ end
106
+
107
+ it "should fill in authentication information if available" do
108
+ @iut.request = TestRequest.new
109
+ @iut.populate_request("http://somewhere.com/something", nil)
110
+ @iut.request.account.should == "user"
111
+ @iut.request.password.should == "password"
112
+
113
+ @iut.username = nil
114
+ @iut.populate_request("http://somewhere.com/something", nil)
115
+ @iut.request.account.nil?.should == true
116
+ @iut.request.password.should == "password"
117
+
118
+ @iut.username = "user"
119
+ @iut.password = nil
120
+ @iut.populate_request("http://somewhere.com/something", nil)
121
+ @iut.request.account.should == "user"
122
+ @iut.request.password.nil?.should == true
123
+
124
+ @iut.username = nil
125
+ @iut.request.account = nil
126
+ @iut.request.password = nil
127
+ @iut.populate_request("http://somewhere.com/something", nil)
128
+ @iut.request.account.nil?.should == true
129
+ @iut.request.password.nil?.should == true
130
+ end
131
+
132
+ it "should notify subscribers of the request update" do
133
+ @iut.subscribe(@subscriber)
134
+ @iut.request = TestRequest.new
135
+ @subscriber.should_receive(:notify).with("HTTP=>\nhttp://somewhere.com/something\nbody\n")
136
+ @iut.populate_request("http://somewhere.com/something", nil)
137
+ end
138
+ end
139
+
140
+ context "when asked to connect" do
141
+ it "should call Net::HTTP.start without SSL parameters if SSL is not configured" do
142
+ @iut.use_ssl = false
143
+ Net::HTTP.should_receive(:start) do |host, port|
144
+ host.should == "somewhere.com"
145
+ port.should == 9876
146
+ end
147
+ @iut.connect
148
+ end
149
+
150
+ it "should call Net::HTTP.start with SSL parameters if SSL is configured" do
151
+ @iut.use_ssl = true
152
+ Net::HTTP.should_receive(:start) do |host, port, ssl|
153
+ host.should == "somewhere.com"
154
+ port.should == 9876
155
+ ssl.should == {:use_ssl=>"yes"}
156
+ end
157
+ @iut.connect
158
+ end
159
+ end
160
+
161
+ context "when conversing" do
162
+ it "should populate the request with the data provided, connect and issue the request, then notify subscribers with and return the response" do
163
+ prepare_converse
164
+ test_response
165
+ end
166
+
167
+ it "should create a Net:HTTP:Get request and converse when asking" do
168
+ prepare_converse
169
+ Net::HTTP::Get.should_receive(:new).with("http://newpath/go").and_return(@iut.request)
170
+ @iut.ask "http://newpath/go", "some data"
171
+ end
172
+
173
+ it "should create a Net:HTTP:Post request and converse when saying" do
174
+ prepare_converse
175
+ Net::HTTP::Post.should_receive(:new).with("http://newpath/go").and_return(@iut.request)
176
+ @iut.say"http://newpath/go", "some data"
177
+ end
178
+
179
+ def prepare_converse
180
+ @iut.request = TestRequest.new
181
+ @iut.subscribe(@subscriber)
182
+ Net::HTTP.should_receive(:start).and_return(@mock_connection)
183
+ @test_response = TestResponse.new
184
+ @mock_connection.should_receive(:request).with(@iut.request).and_return(@test_response)
185
+ @subscriber.should_receive(:notify).with("HTTP=>\nhttp://newpath/go\nsome data\n")
186
+ @subscriber.should_receive(:notify).with("<=HTTP\nresponse body\n")
187
+ end
188
+
189
+ def test_response
190
+ result = @iut.converse("http://newpath/go", "some data")
191
+ @iut.request.body.should == "some data"
192
+ result.should == @test_response
193
+ end
194
+ end
195
+ end
196
+ end
197
+
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+ require "comms/mysql/mysql_conversation"
3
+
4
+ module Converse
5
+ describe MysqlConversation do
6
+ before :each do
7
+ @iut = MysqlConversation.new("mysql://user:pass@somewhere.com:7743/databasename")
8
+ @client = "client"
9
+ end
10
+
11
+ context "on construction" do
12
+ it "should parse the URI provided and extract the username, password and database" do
13
+ setup_connection
14
+ @iut.connect
15
+ end
16
+ end
17
+
18
+ context "when asked to connect to the database" do
19
+ it "should create a mysql client and attempt to connect" do
20
+ setup_connection
21
+ @iut.connect
22
+ end
23
+ end
24
+
25
+ context "when asked to converse given a query" do
26
+ it "should connect to the database and issue the query on converse" do
27
+ setup_query
28
+ @iut.converse
29
+ end
30
+
31
+ it "should connect to the database and issue the query on ask" do
32
+ setup_query
33
+ @iut.ask
34
+ end
35
+
36
+ it "should connect to the database and issue the query on say" do
37
+ setup_query
38
+ @iut.say
39
+ end
40
+ end
41
+
42
+ def setup_query
43
+ @iut.query = "SHOW DATABASES"
44
+ setup_connection
45
+ @client.should_receive(:query).with("SHOW DATABASES")
46
+ end
47
+
48
+ def setup_connection
49
+ Mysql2::Client.should_receive(:new).with({:host => "somewhere.com",
50
+ :port => 7743,
51
+ :username => "user",
52
+ :password => "pass",
53
+ :database => "databasename"}).and_return(@client)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+ require 'rspec/mocks/standalone'
3
+
4
+ module Converse
5
+ describe SimpleLogger do
6
+ before :each do
7
+ @iut = SimpleLogger.new
8
+ end
9
+
10
+ context "when notified" do
11
+ it "should output the message to standard output" do
12
+ @iut.stub!(:puts).with("testing")
13
+ @iut.notify("testing")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,257 @@
1
+ require "spec_helper"
2
+ require "interaction"
3
+
4
+ module Converse
5
+ describe Interaction do
6
+ before :each do
7
+ @iut = Converse::Interaction.new
8
+ @broker = "test broker"
9
+ @concern = "test concern"
10
+ @action = "action"
11
+ @substance = "substance"
12
+ @conversation = "conversation"
13
+ end
14
+
15
+ context "on construction" do
16
+ it "should have all attributes set to nil" do
17
+ @iut.broker.nil?.should == true
18
+ @iut.concern.nil?.should == true
19
+ @iut.action.nil?.should == true
20
+ @iut.substance.nil?.should == true
21
+ @iut.conversation.nil?.should == true
22
+ @iut.should_i_ask.nil?.should == true
23
+ end
24
+ end
25
+
26
+ context "when asked to discuss a concern with a broker" do
27
+ it "should remember the broken and concern and return the interaction" do
28
+ out = @iut.discuss_with_broker_concerning(@broker, @concern)
29
+ @iut.broker.should == @broker
30
+ @iut.concern.should == @concern
31
+ out.should == @iut
32
+ end
33
+ end
34
+
35
+ context "when configured to ask a broker about a concern" do
36
+ it "should remember the broker and concern, and the fact that it should ask, and return the interaction" do
37
+ out = @iut.ask_broker_concerning(@broker, @concern)
38
+ @iut.broker.should == @broker
39
+ @iut.concern.should == @concern
40
+ @iut.should_i_ask.should == true
41
+ out.should == @iut
42
+ end
43
+ end
44
+
45
+ context "when configured to tell a broker about a concern" do
46
+ it "should remember the broker and concern, and the fact that it should tell, and return the interaction" do
47
+ out = @iut.tell_broker_concerning(@broker, @concern)
48
+ @iut.broker.should == @broker
49
+ @iut.concern.should == @concern
50
+ @iut.should_i_ask.should == false
51
+ out.should == @iut
52
+ end
53
+ end
54
+
55
+ context "when configured to ask a broker" do
56
+ it "should remember the broker and the fact that it should ask and return the interaction (ask_broker)" do
57
+ out = @iut.ask_broker(@broker)
58
+ @iut.broker.should == @broker
59
+ @iut.should_i_ask.should == true
60
+ out.should == @iut
61
+ end
62
+
63
+ it "should remember the fact that it should ask and return the interaction (by_asking)" do
64
+ out = @iut.by_asking
65
+ @iut.should_i_ask.should == true
66
+ out.should == @iut
67
+ end
68
+ end
69
+
70
+ context "when configured to tell a broker" do
71
+ it "should remember the broker and the fact that it should tell and return the interaction (tell_broker)" do
72
+ out = @iut.tell_broker(@broker)
73
+ @iut.broker.should == @broker
74
+ @iut.should_i_ask.should == false
75
+ out.should == @iut
76
+ end
77
+
78
+ it "should remember the fact that it should tell and return the interaction (by_saying)" do
79
+ out = @iut.by_saying
80
+ @iut.should_i_ask.should == false
81
+ out.should == @iut
82
+ end
83
+ end
84
+
85
+ context "when asked to discuss with a broker" do
86
+ it "should remember the broker and return the interaction" do
87
+ out = @iut.discuss_with(@broker)
88
+ @iut.broker.should == @broker
89
+ out.should == @iut
90
+ end
91
+ end
92
+
93
+ context "when raising a concern" do
94
+ it "should remember the concern and return the interaction" do
95
+ out = @iut.concerning(@concern)
96
+ @iut.concern.should == @concern
97
+ out.should == @iut
98
+ end
99
+ end
100
+
101
+ context "when indicating an action" do
102
+ it "should remember the action and return the interaction (about)" do
103
+ out = @iut.about(@action)
104
+ @iut.action.should == @action
105
+ out.should == @iut
106
+ end
107
+
108
+ it "should remember the action and return the interaction (to)" do
109
+ out = @iut.to(@action)
110
+ @iut.action.should == @action
111
+ out.should == @iut
112
+ end
113
+ end
114
+
115
+ context "when provided with substance" do
116
+ it "should remember the substance and return the interaction (detailed_by)" do
117
+ out = @iut.detailed_by(@substance)
118
+ @iut.substance.should == @substance
119
+ out.should == @iut
120
+ end
121
+
122
+ it "should remember the substance and return the interaction (using)" do
123
+ out = @iut.using(@substance)
124
+ @iut.substance.should == @substance
125
+ out.should == @iut
126
+ end
127
+
128
+ it "should remember the substance and return the interaction (with)" do
129
+ out = @iut.with(@substance)
130
+ @iut.substance.should == @substance
131
+ out.should == @iut
132
+ end
133
+ end
134
+
135
+ context "when engaging in conversation" do
136
+ it "should ask the conversation to say when saying" do
137
+ @iut.conversation = @conversation
138
+ @conversation.should_receive(:say)
139
+ @iut.say
140
+ end
141
+
142
+ it "should ask the conversation to ask when asking" do
143
+ @iut.conversation = @conversation
144
+ @conversation.should_receive(:ask)
145
+ @iut.ask
146
+ end
147
+
148
+ it "should subscribe a simple logger to the conversation" do
149
+ @iut.discuss_with(@broker)
150
+ @conversation.should_receive(:subscribe)
151
+ @conversation.should_receive(:say)
152
+ @broker.should_receive(:open_topic)
153
+ @broker.should_receive(:broker_conversation).and_return(@conversation)
154
+ @broker.should_receive(:translate_response)
155
+ @iut.discuss
156
+ end
157
+
158
+ it "should ask the broker to open the topic with the concern and action and construct a conversation" do
159
+ @iut.discuss_with(@broker).concerning(@concern).about(@action)
160
+ @conversation.should_receive(:subscribe)
161
+ @conversation.should_receive(:say)
162
+ @broker.should_receive(:open_topic) do |concern, action|
163
+ concern.should == "test concern"
164
+ action.should == "action"
165
+ end.and_return "topic"
166
+ @broker.should_receive(:broker_conversation).with("topic").and_return(@conversation)
167
+ @broker.should_receive(:translate_response)
168
+ @iut.discuss
169
+ end
170
+
171
+ it "should ask the broker to translate the response received and then interpret the response" do
172
+ @iut.discuss_with(@broker).concerning(@concern).about(@action)
173
+ @conversation.should_receive(:subscribe)
174
+ @conversation.should_receive(:say).and_return("response")
175
+ @broker.should_receive(:open_topic) do |concern, action|
176
+ concern.should == "test concern"
177
+ action.should == "action"
178
+ end.and_return "topic"
179
+ @broker.should_receive(:broker_conversation).with("topic").and_return(@conversation)
180
+ @broker.should_receive(:translate_response).with("response").and_return("response")
181
+ @iut.discuss.should == "response"
182
+ end
183
+
184
+ it "should call ask on the conversation when configured to ask" do
185
+ @iut.discuss_with(@broker).concerning(@concern).about(@action).by_asking
186
+ @conversation.should_receive(:subscribe)
187
+ @conversation.should_receive(:ask).and_return("response")
188
+ @broker.should_receive(:open_topic) do |concern, action|
189
+ concern.should == "test concern"
190
+ action.should == "action"
191
+ end.and_return "topic"
192
+ @broker.should_receive(:broker_conversation).with("topic").and_return(@conversation)
193
+ @broker.should_receive(:translate_response).with("response").and_return("response")
194
+ @iut.discuss.should == "response"
195
+ end
196
+ end
197
+
198
+ context "when evaluating responses" do
199
+ it "should always indicate success" do
200
+ @iut.success?("anything").should == true
201
+ end
202
+ end
203
+
204
+ context "when handling error responses" do
205
+ it "should return the response intact" do
206
+ @iut.handle_error!("error").should == "error"
207
+ end
208
+ end
209
+
210
+ context "when handling errors" do
211
+ it "should call the error handling hook method" do
212
+ @iut.stub(:success?).and_return(false)
213
+ @iut.stub(:handle_error!).and_return "called"
214
+
215
+ @iut.discuss_with(@broker).concerning(@concern).about(@action).by_asking
216
+ @conversation.should_receive(:subscribe)
217
+ @conversation.should_receive(:ask).and_return("response")
218
+ @broker.should_receive(:open_topic) do |concern, action|
219
+ concern.should == "test concern"
220
+ action.should == "action"
221
+ end.and_return "topic"
222
+ @broker.should_receive(:broker_conversation).with("topic").and_return(@conversation)
223
+ @broker.should_receive(:translate_response).with("called").and_return("called")
224
+ @iut.discuss.should == "called"
225
+ end
226
+
227
+ it "should return nil if the response is nil" do
228
+ @iut.stub(:success?).and_return(false)
229
+
230
+ @iut.discuss_with(@broker).concerning(@concern).about(@action).by_asking
231
+ @conversation.should_receive(:subscribe)
232
+ @conversation.should_receive(:ask).and_return(nil)
233
+ @broker.should_receive(:open_topic) do |concern, action|
234
+ concern.should == "test concern"
235
+ action.should == "action"
236
+ end.and_return "topic"
237
+ @broker.should_receive(:broker_conversation).with("topic").and_return(@conversation)
238
+ @iut.discuss.nil?.should == true
239
+ end
240
+
241
+ it "should return the response if the response is not nil" do
242
+ @iut.stub(:success?).and_return(false)
243
+
244
+ @iut.discuss_with(@broker).concerning(@concern).about(@action).by_asking
245
+ @conversation.should_receive(:subscribe)
246
+ @conversation.should_receive(:ask).and_return("response")
247
+ @broker.should_receive(:open_topic) do |concern, action|
248
+ concern.should == "test concern"
249
+ action.should == "action"
250
+ end.and_return "topic"
251
+ @broker.should_receive(:broker_conversation).with("topic").and_return(@conversation)
252
+ @broker.should_receive(:translate_response).with("response").and_return("response")
253
+ @iut.discuss.should == "response"
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,86 @@
1
+ require "spec_helper"
2
+ require "rest/rest_broker"
3
+ require "comms/html/html_conversation"
4
+
5
+ module Converse
6
+ describe RESTBroker do
7
+ before :each do
8
+ @iut = RESTBroker.new
9
+ @iut.host = "somewhere.com"
10
+ @iut.port = "8080"
11
+ end
12
+
13
+ context "when asked to broker a conversation given a topic" do
14
+ it "should do broker an HTML conversation on the topic" do
15
+ conversation = @iut.broker_conversation("topic")
16
+ conversation.is_a?(HTMLConversation).should == true
17
+ conversation.uri.should == "topic"
18
+ conversation.username.nil?.should == true
19
+ conversation.password.nil?.should == true
20
+ end
21
+
22
+ it "should configure the username if provided" do
23
+ @iut.username = "user"
24
+ conversation = @iut.broker_conversation("topic")
25
+ conversation.is_a?(HTMLConversation).should == true
26
+ conversation.uri.should == "topic"
27
+ conversation.username.should == "user"
28
+ conversation.password.nil?.should == true
29
+ end
30
+
31
+ it "should configure the password if provided" do
32
+ @iut.password = "password"
33
+ conversation = @iut.broker_conversation("topic")
34
+ conversation.is_a?(HTMLConversation).should == true
35
+ conversation.uri.should == "topic"
36
+ conversation.username.nil?.should == true
37
+ conversation.password.should == "password"
38
+ end
39
+ end
40
+
41
+ context "when asked to open a topic with no concern" do
42
+ it "should return host_and_port/action" do
43
+ @iut.open_topic("", "action").should == "http://somewhere.com:8080/action"
44
+ @iut.open_topic(nil, "action").should == "http://somewhere.com:8080/action"
45
+ end
46
+ end
47
+
48
+ context "when asked to open a topic with a concern" do
49
+ it "should return host_and_port/concern/action" do
50
+ @iut.open_topic("concern", "action").should == "http://somewhere.com:8080/concern/action"
51
+ end
52
+ end
53
+
54
+ context "when configuring" do
55
+ it "should return host:port if port is specified" do
56
+ @iut.host_and_port.should == "somewhere.com:8080"
57
+ end
58
+
59
+ it "should return host only if port is specified" do
60
+ @iut.port = nil
61
+ @iut.host_and_port.should == "somewhere.com"
62
+ end
63
+
64
+ it "should remember a host" do
65
+ @iut.talks_to("somewhereelse.com")
66
+ @iut.host.should == "somewhereelse.com"
67
+ end
68
+
69
+ it "should remember a port" do
70
+ @iut.on_port("9090")
71
+ @iut.port.should == "9090"
72
+ end
73
+
74
+ it "should remember a username" do
75
+ @iut.authenticated_by("username")
76
+ @iut.username.should == "username"
77
+ end
78
+
79
+ it "should remember a password" do
80
+ @iut.with_password("password")
81
+ @iut.password.should == "password"
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,157 @@
1
+ require "spec_helper"
2
+ require "rest/rest_interaction"
3
+
4
+ module Converse
5
+ describe RESTInteraction do
6
+ before :each do
7
+ @iut = RESTInteraction.new
8
+ @broker = "broker"
9
+ @action = "action"
10
+ @substance = "substance"
11
+ end
12
+
13
+ context "when asked to ask a broker about an action with substance" do
14
+ it "should initialize the broker using an empty concern, the action and substance" do
15
+ @iut.ask_broker_about(@broker, @action, @substance)
16
+ @iut.broker.should == @broker
17
+ @iut.concern.should == ""
18
+ @iut.action.should == @action
19
+ @iut.substance.should == @substance
20
+ end
21
+ end
22
+
23
+ context "when asked to tell a broker about an action with substance" do
24
+ it "should initialize the broker using an empty concern, the action and substance" do
25
+ @iut.tell_broker_to(@broker, @action, @substance)
26
+ @iut.broker.should == @broker
27
+ @iut.concern.should == ""
28
+ @iut.action.should == @action
29
+ @iut.substance.should == @substance
30
+ end
31
+ end
32
+
33
+ context "when discussing" do
34
+ class TestConversation
35
+ attr_accessor :path
36
+ attr_accessor :data
37
+
38
+ def initialize
39
+ @path = "somewhere.com/someplace"
40
+ end
41
+
42
+ def ask(data)
43
+ @data = data
44
+ end
45
+
46
+ def say(path, data)
47
+ @path = path
48
+ @data = data
49
+ end
50
+ end
51
+
52
+ it "should ask the conversation with path and parameters adapted" do
53
+ @conversation = TestConversation.new
54
+ @iut.conversation = @conversation
55
+ @iut.substance = {:param_a => "value_a", :param_b => "value_b"}
56
+ @iut.ask
57
+ #cannot guarantee hash ordering, so check for includes
58
+ @conversation.data.include?("somewhere.com/someplace?").should == true
59
+ @conversation.data.include?("param_a=value_a").should == true
60
+ @conversation.data.include?("param_b=value_b").should == true
61
+ @conversation.data.include?("&").should == true
62
+ end
63
+
64
+ it "should say to the conversation with path and parameters adapted" do
65
+ @conversation = TestConversation.new
66
+ @iut.conversation = @conversation
67
+ @iut.substance = {:param_a => "value_a", :param_b => "value_b"}
68
+ @conversation.should_receive(:say) do |path, params|
69
+ path.should == "somewhere.com/someplace"
70
+ #cannot guarantee hash ordering, so check for includes
71
+ params.include?("param_a=value_a").should == true
72
+ params.include?("param_b=value_b").should == true
73
+ params.include?("&").should == true
74
+ end
75
+ @iut.say
76
+ end
77
+
78
+ end
79
+
80
+ context "when preparing for RESTful communication" do
81
+ it "should compile a list of CGI compatible parameters and present it in a string output ready for HTTP communication" do
82
+ result = @iut.compile_params({:param_a => "value_a", :param_b => "value_b"})
83
+ #cannot guarantee hash ordering, so check for includes
84
+ result.include?("param_a=value_a").should == true
85
+ result.include?("param_b=value_b").should == true
86
+ result.include?("&").should == true end
87
+
88
+ it "should compile a path and parameter string ready for HTTP communication" do
89
+ result = @iut.path_with_params("somewhere.com/someplace", {:param_a => "value_a", :param_b => "value_b"})
90
+ result.include?("somewhere.com/someplace?").should == true
91
+ result.include?("param_a=value_a").should == true
92
+ result.include?("param_b=value_b").should == true
93
+ result.include?("&").should == true
94
+ end
95
+
96
+ it "should output the path if the list of parameters is empty" do
97
+ result = @iut.path_with_params("somewhere.com/someplace", {})
98
+ result.should == "somewhere.com/someplace"
99
+ end
100
+
101
+ it "should output the path if the list of parameters is nil" do
102
+ result = @iut.path_with_params("somewhere.com/someplace", nil)
103
+ result.should == "somewhere.com/someplace"
104
+ end
105
+ end
106
+
107
+ context "when receiving a response" do
108
+ class TestResponse
109
+ attr_accessor :code
110
+ attr_accessor :body
111
+ end
112
+ it "should return true if the response code is 200" do
113
+ response = TestResponse.new
114
+ response.code = "200"
115
+ @iut.success?(response).should == true
116
+ end
117
+
118
+ it "should return false if the response code is 200" do
119
+ response = TestResponse.new
120
+ response.code = "404"
121
+ @iut.success?(response).should == false
122
+ end
123
+
124
+ it "should transform the response by transparently returning the response" do
125
+ @iut.format_response("dontchangeme").should == "dontchangeme"
126
+ end
127
+
128
+ it "should interpret the response by transparently returning the response" do
129
+ response = TestResponse.new
130
+ response.body = "dontchangeme"
131
+ @iut.interpret_conversation(response).should == "dontchangeme"
132
+ end
133
+
134
+ it "should format an error response as an array with code and error body" do
135
+ response = TestResponse.new
136
+ response.code = "404"
137
+ response.body = "this is an error"
138
+ @iut.format_error(response).should == ["404", "this is an error"]
139
+ end
140
+ end
141
+
142
+ context "as a validator" do
143
+ it "should not raise an error if validation is in JSON format" do
144
+ @iut.ensure_that({:param_a => "value_a", :param_b => "value_b"}.to_json)
145
+ @iut.is_json.should
146
+ end
147
+
148
+ it "should raise an error if validation is not in JSON format" do
149
+ @iut.ensure_that("nope")
150
+ expect{ @iut.is_json }.to raise_error(ArgumentError)
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+
157
+
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'converse'
4
+
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..")
6
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
7
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib", "converse")
8
+
9
+ RSpec.configure do |config|
10
+
11
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: converse
3
3
  version: !ruby/object:Gem::Version
4
- hash: 37
4
+ hash: 35
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 25
10
- version: 1.0.25
9
+ - 26
10
+ version: 1.0.26
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ernst van Graan
@@ -15,9 +15,50 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-10-31 00:00:00 Z
19
- dependencies: []
20
-
18
+ date: 2012-12-03 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: mysql2
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
21
62
  description: Converse provides Broker/Translator classes to facilitate communication across an API by means of conversations
22
63
  email:
23
64
  - ernst.van.graan@hetzner.co.za
@@ -51,6 +92,16 @@ files:
51
92
  - lib/converse/rest/rest_broker.rb
52
93
  - lib/converse/rest/rest_interaction.rb
53
94
  - lib/converse/version.rb
95
+ - spec/converse/api_spec.rb
96
+ - spec/converse/broker_spec.rb
97
+ - spec/converse/comms/conversation_spec.rb
98
+ - spec/converse/comms/html/html_conversation_spec.rb
99
+ - spec/converse/comms/mysql/mysql_conversation_spec.rb
100
+ - spec/converse/comms/simple_logger_spec.rb
101
+ - spec/converse/interaction_spec.rb
102
+ - spec/converse/rest/rest_broker_spec.rb
103
+ - spec/converse/rest/rest_interaction_spec.rb
104
+ - spec/spec_helper.rb
54
105
  homepage: ""
55
106
  licenses: []
56
107
 
@@ -84,5 +135,14 @@ rubygems_version: 1.8.24
84
135
  signing_key:
85
136
  specification_version: 3
86
137
  summary: Converse provides Broker/Translator classes to facilitate communication across an API by means of conversations
87
- test_files: []
88
-
138
+ test_files:
139
+ - spec/converse/api_spec.rb
140
+ - spec/converse/broker_spec.rb
141
+ - spec/converse/comms/conversation_spec.rb
142
+ - spec/converse/comms/html/html_conversation_spec.rb
143
+ - spec/converse/comms/mysql/mysql_conversation_spec.rb
144
+ - spec/converse/comms/simple_logger_spec.rb
145
+ - spec/converse/interaction_spec.rb
146
+ - spec/converse/rest/rest_broker_spec.rb
147
+ - spec/converse/rest/rest_interaction_spec.rb
148
+ - spec/spec_helper.rb