converse 1.0.25 → 1.0.26

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