and-son 0.1.0

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.
@@ -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