actionpack 4.1.0.rc1 → 4.1.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48441494a6b94b3b37656c33c887284d571c4950
4
- data.tar.gz: 159b15d6c50c7eda3830b4f28700c260d3e9f2aa
3
+ metadata.gz: b6c555c15afe7bbf436b5da70ea45df0d4fc6578
4
+ data.tar.gz: 5940cf368c174b4c945db943b07867baafea367c
5
5
  SHA512:
6
- metadata.gz: fe168a619210d069350c142ccdf35cbf08e0cc1ef6762be5c7616182f26ec334eb3cf4ce948cfb2dc3e3245957886514e2e04243860a609ce5254c8de68976b5
7
- data.tar.gz: c51d0e2a179ea132ec8ad8814917cdaefa646b3d0d93f6c68ad7f0d06a18fdf82e80ccdf118b0f13d486f47c850c41f1d605adb13e175038f4bda73de961a1a9
6
+ metadata.gz: 722e8d0402501afcbbd87de1ee7d1e0da5460e4cad57dbd6b02713612ae73ea317f3479c8b31f56ed62ef6dfeb3b48c01d363138d0d912074f3630a973f67066
7
+ data.tar.gz: 6c87df659e5dd0ebd123d37f0f53bc6f3a48d147b1bcd779c35b86475df6a6342b7346fdd1e3ccba104426b998ea1d6199e246c0fb43ea9afed6b945f9b16a8c
@@ -1,9 +1,21 @@
1
+ * Swapped the parameters of assert_equal in `assert_select` so that the
2
+ proper values were printed correctly
3
+
4
+ Fixes #14422.
5
+
6
+ *Vishal Lal*
7
+
8
+ * Fix URL generation in controller tests with request-dependent
9
+ `default_url_options` methods.
10
+
11
+ *Tony Wooster*
12
+
1
13
  * Introduce `render :html` as an option to render HTML content with a content
2
14
  type of `text/html`. This rendering option calls `ERB::Util.html_escape`
3
15
  internally to escape unsafe HTML string, so you will have to mark your
4
16
  string as html safe if you have any HTML tag in it.
5
17
 
6
- Please see #12374 for more detail.
18
+ See #14062, #12374.
7
19
 
8
20
  *Prem Sichanugrist*
9
21
 
@@ -11,19 +23,19 @@
11
23
  of `text/plain`. This is the preferred option if you are planning to render
12
24
  a plain text content.
13
25
 
14
- Please see #12374 for more detail.
26
+ See #14062, #12374.
15
27
 
16
28
  *Prem Sichanugrist*
17
29
 
18
30
  * Introduce `render :body` as an option for sending a raw content back to
19
- browser. Note that this rendering option will unset the default content type
20
- and does not include "Content-Type" header back in the response.
31
+ browser. Note that this rendering option does not include "Content-Type"
32
+ header back in the response.
21
33
 
22
- You should only use this option if you are expecting the "Content-Type"
23
- header to not be set. More information on "Content-Type" header can be found
34
+ You should only use this option if you don't care about the content type
35
+ of the response. More information on "Content-Type" header can be found
24
36
  on RFC 2616, section 7.2.1.
25
37
 
26
- Please see #12374 for more detail.
38
+ See #14062, #12374.
27
39
 
28
40
  *Prem Sichanugrist*
29
41
 
@@ -117,7 +129,7 @@
117
129
 
118
130
  * Fix stream closing when sending file with `ActionController::Live` included.
119
131
 
120
- Fixes #12381
132
+ Fixes #12381.
121
133
 
122
134
  *Alessandro Diaferia*
123
135
 
@@ -32,7 +32,7 @@ The latest version of Action Pack can be installed with RubyGems:
32
32
 
33
33
  Source code can be downloaded as part of the Rails project on GitHub
34
34
 
35
- * https://github.com/rails/rails/tree/master/actionpack
35
+ * https://github.com/rails/rails/tree/4-1-stable/actionpack
36
36
 
37
37
 
38
38
  == License
@@ -45,7 +45,7 @@ module ActionController
45
45
  #
46
46
  # def server_ip
47
47
  # location = request.env["SERVER_ADDR"]
48
- # render text: "This server hosted at #{location}"
48
+ # render plain: "This server hosted at #{location}"
49
49
  # end
50
50
  #
51
51
  # == Parameters
@@ -54,9 +54,9 @@ module ActionController
54
54
  end
55
55
 
56
56
  def deep_munge(event)
57
- message = "Value for params[:#{event.payload[:keys].join('][:')}] was set"\
58
- "to nil, because it was one of [], [null] or [null, null, ...]."\
59
- "Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation"\
57
+ message = "Value for params[:#{event.payload[:keys].join('][:')}] was set "\
58
+ "to nil, because it was one of [], [null] or [null, null, ...]. "\
59
+ "Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation "\
60
60
  "for more information."\
61
61
 
62
62
  debug(message)
@@ -96,7 +96,7 @@ module ActionController #:nodoc:
96
96
  end
97
97
 
98
98
  # Sends the given binary data to the browser. This method is similar to
99
- # <tt>render text: data</tt>, but also allows you to specify whether
99
+ # <tt>render plain: data</tt>, but also allows you to specify whether
100
100
  # the browser should display the response as a file attachment (i.e. in a
101
101
  # download dialog) or as inline data. You may also set the content type,
102
102
  # the apparent file name, and other things.
@@ -11,11 +11,11 @@ module ActionController
11
11
  # http_basic_authenticate_with name: "dhh", password: "secret", except: :index
12
12
  #
13
13
  # def index
14
- # render text: "Everyone can see me!"
14
+ # render plain: "Everyone can see me!"
15
15
  # end
16
16
  #
17
17
  # def edit
18
- # render text: "I'm only accessible if you know the password"
18
+ # render plain: "I'm only accessible if you know the password"
19
19
  # end
20
20
  # end
21
21
  #
@@ -127,11 +127,11 @@ module ActionController
127
127
  # before_action :authenticate, except: [:index]
128
128
  #
129
129
  # def index
130
- # render text: "Everyone can see me!"
130
+ # render plain: "Everyone can see me!"
131
131
  # end
132
132
  #
133
133
  # def edit
134
- # render text: "I'm only accessible if you know the password"
134
+ # render plain: "I'm only accessible if you know the password"
135
135
  # end
136
136
  #
137
137
  # private
@@ -321,11 +321,11 @@ module ActionController
321
321
  # before_action :authenticate, except: [ :index ]
322
322
  #
323
323
  # def index
324
- # render text: "Everyone can see me!"
324
+ # render plain: "Everyone can see me!"
325
325
  # end
326
326
  #
327
327
  # def edit
328
- # render text: "I'm only accessible if you know the password"
328
+ # render plain: "I'm only accessible if you know the password"
329
329
  # end
330
330
  #
331
331
  # private
@@ -107,8 +107,11 @@ module ActionController
107
107
  end
108
108
 
109
109
  class Buffer < ActionDispatch::Response::Buffer #:nodoc:
110
+ include MonitorMixin
111
+
110
112
  def initialize(response)
111
- @error_callback = nil
113
+ @error_callback = lambda { true }
114
+ @cv = new_cond
112
115
  super(response, SizedQueue.new(10))
113
116
  end
114
117
 
@@ -122,14 +125,25 @@ module ActionController
122
125
  end
123
126
 
124
127
  def each
128
+ @response.sending!
125
129
  while str = @buf.pop
126
130
  yield str
127
131
  end
132
+ @response.sent!
128
133
  end
129
134
 
130
135
  def close
131
- super
132
- @buf.push nil
136
+ synchronize do
137
+ super
138
+ @buf.push nil
139
+ @cv.broadcast
140
+ end
141
+ end
142
+
143
+ def await_close
144
+ synchronize do
145
+ @cv.wait_until { @closed }
146
+ end
133
147
  end
134
148
 
135
149
  def on_error(&block)
@@ -165,12 +179,20 @@ module ActionController
165
179
  end
166
180
  end
167
181
 
168
- def commit!
169
- headers.freeze
182
+ private
183
+
184
+ def before_committed
170
185
  super
186
+ jar = request.cookie_jar
187
+ # The response can be committed multiple times
188
+ jar.write self unless committed?
171
189
  end
172
190
 
173
- private
191
+ def before_sending
192
+ super
193
+ request.cookie_jar.commit!
194
+ headers.freeze
195
+ end
174
196
 
175
197
  def build_buffer(response, body)
176
198
  buf = Live::Buffer.new response
@@ -191,6 +213,7 @@ module ActionController
191
213
  t1 = Thread.current
192
214
  locals = t1.keys.map { |key| [key, t1[key]] }
193
215
 
216
+ error = nil
194
217
  # This processes the action in a child thread. It lets us return the
195
218
  # response code and headers back up the rack stack, and still process
196
219
  # the body in parallel with sending data to the client
@@ -205,16 +228,18 @@ module ActionController
205
228
  begin
206
229
  super(name)
207
230
  rescue => e
208
- @_response.status = 500 unless @_response.committed?
209
- @_response.status = 400 if e.class == ActionController::BadRequest
210
- begin
211
- @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
212
- @_response.stream.call_on_error
213
- rescue => exception
214
- log_error(exception)
215
- ensure
216
- log_error(e)
217
- @_response.stream.close
231
+ if @_response.committed?
232
+ begin
233
+ @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
234
+ @_response.stream.call_on_error
235
+ rescue => exception
236
+ log_error(exception)
237
+ ensure
238
+ log_error(e)
239
+ @_response.stream.close
240
+ end
241
+ else
242
+ error = e
218
243
  end
219
244
  ensure
220
245
  @_response.commit!
@@ -222,6 +247,7 @@ module ActionController
222
247
  }
223
248
 
224
249
  @_response.await_commit
250
+ raise error if error
225
251
  end
226
252
 
227
253
  def log_error(exception)
@@ -5,8 +5,8 @@ module ActionController
5
5
  module RackDelegation
6
6
  extend ActiveSupport::Concern
7
7
 
8
- delegate :headers, :status=, :location=, :content_type=, :no_content_type=,
9
- :status, :location, :content_type, :no_content_type, :to => "@_response"
8
+ delegate :headers, :status=, :location=, :content_type=,
9
+ :status, :location, :content_type, :to => "@_response"
10
10
 
11
11
  def dispatch(action, request)
12
12
  set_response!(request)
@@ -45,9 +45,7 @@ module ActionController
45
45
  def _process_format(format, options = {})
46
46
  super
47
47
 
48
- if options[:body]
49
- self.headers.delete "Content-Type"
50
- elsif options[:plain]
48
+ if options[:plain]
51
49
  self.content_type = Mime::TEXT
52
50
  else
53
51
  self.content_type ||= format.to_s
@@ -17,7 +17,6 @@ module ActionController
17
17
 
18
18
  def recycle!
19
19
  @_url_options = nil
20
- self.response_body = nil
21
20
  self.formats = nil
22
21
  self.params = nil
23
22
  end
@@ -258,6 +258,29 @@ module ActionController
258
258
  end
259
259
  end
260
260
 
261
+ class LiveTestResponse < Live::Response
262
+ def recycle!
263
+ @body = nil
264
+ initialize
265
+ end
266
+
267
+ def body
268
+ @body ||= super
269
+ end
270
+
271
+ # Was the response successful?
272
+ alias_method :success?, :successful?
273
+
274
+ # Was the URL not found?
275
+ alias_method :missing?, :not_found?
276
+
277
+ # Were we redirected?
278
+ alias_method :redirect?, :redirection?
279
+
280
+ # Was there a server-side error?
281
+ alias_method :error?, :server_error?
282
+ end
283
+
261
284
  # Methods #destroy and #load! are overridden to avoid calling methods on the
262
285
  # @store object, which does not exist for the TestSession class.
263
286
  class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
@@ -568,10 +591,13 @@ module ActionController
568
591
 
569
592
  name = @request.parameters[:action]
570
593
 
594
+ @controller.recycle!
571
595
  @controller.process(name)
572
596
 
573
597
  if cookies = @request.env['action_dispatch.cookies']
574
- cookies.write(@response)
598
+ unless @response.committed?
599
+ cookies.write(@response)
600
+ end
575
601
  end
576
602
  @response.prepare!
577
603
 
@@ -582,13 +608,14 @@ module ActionController
582
608
  end
583
609
 
584
610
  def setup_controller_request_and_response
585
- @request = build_request
586
- @response = build_response
587
- @response.request = @request
588
-
589
611
  @controller = nil unless defined? @controller
590
612
 
613
+ response_klass = TestResponse
614
+
591
615
  if klass = self.class.controller_class
616
+ if klass < ActionController::Live
617
+ response_klass = LiveTestResponse
618
+ end
592
619
  unless @controller
593
620
  begin
594
621
  @controller = klass.new
@@ -598,6 +625,10 @@ module ActionController
598
625
  end
599
626
  end
600
627
 
628
+ @request = build_request
629
+ @response = build_response response_klass
630
+ @response.request = @request
631
+
601
632
  if @controller
602
633
  @controller.request = @request
603
634
  @controller.params = {}
@@ -608,8 +639,8 @@ module ActionController
608
639
  TestRequest.new
609
640
  end
610
641
 
611
- def build_response
612
- TestResponse.new
642
+ def build_response(klass)
643
+ klass.new
613
644
  end
614
645
 
615
646
  included do
@@ -52,7 +52,6 @@ module ActionDispatch
52
52
  autoload :DebugExceptions
53
53
  autoload :ExceptionWrapper
54
54
  autoload :Flash
55
- autoload :Head
56
55
  autoload :ParamsParser
57
56
  autoload :PublicExceptions
58
57
  autoload :Reloader
@@ -63,8 +63,6 @@ module ActionDispatch # :nodoc:
63
63
  # content you're giving them, so we need to send that along.
64
64
  attr_accessor :charset
65
65
 
66
- attr_accessor :no_content_type # :nodoc:
67
-
68
66
  CONTENT_TYPE = "Content-Type".freeze
69
67
  SET_COOKIE = "Set-Cookie".freeze
70
68
  LOCATION = "Location".freeze
@@ -93,7 +91,10 @@ module ActionDispatch # :nodoc:
93
91
  end
94
92
 
95
93
  def each(&block)
96
- @buf.each(&block)
94
+ @response.sending!
95
+ x = @buf.each(&block)
96
+ @response.sent!
97
+ x
97
98
  end
98
99
 
99
100
  def close
@@ -120,6 +121,8 @@ module ActionDispatch # :nodoc:
120
121
  @blank = false
121
122
  @cv = new_cond
122
123
  @committed = false
124
+ @sending = false
125
+ @sent = false
123
126
  @content_type = nil
124
127
  @charset = nil
125
128
 
@@ -140,17 +143,37 @@ module ActionDispatch # :nodoc:
140
143
  end
141
144
  end
142
145
 
146
+ def await_sent
147
+ synchronize { @cv.wait_until { @sent } }
148
+ end
149
+
143
150
  def commit!
144
151
  synchronize do
152
+ before_committed
145
153
  @committed = true
146
154
  @cv.broadcast
147
155
  end
148
156
  end
149
157
 
150
- def committed?
151
- @committed
158
+ def sending!
159
+ synchronize do
160
+ before_sending
161
+ @sending = true
162
+ @cv.broadcast
163
+ end
164
+ end
165
+
166
+ def sent!
167
+ synchronize do
168
+ @sent = true
169
+ @cv.broadcast
170
+ end
152
171
  end
153
172
 
173
+ def sending?; synchronize { @sending }; end
174
+ def committed?; synchronize { @committed }; end
175
+ def sent?; synchronize { @sent }; end
176
+
154
177
  # Sets the HTTP status code.
155
178
  def status=(status)
156
179
  @status = Rack::Utils.status_code(status)
@@ -275,6 +298,12 @@ module ActionDispatch # :nodoc:
275
298
 
276
299
  private
277
300
 
301
+ def before_committed
302
+ end
303
+
304
+ def before_sending
305
+ end
306
+
278
307
  def merge_default_headers(original, default)
279
308
  return original unless default.respond_to?(:merge)
280
309
 
@@ -305,17 +334,8 @@ module ActionDispatch # :nodoc:
305
334
  !@sending_file && @charset != false
306
335
  end
307
336
 
308
- def remove_content_type!
309
- headers.delete CONTENT_TYPE
310
- end
311
-
312
337
  def rack_response(status, header)
313
- if no_content_type
314
- remove_content_type!
315
- else
316
- assign_default_content_type_and_charset!(header)
317
- end
318
-
338
+ assign_default_content_type_and_charset!(header)
319
339
  handle_conditional_get!
320
340
 
321
341
  header[SET_COOKIE] = header[SET_COOKIE].join("\n") if header[SET_COOKIE].respond_to?(:join)
@@ -237,6 +237,15 @@ module ActionDispatch
237
237
  @secure = secure
238
238
  @options = options
239
239
  @cookies = {}
240
+ @committed = false
241
+ end
242
+
243
+ def committed?; @committed; end
244
+
245
+ def commit!
246
+ @committed = true
247
+ @set_cookies.freeze
248
+ @delete_cookies.freeze
240
249
  end
241
250
 
242
251
  def each(&block)
@@ -336,8 +345,8 @@ module ActionDispatch
336
345
  end
337
346
 
338
347
  def recycle! #:nodoc:
339
- @set_cookies.clear
340
- @delete_cookies.clear
348
+ @set_cookies = {}
349
+ @delete_cookies = {}
341
350
  end
342
351
 
343
352
  mattr_accessor :always_write_cookie
@@ -551,9 +560,11 @@ module ActionDispatch
551
560
  status, headers, body = @app.call(env)
552
561
 
553
562
  if cookie_jar = env['action_dispatch.cookies']
554
- cookie_jar.write(headers)
555
- if headers[HTTP_HEADER].respond_to?(:join)
556
- headers[HTTP_HEADER] = headers[HTTP_HEADER].join("\n")
563
+ unless cookie_jar.committed?
564
+ cookie_jar.write(headers)
565
+ if headers[HTTP_HEADER].respond_to?(:join)
566
+ headers[HTTP_HEADER] = headers[HTTP_HEADER].join("\n")
567
+ end
557
568
  end
558
569
  end
559
570
 
@@ -51,7 +51,7 @@ module ActionDispatch
51
51
  # decode signed cookies generated by your app in external applications or
52
52
  # Javascript before upgrading.
53
53
  #
54
- # Note that changing digest or secret invalidates all existing sessions!
54
+ # Note that changing the secret key will invalidate all existing sessions!
55
55
  class CookieStore < Rack::Session::Abstract::ID
56
56
  include Compatibility
57
57
  include StaleSessionCheck
@@ -708,7 +708,8 @@ module ActionDispatch
708
708
  options[:constraints] ||= {}
709
709
 
710
710
  unless shallow?
711
- options[:shallow_path] = options[:path] if args.any?
711
+ options[:shallow_path] ||= options[:path] if options.key?(:path)
712
+ options[:shallow_prefix] ||= options[:as] if options.key?(:as)
712
713
  end
713
714
 
714
715
  if options[:constraints].is_a?(Hash)
@@ -792,9 +793,16 @@ module ActionDispatch
792
793
  # end
793
794
  def namespace(path, options = {})
794
795
  path = path.to_s
795
- options = { :path => path, :as => path, :module => path,
796
- :shallow_path => path, :shallow_prefix => path }.merge!(options)
797
- scope(options) { yield }
796
+
797
+ defaults = {
798
+ module: path,
799
+ path: options.fetch(:path, path),
800
+ as: options.fetch(:as, path),
801
+ shallow_path: options.fetch(:path, path),
802
+ shallow_prefix: options.fetch(:as, path)
803
+ }
804
+
805
+ scope(defaults.merge!(options)) { yield }
798
806
  end
799
807
 
800
808
  # === Parameter Restriction
@@ -1323,8 +1331,10 @@ module ActionDispatch
1323
1331
  end
1324
1332
 
1325
1333
  with_scope_level(:member) do
1326
- scope(parent_resource.member_scope) do
1327
- yield
1334
+ if shallow?
1335
+ shallow_scope(parent_resource.member_scope) { yield }
1336
+ else
1337
+ scope(parent_resource.member_scope) { yield }
1328
1338
  end
1329
1339
  end
1330
1340
  end
@@ -1347,16 +1357,8 @@ module ActionDispatch
1347
1357
  end
1348
1358
 
1349
1359
  with_scope_level(:nested) do
1350
- if shallow?
1351
- with_exclusive_scope do
1352
- if @scope[:shallow_path].blank?
1353
- scope(parent_resource.nested_scope, nested_options) { yield }
1354
- else
1355
- scope(@scope[:shallow_path], :as => @scope[:shallow_prefix]) do
1356
- scope(parent_resource.nested_scope, nested_options) { yield }
1357
- end
1358
- end
1359
- end
1360
+ if shallow? && nesting_depth > 1
1361
+ shallow_scope(parent_resource.nested_scope, nested_options) { yield }
1360
1362
  else
1361
1363
  scope(parent_resource.nested_scope, nested_options) { yield }
1362
1364
  end
@@ -1558,21 +1560,23 @@ module ActionDispatch
1558
1560
  end
1559
1561
  end
1560
1562
 
1561
- def with_scope_level(kind, resource = parent_resource)
1563
+ def with_scope_level(kind)
1562
1564
  old, @scope[:scope_level] = @scope[:scope_level], kind
1563
- old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource
1564
1565
  yield
1565
1566
  ensure
1566
1567
  @scope[:scope_level] = old
1567
- @scope[:scope_level_resource] = old_resource
1568
1568
  end
1569
1569
 
1570
1570
  def resource_scope(kind, resource) #:nodoc:
1571
- with_scope_level(kind, resource) do
1572
- scope(parent_resource.resource_scope) do
1573
- yield
1574
- end
1571
+ old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource
1572
+ @nesting.push(resource)
1573
+
1574
+ with_scope_level(kind) do
1575
+ scope(parent_resource.resource_scope) { yield }
1575
1576
  end
1577
+ ensure
1578
+ @nesting.pop
1579
+ @scope[:scope_level_resource] = old_resource
1576
1580
  end
1577
1581
 
1578
1582
  def nested_options #:nodoc:
@@ -1584,6 +1588,10 @@ module ActionDispatch
1584
1588
  options
1585
1589
  end
1586
1590
 
1591
+ def nesting_depth #:nodoc:
1592
+ @nesting.size
1593
+ end
1594
+
1587
1595
  def param_constraint? #:nodoc:
1588
1596
  @scope[:constraints] && @scope[:constraints][parent_resource.param].is_a?(Regexp)
1589
1597
  end
@@ -1596,18 +1604,20 @@ module ActionDispatch
1596
1604
  flag && resource_method_scope? && CANONICAL_ACTIONS.include?(action.to_s)
1597
1605
  end
1598
1606
 
1599
- def shallow_scoping? #:nodoc:
1600
- shallow? && @scope[:scope_level] == :member
1607
+ def shallow_scope(path, options = {}) #:nodoc:
1608
+ old_name_prefix, old_path = @scope[:as], @scope[:path]
1609
+ @scope[:as], @scope[:path] = @scope[:shallow_prefix], @scope[:shallow_path]
1610
+
1611
+ scope(path, options) { yield }
1612
+ ensure
1613
+ @scope[:as], @scope[:path] = old_name_prefix, old_path
1601
1614
  end
1602
1615
 
1603
1616
  def path_for_action(action, path) #:nodoc:
1604
- prefix = shallow_scoping? ?
1605
- "#{@scope[:shallow_path]}/#{parent_resource.shallow_scope}" : @scope[:path]
1606
-
1607
1617
  if canonical_action?(action, path.blank?)
1608
- prefix.to_s
1618
+ @scope[:path].to_s
1609
1619
  else
1610
- "#{prefix}/#{action_path(action, path)}"
1620
+ "#{@scope[:path]}/#{action_path(action, path)}"
1611
1621
  end
1612
1622
  end
1613
1623
 
@@ -1645,7 +1655,7 @@ module ActionDispatch
1645
1655
  when :new
1646
1656
  [prefix, :new, name_prefix, member_name]
1647
1657
  when :member
1648
- [prefix, shallow_scoping? ? @scope[:shallow_prefix] : name_prefix, member_name]
1658
+ [prefix, name_prefix, member_name]
1649
1659
  when :root
1650
1660
  [name_prefix, collection_name, prefix]
1651
1661
  else
@@ -1786,6 +1796,7 @@ module ActionDispatch
1786
1796
  @set = set
1787
1797
  @scope = { :path_names => @set.resources_path_names }
1788
1798
  @concerns = {}
1799
+ @nesting = []
1789
1800
  end
1790
1801
 
1791
1802
  include Base
@@ -291,7 +291,7 @@ module ActionDispatch
291
291
  # so is this custom message really needed?
292
292
  message = message || %(Expected #{count_description(min, max, count)} matching "#{selector.to_s}", found #{matches.size}.)
293
293
  if count
294
- assert_equal matches.size, count, message
294
+ assert_equal count, matches.size, message
295
295
  else
296
296
  assert_operator matches.size, :>=, min, message if min
297
297
  assert_operator matches.size, :<=, max, message if max
@@ -0,0 +1,15 @@
1
+ module ActionPack
2
+ # Returns the version of the currently loaded ActionPack as a <tt>Gem::Version</tt>
3
+ def self.gem_version
4
+ Gem::Version.new VERSION::STRING
5
+ end
6
+
7
+ module VERSION
8
+ MAJOR = 4
9
+ MINOR = 1
10
+ TINY = 0
11
+ PRE = "rc2"
12
+
13
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
+ end
15
+ end
@@ -1,11 +1,8 @@
1
+ require_relative 'gem_version'
2
+
1
3
  module ActionPack
2
- # Returns the version of the currently loaded ActionPack as a Gem::Version
4
+ # Returns the version of the currently loaded ActionPack as a <tt>Gem::Version</tt>
3
5
  def self.version
4
- Gem::Version.new "4.1.0.rc1"
5
- end
6
-
7
- module VERSION #:nodoc:
8
- MAJOR, MINOR, TINY, PRE = ActionPack.version.segments
9
- STRING = ActionPack.version.to_s
6
+ gem_version
10
7
  end
11
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0.rc1
4
+ version: 4.1.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-18 00:00:00.000000000 Z
11
+ date: 2014-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 4.1.0.rc1
19
+ version: 4.1.0.rc2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 4.1.0.rc1
26
+ version: 4.1.0.rc2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 4.1.0.rc1
61
+ version: 4.1.0.rc2
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 4.1.0.rc1
68
+ version: 4.1.0.rc2
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activemodel
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 4.1.0.rc1
75
+ version: 4.1.0.rc2
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 4.1.0.rc1
82
+ version: 4.1.0.rc2
83
83
  description: Web apps on Rails. Simple, battle-tested conventions for building and
84
84
  testing MVC web applications. Works with any Rack-compatible server.
85
85
  email: david@loudthinking.com
@@ -235,6 +235,7 @@ files:
235
235
  - lib/action_dispatch/testing/test_request.rb
236
236
  - lib/action_dispatch/testing/test_response.rb
237
237
  - lib/action_pack.rb
238
+ - lib/action_pack/gem_version.rb
238
239
  - lib/action_pack/version.rb
239
240
  homepage: http://www.rubyonrails.org
240
241
  licenses: