and-son 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in and-son.gemspec
4
+ gemspec
5
+
6
+ gem 'bundler', '~>1.1'
7
+ gem 'rake', '~>0.9.2'
8
+
9
+ gem 'bson_ext'
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Collin Redding
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,104 @@
1
+ # AndSon
2
+
3
+ AndSon is a simple Sanford client for Ruby. It provides an API for calling services and handling responses. It uses [Sanford::Protocol](https://github.com/redding/sanford-protocol) to communicate with Sanford servers.
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ # create a client
9
+ client = AndSon.new('127.0.0.1', 8000, 'v1')
10
+
11
+ # call a service and get its response data:
12
+ user_data = client.call('get_user', {:user_name => 'joetest'})
13
+ ```
14
+
15
+ ## Calling Services
16
+
17
+ To call a service, you first need a client to make the calls. You define clients by specifying the host's ip address and port plus the version of the API to make calls against.
18
+
19
+ Once you have your client defined, make service calls using the `call` method. It will return any response data and raise an exception if anything goes wrong.
20
+
21
+ ### Timeouts
22
+
23
+ By default, all requests timeout after 60s. You can override this globally using the `ANDSON_TIMEOUT` env var. You can override this global timeout on a per-call basis by chaining in the `timeout` method.
24
+
25
+ ```ruby
26
+ # timeout this request after 10 seconds
27
+ client.timeout(10).call('get_user', {:user_name => 'joetest'})
28
+ ```
29
+
30
+ When a request times out, a `Sanford::Protocol::TimeoutError` is raised:
31
+
32
+ ```ruby
33
+ begin
34
+ client.timeout(10).call('get_user', {:user_name => 'joetest'})
35
+ rescue Sanford::Protocol::TimeoutError => err
36
+ puts "timeout - so sad :("
37
+ end
38
+ ```
39
+
40
+ ### Default Params
41
+
42
+ Similarly to timeouts, all requests default their params to an empty `Hash` (`{}`). This can be overriden using the `params` method.
43
+
44
+ ```ruby
45
+ # add an API key to all requests made by this client, to authorize our client
46
+ client.params({ 'api_key' => 12345 }).call('get_user', {:user_name => 'joetest'})
47
+ ```
48
+
49
+ One thing to be aware of, AndSon has limited ability to 'merge' or 'append' params. For example:
50
+
51
+ ```ruby
52
+ # raises an exception, can't merge a string on to a hash
53
+ client.params({ 'api_key' => 12345 }).call('get_user', 'joetest')
54
+ ```
55
+
56
+ Be aware of this when setting default params and passing additional params with the `call` method. In general, it's recommended to use ruby's `Hash` for the best results.
57
+
58
+ ### Exception Handling
59
+
60
+ AndSon raises exceptions when a call responds with a `4xx` or `5xx` response code (see [Sanford Status Codes](https://github.com/redding/sanford-protocol#status-codes) for more on response codes):
61
+
62
+ * `400`: `BadRequestError < ClientError`
63
+ * `404`: `NotFoundError < ClientError`
64
+ * `4xx`: `ClientError < RequestError`
65
+ * `5xx`: `ServerError < RequestError`
66
+
67
+ ```ruby
68
+ client.call('some_unknown_service') #=> NotFoundError...
69
+ ```
70
+
71
+ Each exception knows about the response that raised it:
72
+
73
+ ```ruby
74
+ begin
75
+ client.call('some_unknown_service')
76
+ rescue AndSon::NotFoundError => err
77
+ err.response #=> AndSon::Response ...
78
+ err.response.code #=> 404
79
+ end
80
+ ```
81
+
82
+ ### Response Handling
83
+
84
+ If you call a service and pass it a block, no exceptions will be raised and the call will yield its response to the block. The call will return the return value of the block.
85
+
86
+ ```ruby
87
+ user = client.call('get_user', { :user_name => 'joetest' }) do |response|
88
+ if response.code == 200
89
+ User.new(response.data)
90
+ else
91
+ NullUser.new
92
+ end
93
+ end
94
+ ```
95
+
96
+ For more details about the response object, see [sanford-protocol](https://github.com/redding/sanford-protocol#response).
97
+
98
+ ## Contributing
99
+
100
+ 1. Fork it
101
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
102
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
103
+ 4. Push to the branch (`git push origin my-new-feature`)
104
+ 5. Create new Pull Request
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "assert/rake_tasks"
4
+ Assert::RakeTasks.install
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'and-son/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "and-son"
8
+ gem.version = AndSon::VERSION
9
+ gem.authors = ["Collin Redding", "Kelly Redding"]
10
+ gem.email = ["collin.redding@me.com", "kelly@kellyredding.com"]
11
+ gem.description = "Simple Sanford client for Ruby."
12
+ gem.summary = "Simple Sanford client for Ruby."
13
+ gem.homepage = "https://github.com/redding/and-son"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency("sanford-protocol", ["~>0.4"])
21
+
22
+ gem.add_development_dependency("assert", ["~>1.0"])
23
+ gem.add_development_dependency("assert-mocha", ["~>1.0"])
24
+ end
@@ -0,0 +1,10 @@
1
+ require 'and-son/client'
2
+ require 'and-son/version'
3
+
4
+ module AndSon
5
+
6
+ def self.new(*args)
7
+ AndSon::Client.new(*args)
8
+ end
9
+
10
+ end
@@ -0,0 +1,73 @@
1
+ require 'ostruct'
2
+ require 'sanford-protocol'
3
+ require 'and-son/connection'
4
+ require 'and-son/response'
5
+
6
+ module AndSon
7
+
8
+ module CallRunnerMethods
9
+
10
+ # define methods here to allow configuring call runner params. be sure to
11
+ # use `tap` to return whatever instance `self.call_runner` returns so you
12
+ # can method-chain. `self.call_runner` returns a new runner instance if
13
+ # called on a client, but returns the chained instance if called on a runner
14
+
15
+ def timeout(seconds)
16
+ self.call_runner.tap{|r| r.timeout_value = seconds.to_f}
17
+ end
18
+
19
+ def params(hash = nil)
20
+ if !hash.kind_of?(Hash)
21
+ raise ArgumentError, "expected params to be a Hash instead of a #{hash.class}"
22
+ end
23
+ self.call_runner.tap{|r| r.params_value.merge!(hash) }
24
+ end
25
+
26
+ end
27
+
28
+ class Client < Struct.new(:host, :port, :version)
29
+ include CallRunnerMethods
30
+
31
+ DEFAULT_TIMEOUT = 60 #seconds
32
+
33
+ # proxy the call method to the call runner
34
+ def call(*args, &block); self.call_runner.call(*args, &block); end
35
+
36
+ def call_runner
37
+ # always start with this default CallRunner
38
+ CallRunner.new({
39
+ :host => host,
40
+ :port => port,
41
+ :version => version,
42
+ :timeout_value => (ENV['ANDSON_TIMEOUT'] || DEFAULT_TIMEOUT).to_f,
43
+ :params_value => {}
44
+ })
45
+ end
46
+ end
47
+
48
+ class CallRunner < OpenStruct # {:host, :port, :version, :timeout_value, :params_value}
49
+ include CallRunnerMethods
50
+
51
+ # chain runner methods by returning itself
52
+ def call_runner; self; end
53
+
54
+ def call(name, params = {})
55
+ if !params.kind_of?(Hash)
56
+ raise ArgumentError, "expected params to be a Hash instead of a #{hash.class}"
57
+ end
58
+ call_params = self.params_value.merge(params)
59
+ AndSon::Connection.new(host, port).open do |connection|
60
+ connection.write(Sanford::Protocol::Request.new(version, name, call_params).to_hash)
61
+ client_response = AndSon::Response.parse(connection.read(timeout_value))
62
+
63
+ if block_given?
64
+ yield client_response.protocol_response
65
+ else
66
+ client_response.data
67
+ end
68
+ end
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,33 @@
1
+ require 'socket'
2
+ require 'sanford-protocol'
3
+
4
+ module AndSon
5
+
6
+ class Connection < Struct.new(:host, :port)
7
+ module NoRequest
8
+ def self.to_s; "[?]"; end
9
+ end
10
+
11
+ def open
12
+ protocol_connection = Sanford::Protocol::Connection.new(tcp_socket)
13
+ yield protocol_connection if block_given?
14
+ ensure
15
+ protocol_connection.close rescue false
16
+ end
17
+
18
+ private
19
+
20
+ # TCP_NODELAY is set to disable buffering. In the case of Sanford
21
+ # communication, we have all the information we need to send up front and
22
+ # are closing the connection, so it doesn't need to buffer.
23
+ # See http://linux.die.net/man/7/tcp
24
+
25
+ def tcp_socket
26
+ TCPSocket.new(host, port).tap do |socket|
27
+ socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true)
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,19 @@
1
+ module AndSon
2
+
3
+ class RequestError < RuntimeError
4
+ attr_reader :response
5
+
6
+ def initialize(protocol_response)
7
+ super(protocol_response.status.message)
8
+ @response = protocol_response
9
+ end
10
+ end
11
+
12
+ ClientError = Class.new(RequestError)
13
+
14
+ BadRequestError = Class.new(ClientError)
15
+ NotFoundError = Class.new(ClientError)
16
+
17
+ ServerError = Class.new(RequestError)
18
+
19
+ end
@@ -0,0 +1,44 @@
1
+ require 'sanford-protocol'
2
+
3
+ require 'and-son/exceptions'
4
+
5
+ module AndSon
6
+
7
+ class Response < Struct.new(:protocol_response)
8
+
9
+ CODE_MATCHERS = {
10
+ '400' => 400,
11
+ '404' => 404,
12
+ '4xx' => /4[0-9][0-9]/,
13
+ '5xx' => /5[0-9][0-9]/
14
+ }
15
+
16
+ def self.parse(hash)
17
+ self.new(Sanford::Protocol::Response.parse(hash))
18
+ end
19
+
20
+ def data
21
+ if self.code_is_5xx?
22
+ raise ServerError.new(self.protocol_response)
23
+ elsif self.code_is_404?
24
+ raise NotFoundError.new(self.protocol_response)
25
+ elsif self.code_is_400?
26
+ raise BadRequestError.new(self.protocol_response)
27
+ elsif self.code_is_4xx?
28
+ raise ClientError.new(self.protocol_response)
29
+ else
30
+ self.protocol_response.data
31
+ end
32
+ end
33
+
34
+ CODE_MATCHERS.each do |name, matcher|
35
+ matcher = matcher.kind_of?(Regexp) ? matcher : Regexp.new(matcher.to_s)
36
+
37
+ define_method("code_is_#{name}?") do
38
+ !!(self.protocol_response.code.to_s =~ matcher)
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,3 @@
1
+ module AndSon
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,11 @@
1
+ require 'ostruct'
2
+
3
+ ROOT = File.expand_path('../..', __FILE__)
4
+
5
+ require 'and-son'
6
+
7
+ require 'test/support/fake_server'
8
+
9
+ if defined?(Assert)
10
+ require 'assert-mocha'
11
+ end
@@ -0,0 +1,57 @@
1
+ class FakeServer
2
+
3
+ def initialize(port)
4
+ @port = port
5
+ @handlers = {}
6
+ end
7
+
8
+ def add_handler(version, name, &block)
9
+ @handlers["#{version}-#{name}"] = block
10
+ end
11
+
12
+ def run
13
+ server = TCPServer.new("localhost", @port)
14
+ socket = server.accept
15
+
16
+ serve(socket)
17
+
18
+ server.close rescue false
19
+ end
20
+
21
+ protected
22
+
23
+ def serve(socket)
24
+ connection = Sanford::Protocol::Connection.new(socket)
25
+ request = Sanford::Protocol::Request.parse(connection.read)
26
+ status, result = route(request)
27
+ response = Sanford::Protocol::Response.new(status, result)
28
+ connection.write(response.to_hash)
29
+ end
30
+
31
+ def route(request)
32
+ handler = @handlers["#{request.version}-#{request.name}"]
33
+ returned = handler.call(request.params)
34
+ end
35
+
36
+ module Helper
37
+
38
+ def run_fake_server(server, &block)
39
+ begin
40
+ pid = fork do
41
+ trap("TERM"){ exit }
42
+ server.run
43
+ end
44
+
45
+ sleep 0.3 # Give time for the socket to start listening.
46
+ yield
47
+ ensure
48
+ if pid
49
+ Process.kill("TERM", pid)
50
+ Process.wait(pid)
51
+ end
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,163 @@
1
+ require 'assert'
2
+
3
+ class MakingRequestsTest < Assert::Context
4
+ include FakeServer::Helper
5
+
6
+ desc "making a request that"
7
+ setup do
8
+ @fake_server = FakeServer.new(12000)
9
+ end
10
+
11
+ class SuccessTest < MakingRequestsTest
12
+ desc "returns a successful response"
13
+ setup do
14
+ @fake_server.add_handler('v1', 'echo'){|params| [ 200, params['message'] ] }
15
+ end
16
+
17
+ should "get a 200 response with the parameter echoed back" do
18
+ self.run_fake_server(@fake_server) do
19
+
20
+ client = AndSon.new('localhost', 12000, 'v1')
21
+ client.call('echo', :message => 'test') do |response|
22
+ assert_equal 200, response.status.code
23
+ assert_equal nil, response.status.message
24
+ assert_equal 'test', response.data
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ class AuthorizeTest < MakingRequestsTest
33
+ setup do
34
+ @fake_server.add_handler('v1', 'authorize_it') do |params|
35
+ if params['api_key'] == 12345
36
+ [ 200, params['data'] ]
37
+ else
38
+ [ 401, params['data'] ]
39
+ end
40
+ end
41
+ end
42
+
43
+ should "get a 200 response when api_key is passed with the correct value" do
44
+ self.run_fake_server(@fake_server) do
45
+
46
+ client = AndSon.new('localhost', 12000, 'v1').params({ 'api_key' => 12345 })
47
+ client.call('authorize_it', { 'data' => 'holla' }) do |response|
48
+ assert_equal 200, response.status.code
49
+ assert_equal nil, response.status.message
50
+ assert_equal 'holla', response.data
51
+ end
52
+
53
+ end
54
+ end
55
+
56
+ should "get a 401 response when api_key isn't passed" do
57
+ self.run_fake_server(@fake_server) do
58
+
59
+ client = AndSon.new('localhost', 12000, 'v1')
60
+ client.call('authorize_it', { 'data' => 'holla' }) do |response|
61
+ assert_equal 401, response.status.code
62
+ assert_equal nil, response.status.message
63
+ assert_equal 'holla', response.data
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
70
+ class Failure400Test < MakingRequestsTest
71
+ desc "when a request fails with a 400"
72
+ setup do
73
+ @fake_server.add_handler('v1', '400'){|params| [ 400, false ] }
74
+ end
75
+
76
+ should "raise a bad request error" do
77
+ self.run_fake_server(@fake_server) do
78
+
79
+ assert_raises(AndSon::BadRequestError) do
80
+ client = AndSon.new('localhost', 12000, 'v1')
81
+ client.call('400')
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+
88
+ class Failure404Test < MakingRequestsTest
89
+ desc "when a request fails with a 404"
90
+ setup do
91
+ @fake_server.add_handler('v1', '404'){|params| [ 404, false ] }
92
+ end
93
+
94
+ should "raise a not found error" do
95
+ self.run_fake_server(@fake_server) do
96
+
97
+ assert_raises(AndSon::NotFoundError) do
98
+ client = AndSon.new('localhost', 12000, 'v1')
99
+ client.call('404')
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+
106
+ class Failure4xxTest < MakingRequestsTest
107
+ desc "when a request fails with a 4xx"
108
+ setup do
109
+ @fake_server.add_handler('v1', '4xx'){|params| [ 402, false ] }
110
+ end
111
+
112
+ should "raise a client error" do
113
+ self.run_fake_server(@fake_server) do
114
+
115
+ assert_raises(AndSon::ClientError) do
116
+ client = AndSon.new('localhost', 12000, 'v1')
117
+ client.call('4xx')
118
+ end
119
+
120
+ end
121
+ end
122
+ end
123
+
124
+ class Failure5xxTest < MakingRequestsTest
125
+ desc "when a request fails with a 5xx"
126
+ setup do
127
+ @fake_server.add_handler('v1', '5xx'){|params| [ 500, false ] }
128
+ end
129
+
130
+ should "raise a server error" do
131
+ self.run_fake_server(@fake_server) do
132
+
133
+ assert_raises(AndSon::ServerError) do
134
+ client = AndSon.new('localhost', 12000, 'v1')
135
+ client.call('5xx')
136
+ end
137
+
138
+ end
139
+ end
140
+ end
141
+
142
+ class TimeoutErrorTest < MakingRequestsTest
143
+ desc "when a request takes to long to respond"
144
+ setup do
145
+ @fake_server.add_handler('v1', 'forever') do |params|
146
+ sleep 0.2
147
+ [ 200, true ]
148
+ end
149
+ end
150
+
151
+ should "raise a timeout error" do
152
+ self.run_fake_server(@fake_server) do
153
+
154
+ assert_raises(Sanford::Protocol::TimeoutError) do
155
+ client = AndSon.new('localhost', 12000, 'v1')
156
+ client.timeout(0.1).call('forever')
157
+ end
158
+
159
+ end
160
+ end
161
+ end
162
+
163
+ end
@@ -0,0 +1,13 @@
1
+ require 'assert'
2
+
3
+ module AndSon
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AndSon"
7
+ subject{ AndSon }
8
+
9
+ should have_instance_methods :new
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,68 @@
1
+ require 'assert'
2
+
3
+ class AndSon::Client
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AndSon::Client"
7
+ setup do
8
+ @host, @port, @version = '0.0.0.0', 8000, "v1"
9
+ @client = AndSon::Client.new(@host, @port, @version)
10
+ end
11
+ subject{ @client }
12
+
13
+ should have_imeths :host, :port, :version
14
+ should have_imeths :call_runner, :call, :timeout
15
+
16
+ should "know its default call runner" do
17
+ default_runner = subject.call_runner
18
+
19
+ assert_equal @host, default_runner.host
20
+ assert_equal @port, default_runner.port
21
+ assert_equal @version, default_runner.version
22
+ assert_equal 60.0, default_runner.timeout_value
23
+ end
24
+
25
+ should "override the default call runner timeout with an env var" do
26
+ prev = ENV['ANDSON_TIMEOUT']
27
+ ENV['ANDSON_TIMEOUT'] = '20'
28
+
29
+ assert_equal 20.0, subject.call_runner.timeout_value
30
+
31
+ ENV['ANDSON_TIMEOUT'] = prev
32
+ end
33
+
34
+ should "return a CallRunner with a timeout value set #timeout" do
35
+ runner = subject.timeout(10)
36
+
37
+ assert_kind_of AndSon::CallRunner, runner
38
+ assert_respond_to :call, runner
39
+ assert_equal 10.0, runner.timeout_value
40
+ end
41
+
42
+ should "return a CallRunner with params_value set using #params" do
43
+ runner = subject.params({ :api_key => 12345 })
44
+
45
+ assert_kind_of AndSon::CallRunner, runner
46
+ assert_respond_to :call, runner
47
+ assert_equal({ :api_key => 12345 }, runner.params_value)
48
+ end
49
+
50
+ should "raise an ArgumentError when #params is not passed a Hash" do
51
+ assert_raises(ArgumentError) do
52
+ subject.params('test')
53
+ end
54
+ end
55
+
56
+ should "raise an ArgumentError when #call is not passed a Hash for params" do
57
+ runner = subject.timeout(0.1) # in case it actually tries to make the request
58
+
59
+ assert_raises(ArgumentError) do
60
+ runner.call('something', 'test')
61
+ end
62
+ end
63
+ end
64
+
65
+ # the `call` method is tested in the file test/system/making_requests_test.rb,
66
+ # because there is a lot of setup needed to call this method
67
+
68
+ end
@@ -0,0 +1,108 @@
1
+ require 'assert'
2
+
3
+ class AndSon::Response
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AndSon::Response"
7
+ setup do
8
+ @protocol_response = Sanford::Protocol::Response.new([ 200, 'message' ], 'data')
9
+ @response = AndSon::Response.new(@protocol_response)
10
+ end
11
+ subject{ @response }
12
+
13
+ should have_instance_methods :data, :code_is_5xx?, :code_is_404?, :code_is_400?, :code_is_4xx?
14
+ should have_class_methods :parse
15
+
16
+ should "return the protocol response's data with #data" do
17
+ assert_equal @protocol_response.data, subject.data
18
+ end
19
+ should "return false for all the code_is methods" do
20
+ assert_equal false, subject.code_is_5xx?
21
+ assert_equal false, subject.code_is_404?
22
+ assert_equal false, subject.code_is_400?
23
+ assert_equal false, subject.code_is_4xx?
24
+ end
25
+ end
26
+
27
+ class FailedResponseTest < BaseTest
28
+ desc "given a failed response"
29
+ setup do
30
+ @protocol_response = Sanford::Protocol::Response.new([ 500, 'message' ])
31
+ @response = AndSon::Response.new(@protocol_response)
32
+ end
33
+
34
+ should "raise an exception using the response's message and the exception should have the" \
35
+ "response as well" do
36
+ exception = nil
37
+ begin; subject.data; rescue Exception => exception; end
38
+
39
+ assert_instance_of AndSon::ServerError, exception
40
+ assert_equal @protocol_response.status.message, exception.message
41
+ assert_equal @protocol_response, exception.response
42
+ end
43
+ end
44
+
45
+ class Response5xxTest < BaseTest
46
+ desc "given a 5xx response"
47
+ setup do
48
+ @protocol_response = Sanford::Protocol::Response.new(500)
49
+ @response = AndSon::Response.new(@protocol_response)
50
+ end
51
+
52
+ should "return true with code_is_5xx? and false for all the other code_is methods" do
53
+ assert_equal true, subject.code_is_5xx?
54
+ assert_equal false, subject.code_is_404?
55
+ assert_equal false, subject.code_is_400?
56
+ assert_equal false, subject.code_is_4xx?
57
+ end
58
+ end
59
+
60
+ class Response404Test < BaseTest
61
+ desc "given a 404 response"
62
+ setup do
63
+ @protocol_response = Sanford::Protocol::Response.new(404)
64
+ @response = AndSon::Response.new(@protocol_response)
65
+ end
66
+
67
+ should "return true with code_is_404? and code_is_4xx?; false for all the other " \
68
+ "code_is methods" do
69
+ assert_equal false, subject.code_is_5xx?
70
+ assert_equal true, subject.code_is_404?
71
+ assert_equal false, subject.code_is_400?
72
+ assert_equal true, subject.code_is_4xx?
73
+ end
74
+ end
75
+
76
+ class Response400Test < BaseTest
77
+ desc "given a 400 response"
78
+ setup do
79
+ @protocol_response = Sanford::Protocol::Response.new(400)
80
+ @response = AndSon::Response.new(@protocol_response)
81
+ end
82
+
83
+ should "return true with code_is_400? and code_is_4xx?; false for all the other " \
84
+ "code_is methods" do
85
+ assert_equal false, subject.code_is_5xx?
86
+ assert_equal false, subject.code_is_404?
87
+ assert_equal true, subject.code_is_400?
88
+ assert_equal true, subject.code_is_4xx?
89
+ end
90
+ end
91
+
92
+ class Response4xxTest < BaseTest
93
+ desc "given a 4xx response"
94
+ setup do
95
+ @protocol_response = Sanford::Protocol::Response.new(402)
96
+ @response = AndSon::Response.new(@protocol_response)
97
+ end
98
+
99
+ should "return true with code_is_4xx? and false for all the other code_is methods" do
100
+ assert_equal false, subject.code_is_5xx?
101
+ assert_equal false, subject.code_is_404?
102
+ assert_equal false, subject.code_is_400?
103
+ assert_equal true, subject.code_is_4xx?
104
+ end
105
+ end
106
+
107
+ end
108
+
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: and-son
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Collin Redding
14
+ - Kelly Redding
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-11-28 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ - 4
32
+ version: "0.4"
33
+ requirement: *id001
34
+ name: sanford-protocol
35
+ type: :runtime
36
+ - !ruby/object:Gem::Dependency
37
+ prerelease: false
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 15
44
+ segments:
45
+ - 1
46
+ - 0
47
+ version: "1.0"
48
+ requirement: *id002
49
+ name: assert
50
+ type: :development
51
+ - !ruby/object:Gem::Dependency
52
+ prerelease: false
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ hash: 15
59
+ segments:
60
+ - 1
61
+ - 0
62
+ version: "1.0"
63
+ requirement: *id003
64
+ name: assert-mocha
65
+ type: :development
66
+ description: Simple Sanford client for Ruby.
67
+ email:
68
+ - collin.redding@me.com
69
+ - kelly@kellyredding.com
70
+ executables: []
71
+
72
+ extensions: []
73
+
74
+ extra_rdoc_files: []
75
+
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - and-son.gemspec
83
+ - lib/and-son.rb
84
+ - lib/and-son/client.rb
85
+ - lib/and-son/connection.rb
86
+ - lib/and-son/exceptions.rb
87
+ - lib/and-son/response.rb
88
+ - lib/and-son/version.rb
89
+ - test/helper.rb
90
+ - test/support/fake_server.rb
91
+ - test/system/making_requests_test.rb
92
+ - test/unit/and-son_test.rb
93
+ - test/unit/client_test.rb
94
+ - test/unit/response_test.rb
95
+ homepage: https://github.com/redding/and-son
96
+ licenses: []
97
+
98
+ post_install_message:
99
+ rdoc_options: []
100
+
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.15
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Simple Sanford client for Ruby.
128
+ test_files:
129
+ - test/helper.rb
130
+ - test/support/fake_server.rb
131
+ - test/system/making_requests_test.rb
132
+ - test/unit/and-son_test.rb
133
+ - test/unit/client_test.rb
134
+ - test/unit/response_test.rb