rack-test 0.6.3 → 0.8.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,5 @@
1
+ module Rack
2
+ module Test
3
+ VERSION = '0.8.0'.freeze
4
+ end
5
+ end
data/lib/rack/test.rb CHANGED
@@ -1,18 +1,17 @@
1
- require "uri"
2
- require "rack"
3
- require "rack/mock_session"
4
- require "rack/test/cookie_jar"
5
- require "rack/test/mock_digest_request"
6
- require "rack/test/utils"
7
- require "rack/test/methods"
8
- require "rack/test/uploaded_file"
1
+ require 'uri'
2
+ require 'rack'
3
+ require 'rack/mock_session'
4
+ require 'rack/test/cookie_jar'
5
+ require 'rack/test/mock_digest_request'
6
+ require 'rack/test/utils'
7
+ require 'rack/test/methods'
8
+ require 'rack/test/uploaded_file'
9
+ require 'rack/test/version'
9
10
 
10
11
  module Rack
11
12
  module Test
12
- VERSION = "0.6.3"
13
-
14
- DEFAULT_HOST = "example.org"
15
- MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
13
+ DEFAULT_HOST = 'example.org'.freeze
14
+ MULTIPART_BOUNDARY = '----------XnJLe9ZIbbGUYtzPQJ16u1'.freeze
16
15
 
17
16
  # The common base class for exceptions raised by Rack::Test
18
17
  class Error < StandardError; end
@@ -36,11 +35,13 @@ module Rack
36
35
  def initialize(mock_session)
37
36
  @headers = {}
38
37
  @env = {}
38
+ @digest_username = nil
39
+ @digest_password = nil
39
40
 
40
- if mock_session.is_a?(MockSession)
41
- @rack_mock_session = mock_session
41
+ @rack_mock_session = if mock_session.is_a?(MockSession)
42
+ mock_session
42
43
  else
43
- @rack_mock_session = MockSession.new(mock_session)
44
+ MockSession.new(mock_session)
44
45
  end
45
46
 
46
47
  @default_host = @rack_mock_session.default_host
@@ -54,8 +55,7 @@ module Rack
54
55
  # Example:
55
56
  # get "/"
56
57
  def get(uri, params = {}, env = {}, &block)
57
- env = env_for(uri, env.merge(:method => "GET", :params => params))
58
- process_request(uri, env, &block)
58
+ custom_request('GET', uri, params, env, &block)
59
59
  end
60
60
 
61
61
  # Issue a POST request for the given URI. See #get
@@ -63,8 +63,7 @@ module Rack
63
63
  # Example:
64
64
  # post "/signup", "name" => "Bryan"
65
65
  def post(uri, params = {}, env = {}, &block)
66
- env = env_for(uri, env.merge(:method => "POST", :params => params))
67
- process_request(uri, env, &block)
66
+ custom_request('POST', uri, params, env, &block)
68
67
  end
69
68
 
70
69
  # Issue a PUT request for the given URI. See #get
@@ -72,8 +71,7 @@ module Rack
72
71
  # Example:
73
72
  # put "/"
74
73
  def put(uri, params = {}, env = {}, &block)
75
- env = env_for(uri, env.merge(:method => "PUT", :params => params))
76
- process_request(uri, env, &block)
74
+ custom_request('PUT', uri, params, env, &block)
77
75
  end
78
76
 
79
77
  # Issue a PATCH request for the given URI. See #get
@@ -81,8 +79,7 @@ module Rack
81
79
  # Example:
82
80
  # patch "/"
83
81
  def patch(uri, params = {}, env = {}, &block)
84
- env = env_for(uri, env.merge(:method => "PATCH", :params => params))
85
- process_request(uri, env, &block)
82
+ custom_request('PATCH', uri, params, env, &block)
86
83
  end
87
84
 
88
85
  # Issue a DELETE request for the given URI. See #get
@@ -90,8 +87,7 @@ module Rack
90
87
  # Example:
91
88
  # delete "/"
92
89
  def delete(uri, params = {}, env = {}, &block)
93
- env = env_for(uri, env.merge(:method => "DELETE", :params => params))
94
- process_request(uri, env, &block)
90
+ custom_request('DELETE', uri, params, env, &block)
95
91
  end
96
92
 
97
93
  # Issue an OPTIONS request for the given URI. See #get
@@ -99,8 +95,7 @@ module Rack
99
95
  # Example:
100
96
  # options "/"
101
97
  def options(uri, params = {}, env = {}, &block)
102
- env = env_for(uri, env.merge(:method => "OPTIONS", :params => params))
103
- process_request(uri, env, &block)
98
+ custom_request('OPTIONS', uri, params, env, &block)
104
99
  end
105
100
 
106
101
  # Issue a HEAD request for the given URI. See #get
@@ -108,8 +103,7 @@ module Rack
108
103
  # Example:
109
104
  # head "/"
110
105
  def head(uri, params = {}, env = {}, &block)
111
- env = env_for(uri, env.merge(:method => "HEAD", :params => params))
112
- process_request(uri, env, &block)
106
+ custom_request('HEAD', uri, params, env, &block)
113
107
  end
114
108
 
115
109
  # Issue a request to the Rack app for the given URI and optional Rack
@@ -120,10 +114,21 @@ module Rack
120
114
  # Example:
121
115
  # request "/"
122
116
  def request(uri, env = {}, &block)
117
+ uri = parse_uri(uri, env)
123
118
  env = env_for(uri, env)
124
119
  process_request(uri, env, &block)
125
120
  end
126
121
 
122
+ # Issue a request using the given verb for the given URI. See #get
123
+ #
124
+ # Example:
125
+ # custom_request "LINK", "/"
126
+ def custom_request(verb, uri, params = {}, env = {}, &block)
127
+ uri = parse_uri(uri, env)
128
+ env = env_for(uri, env.merge(method: verb.to_s.upcase, params: params))
129
+ process_request(uri, env, &block)
130
+ end
131
+
127
132
  # Set a header to be included on all subsequent requests through the
128
133
  # session. Use a value of nil to remove a previously configured header.
129
134
  #
@@ -159,11 +164,11 @@ module Rack
159
164
  # Example:
160
165
  # basic_authorize "bryan", "secret"
161
166
  def basic_authorize(username, password)
162
- encoded_login = ["#{username}:#{password}"].pack("m*")
167
+ encoded_login = ["#{username}:#{password}"].pack('m0')
163
168
  header('Authorization', "Basic #{encoded_login}")
164
169
  end
165
170
 
166
- alias_method :authorize, :basic_authorize
171
+ alias authorize basic_authorize
167
172
 
168
173
  # Set the username and password for HTTP Digest authorization, to be
169
174
  # included in subsequent requests in the HTTP_AUTHORIZATION header.
@@ -181,45 +186,52 @@ module Rack
181
186
  # a redirect, an error will be raised.
182
187
  def follow_redirect!
183
188
  unless last_response.redirect?
184
- raise Error.new("Last response was not a redirect. Cannot follow_redirect!")
189
+ raise Error, 'Last response was not a redirect. Cannot follow_redirect!'
190
+ end
191
+ if last_response.status == 307
192
+ send(last_request.request_method.downcase.to_sym, last_response['Location'], last_request.params, 'HTTP_REFERER' => last_request.url)
193
+ else
194
+ get(last_response['Location'], {}, 'HTTP_REFERER' => last_request.url)
185
195
  end
186
-
187
- get(last_response["Location"], {}, { "HTTP_REFERER" => last_request.url })
188
196
  end
189
197
 
190
- private
198
+ private
191
199
 
192
- def env_for(path, env)
193
- uri = URI.parse(path)
194
- uri.path = "/#{uri.path}" unless uri.path[0] == ?/
195
- uri.host ||= @default_host
200
+ def parse_uri(path, env)
201
+ URI.parse(path).tap do |uri|
202
+ uri.path = "/#{uri.path}" unless uri.path[0] == '/'
203
+ uri.host ||= @default_host
204
+ uri.scheme ||= 'https' if env['HTTPS'] == 'on'
205
+ end
206
+ end
196
207
 
208
+ def env_for(uri, env)
197
209
  env = default_env.merge(env)
198
210
 
199
- env["HTTP_HOST"] ||= [uri.host, (uri.port if uri.port != uri.default_port)].compact.join(":")
211
+ env['HTTP_HOST'] ||= [uri.host, (uri.port if uri.port != uri.default_port)].compact.join(':')
200
212
 
201
- env.update("HTTPS" => "on") if URI::HTTPS === uri
202
- env["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" if env[:xhr]
213
+ env.update('HTTPS' => 'on') if URI::HTTPS === uri
214
+ env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' if env[:xhr]
203
215
 
204
216
  # TODO: Remove this after Rack 1.1 has been released.
205
217
  # Stringifying and upcasing methods has be commit upstream
206
- env["REQUEST_METHOD"] ||= env[:method] ? env[:method].to_s.upcase : "GET"
218
+ env['REQUEST_METHOD'] ||= env[:method] ? env[:method].to_s.upcase : 'GET'
207
219
 
208
- if env["REQUEST_METHOD"] == "GET"
220
+ if %w[GET DELETE].include?(env['REQUEST_METHOD'])
209
221
  # merge :params with the query string
210
222
  if params = env[:params]
211
223
  params = parse_nested_query(params) if params.is_a?(String)
212
- params.update(parse_nested_query(uri.query))
213
- uri.query = build_nested_query(params)
224
+
225
+ uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join('&')
214
226
  end
215
- elsif !env.has_key?(:input)
216
- env["CONTENT_TYPE"] ||= "application/x-www-form-urlencoded"
227
+ elsif !env.key?(:input)
228
+ env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded'
217
229
 
218
230
  if env[:params].is_a?(Hash)
219
231
  if data = build_multipart(env[:params])
220
232
  env[:input] = data
221
- env["CONTENT_LENGTH"] ||= data.length.to_s
222
- env["CONTENT_TYPE"] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}"
233
+ env['CONTENT_LENGTH'] ||= data.length.to_s
234
+ env['CONTENT_TYPE'] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}"
223
235
  else
224
236
  env[:input] = params_to_string(env[:params])
225
237
  end
@@ -230,24 +242,17 @@ module Rack
230
242
 
231
243
  env.delete(:params)
232
244
 
233
- if env.has_key?(:cookie)
234
- set_cookie(env.delete(:cookie), uri)
235
- end
245
+ set_cookie(env.delete(:cookie), uri) if env.key?(:cookie)
236
246
 
237
247
  Rack::MockRequest.env_for(uri.to_s, env)
238
248
  end
239
249
 
240
250
  def process_request(uri, env)
241
- uri = URI.parse(uri)
242
- uri.host ||= @default_host
243
-
244
251
  @rack_mock_session.request(uri, env)
245
252
 
246
253
  if retry_with_digest_auth?(env)
247
- auth_env = env.merge({
248
- "HTTP_AUTHORIZATION" => digest_auth_header,
249
- "rack-test.digest_auth_retry" => true
250
- })
254
+ auth_env = env.merge('HTTP_AUTHORIZATION' => digest_auth_header,
255
+ 'rack-test.digest_auth_retry' => true)
251
256
  auth_env.delete('rack.request')
252
257
  process_request(uri.path, auth_env)
253
258
  else
@@ -258,26 +263,24 @@ module Rack
258
263
  end
259
264
 
260
265
  def digest_auth_header
261
- challenge = last_response["WWW-Authenticate"].split(" ", 2).last
266
+ challenge = last_response['WWW-Authenticate'].split(' ', 2).last
262
267
  params = Rack::Auth::Digest::Params.parse(challenge)
263
268
 
264
- params.merge!({
265
- "username" => @digest_username,
266
- "nc" => "00000001",
267
- "cnonce" => "nonsensenonce",
268
- "uri" => last_request.fullpath,
269
- "method" => last_request.env["REQUEST_METHOD"],
270
- })
269
+ params.merge!('username' => @digest_username,
270
+ 'nc' => '00000001',
271
+ 'cnonce' => 'nonsensenonce',
272
+ 'uri' => last_request.fullpath,
273
+ 'method' => last_request.env['REQUEST_METHOD'])
271
274
 
272
- params["response"] = MockDigestRequest.new(params).response(@digest_password)
275
+ params['response'] = MockDigestRequest.new(params).response(@digest_password)
273
276
 
274
277
  "Digest #{params}"
275
278
  end
276
279
 
277
280
  def retry_with_digest_auth?(env)
278
281
  last_response.status == 401 &&
279
- digest_auth_configured? &&
280
- !env["rack-test.digest_auth_retry"]
282
+ digest_auth_configured? &&
283
+ !env['rack-test.digest_auth_retry']
281
284
  end
282
285
 
283
286
  def digest_auth_configured?
@@ -285,15 +288,15 @@ module Rack
285
288
  end
286
289
 
287
290
  def default_env
288
- { "rack.test" => true, "REMOTE_ADDR" => "127.0.0.1" }.merge(@env).merge(headers_for_env)
291
+ { 'rack.test' => true, 'REMOTE_ADDR' => '127.0.0.1' }.merge(@env).merge(headers_for_env)
289
292
  end
290
293
 
291
294
  def headers_for_env
292
295
  converted_headers = {}
293
296
 
294
297
  @headers.each do |name, value|
295
- env_key = name.upcase.gsub("-", "_")
296
- env_key = "HTTP_" + env_key unless "CONTENT_TYPE" == env_key
298
+ env_key = name.upcase.tr('-', '_')
299
+ env_key = 'HTTP_' + env_key unless env_key == 'CONTENT_TYPE'
297
300
  converted_headers[env_key] = value
298
301
  end
299
302
 
@@ -303,16 +306,14 @@ module Rack
303
306
  def params_to_string(params)
304
307
  case params
305
308
  when Hash then build_nested_query(params)
306
- when nil then ""
309
+ when nil then ''
307
310
  else params
308
311
  end
309
312
  end
310
-
311
313
  end
312
314
 
313
315
  def self.encoding_aware_strings?
314
- defined?(Encoding) && "".respond_to?(:encode)
316
+ defined?(Encoding) && ''.respond_to?(:encode)
315
317
  end
316
-
317
318
  end
318
319
  end
metadata CHANGED
@@ -1,56 +1,158 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
5
- prerelease:
4
+ version: 0.8.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Bryan Helmkamp
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2017-11-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rack
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
22
23
  type: :runtime
23
24
  prerelease: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  version: '1.0'
30
- description: ! 'Rack::Test is a small, simple testing API for Rack apps. It can be
31
- used on its
32
-
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '12.0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '12.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.6'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.6'
61
+ - !ruby/object:Gem::Dependency
62
+ name: sinatra
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '1.0'
68
+ - - "<"
69
+ - !ruby/object:Gem::Version
70
+ version: '3'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '3'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rdoc
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '5.1'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '5.1'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rubocop
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0.49'
102
+ - - "<"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.50'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0.49'
112
+ - - "<"
113
+ - !ruby/object:Gem::Version
114
+ version: '0.50'
115
+ - !ruby/object:Gem::Dependency
116
+ name: codeclimate-test-reporter
117
+ requirement: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '0.6'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '0.6'
129
+ - !ruby/object:Gem::Dependency
130
+ name: thor
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '0.19'
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '0.19'
143
+ description: |-
144
+ Rack::Test is a small, simple testing API for Rack apps. It can be used on its
33
145
  own or as a reusable starting point for Web frameworks and testing libraries
34
-
35
- to build on. Most of its initial functionality is an extraction of Merb 1.0''s
36
-
37
- request helpers feature.'
146
+ to build on. Most of its initial functionality is an extraction of Merb 1.0's
147
+ request helpers feature.
38
148
  email: bryan@brynary.com
39
149
  executables: []
40
150
  extensions: []
41
- extra_rdoc_files:
42
- - README.rdoc
43
- - MIT-LICENSE.txt
151
+ extra_rdoc_files: []
44
152
  files:
45
- - .document
46
- - .gitignore
47
- - Gemfile
48
- - Gemfile.lock
49
- - History.txt
153
+ - History.md
50
154
  - MIT-LICENSE.txt
51
- - README.rdoc
52
- - Rakefile
53
- - Thorfile
155
+ - README.md
54
156
  - lib/rack/mock_session.rb
55
157
  - lib/rack/test.rb
56
158
  - lib/rack/test/cookie_jar.rb
@@ -58,52 +160,29 @@ files:
58
160
  - lib/rack/test/mock_digest_request.rb
59
161
  - lib/rack/test/uploaded_file.rb
60
162
  - lib/rack/test/utils.rb
61
- - rack-test.gemspec
62
- - spec/fixtures/bar.txt
63
- - spec/fixtures/config.ru
64
- - spec/fixtures/fake_app.rb
65
- - spec/fixtures/foo.txt
66
- - spec/rack/test/cookie_spec.rb
67
- - spec/rack/test/digest_auth_spec.rb
68
- - spec/rack/test/multipart_spec.rb
69
- - spec/rack/test/uploaded_file_spec.rb
70
- - spec/rack/test/utils_spec.rb
71
- - spec/rack/test_spec.rb
72
- - spec/spec_helper.rb
73
- - spec/support/matchers/body.rb
74
- - spec/support/matchers/challenge.rb
75
- homepage: http://github.com/brynary/rack-test
76
- licenses: []
163
+ - lib/rack/test/version.rb
164
+ homepage: http://github.com/rack-test/rack-test
165
+ licenses:
166
+ - MIT
167
+ metadata: {}
77
168
  post_install_message:
78
169
  rdoc_options: []
79
170
  require_paths:
80
171
  - lib
81
172
  required_ruby_version: !ruby/object:Gem::Requirement
82
- none: false
83
173
  requirements:
84
- - - ! '>='
174
+ - - ">="
85
175
  - !ruby/object:Gem::Version
86
- version: '0'
176
+ version: 2.2.2
87
177
  required_rubygems_version: !ruby/object:Gem::Requirement
88
- none: false
89
178
  requirements:
90
- - - ! '>='
179
+ - - ">="
91
180
  - !ruby/object:Gem::Version
92
181
  version: '0'
93
182
  requirements: []
94
- rubyforge_project: rack-test
95
- rubygems_version: 1.8.23.2
183
+ rubyforge_project:
184
+ rubygems_version: 2.6.11
96
185
  signing_key:
97
- specification_version: 3
186
+ specification_version: 4
98
187
  summary: Simple testing API built on Rack
99
- test_files:
100
- - spec/fixtures/fake_app.rb
101
- - spec/rack/test/cookie_spec.rb
102
- - spec/rack/test/digest_auth_spec.rb
103
- - spec/rack/test/multipart_spec.rb
104
- - spec/rack/test/uploaded_file_spec.rb
105
- - spec/rack/test/utils_spec.rb
106
- - spec/rack/test_spec.rb
107
- - spec/spec_helper.rb
108
- - spec/support/matchers/body.rb
109
- - spec/support/matchers/challenge.rb
188
+ test_files: []