chassis 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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +362 -0
  6. data/Rakefile +33 -0
  7. data/chassis.gemspec +41 -0
  8. data/examples/repo.rb +40 -0
  9. data/lib/chassis.rb +81 -0
  10. data/lib/chassis/array_utils.rb +8 -0
  11. data/lib/chassis/circuit_panel.rb +22 -0
  12. data/lib/chassis/core_ext/array.rb +5 -0
  13. data/lib/chassis/core_ext/hash.rb +5 -0
  14. data/lib/chassis/core_ext/string.rb +13 -0
  15. data/lib/chassis/delegate.rb +29 -0
  16. data/lib/chassis/dirty_session.rb +105 -0
  17. data/lib/chassis/error.rb +7 -0
  18. data/lib/chassis/faraday.rb +226 -0
  19. data/lib/chassis/form.rb +56 -0
  20. data/lib/chassis/hash_utils.rb +16 -0
  21. data/lib/chassis/heroku.rb +5 -0
  22. data/lib/chassis/initializable.rb +11 -0
  23. data/lib/chassis/logger.rb +8 -0
  24. data/lib/chassis/observable.rb +19 -0
  25. data/lib/chassis/persistence.rb +49 -0
  26. data/lib/chassis/rack/bouncer.rb +33 -0
  27. data/lib/chassis/rack/builder_shim_patch.rb +7 -0
  28. data/lib/chassis/rack/health_check.rb +45 -0
  29. data/lib/chassis/rack/instrumentation.rb +20 -0
  30. data/lib/chassis/rack/json_body_parser.rb +20 -0
  31. data/lib/chassis/rack/no_robots.rb +24 -0
  32. data/lib/chassis/registry.rb +30 -0
  33. data/lib/chassis/repo.rb +73 -0
  34. data/lib/chassis/repo/base_repo.rb +99 -0
  35. data/lib/chassis/repo/delegation.rb +78 -0
  36. data/lib/chassis/repo/lazy_association.rb +57 -0
  37. data/lib/chassis/repo/memory_repo.rb +7 -0
  38. data/lib/chassis/repo/null_repo.rb +64 -0
  39. data/lib/chassis/repo/pstore_repo.rb +54 -0
  40. data/lib/chassis/repo/record_map.rb +44 -0
  41. data/lib/chassis/repo/redis_repo.rb +55 -0
  42. data/lib/chassis/serializable.rb +52 -0
  43. data/lib/chassis/string_utils.rb +50 -0
  44. data/lib/chassis/version.rb +3 -0
  45. data/lib/chassis/web_service.rb +61 -0
  46. data/test/array_utils_test.rb +23 -0
  47. data/test/chassis_test.rb +7 -0
  48. data/test/circuit_panel_test.rb +22 -0
  49. data/test/core_ext/array_test.rb +8 -0
  50. data/test/core_ext/hash_test.rb +8 -0
  51. data/test/core_ext/string_test.rb +16 -0
  52. data/test/delegate_test.rb +41 -0
  53. data/test/dirty_session_test.rb +138 -0
  54. data/test/error_test.rb +12 -0
  55. data/test/faraday_test.rb +749 -0
  56. data/test/form_test.rb +29 -0
  57. data/test/hash_utils_test.rb +17 -0
  58. data/test/initializable_test.rb +22 -0
  59. data/test/logger_test.rb +43 -0
  60. data/test/observable_test.rb +27 -0
  61. data/test/persistence_test.rb +112 -0
  62. data/test/prox_test.rb +7 -0
  63. data/test/rack/bouncer_test.rb +42 -0
  64. data/test/rack/builder_patch_test.rb +36 -0
  65. data/test/rack/health_check_test.rb +35 -0
  66. data/test/rack/instrumentation_test.rb +38 -0
  67. data/test/rack/json_body_parser_test.rb +38 -0
  68. data/test/rack/no_robots_test.rb +34 -0
  69. data/test/registry_test.rb +26 -0
  70. data/test/repo/delegation_test.rb +101 -0
  71. data/test/repo/lazy_association_test.rb +115 -0
  72. data/test/repo/memory_repo_test.rb +25 -0
  73. data/test/repo/null_repo_test.rb +48 -0
  74. data/test/repo/pstore_repo_test.rb +28 -0
  75. data/test/repo/redis_repo_test.rb +26 -0
  76. data/test/repo/repo_tests.rb +120 -0
  77. data/test/repo_test.rb +76 -0
  78. data/test/serializable_test.rb +77 -0
  79. data/test/string_utils_test.rb +21 -0
  80. data/test/test_helper.rb +10 -0
  81. data/test/web_service_test.rb +107 -0
  82. metadata +426 -0
@@ -0,0 +1,3 @@
1
+ module Chassis
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,61 @@
1
+ require 'sinatra'
2
+ require 'sinatra/json'
3
+ require 'rack/contrib/bounce_favicon'
4
+ require 'rack/deflater'
5
+
6
+ module Chassis
7
+ class WebService < Sinatra::Base
8
+ ParameterMissingError = Chassis.error do |key|
9
+ %Q{Request did not provide "#{@key}"}
10
+ end
11
+
12
+ helpers do
13
+ def extract!(key)
14
+ value = params.fetch(key.to_s) do
15
+ raise ParameterMissingError, key
16
+ end
17
+
18
+ raise ParameterMissingError, key unless value.is_a?(Hash)
19
+
20
+ value
21
+ end
22
+
23
+ def halt_json_error(code, errors = {})
24
+ json_error env.fetch('sinatra.error'), code, errors
25
+ end
26
+
27
+ def json_error(ex, code, errors = {})
28
+ halt code, { 'Content-Type' => 'application/json' }, JSON.dump({
29
+ error: { message: ex.message }
30
+ }.merge(errors))
31
+ end
32
+ end
33
+
34
+ error ParameterMissingError do
35
+ halt_json_error 400
36
+ end
37
+
38
+ error Chassis::UnknownFormFieldError do
39
+ halt_json_error 400
40
+ end
41
+
42
+ error Chassis::RecordNotFoundError do
43
+ halt_json_error 404
44
+ end
45
+
46
+ use Rack::NoRobots
47
+ use Rack::Bouncer
48
+ use ::Rack::BounceFavicon
49
+ use ::Rack::Deflater
50
+ use Rack::JsonBodyParser
51
+
52
+ set :cors, false
53
+
54
+ class << self
55
+ def setup_default_middleware(builder)
56
+ super
57
+ builder.use Manifold::Middleware if settings.cors?
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'test_helper'
2
+
3
+ class ArrayUtilsTest < MiniTest::Unit::TestCase
4
+ def utils
5
+ Chassis::ArrayUtils
6
+ end
7
+
8
+ def test_extract_options_removes_options_hash_if_present
9
+ args = ['foo', { bar: 'baz' }]
10
+ options = utils.extract_options! args
11
+
12
+ assert_equal({ bar: 'baz' }, options)
13
+ assert_equal(%w(foo), args)
14
+ end
15
+
16
+ def test_extract_options_does_nothing_if_no_options
17
+ args = %w(foo)
18
+ options = utils.extract_options! args
19
+
20
+ assert_equal({}, options)
21
+ assert_equal(%w(foo), args)
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'test_helper'
2
+
3
+ class ChassisTest < MiniTest::Unit::TestCase
4
+ def test_it_should_define_a_version
5
+ assert Chassis::VERSION
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'test_helper'
2
+
3
+ class CircuitPanelTest < MiniTest::Unit::TestCase
4
+ def test_circuit_method_returns_the_given_circuit
5
+ panel = Chassis.circuit_panel do
6
+ circuit :test, timeout: 10
7
+ end.new
8
+
9
+ circuit = panel.test
10
+ assert_kind_of Breaker::Circuit, circuit
11
+ assert_equal :test, circuit.name
12
+ end
13
+
14
+ def test_options_passed_to_circuit_are_set_on_the_circuit
15
+ panel = Chassis.circuit_panel do
16
+ circuit :test, timeout: 10
17
+ end.new
18
+
19
+ circuit = panel.test
20
+ assert_equal 10, circuit.timeout
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../test_helper'
2
+ require 'chassis/core_ext/array'
3
+
4
+ class ArrayCoreExtTest < MiniTest::Unit::TestCase
5
+ def test_extract_options!
6
+ assert_equal({}, [].extract_options!)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require_relative '../test_helper'
2
+ require 'chassis/core_ext/hash'
3
+
4
+ class HashCoreExtTest < MiniTest::Unit::TestCase
5
+ def test_symbolize
6
+ assert_equal({ foo: 'bar' }, { 'foo' => 'bar' }.symbolize)
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../test_helper'
2
+ require 'chassis/core_ext/string'
3
+
4
+ class StringCoreExtTest < MiniTest::Unit::TestCase
5
+ def test_underscore
6
+ assert_equal('foo_bar', 'FooBar'.underscore)
7
+ end
8
+
9
+ def test_demodulize
10
+ assert_equal('Bar', 'Foo::Bar'.demodulize)
11
+ end
12
+
13
+ def test_constantize
14
+ assert_equal self.class, self.class.name.constantize
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ require_relative 'test_helper'
2
+
3
+ class DelegateTest < MiniTest::Unit::TestCase
4
+ class Delegator
5
+ include Chassis.delegate(:add, to: :object)
6
+
7
+ attr_reader :object
8
+
9
+ def initialize(object)
10
+ @object = object
11
+ end
12
+ end
13
+
14
+ def test_methods_are_delegated
15
+ delegate = Class.new do
16
+ def add(number)
17
+ number + 5
18
+ end
19
+ end.new
20
+
21
+ delegator = Delegator.new delegate
22
+
23
+ assert_equal 10, delegator.add(5)
24
+ end
25
+
26
+ def test_raises_an_error_if_no_object_to_delegate_to
27
+ delegator = Delegator.new nil
28
+
29
+ assert_raises Chassis::DelegationError do
30
+ delegator.add 1
31
+ end
32
+ end
33
+
34
+ def test_fails_with_an_error_if_nothing_to_delegate_to
35
+ assert_raises ArgumentError do
36
+ Class.new do
37
+ include Chassis.delegate(:foo, :bar)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,138 @@
1
+ require_relative 'test_helper'
2
+
3
+ class DirtySessionTest < MiniTest::Unit::TestCase
4
+ class Person
5
+ include Chassis::Initializable
6
+
7
+ attr_accessor :name, :email, :id
8
+ end
9
+
10
+ attr_reader :person
11
+
12
+ def setup
13
+ @person = Person.new do |person|
14
+ person.name = 'adam'
15
+ person.email = 'example@example.com'
16
+ person.id = 1
17
+ end
18
+ end
19
+
20
+ def test_initialize_as_clean
21
+ session = Chassis::DirtySession.new person
22
+ assert session.clean?
23
+ refute session.dirty?
24
+ end
25
+
26
+ def test_assigning_new_value_marks_the_session_dirty
27
+ session = Chassis::DirtySession.new person
28
+ session.name = 'foo'
29
+
30
+ refute session.clean?
31
+ assert session.dirty?
32
+ end
33
+
34
+ def test_changes_can_be_tested_via_query_method
35
+ session = Chassis::DirtySession.new person
36
+ session.name = 'foo'
37
+
38
+ refute session.clean?
39
+ assert session.dirty?
40
+
41
+ assert_respond_to session, :name_changed?, "Session should respond to changed queries"
42
+ assert session.name_changed?
43
+ end
44
+
45
+ def test_changes_include_all_new_assignments
46
+ session = Chassis::DirtySession.new person
47
+ session.name = 'foo'
48
+
49
+ refute session.clean?
50
+ assert session.dirty?
51
+
52
+ assert_equal(Set.new([:name]), session.changes)
53
+ end
54
+
55
+ def test_changes_are_accessible
56
+ session = Chassis::DirtySession.new person
57
+ session.name = 'foo'
58
+
59
+ refute session.clean?
60
+ assert session.dirty?
61
+
62
+ assert_equal({ name: 'foo' }, session.new_values)
63
+ end
64
+
65
+ def test_assigning_a_new_value_records_the_original_value
66
+ original_name = person.name
67
+ assert original_name, "Precondition: person must have a name"
68
+
69
+ session = Chassis::DirtySession.new person
70
+ session.name = 'foo'
71
+
72
+ refute session.clean?
73
+ assert session.dirty?
74
+
75
+ assert_equal({ name: original_name}, session.original_values)
76
+ end
77
+
78
+ def test_original_values_are_accessible_via_an_original_method
79
+ original_name = person.name
80
+ assert original_name, "Precondition: person must have a name"
81
+
82
+ session = Chassis::DirtySession.new person
83
+ session.name = 'foo'
84
+
85
+ refute session.clean?
86
+ assert session.dirty?
87
+
88
+ assert_respond_to session, :original_name, "Session should respond to original_XXX methods"
89
+ assert_equal original_name, session.original_name
90
+ end
91
+
92
+ def test_assigning_the_same_value_does_not_count_as_a_change
93
+ original_name = person.name
94
+ assert original_name, "Precondition: person must have a name"
95
+
96
+ session = Chassis::DirtySession.new person
97
+ session.name = original_name
98
+
99
+ assert session.clean?, "Setting the same value should not count as a change"
100
+ refute session.dirty?
101
+ end
102
+
103
+ def test_assigning_the_same_value_multiple_times_saves_the_initial_value
104
+ original_name = person.name
105
+ assert original_name, "Precondition: person must have a name"
106
+
107
+ session = Chassis::DirtySession.new person
108
+ session.name = 'matthew'
109
+ session.name = 'michael'
110
+
111
+ refute session.clean?
112
+ assert session.dirty?
113
+
114
+ assert_equal original_name, session.original_name
115
+ end
116
+
117
+ def test_reset_moves_session_to_initial_state
118
+ original_name = person.name
119
+ assert original_name, "Precondition: person must have a name"
120
+
121
+ session = Chassis::DirtySession.new person
122
+ session.name = 'matthew'
123
+
124
+ refute session.clean?
125
+ assert session.dirty?
126
+
127
+ session.reset!
128
+
129
+ assert session.clean?
130
+ refute session.dirty?
131
+
132
+ assert_empty session.changes
133
+ assert_empty session.new_values
134
+ assert_empty session.original_values
135
+
136
+ refute session.name_changed?
137
+ end
138
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'test_helper'
2
+
3
+ class ErrorTest < MiniTest::Unit::TestCase
4
+ def test_delegates_to_tnt
5
+ klass = Chassis.error do |foo|
6
+ "#{foo} bar"
7
+ end
8
+
9
+ error = klass.new "Adam"
10
+ assert_equal "Adam bar", error.message
11
+ end
12
+ end
@@ -0,0 +1,749 @@
1
+ require_relative "test_helper"
2
+
3
+ class FaradayTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ Harness.config.queue = Harness::SyncQueue.new
6
+ Harness.config.collector = Harness::FakeCollector.new
7
+ end
8
+
9
+ def stats
10
+ Harness.config.collector
11
+ end
12
+
13
+ def build(url = nil, options = {}, &block)
14
+ Faraday.new url, options, &block
15
+ end
16
+
17
+ def test_instruments_all_requests
18
+ faraday = build do |conn|
19
+ conn.request :instrumentation
20
+
21
+ conn.adapter :test do |stub|
22
+ stub.get 'test' do
23
+ [200, {'Content-Type' => 'application/json'}, JSON.dump(foo: 'bar')]
24
+ end
25
+ end
26
+ end
27
+
28
+ faraday.get 'test'
29
+
30
+ refute_empty stats.timers
31
+ timer = stats.timers.first
32
+
33
+ assert_equal 'faraday.get', timer.name
34
+ end
35
+
36
+ def test_instrumentation_namespace_can_be_customized
37
+ faraday = build 'http://example.com' do |conn|
38
+ conn.request :instrumentation, 'http'
39
+
40
+ conn.adapter :test do |stub|
41
+ stub.get 'test' do
42
+ [200, {'Content-Type' => 'application/json'}, JSON.dump(foo: 'bar')]
43
+ end
44
+ end
45
+ end
46
+
47
+ faraday.get 'test'
48
+
49
+ refute_empty stats.timers
50
+ timer = stats.timers.first
51
+
52
+ assert_equal 'http.get', timer.name
53
+ end
54
+
55
+ def test_sends_requests_in_json
56
+ faraday = build do |conn|
57
+ conn.request :encode_json
58
+
59
+ conn.adapter :test do |stub|
60
+ stub.post 'test' do |env|
61
+ json = JSON.load env.fetch(:body)
62
+ [200, {'Content-Type' => 'text/plain'}, json.fetch('foo')]
63
+ end
64
+ end
65
+ end
66
+
67
+ response = faraday.post 'test', foo: 'bar'
68
+
69
+ assert_equal 'bar', response.body
70
+ end
71
+
72
+ def test_parses_json_bodies
73
+ faraday = build do |conn|
74
+ conn.request :encode_json
75
+ conn.response :parse_json
76
+
77
+ conn.adapter :test do |stub|
78
+ stub.post 'test' do |env|
79
+ [ 200,
80
+ {'Requested-Type' => env.fetch(:request_headers).fetch('Content-Type')},
81
+ env.fetch(:body)
82
+ ]
83
+ end
84
+ end
85
+ end
86
+
87
+ response = faraday.post 'test', foo: 'bar'
88
+
89
+ assert_equal(JSON.dump({ 'foo' => 'bar' }), response.body)
90
+ assert_equal 'application/json', response.headers.fetch('Requested-Type')
91
+ end
92
+
93
+ def test_does_not_parse_nil_bodies
94
+ faraday = build do |conn|
95
+ conn.response :parse_json
96
+
97
+ conn.adapter :test do |stub|
98
+ stub.get 'test' do
99
+ [200, {'Content-Type' => 'application/json'}, nil]
100
+ end
101
+ end
102
+ end
103
+
104
+ response = faraday.get 'test'
105
+
106
+ assert_nil response[:body]
107
+ end
108
+
109
+ def test_does_not_parse_empty_bodies
110
+ faraday = build do |conn|
111
+ conn.response :parse_json
112
+
113
+ conn.adapter :test do |stub|
114
+ stub.get 'test' do
115
+ [200, {'Content-Type' => 'application/json'}, '']
116
+ end
117
+ end
118
+ end
119
+
120
+ response = faraday.get 'test'
121
+
122
+ assert_nil response[:body]
123
+ end
124
+
125
+ def test_does_not_parse_empty_strings
126
+ faraday = build do |conn|
127
+ conn.response :parse_json
128
+
129
+ conn.adapter :test do |stub|
130
+ stub.get 'test' do
131
+ [200, {'Content-Type' => 'application/json'}, ' ']
132
+ end
133
+ end
134
+ end
135
+
136
+ response = faraday.get 'test'
137
+
138
+ assert_nil response[:body]
139
+ end
140
+
141
+ def test_does_not_parse_204s
142
+ faraday = build do |conn|
143
+ conn.response :parse_json
144
+
145
+ conn.adapter :test do |stub|
146
+ stub.get 'test' do
147
+ [204, {'Content-Type' => 'application/json'}, '']
148
+ end
149
+ end
150
+ end
151
+
152
+ response = faraday.get 'test'
153
+
154
+ assert_nil response[:body]
155
+ end
156
+
157
+ def test_does_not_parse_304s
158
+ faraday = build do |conn|
159
+ conn.response :parse_json
160
+
161
+ conn.adapter :test do |stub|
162
+ stub.get 'test' do
163
+ [304, {'Content-Type' => 'application/json'}, '']
164
+ end
165
+ end
166
+ end
167
+
168
+ response = faraday.get 'test'
169
+
170
+ assert_nil response[:body]
171
+ end
172
+
173
+ def test_logs_requests
174
+ stream = StringIO.new
175
+ logger = Logger.new stream
176
+ logger.level = :debug
177
+
178
+ faraday = build 'http://example.com' do |conn|
179
+ conn.response :logging, logger
180
+
181
+ conn.adapter :test do |stub|
182
+ stub.get 'test' do
183
+ [200, {}, 'dead']
184
+ end
185
+ end
186
+ end
187
+
188
+ faraday.get 'test', { foo: 'bar' }, { 'This-Header' => 'has_a_value' }
189
+
190
+ stream.rewind ; content = stream.read
191
+
192
+ assert_includes content, 'http://example.com/test'
193
+ assert_includes content, 'This-Header'
194
+ assert_includes content, 'has_a_value'
195
+ assert_includes content, 'foo'
196
+ assert_includes content, 'bar'
197
+ end
198
+
199
+ def test_logs_responses
200
+ stream = StringIO.new
201
+ logger = Logger.new stream
202
+ logger.level = :debug
203
+
204
+ faraday = build 'http://example.com' do |conn|
205
+ conn.response :logging, logger
206
+
207
+ conn.adapter :test do |stub|
208
+ stub.get 'test' do
209
+ [200, {'This-Header' => 'has_a_value'}, 'the_body']
210
+ end
211
+ end
212
+ end
213
+
214
+ faraday.get 'test'
215
+
216
+ stream.rewind ; content = stream.read
217
+
218
+ assert_includes content, '200'
219
+ assert_includes content, 'This-Header'
220
+ assert_includes content, 'has_a_value'
221
+ assert_includes content, 'the_body'
222
+ end
223
+
224
+ def test_raises_a_bad_request_error
225
+ faraday = build do |conn|
226
+ conn.response :server_error_handler
227
+
228
+ conn.adapter :test do |stub|
229
+ stub.get 'test' do
230
+ [400, {}, 'dead']
231
+ end
232
+ end
233
+ end
234
+
235
+ assert_raises Chassis::HttpBadRequestError do
236
+ response = faraday.get 'test'
237
+ end
238
+ end
239
+
240
+ def test_raises_an_unauthorized_error
241
+ faraday = build do |conn|
242
+ conn.response :server_error_handler
243
+
244
+ conn.adapter :test do |stub|
245
+ stub.get 'test' do
246
+ [401, {}, 'dead']
247
+ end
248
+ end
249
+ end
250
+
251
+ assert_raises Chassis::HttpUnauthorizedError do
252
+ response = faraday.get 'test'
253
+ end
254
+ end
255
+
256
+ def test_raises_a_payment_required_error
257
+ faraday = build do |conn|
258
+ conn.response :server_error_handler
259
+ conn.adapter :test do |stub|
260
+ stub.get 'test' do
261
+ [402, {}, 'dead']
262
+ end
263
+ end
264
+ end
265
+
266
+ assert_raises Chassis::HttpPaymentRequiredError do
267
+ response = faraday.get 'test'
268
+ end
269
+ end
270
+
271
+ def test_raises_a_forbidden_error
272
+ faraday = build do |conn|
273
+ conn.response :server_error_handler
274
+ conn.adapter :test do |stub|
275
+ stub.get 'test' do
276
+ [403, {}, 'dead']
277
+ end
278
+ end
279
+ end
280
+
281
+ assert_raises Chassis::HttpForbiddenError do
282
+ response = faraday.get 'test'
283
+ end
284
+ end
285
+
286
+ def test_raises_a_not_found_error
287
+ faraday = build do |conn|
288
+ conn.response :server_error_handler
289
+ conn.adapter :test do |stub|
290
+ stub.get 'test' do
291
+ [404, {}, 'dead']
292
+ end
293
+ end
294
+ end
295
+
296
+ assert_raises Chassis::HttpNotFoundError do
297
+ response = faraday.get 'test'
298
+ end
299
+ end
300
+
301
+ def test_raises_a_method_not_allowed_error
302
+ faraday = build do |conn|
303
+ conn.response :server_error_handler
304
+ conn.adapter :test do |stub|
305
+ stub.get 'test' do
306
+ [405, {}, 'dead']
307
+ end
308
+ end
309
+ end
310
+
311
+ assert_raises Chassis::HttpMethodNotAllowedError do
312
+ response = faraday.get 'test'
313
+ end
314
+ end
315
+
316
+ def test_raises_an_unacceptable_error
317
+ faraday = build do |conn|
318
+ conn.response :server_error_handler
319
+ conn.adapter :test do |stub|
320
+ stub.get 'test' do
321
+ [406, {}, 'dead']
322
+ end
323
+ end
324
+ end
325
+
326
+ assert_raises Chassis::HttpNotAcceptableError do
327
+ response = faraday.get 'test'
328
+ end
329
+ end
330
+
331
+ def test_raises_a_proxy_auth_error
332
+ faraday = build do |conn|
333
+ conn.response :server_error_handler
334
+ conn.adapter :test do |stub|
335
+ stub.get 'test' do
336
+ [407, {}, 'dead']
337
+ end
338
+ end
339
+ end
340
+
341
+ assert_raises Chassis::HttpProxyAuthenticationRequiredError do
342
+ response = faraday.get 'test'
343
+ end
344
+ end
345
+
346
+ def test_raises_a_timeout_error
347
+ faraday = build do |conn|
348
+ conn.response :server_error_handler
349
+ conn.adapter :test do |stub|
350
+ stub.get 'test' do
351
+ [408, {}, 'dead']
352
+ end
353
+ end
354
+ end
355
+
356
+ assert_raises Chassis::HttpRequestTimeoutError do
357
+ response = faraday.get 'test'
358
+ end
359
+ end
360
+
361
+ def test_raises_a_conflict_error
362
+ faraday = build do |conn|
363
+ conn.response :server_error_handler
364
+ conn.adapter :test do |stub|
365
+ stub.get 'test' do
366
+ [409, {}, 'dead']
367
+ end
368
+ end
369
+ end
370
+
371
+ assert_raises Chassis::HttpConflictError do
372
+ response = faraday.get 'test'
373
+ end
374
+ end
375
+
376
+ def test_raises_a_gone_error
377
+ faraday = build do |conn|
378
+ conn.response :server_error_handler
379
+ conn.adapter :test do |stub|
380
+ stub.get 'test' do
381
+ [410, {}, 'dead']
382
+ end
383
+ end
384
+ end
385
+
386
+ assert_raises Chassis::HttpGoneError do
387
+ response = faraday.get 'test'
388
+ end
389
+ end
390
+
391
+ def test_raises_length_required
392
+ faraday = build do |conn|
393
+ conn.response :server_error_handler
394
+ conn.adapter :test do |stub|
395
+ stub.get 'test' do
396
+ [411, {}, 'dead']
397
+ end
398
+ end
399
+ end
400
+
401
+ assert_raises Chassis::HttpLengthRequiredError do
402
+ response = faraday.get 'test'
403
+ end
404
+ end
405
+
406
+ def test_raises_precondition_failed
407
+ faraday = build do |conn|
408
+ conn.response :server_error_handler
409
+ conn.adapter :test do |stub|
410
+ stub.get 'test' do
411
+ [412, {}, 'dead']
412
+ end
413
+ end
414
+ end
415
+
416
+ assert_raises Chassis::HttpPreconditionFailedError do
417
+ response = faraday.get 'test'
418
+ end
419
+ end
420
+
421
+ def test_raises_request_entity_too_large
422
+ faraday = build do |conn|
423
+ conn.response :server_error_handler
424
+ conn.adapter :test do |stub|
425
+ stub.get 'test' do
426
+ [413, {}, 'dead']
427
+ end
428
+ end
429
+ end
430
+
431
+ assert_raises Chassis::HttpRequestEntityTooLargeError do
432
+ response = faraday.get 'test'
433
+ end
434
+ end
435
+
436
+ def test_raises_request_uri_too_long
437
+ faraday = build do |conn|
438
+ conn.response :server_error_handler
439
+ conn.adapter :test do |stub|
440
+ stub.get 'test' do
441
+ [414, {}, 'dead']
442
+ end
443
+ end
444
+ end
445
+
446
+ assert_raises Chassis::HttpRequestUriTooLongError do
447
+ response = faraday.get 'test'
448
+ end
449
+ end
450
+
451
+ def test_raises_unsupported_media_type
452
+ faraday = build do |conn|
453
+ conn.response :server_error_handler
454
+ conn.adapter :test do |stub|
455
+ stub.get 'test' do
456
+ [415, {}, 'dead']
457
+ end
458
+ end
459
+ end
460
+
461
+ assert_raises Chassis::HttpUnsupportedMediaTypeError do
462
+ response = faraday.get 'test'
463
+ end
464
+ end
465
+
466
+ def test_raises_range_not_satisfiable
467
+ faraday = build do |conn|
468
+ conn.response :server_error_handler
469
+ conn.adapter :test do |stub|
470
+ stub.get 'test' do
471
+ [416, {}, 'dead']
472
+ end
473
+ end
474
+ end
475
+
476
+ assert_raises Chassis::HttpRequestRangeNotSatisfiableError do
477
+ response = faraday.get 'test'
478
+ end
479
+ end
480
+
481
+ def test_raises_expectation_failed
482
+ faraday = build do |conn|
483
+ conn.response :server_error_handler
484
+ conn.adapter :test do |stub|
485
+ stub.get 'test' do
486
+ [417, {}, 'dead']
487
+ end
488
+ end
489
+ end
490
+
491
+ assert_raises Chassis::HttpExpectationFailedError do
492
+ response = faraday.get 'test'
493
+ end
494
+ end
495
+
496
+ def test_raises_unprocessable_entity
497
+ faraday = build do |conn|
498
+ conn.response :server_error_handler
499
+ conn.adapter :test do |stub|
500
+ stub.get 'test' do
501
+ [422, {}, 'dead']
502
+ end
503
+ end
504
+ end
505
+
506
+ assert_raises Chassis::HttpUnprocessableEntityError do
507
+ response = faraday.get 'test'
508
+ end
509
+ end
510
+
511
+ def test_raises_locked_error
512
+ faraday = build do |conn|
513
+ conn.response :server_error_handler
514
+ conn.adapter :test do |stub|
515
+ stub.get 'test' do
516
+ [423, {}, 'dead']
517
+ end
518
+ end
519
+ end
520
+
521
+ assert_raises Chassis::HttpLockedError do
522
+ response = faraday.get 'test'
523
+ end
524
+ end
525
+
526
+ def test_raises_failed_dependency_error
527
+ faraday = build do |conn|
528
+ conn.response :server_error_handler
529
+ conn.adapter :test do |stub|
530
+ stub.get 'test' do
531
+ [424, {}, 'dead']
532
+ end
533
+ end
534
+ end
535
+
536
+ assert_raises Chassis::HttpFailedDependencyError do
537
+ response = faraday.get 'test'
538
+ end
539
+ end
540
+
541
+ def test_raises_upgrade_require_error
542
+ faraday = build do |conn|
543
+ conn.response :server_error_handler
544
+ conn.adapter :test do |stub|
545
+ stub.get 'test' do
546
+ [426, {}, 'dead']
547
+ end
548
+ end
549
+ end
550
+
551
+ assert_raises Chassis::HttpUpgradeRequiredError do
552
+ response = faraday.get 'test'
553
+ end
554
+ end
555
+
556
+ def test_raises_internal_server_error
557
+ faraday = build do |conn|
558
+ conn.response :server_error_handler
559
+ conn.adapter :test do |stub|
560
+ stub.get 'test' do
561
+ [500, {}, 'dead']
562
+ end
563
+ end
564
+ end
565
+
566
+ assert_raises Chassis::HttpInternalServerError do
567
+ response = faraday.get 'test'
568
+ end
569
+ end
570
+
571
+ def test_raises_not_implemented_error
572
+ faraday = build do |conn|
573
+ conn.response :server_error_handler
574
+ conn.adapter :test do |stub|
575
+ stub.get 'test' do
576
+ [501, {}, 'dead']
577
+ end
578
+ end
579
+ end
580
+
581
+ assert_raises Chassis::HttpNotImplementedError do
582
+ response = faraday.get 'test'
583
+ end
584
+ end
585
+
586
+ def test_raises_bad_gateway_error
587
+ faraday = build do |conn|
588
+ conn.response :server_error_handler
589
+ conn.adapter :test do |stub|
590
+ stub.get 'test' do
591
+ [502, {}, 'dead']
592
+ end
593
+ end
594
+ end
595
+
596
+ assert_raises Chassis::HttpBadGatewayError do
597
+ response = faraday.get 'test'
598
+ end
599
+ end
600
+
601
+ def test_raises_service_unavailable
602
+ faraday = build do |conn|
603
+ conn.response :server_error_handler
604
+ conn.adapter :test do |stub|
605
+ stub.get 'test' do
606
+ [503, {}, 'dead']
607
+ end
608
+ end
609
+ end
610
+
611
+ assert_raises Chassis::HttpServiceUnavailableError do
612
+ response = faraday.get 'test'
613
+ end
614
+ end
615
+
616
+ def test_raises_gateway_timeout
617
+ faraday = build do |conn|
618
+ conn.response :server_error_handler
619
+ conn.adapter :test do |stub|
620
+ stub.get 'test' do
621
+ [504, {}, 'dead']
622
+ end
623
+ end
624
+ end
625
+
626
+ assert_raises Chassis::HttpGatewayTimeoutError do
627
+ response = faraday.get 'test'
628
+ end
629
+ end
630
+
631
+ def test_raises_http_version_not_supported_error
632
+ faraday = build do |conn|
633
+ conn.response :server_error_handler
634
+ conn.adapter :test do |stub|
635
+ stub.get 'test' do
636
+ [505, {}, 'dead']
637
+ end
638
+ end
639
+ end
640
+
641
+ assert_raises Chassis::HttpVersionNotSupportedError do
642
+ response = faraday.get 'test'
643
+ end
644
+ end
645
+
646
+ def test_raises_insuffcient_storage
647
+ faraday = build do |conn|
648
+ conn.response :server_error_handler
649
+ conn.adapter :test do |stub|
650
+ stub.get 'test' do
651
+ [507, {}, 'dead']
652
+ end
653
+ end
654
+ end
655
+
656
+ assert_raises Chassis::HttpInsufficientStorageError do
657
+ response = faraday.get 'test'
658
+ end
659
+ end
660
+
661
+ def test_raises_not_extended_error
662
+ faraday = build do |conn|
663
+ conn.response :server_error_handler
664
+ conn.adapter :test do |stub|
665
+ stub.get 'test' do
666
+ [510, {}, 'dead']
667
+ end
668
+ end
669
+ end
670
+
671
+ assert_raises Chassis::HttpNotExtendedError do
672
+ response = faraday.get 'test'
673
+ end
674
+ end
675
+
676
+ def test_server_errors_contain_useful_information
677
+ faraday = build 'http://example.com' do |conn|
678
+ conn.response :server_error_handler
679
+ conn.adapter :test do |stub|
680
+ stub.get 'test.error' do
681
+ [500, {}, 'dead']
682
+ end
683
+ end
684
+ end
685
+
686
+ begin
687
+ faraday.get 'test.error'
688
+ rescue => ex
689
+ exception = ex
690
+ end
691
+
692
+ assert exception
693
+ msg = exception.to_s
694
+ assert_includes msg, "http://example.com/test.error"
695
+ end
696
+
697
+ def test_has_factory_for_faraday_connections
698
+ faraday = Chassis.faraday 'http://example.com'
699
+
700
+ stack = faraday.builder.handlers
701
+
702
+ assert_includes stack, Chassis::Instrumentation
703
+ assert_includes stack, Chassis::EncodeJson
704
+ assert_includes stack, Chassis::ParseJson
705
+ assert_includes stack, Chassis::ServerErrorHandler
706
+ assert_includes stack, Chassis::Logging
707
+ end
708
+
709
+ def test_factory_can_change_the_namespace
710
+ faraday = Chassis.faraday 'http://example.com', namespace: 'test' do |conn|
711
+ conn.adapter :test do |stub|
712
+ stub.get 'test' do
713
+ [200, {'Content-Type' => 'application/json'}, JSON.dump(foo: 'bar')]
714
+ end
715
+ end
716
+ end
717
+
718
+ faraday.get 'test'
719
+
720
+ refute_empty stats.timers
721
+ timer = stats.timers.first
722
+
723
+ assert_equal 'test.get', timer.name
724
+ end
725
+
726
+ def test_factory_can_change_the_logger
727
+ stream = StringIO.new
728
+ logger = Logger.new stream
729
+ logger.level = :debug
730
+
731
+ faraday = Chassis.faraday 'http://example.com', logger: logger do |conn|
732
+ conn.adapter :test do |stub|
733
+ stub.get 'test' do
734
+ [200, {}, 'dead']
735
+ end
736
+ end
737
+ end
738
+
739
+ faraday.get 'test', { foo: 'bar' }, { 'This-Header' => 'has_a_value' }
740
+
741
+ stream.rewind ; content = stream.read
742
+
743
+ assert_includes content, 'http://example.com/test'
744
+ assert_includes content, 'This-Header'
745
+ assert_includes content, 'has_a_value'
746
+ assert_includes content, 'foo'
747
+ assert_includes content, 'bar'
748
+ end
749
+ end