rack-test 0.7.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a276395f953e48d223d387a9ca830fec7bc17f4
4
- data.tar.gz: 75368392e7c13919d3073d9b69fb5c0e3c271b10
3
+ metadata.gz: 1c2c9dca5557f9f1d5894f9379e38e660698a178
4
+ data.tar.gz: aabbb52783cc359935090e319d462076cc0ce95c
5
5
  SHA512:
6
- metadata.gz: 874eb9d53b22b2842d9659144acdc4bf222cb18474f4d8b496292e3209bf53d2564a2fcef5d9541dc81a825780766d48da46a1a7643ac8f04807fc41094bba11
7
- data.tar.gz: 17b51e137c7bc2e2b59276bdaf90781dc6a701f082cd17b8faccbc179668c05914e34025474134ab87bd4e5a1c42821a07e0193665444062cfd77a6b24492e7a
6
+ metadata.gz: ed423ebaf4bbdb79a77804f3ed9314f88b5b9e97e9a0eeee0d596c43718bac918f62d4cfd8c1adaa72a0e8fce28f093f5bb7bc3268eec5025c6e47b7ce2556b9
7
+ data.tar.gz: a4ef34a8cb3e12bc432012444485af04c50c2780ec658ead424c337dbd3ecd3805a957065bb804b2b1dd73d495819094dfb018c0784cd9766a4f1be6110d7815
data/History.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## 0.8.0 / 2017-11-20
2
+
3
+ * Minor enhancements
4
+ * Add a required_ruby_version of >= 2.2.2, similar to rack 2.0.1.
5
+ (Samuel Giddins #194)
6
+ * Remove new line from basic auth. (Felix Kleinschmidt #185)
7
+ * Rubocop fixes (Per Lundberg #196)
8
+ * Add how to install rack-test from github to README. (Jun Aruga #189)
9
+ * Update CodeClimate badges (Toshimaru #195)
10
+ * Add the ability to create Test::UploadedFile instances without
11
+ the file system (Adam Milligan #149)
12
+ * Add custom_request, remove duplication (Johannes Barre #184)
13
+ * README.md: Added note about how to post JSON (Per Lundberg #198)
14
+ * README.md: Added version badge (Per Lundberg #199)
15
+ * Bug fixes
16
+ * Bugfix for Cookies with multiple paths (Kyle Welsby #197)
17
+
1
18
  ## 0.7.0 / 2017-07-10
2
19
 
3
20
  * Major enhancements
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Rack::Test
2
+ [![Gem Version](https://badge.fury.io/rb/rack-test.svg)](https://badge.fury.io/rb/rack-test)
2
3
  [<img src="https://travis-ci.org/rack-test/rack-test.svg?branch=master" />](https://travis-ci.org/rack-test/rack-test)
3
- [<img src="https://codeclimate.com/github/rack-test/rack-test.png" />](https://codeclimate.com/github/rack-test/rack-test)
4
- [<img src="https://codeclimate.com/github/rack-test/rack-test/coverage.png" />](https://codeclimate.com/github/rack-test/rack-test)
4
+ [![Code Climate](https://codeclimate.com/github/codeclimate/codeclimate/badges/gpa.svg)](https://codeclimate.com/github/codeclimate/codeclimate)
5
+ [![Test Coverage](https://codeclimate.com/github/codeclimate/codeclimate/badges/coverage.svg)](https://codeclimate.com/github/codeclimate/codeclimate/coverage)
5
6
 
6
7
  Code: https://github.com/rack-test/rack-test
7
8
 
@@ -18,7 +19,18 @@ to build on.
18
19
  * Set request headers to be used by all subsequent requests
19
20
  * Small footprint. Approximately 200 LOC
20
21
 
22
+ ## Supported platforms
23
+
24
+ * 2.2.2+
25
+ * 2.3
26
+ * 2.4
27
+ * JRuby 9.1.+
28
+
29
+ If you are using Ruby 1.8, 1.9 or JRuby 1.7, use rack-test 0.6.3.
30
+
21
31
  ## Examples
32
+ (The examples use `Test::Unit` but it's equally possible to use `rack-test` with other testing frameworks like `rspec`.)
33
+
22
34
  ```ruby
23
35
  require "test/unit"
24
36
  require "rack/test"
@@ -33,25 +45,32 @@ class HomepageTest < Test::Unit::TestCase
33
45
  end
34
46
 
35
47
  def test_response_is_ok
36
- get "/"
48
+ get '/'
37
49
 
38
50
  assert last_response.ok?
39
- assert_equal last_response.body, "All responses are OK"
51
+ assert_equal last_response.body, 'All responses are OK'
40
52
  end
41
-
53
+
42
54
  def set_request_headers
43
55
  headers 'Accept-Charset', 'utf-8'
44
- get "/"
56
+ get '/'
45
57
 
46
58
  assert last_response.ok?
47
- assert_equal last_response.body, "All responses are OK"
59
+ assert_equal last_response.body, 'All responses are OK'
48
60
  end
49
61
 
50
62
  def test_response_is_ok_for_other_paths
51
- get "/other_paths"
63
+ get '/other_paths'
52
64
 
53
65
  assert last_response.ok?
54
- assert_equal last_response.body, "All responses are OK"
66
+ assert_equal last_response.body, 'All responses are OK'
67
+ end
68
+
69
+ def post_with_json
70
+ # No assertion in this, we just demonstrate how you can post a JSON-encoded string.
71
+ # By default, Rack::Test will use HTTP form encoding if you pass in a Hash as the
72
+ # parameters, so make sure that `json` below is already a JSON-serialized string.
73
+ post(uri, json, { 'CONTENT_TYPE' => 'application/json' })
55
74
  end
56
75
  end
57
76
  ```
@@ -80,11 +99,21 @@ end
80
99
 
81
100
  To install the latest release as a gem:
82
101
 
83
- `gem install rack-test`
102
+ ```
103
+ gem install rack-test
104
+ ```
84
105
 
85
106
  Or via Bundler:
86
107
 
87
- `gem "rack-test", require: "rack/test"`
108
+ ```
109
+ gem 'rack-test', require: 'rack/test'
110
+ ```
111
+
112
+ Or to install unreleased version via Bundler:
113
+
114
+ ```
115
+ gem 'rack-test', github: 'rack-test', branch: 'master'
116
+ ```
88
117
 
89
118
  ## Authors
90
119
 
@@ -1,5 +1,4 @@
1
1
  module Rack
2
-
3
2
  class MockSession # :nodoc:
4
3
  attr_writer :cookie_jar
5
4
  attr_reader :default_host
@@ -25,16 +24,16 @@ module Rack
25
24
  end
26
25
 
27
26
  def request(uri, env)
28
- env["HTTP_COOKIE"] ||= cookie_jar.for(uri)
27
+ env['HTTP_COOKIE'] ||= cookie_jar.for(uri)
29
28
  @last_request = Rack::Request.new(env)
30
29
  status, headers, body = @app.call(@last_request.env)
31
30
 
32
- @last_response = MockResponse.new(status, headers, body, env["rack.errors"].flush)
31
+ @last_response = MockResponse.new(status, headers, body, env['rack.errors'].flush)
33
32
  body.close if body.respond_to?(:close)
34
33
 
35
- cookie_jar.merge(last_response.headers["Set-Cookie"], uri)
34
+ cookie_jar.merge(last_response.headers['Set-Cookie'], uri)
36
35
 
37
- @after_request.each { |hook| hook.call }
36
+ @after_request.each(&:call)
38
37
 
39
38
  if @last_response.respond_to?(:finish)
40
39
  @last_response.finish
@@ -46,21 +45,19 @@ module Rack
46
45
  # Return the last request issued in the session. Raises an error if no
47
46
  # requests have been sent yet.
48
47
  def last_request
49
- raise Rack::Test::Error.new("No request yet. Request a page first.") unless @last_request
48
+ raise Rack::Test::Error, 'No request yet. Request a page first.' unless @last_request
50
49
  @last_request
51
50
  end
52
51
 
53
52
  # Return the last response received in the session. Raises an error if
54
53
  # no requests have been sent yet.
55
54
  def last_response
56
- raise Rack::Test::Error.new("No response yet. Request a page first.") unless @last_response
55
+ raise Rack::Test::Error, 'No response yet. Request a page first.' unless @last_response
57
56
  @last_response
58
57
  end
59
58
 
60
59
  def cookie_jar
61
60
  @cookie_jar ||= Rack::Test::CookieJar.new([], @default_host)
62
61
  end
63
-
64
62
  end
65
-
66
63
  end
@@ -1,17 +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"
9
- require "rack/test/version"
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'
10
10
 
11
11
  module Rack
12
12
  module Test
13
- DEFAULT_HOST = "example.org"
14
- MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
13
+ DEFAULT_HOST = 'example.org'.freeze
14
+ MULTIPART_BOUNDARY = '----------XnJLe9ZIbbGUYtzPQJ16u1'.freeze
15
15
 
16
16
  # The common base class for exceptions raised by Rack::Test
17
17
  class Error < StandardError; end
@@ -38,10 +38,10 @@ module Rack
38
38
  @digest_username = nil
39
39
  @digest_password = nil
40
40
 
41
- if mock_session.is_a?(MockSession)
42
- @rack_mock_session = mock_session
41
+ @rack_mock_session = if mock_session.is_a?(MockSession)
42
+ mock_session
43
43
  else
44
- @rack_mock_session = MockSession.new(mock_session)
44
+ MockSession.new(mock_session)
45
45
  end
46
46
 
47
47
  @default_host = @rack_mock_session.default_host
@@ -55,8 +55,7 @@ module Rack
55
55
  # Example:
56
56
  # get "/"
57
57
  def get(uri, params = {}, env = {}, &block)
58
- env = env_for(uri, env.merge(:method => "GET", :params => params))
59
- process_request(uri, env, &block)
58
+ custom_request('GET', uri, params, env, &block)
60
59
  end
61
60
 
62
61
  # Issue a POST request for the given URI. See #get
@@ -64,8 +63,7 @@ module Rack
64
63
  # Example:
65
64
  # post "/signup", "name" => "Bryan"
66
65
  def post(uri, params = {}, env = {}, &block)
67
- env = env_for(uri, env.merge(:method => "POST", :params => params))
68
- process_request(uri, env, &block)
66
+ custom_request('POST', uri, params, env, &block)
69
67
  end
70
68
 
71
69
  # Issue a PUT request for the given URI. See #get
@@ -73,8 +71,7 @@ module Rack
73
71
  # Example:
74
72
  # put "/"
75
73
  def put(uri, params = {}, env = {}, &block)
76
- env = env_for(uri, env.merge(:method => "PUT", :params => params))
77
- process_request(uri, env, &block)
74
+ custom_request('PUT', uri, params, env, &block)
78
75
  end
79
76
 
80
77
  # Issue a PATCH request for the given URI. See #get
@@ -82,8 +79,7 @@ module Rack
82
79
  # Example:
83
80
  # patch "/"
84
81
  def patch(uri, params = {}, env = {}, &block)
85
- env = env_for(uri, env.merge(:method => "PATCH", :params => params))
86
- process_request(uri, env, &block)
82
+ custom_request('PATCH', uri, params, env, &block)
87
83
  end
88
84
 
89
85
  # Issue a DELETE request for the given URI. See #get
@@ -91,8 +87,7 @@ module Rack
91
87
  # Example:
92
88
  # delete "/"
93
89
  def delete(uri, params = {}, env = {}, &block)
94
- env = env_for(uri, env.merge(:method => "DELETE", :params => params))
95
- process_request(uri, env, &block)
90
+ custom_request('DELETE', uri, params, env, &block)
96
91
  end
97
92
 
98
93
  # Issue an OPTIONS request for the given URI. See #get
@@ -100,8 +95,7 @@ module Rack
100
95
  # Example:
101
96
  # options "/"
102
97
  def options(uri, params = {}, env = {}, &block)
103
- env = env_for(uri, env.merge(:method => "OPTIONS", :params => params))
104
- process_request(uri, env, &block)
98
+ custom_request('OPTIONS', uri, params, env, &block)
105
99
  end
106
100
 
107
101
  # Issue a HEAD request for the given URI. See #get
@@ -109,8 +103,7 @@ module Rack
109
103
  # Example:
110
104
  # head "/"
111
105
  def head(uri, params = {}, env = {}, &block)
112
- env = env_for(uri, env.merge(:method => "HEAD", :params => params))
113
- process_request(uri, env, &block)
106
+ custom_request('HEAD', uri, params, env, &block)
114
107
  end
115
108
 
116
109
  # Issue a request to the Rack app for the given URI and optional Rack
@@ -121,10 +114,21 @@ module Rack
121
114
  # Example:
122
115
  # request "/"
123
116
  def request(uri, env = {}, &block)
117
+ uri = parse_uri(uri, env)
124
118
  env = env_for(uri, env)
125
119
  process_request(uri, env, &block)
126
120
  end
127
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
+
128
132
  # Set a header to be included on all subsequent requests through the
129
133
  # session. Use a value of nil to remove a previously configured header.
130
134
  #
@@ -160,11 +164,11 @@ module Rack
160
164
  # Example:
161
165
  # basic_authorize "bryan", "secret"
162
166
  def basic_authorize(username, password)
163
- encoded_login = ["#{username}:#{password}"].pack("m*")
167
+ encoded_login = ["#{username}:#{password}"].pack('m0')
164
168
  header('Authorization', "Basic #{encoded_login}")
165
169
  end
166
170
 
167
- alias_method :authorize, :basic_authorize
171
+ alias authorize basic_authorize
168
172
 
169
173
  # Set the username and password for HTTP Digest authorization, to be
170
174
  # included in subsequent requests in the HTTP_AUTHORIZATION header.
@@ -182,48 +186,52 @@ module Rack
182
186
  # a redirect, an error will be raised.
183
187
  def follow_redirect!
184
188
  unless last_response.redirect?
185
- raise Error.new("Last response was not a redirect. Cannot follow_redirect!")
189
+ raise Error, 'Last response was not a redirect. Cannot follow_redirect!'
186
190
  end
187
191
  if last_response.status == 307
188
- send(last_request.request_method.downcase.to_sym, last_response["Location"], last_request.params, { "HTTP_REFERER" => last_request.url })
192
+ send(last_request.request_method.downcase.to_sym, last_response['Location'], last_request.params, 'HTTP_REFERER' => last_request.url)
189
193
  else
190
- get(last_response["Location"], {}, { "HTTP_REFERER" => last_request.url })
194
+ get(last_response['Location'], {}, 'HTTP_REFERER' => last_request.url)
191
195
  end
192
196
  end
193
197
 
194
- private
198
+ private
195
199
 
196
- def env_for(path, env)
197
- uri = URI.parse(path)
198
- uri.path = "/#{uri.path}" unless uri.path[0] == ?/
199
- 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
200
207
 
208
+ def env_for(uri, env)
201
209
  env = default_env.merge(env)
202
210
 
203
- 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(':')
204
212
 
205
- env.update("HTTPS" => "on") if URI::HTTPS === uri
206
- 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]
207
215
 
208
216
  # TODO: Remove this after Rack 1.1 has been released.
209
217
  # Stringifying and upcasing methods has be commit upstream
210
- env["REQUEST_METHOD"] ||= env[:method] ? env[:method].to_s.upcase : "GET"
218
+ env['REQUEST_METHOD'] ||= env[:method] ? env[:method].to_s.upcase : 'GET'
211
219
 
212
- if ["GET", "DELETE"].include?(env["REQUEST_METHOD"])
220
+ if %w[GET DELETE].include?(env['REQUEST_METHOD'])
213
221
  # merge :params with the query string
214
222
  if params = env[:params]
215
223
  params = parse_nested_query(params) if params.is_a?(String)
216
224
 
217
- uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join("&")
225
+ uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join('&')
218
226
  end
219
- elsif !env.has_key?(:input)
220
- env["CONTENT_TYPE"] ||= "application/x-www-form-urlencoded"
227
+ elsif !env.key?(:input)
228
+ env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded'
221
229
 
222
230
  if env[:params].is_a?(Hash)
223
231
  if data = build_multipart(env[:params])
224
232
  env[:input] = data
225
- env["CONTENT_LENGTH"] ||= data.length.to_s
226
- 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}"
227
235
  else
228
236
  env[:input] = params_to_string(env[:params])
229
237
  end
@@ -234,25 +242,17 @@ module Rack
234
242
 
235
243
  env.delete(:params)
236
244
 
237
- if env.has_key?(:cookie)
238
- set_cookie(env.delete(:cookie), uri)
239
- end
245
+ set_cookie(env.delete(:cookie), uri) if env.key?(:cookie)
240
246
 
241
247
  Rack::MockRequest.env_for(uri.to_s, env)
242
248
  end
243
249
 
244
250
  def process_request(uri, env)
245
- uri = URI.parse(uri)
246
- uri.host ||= @default_host
247
- uri.scheme ||= "https" if env["HTTPS"] == "on"
248
-
249
251
  @rack_mock_session.request(uri, env)
250
252
 
251
253
  if retry_with_digest_auth?(env)
252
- auth_env = env.merge({
253
- "HTTP_AUTHORIZATION" => digest_auth_header,
254
- "rack-test.digest_auth_retry" => true
255
- })
254
+ auth_env = env.merge('HTTP_AUTHORIZATION' => digest_auth_header,
255
+ 'rack-test.digest_auth_retry' => true)
256
256
  auth_env.delete('rack.request')
257
257
  process_request(uri.path, auth_env)
258
258
  else
@@ -263,26 +263,24 @@ module Rack
263
263
  end
264
264
 
265
265
  def digest_auth_header
266
- challenge = last_response["WWW-Authenticate"].split(" ", 2).last
266
+ challenge = last_response['WWW-Authenticate'].split(' ', 2).last
267
267
  params = Rack::Auth::Digest::Params.parse(challenge)
268
268
 
269
- params.merge!({
270
- "username" => @digest_username,
271
- "nc" => "00000001",
272
- "cnonce" => "nonsensenonce",
273
- "uri" => last_request.fullpath,
274
- "method" => last_request.env["REQUEST_METHOD"],
275
- })
269
+ params.merge!('username' => @digest_username,
270
+ 'nc' => '00000001',
271
+ 'cnonce' => 'nonsensenonce',
272
+ 'uri' => last_request.fullpath,
273
+ 'method' => last_request.env['REQUEST_METHOD'])
276
274
 
277
- params["response"] = MockDigestRequest.new(params).response(@digest_password)
275
+ params['response'] = MockDigestRequest.new(params).response(@digest_password)
278
276
 
279
277
  "Digest #{params}"
280
278
  end
281
279
 
282
280
  def retry_with_digest_auth?(env)
283
281
  last_response.status == 401 &&
284
- digest_auth_configured? &&
285
- !env["rack-test.digest_auth_retry"]
282
+ digest_auth_configured? &&
283
+ !env['rack-test.digest_auth_retry']
286
284
  end
287
285
 
288
286
  def digest_auth_configured?
@@ -290,15 +288,15 @@ module Rack
290
288
  end
291
289
 
292
290
  def default_env
293
- { "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)
294
292
  end
295
293
 
296
294
  def headers_for_env
297
295
  converted_headers = {}
298
296
 
299
297
  @headers.each do |name, value|
300
- env_key = name.upcase.gsub("-", "_")
301
- 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'
302
300
  converted_headers[env_key] = value
303
301
  end
304
302
 
@@ -308,16 +306,14 @@ module Rack
308
306
  def params_to_string(params)
309
307
  case params
310
308
  when Hash then build_nested_query(params)
311
- when nil then ""
309
+ when nil then ''
312
310
  else params
313
311
  end
314
312
  end
315
-
316
313
  end
317
314
 
318
315
  def self.encoding_aware_strings?
319
- defined?(Encoding) && "".respond_to?(:encode)
316
+ defined?(Encoding) && ''.respond_to?(:encode)
320
317
  end
321
-
322
318
  end
323
319
  end
@@ -1,9 +1,8 @@
1
- require "uri"
2
- require "time"
1
+ require 'uri'
2
+ require 'time'
3
3
 
4
4
  module Rack
5
5
  module Test
6
-
7
6
  class Cookie # :nodoc:
8
7
  include Rack::Utils
9
8
 
@@ -21,8 +20,8 @@ module Rack
21
20
  @name, @value = parse_query(@name_value_raw, ';').to_a.first
22
21
  @options = parse_query(options, ';')
23
22
 
24
- @options["domain"] ||= (uri.host || default_host)
25
- @options["path"] ||= uri.path.sub(/\/[^\/]*\Z/, "")
23
+ @options['domain'] ||= (uri.host || default_host)
24
+ @options['path'] ||= uri.path.sub(/\/[^\/]*\Z/, '')
26
25
  end
27
26
 
28
27
  def replaces?(other)
@@ -41,25 +40,25 @@ module Rack
41
40
 
42
41
  # :api: private
43
42
  def domain
44
- @options["domain"]
43
+ @options['domain']
45
44
  end
46
45
 
47
46
  def secure?
48
- @options.has_key?("secure")
47
+ @options.key?('secure')
49
48
  end
50
49
 
51
50
  def http_only?
52
- @options.has_key?('HttpOnly')
51
+ @options.key?('HttpOnly')
53
52
  end
54
53
 
55
54
  # :api: private
56
55
  def path
57
- @options["path"].strip || "/"
56
+ ([*@options['path']].first.split(',').first || '/').strip
58
57
  end
59
58
 
60
59
  # :api: private
61
60
  def expires
62
- Time.parse(@options["expires"]) if @options["expires"]
61
+ Time.parse(@options['expires']) if @options['expires']
63
62
  end
64
63
 
65
64
  # :api: private
@@ -71,19 +70,17 @@ module Rack
71
70
  def valid?(uri)
72
71
  uri ||= default_uri
73
72
 
74
- if uri.host.nil?
75
- uri.host = @default_host
76
- end
73
+ uri.host = @default_host if uri.host.nil?
77
74
 
78
75
  real_domain = domain =~ /^\./ ? domain[1..-1] : domain
79
- (!secure? || (secure? && uri.scheme == "https")) &&
80
- uri.host =~ Regexp.new("#{Regexp.escape(real_domain)}$", Regexp::IGNORECASE) &&
81
- uri.path =~ Regexp.new("^#{Regexp.escape(path)}")
76
+ (!secure? || (secure? && uri.scheme == 'https')) &&
77
+ uri.host =~ Regexp.new("#{Regexp.escape(real_domain)}$", Regexp::IGNORECASE) &&
78
+ uri.path =~ Regexp.new("^#{Regexp.escape(path)}")
82
79
  end
83
80
 
84
81
  # :api: private
85
82
  def matches?(uri)
86
- ! expired? && valid?(uri)
83
+ !expired? && valid?(uri)
87
84
  end
88
85
 
89
86
  # :api: private
@@ -91,25 +88,24 @@ module Rack
91
88
  # Orders the cookies from least specific to most
92
89
  [name, path, domain.reverse] <=> [other.name, other.path, other.domain.reverse]
93
90
  end
91
+
94
92
  def to_h
95
93
  @options.merge(
96
94
  'value' => @value,
97
95
  'HttpOnly' => http_only?,
98
- 'secure' => secure?,
96
+ 'secure' => secure?
99
97
  )
100
98
  end
101
- alias_method :to_hash, :to_h
99
+ alias to_hash to_h
102
100
 
103
- protected
101
+ protected
104
102
 
105
103
  def default_uri
106
- URI.parse("//" + @default_host + "/")
104
+ URI.parse('//' + @default_host + '/')
107
105
  end
108
-
109
106
  end
110
107
 
111
108
  class CookieJar # :nodoc:
112
-
113
109
  # :api: private
114
110
  def initialize(cookies = [], default_host = DEFAULT_HOST)
115
111
  @default_host = default_host
@@ -128,7 +124,7 @@ module Rack
128
124
  end
129
125
 
130
126
  def get_cookie(name)
131
- hash_for(nil).fetch(name,nil)
127
+ hash_for(nil).fetch(name, nil)
132
128
  end
133
129
 
134
130
  def delete(name)
@@ -142,7 +138,7 @@ module Rack
142
138
 
143
139
  if raw_cookies.is_a? String
144
140
  raw_cookies = raw_cookies.split("\n")
145
- raw_cookies.reject!{|c| c.empty? }
141
+ raw_cookies.reject!(&:empty?)
146
142
  end
147
143
 
148
144
  raw_cookies.each do |raw_cookie|
@@ -162,7 +158,7 @@ module Rack
162
158
 
163
159
  # :api: private
164
160
  def for(uri)
165
- hash_for(uri).values.map { |c| c.raw }.join(';')
161
+ hash_for(uri).values.map(&:raw).join(';')
166
162
  end
167
163
 
168
164
  def to_hash
@@ -172,10 +168,10 @@ module Rack
172
168
  cookies[name] = cookie.value
173
169
  end
174
170
 
175
- return cookies
171
+ cookies
176
172
  end
177
173
 
178
- protected
174
+ protected
179
175
 
180
176
  def hash_for(uri = nil)
181
177
  cookies = {}
@@ -189,10 +185,8 @@ module Rack
189
185
  cookies[cookie.name] = cookie if !uri || cookie.matches?(uri)
190
186
  end
191
187
 
192
- return cookies
188
+ cookies
193
189
  end
194
-
195
190
  end
196
-
197
191
  end
198
192
  end
@@ -1,8 +1,7 @@
1
- require "forwardable"
1
+ require 'forwardable'
2
2
 
3
3
  module Rack
4
4
  module Test
5
-
6
5
  # This module serves as the primary integration point for using Rack::Test
7
6
  # in a testing environment. It depends on an app method being defined in the
8
7
  # same context, and provides the Rack::Test API methods (see Rack::Test::Session
@@ -56,26 +55,27 @@ module Rack
56
55
  @_current_session_names ||= [:default]
57
56
  end
58
57
 
59
- METHODS = [
60
- :request,
61
- :get,
62
- :post,
63
- :put,
64
- :patch,
65
- :delete,
66
- :options,
67
- :head,
68
- :follow_redirect!,
69
- :header,
70
- :env,
71
- :set_cookie,
72
- :clear_cookies,
73
- :authorize,
74
- :basic_authorize,
75
- :digest_authorize,
76
- :last_response,
77
- :last_request
78
- ]
58
+ METHODS = %i[
59
+ request
60
+ get
61
+ post
62
+ put
63
+ patch
64
+ delete
65
+ options
66
+ head
67
+ custom_request
68
+ follow_redirect!
69
+ header
70
+ env
71
+ set_cookie
72
+ clear_cookies
73
+ authorize
74
+ basic_authorize
75
+ digest_authorize
76
+ last_response
77
+ last_request
78
+ ].freeze
79
79
 
80
80
  def_delegators :current_session, *METHODS
81
81
  end
@@ -1,14 +1,12 @@
1
1
  module Rack
2
2
  module Test
3
-
4
3
  class MockDigestRequest # :nodoc:
5
-
6
4
  def initialize(params)
7
5
  @params = params
8
6
  end
9
7
 
10
8
  def method_missing(sym)
11
- if @params.has_key? k = sym.to_s
9
+ if @params.key? k = sym.to_s
12
10
  return @params[k]
13
11
  end
14
12
 
@@ -22,8 +20,6 @@ module Rack
22
20
  def response(password)
23
21
  Rack::Auth::Digest::MD5.new(nil).send :digest, self, password
24
22
  end
25
-
26
23
  end
27
-
28
24
  end
29
25
  end
@@ -1,16 +1,14 @@
1
- require "tempfile"
2
- require "fileutils"
1
+ require 'tempfile'
2
+ require 'fileutils'
3
3
 
4
4
  module Rack
5
5
  module Test
6
-
7
6
  # Wraps a Tempfile with a content type. Including one or more UploadedFile's
8
7
  # in the params causes Rack::Test to build and issue a multipart request.
9
8
  #
10
9
  # Example:
11
10
  # post "/photos", "file" => Rack::Test::UploadedFile.new("me.jpg", "image/jpeg")
12
11
  class UploadedFile
13
-
14
12
  # The filename, *not* including the path, of the "uploaded" file
15
13
  attr_reader :original_filename
16
14
 
@@ -20,33 +18,28 @@ module Rack
20
18
  # The content type of the "uploaded" file
21
19
  attr_accessor :content_type
22
20
 
23
- def initialize(path, content_type = "text/plain", binary = false)
24
- raise "#{path} file does not exist" unless ::File.exist?(path)
25
-
21
+ def initialize(content, content_type = 'text/plain', binary = false, original_filename: nil)
22
+ if content.respond_to?(:read)
23
+ initialize_from_io(content, original_filename)
24
+ else
25
+ initialize_from_file_path(content)
26
+ end
26
27
  @content_type = content_type
27
- @original_filename = ::File.basename(path)
28
-
29
- @tempfile = Tempfile.new([@original_filename, ::File.extname(path)])
30
- @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
31
28
  @tempfile.binmode if binary
32
-
33
- ObjectSpace.define_finalizer(self, self.class.finalize(@tempfile))
34
-
35
- FileUtils.copy_file(path, @tempfile.path)
36
29
  end
37
30
 
38
31
  def path
39
- @tempfile.path
32
+ tempfile.path
40
33
  end
41
34
 
42
- alias_method :local_path, :path
35
+ alias local_path path
43
36
 
44
37
  def method_missing(method_name, *args, &block) #:nodoc:
45
- @tempfile.__send__(method_name, *args, &block)
38
+ tempfile.public_send(method_name, *args, &block)
46
39
  end
47
40
 
48
- def respond_to?(method_name, include_private = false) #:nodoc:
49
- @tempfile.respond_to?(method_name, include_private) || super
41
+ def respond_to_missing?(method_name, include_private = false) #:nodoc:
42
+ tempfile.respond_to?(method_name, include_private) || super
50
43
  end
51
44
 
52
45
  def self.finalize(file)
@@ -58,7 +51,25 @@ module Rack
58
51
  file.unlink
59
52
  end
60
53
 
61
- end
54
+ private
62
55
 
56
+ def initialize_from_io(io, original_filename)
57
+ @tempfile = io
58
+ @original_filename = original_filename || raise(ArgumentError, 'Missing `original_filename` for IO')
59
+ end
60
+
61
+ def initialize_from_file_path(path)
62
+ raise "#{path} file does not exist" unless ::File.exist?(path)
63
+
64
+ @original_filename = ::File.basename(path)
65
+
66
+ @tempfile = Tempfile.new([@original_filename, ::File.extname(path)])
67
+ @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
68
+
69
+ ObjectSpace.define_finalizer(self, self.class.finalize(@tempfile))
70
+
71
+ FileUtils.copy_file(path, @tempfile.path)
72
+ end
73
+ end
63
74
  end
64
75
  end
@@ -1,6 +1,5 @@
1
1
  module Rack
2
2
  module Test
3
-
4
3
  module Utils # :nodoc:
5
4
  include Rack::Utils
6
5
  extend Rack::Utils
@@ -12,16 +11,14 @@ module Rack
12
11
  "#{prefix}[]="
13
12
  else
14
13
  value.map do |v|
15
- unless unescape(prefix) =~ /\[\]$/
16
- prefix = "#{prefix}[]"
17
- end
18
- build_nested_query(v, "#{prefix}")
19
- end.join("&")
14
+ prefix = "#{prefix}[]" unless unescape(prefix) =~ /\[\]$/
15
+ build_nested_query(v, prefix.to_s)
16
+ end.join('&')
20
17
  end
21
18
  when Hash
22
19
  value.map do |k, v|
23
20
  build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
24
- end.join("&")
21
+ end.join('&')
25
22
  when NilClass
26
23
  prefix.to_s
27
24
  else
@@ -32,9 +29,7 @@ module Rack
32
29
 
33
30
  def build_multipart(params, first = true, multipart = false)
34
31
  if first
35
- unless params.is_a?(Hash)
36
- raise ArgumentError, "value must be a Hash"
37
- end
32
+ raise ArgumentError, 'value must be a Hash' unless params.is_a?(Hash)
38
33
 
39
34
  query = lambda { |value|
40
35
  case value
@@ -50,7 +45,7 @@ module Rack
50
45
  return nil unless multipart
51
46
  end
52
47
 
53
- flattened_params = Hash.new
48
+ flattened_params = {}
54
49
 
55
50
  params.each do |key, value|
56
51
  k = first ? key.to_s : "[#{key}]"
@@ -58,23 +53,21 @@ module Rack
58
53
  case value
59
54
  when Array
60
55
  value.map do |v|
61
-
62
- if (v.is_a?(Hash))
56
+ if v.is_a?(Hash)
63
57
  nested_params = {}
64
- build_multipart(v, false).each { |subkey, subvalue|
58
+ build_multipart(v, false).each do |subkey, subvalue|
65
59
  nested_params[subkey] = subvalue
66
- }
60
+ end
67
61
  flattened_params["#{k}[]"] ||= []
68
62
  flattened_params["#{k}[]"] << nested_params
69
63
  else
70
64
  flattened_params["#{k}[]"] = value
71
65
  end
72
-
73
66
  end
74
67
  when Hash
75
- build_multipart(value, false).each { |subkey, subvalue|
68
+ build_multipart(value, false).each do |subkey, subvalue|
76
69
  flattened_params[k + subkey] = subvalue
77
- }
70
+ end
78
71
  else
79
72
  flattened_params[k] = value
80
73
  end
@@ -89,24 +82,25 @@ module Rack
89
82
  module_function :build_multipart
90
83
 
91
84
  private
85
+
92
86
  def build_parts(parameters)
93
87
  get_parts(parameters).join + "--#{MULTIPART_BOUNDARY}--\r"
94
88
  end
95
89
  module_function :build_parts
96
90
 
97
91
  def get_parts(parameters)
98
- parameters.map { |name, value|
99
- if name =~ /\[\]\Z/ && value.is_a?(Array) && value.all? {|v| v.is_a?(Hash)}
100
- value.map { |hash|
92
+ parameters.map do |name, value|
93
+ if name =~ /\[\]\Z/ && value.is_a?(Array) && value.all? { |v| v.is_a?(Hash) }
94
+ value.map do |hash|
101
95
  new_value = {}
102
- hash.each { |k, v| new_value[name+k] = v }
96
+ hash.each { |k, v| new_value[name + k] = v }
103
97
  get_parts(new_value).join
104
- }.join
98
+ end.join
105
99
  else
106
100
  if value.respond_to?(:original_filename)
107
101
  build_file_part(name, value)
108
102
 
109
- elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) }
103
+ elsif value.is_a?(Array) && value.all? { |v| v.respond_to?(:original_filename) }
110
104
  value.map do |v|
111
105
  build_file_part(name, v)
112
106
  end.join
@@ -116,14 +110,12 @@ module Rack
116
110
  Rack::Test.encoding_aware_strings? ? primitive_part.force_encoding('BINARY') : primitive_part
117
111
  end
118
112
  end
119
- }
113
+ end
120
114
  end
121
115
  module_function :get_parts
122
116
 
123
117
  def build_primitive_part(parameter_name, value)
124
- unless value.is_a? Array
125
- value = [value]
126
- end
118
+ value = [value] unless value.is_a? Array
127
119
  value.map do |v|
128
120
  <<-EOF
129
121
  --#{MULTIPART_BOUNDARY}\r
@@ -136,21 +128,17 @@ EOF
136
128
  module_function :build_primitive_part
137
129
 
138
130
  def build_file_part(parameter_name, uploaded_file)
139
- ::File.open(uploaded_file.path, "rb") do |physical_file|
140
- physical_file.set_encoding(Encoding::BINARY) if physical_file.respond_to?(:set_encoding)
141
- <<-EOF
131
+ uploaded_file.set_encoding(Encoding::BINARY) if uploaded_file.respond_to?(:set_encoding)
132
+ <<-EOF
142
133
  --#{MULTIPART_BOUNDARY}\r
143
134
  Content-Disposition: form-data; name="#{parameter_name}"; filename="#{escape(uploaded_file.original_filename)}"\r
144
135
  Content-Type: #{uploaded_file.content_type}\r
145
- Content-Length: #{::File.stat(uploaded_file.path).size}\r
136
+ Content-Length: #{uploaded_file.size}\r
146
137
  \r
147
- #{physical_file.read}\r
138
+ #{uploaded_file.read}\r
148
139
  EOF
149
- end
150
140
  end
151
141
  module_function :build_file_part
152
-
153
142
  end
154
-
155
143
  end
156
144
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Test
3
- VERSION = '0.7.0'.freeze
3
+ VERSION = '0.8.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Helmkamp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-10 00:00:00.000000000 Z
11
+ date: 2017-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -173,7 +173,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
173
  requirements:
174
174
  - - ">="
175
175
  - !ruby/object:Gem::Version
176
- version: '0'
176
+ version: 2.2.2
177
177
  required_rubygems_version: !ruby/object:Gem::Requirement
178
178
  requirements:
179
179
  - - ">="
OSZAR »