actionpack 5.0.7.2 → 5.1.0.beta1
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 +5 -5
- data/CHANGELOG.md +189 -1002
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/abstract_controller.rb +3 -3
- data/lib/abstract_controller/base.rb +10 -12
- data/lib/abstract_controller/caching.rb +6 -3
- data/lib/abstract_controller/caching/fragments.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +2 -43
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/helpers.rb +19 -19
- data/lib/abstract_controller/rendering.rb +9 -11
- data/lib/abstract_controller/translation.rb +3 -3
- data/lib/action_controller.rb +15 -13
- data/lib/action_controller/api.rb +3 -3
- data/lib/action_controller/base.rb +7 -12
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +2 -2
- data/lib/action_controller/metal.rb +34 -43
- data/lib/action_controller/metal/conditional_get.rb +10 -9
- data/lib/action_controller/metal/data_streaming.rb +8 -9
- data/lib/action_controller/metal/etag_with_flash.rb +16 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +15 -15
- data/lib/action_controller/metal/exceptions.rb +4 -14
- data/lib/action_controller/metal/flash.rb +1 -1
- data/lib/action_controller/metal/force_ssl.rb +6 -6
- data/lib/action_controller/metal/head.rb +13 -19
- data/lib/action_controller/metal/helpers.rb +6 -6
- data/lib/action_controller/metal/http_authentication.rb +22 -23
- data/lib/action_controller/metal/implicit_render.rb +2 -5
- data/lib/action_controller/metal/instrumentation.rb +14 -14
- data/lib/action_controller/metal/live.rb +15 -16
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/parameter_encoding.rb +49 -0
- data/lib/action_controller/metal/params_wrapper.rb +32 -32
- data/lib/action_controller/metal/redirecting.rb +8 -24
- data/lib/action_controller/metal/renderers.rb +2 -3
- data/lib/action_controller/metal/rendering.rb +50 -60
- data/lib/action_controller/metal/request_forgery_protection.rb +51 -49
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +117 -250
- data/lib/action_controller/metal/testing.rb +1 -1
- data/lib/action_controller/metal/url_for.rb +4 -4
- data/lib/action_controller/railtie.rb +9 -13
- data/lib/action_controller/renderer.rb +17 -16
- data/lib/action_controller/test_case.rb +75 -148
- data/lib/action_dispatch.rb +20 -19
- data/lib/action_dispatch/http/cache.rb +9 -10
- data/lib/action_dispatch/http/filter_parameters.rb +8 -8
- data/lib/action_dispatch/http/filter_redirect.rb +2 -4
- data/lib/action_dispatch/http/headers.rb +10 -10
- data/lib/action_dispatch/http/mime_negotiation.rb +17 -22
- data/lib/action_dispatch/http/mime_type.rb +27 -52
- data/lib/action_dispatch/http/parameter_filter.rb +8 -6
- data/lib/action_dispatch/http/parameters.rb +40 -17
- data/lib/action_dispatch/http/request.rb +38 -34
- data/lib/action_dispatch/http/response.rb +16 -16
- data/lib/action_dispatch/http/upload.rb +6 -10
- data/lib/action_dispatch/http/url.rb +48 -74
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/journey/formatter.rb +8 -4
- data/lib/action_dispatch/journey/gtg/builder.rb +5 -5
- data/lib/action_dispatch/journey/gtg/simulator.rb +1 -1
- data/lib/action_dispatch/journey/gtg/transition_table.rb +15 -15
- data/lib/action_dispatch/journey/nfa/builder.rb +3 -3
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -2
- data/lib/action_dispatch/journey/nodes/node.rb +5 -5
- data/lib/action_dispatch/journey/parser.rb +23 -24
- data/lib/action_dispatch/journey/parser.y +3 -2
- data/lib/action_dispatch/journey/parser_extras.rb +2 -2
- data/lib/action_dispatch/journey/path/pattern.rb +10 -3
- data/lib/action_dispatch/journey/route.rb +19 -12
- data/lib/action_dispatch/journey/router.rb +19 -12
- data/lib/action_dispatch/journey/router/utils.rb +9 -9
- data/lib/action_dispatch/journey/scanner.rb +17 -15
- data/lib/action_dispatch/journey/visitors.rb +23 -23
- data/lib/action_dispatch/middleware/callbacks.rb +0 -12
- data/lib/action_dispatch/middleware/cookies.rb +39 -39
- data/lib/action_dispatch/middleware/debug_exceptions.rb +126 -112
- data/lib/action_dispatch/middleware/debug_locks.rb +8 -8
- data/lib/action_dispatch/middleware/exception_wrapper.rb +55 -55
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +17 -16
- data/lib/action_dispatch/middleware/public_exceptions.rb +20 -20
- data/lib/action_dispatch/middleware/reloader.rb +3 -47
- data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
- data/lib/action_dispatch/middleware/request_id.rb +6 -5
- data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +35 -35
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +19 -19
- data/lib/action_dispatch/middleware/ssl.rb +9 -27
- data/lib/action_dispatch/middleware/stack.rb +7 -26
- data/lib/action_dispatch/middleware/static.rb +13 -24
- data/lib/action_dispatch/railtie.rb +9 -11
- data/lib/action_dispatch/request/session.rb +22 -22
- data/lib/action_dispatch/request/utils.rb +11 -2
- data/lib/action_dispatch/routing.rb +8 -6
- data/lib/action_dispatch/routing/inspector.rb +37 -37
- data/lib/action_dispatch/routing/mapper.rb +296 -203
- data/lib/action_dispatch/routing/polymorphic_routes.rb +160 -134
- data/lib/action_dispatch/routing/redirection.rb +27 -22
- data/lib/action_dispatch/routing/route_set.rb +206 -92
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -2
- data/lib/action_dispatch/routing/url_for.rb +14 -12
- data/lib/action_dispatch/system_test_case.rb +119 -0
- data/lib/action_dispatch/system_testing/browser.rb +28 -0
- data/lib/action_dispatch/system_testing/driver.rb +18 -0
- data/lib/action_dispatch/system_testing/server.rb +32 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +61 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +20 -0
- data/lib/action_dispatch/testing/assertion_response.rb +6 -6
- data/lib/action_dispatch/testing/assertions.rb +4 -4
- data/lib/action_dispatch/testing/assertions/response.rb +8 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +11 -11
- data/lib/action_dispatch/testing/integration.rb +47 -138
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_request.rb +16 -16
- data/lib/action_dispatch/testing/test_response.rb +1 -1
- data/lib/action_pack.rb +2 -2
- data/lib/action_pack/gem_version.rb +3 -3
- data/lib/action_pack/version.rb +1 -1
- metadata +20 -12
- data/lib/action_dispatch/middleware/params_parser.rb +0 -46
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Http
|
@@ -42,7 +42,7 @@ module ActionDispatch
|
|
42
42
|
# # Second-level domain example
|
43
43
|
# extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www"
|
44
44
|
def extract_subdomain(host, tld_length)
|
45
|
-
extract_subdomains(host, tld_length).join(
|
45
|
+
extract_subdomains(host, tld_length).join(".")
|
46
46
|
end
|
47
47
|
|
48
48
|
def url_for(options)
|
@@ -59,14 +59,14 @@ module ActionDispatch
|
|
59
59
|
port = options[:port]
|
60
60
|
|
61
61
|
unless host
|
62
|
-
raise ArgumentError,
|
62
|
+
raise ArgumentError, "Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true"
|
63
63
|
end
|
64
64
|
|
65
65
|
build_host_url(host, port, protocol, options, path_for(options))
|
66
66
|
end
|
67
67
|
|
68
68
|
def path_for(options)
|
69
|
-
path
|
69
|
+
path = options[:script_name].to_s.chomp("/".freeze)
|
70
70
|
path << options[:path] if options.key?(:path)
|
71
71
|
|
72
72
|
add_trailing_slash(path) if options[:trailing_slash]
|
@@ -80,7 +80,7 @@ module ActionDispatch
|
|
80
80
|
|
81
81
|
def add_params(path, params)
|
82
82
|
params = { params: params } unless params.is_a?(Hash)
|
83
|
-
params.reject! { |_,v| v.to_param.nil? }
|
83
|
+
params.reject! { |_, v| v.to_param.nil? }
|
84
84
|
query = params.to_query
|
85
85
|
path << "?#{query}" unless query.empty?
|
86
86
|
end
|
@@ -92,17 +92,17 @@ module ActionDispatch
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def extract_domain_from(host, tld_length)
|
95
|
-
host.split(
|
95
|
+
host.split(".").last(1 + tld_length).join(".")
|
96
96
|
end
|
97
97
|
|
98
98
|
def extract_subdomains_from(host, tld_length)
|
99
|
-
parts = host.split(
|
99
|
+
parts = host.split(".")
|
100
100
|
parts[0..-(tld_length + 2)]
|
101
101
|
end
|
102
102
|
|
103
103
|
def add_trailing_slash(path)
|
104
104
|
# includes querysting
|
105
|
-
if path.include?(
|
105
|
+
if path.include?("?")
|
106
106
|
path.sub!(/\?/, '/\&')
|
107
107
|
# does not have a .format
|
108
108
|
elsif !path.include?(".")
|
@@ -162,7 +162,7 @@ module ActionDispatch
|
|
162
162
|
if subdomain == true
|
163
163
|
return _host if domain.nil?
|
164
164
|
|
165
|
-
host << extract_subdomains_from(_host, tld_length).join(
|
165
|
+
host << extract_subdomains_from(_host, tld_length).join(".")
|
166
166
|
elsif subdomain
|
167
167
|
host << subdomain.to_param
|
168
168
|
end
|
@@ -192,11 +192,7 @@ module ActionDispatch
|
|
192
192
|
|
193
193
|
# Returns the complete URL used for this request.
|
194
194
|
#
|
195
|
-
#
|
196
|
-
# include ActionDispatch::Http::URL
|
197
|
-
# end
|
198
|
-
#
|
199
|
-
# req = Request.new 'HTTP_HOST' => 'example.com'
|
195
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
200
196
|
# req.url # => "http://example.com"
|
201
197
|
def url
|
202
198
|
protocol + host_with_port + fullpath
|
@@ -204,61 +200,52 @@ module ActionDispatch
|
|
204
200
|
|
205
201
|
# Returns 'https://' if this is an SSL request and 'http://' otherwise.
|
206
202
|
#
|
207
|
-
#
|
208
|
-
# include ActionDispatch::Http::URL
|
209
|
-
# end
|
210
|
-
#
|
211
|
-
# req = Request.new 'HTTP_HOST' => 'example.com'
|
203
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
212
204
|
# req.protocol # => "http://"
|
213
205
|
#
|
214
|
-
# req = Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
|
206
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
|
215
207
|
# req.protocol # => "https://"
|
216
208
|
def protocol
|
217
|
-
@protocol ||= ssl? ?
|
209
|
+
@protocol ||= ssl? ? "https://" : "http://"
|
218
210
|
end
|
219
211
|
|
220
|
-
# Returns the \host for this request, such as "example.com".
|
212
|
+
# Returns the \host and port for this request, such as "example.com:8080".
|
221
213
|
#
|
222
|
-
#
|
223
|
-
# include ActionDispatch::Http::URL
|
224
|
-
# end
|
225
|
-
#
|
226
|
-
# req = Request.new 'HTTP_HOST' => 'example.com'
|
214
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
227
215
|
# req.raw_host_with_port # => "example.com"
|
228
216
|
#
|
229
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:
|
217
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
218
|
+
# req.raw_host_with_port # => "example.com:80"
|
219
|
+
#
|
220
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
230
221
|
# req.raw_host_with_port # => "example.com:8080"
|
231
222
|
def raw_host_with_port
|
232
223
|
if forwarded = x_forwarded_host.presence
|
233
224
|
forwarded.split(/,\s?/).last
|
234
225
|
else
|
235
|
-
get_header(
|
226
|
+
get_header("HTTP_HOST") || "#{server_name || server_addr}:#{get_header('SERVER_PORT')}"
|
236
227
|
end
|
237
228
|
end
|
238
229
|
|
239
|
-
# Returns the host for this request, such as example.com.
|
230
|
+
# Returns the host for this request, such as "example.com".
|
240
231
|
#
|
241
|
-
#
|
242
|
-
# include ActionDispatch::Http::URL
|
243
|
-
# end
|
244
|
-
#
|
245
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
232
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
246
233
|
# req.host # => "example.com"
|
247
234
|
def host
|
248
|
-
raw_host_with_port.sub(/:\d+$/,
|
235
|
+
raw_host_with_port.sub(/:\d+$/, "".freeze)
|
249
236
|
end
|
250
237
|
|
251
238
|
# Returns a \host:\port string for this request, such as "example.com" or
|
252
|
-
# "example.com:8080".
|
239
|
+
# "example.com:8080". Port is only included if it is not a default port
|
240
|
+
# (80 or 443)
|
253
241
|
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
# end
|
242
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
243
|
+
# req.host_with_port # => "example.com"
|
257
244
|
#
|
258
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:80'
|
245
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
259
246
|
# req.host_with_port # => "example.com"
|
260
247
|
#
|
261
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
248
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
262
249
|
# req.host_with_port # => "example.com:8080"
|
263
250
|
def host_with_port
|
264
251
|
"#{host}#{port_string}"
|
@@ -266,14 +253,10 @@ module ActionDispatch
|
|
266
253
|
|
267
254
|
# Returns the port number of this request as an integer.
|
268
255
|
#
|
269
|
-
#
|
270
|
-
# include ActionDispatch::Http::URL
|
271
|
-
# end
|
272
|
-
#
|
273
|
-
# req = Request.new 'HTTP_HOST' => 'example.com'
|
256
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
274
257
|
# req.port # => 80
|
275
258
|
#
|
276
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
259
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
277
260
|
# req.port # => 8080
|
278
261
|
def port
|
279
262
|
@port ||= begin
|
@@ -287,29 +270,21 @@ module ActionDispatch
|
|
287
270
|
|
288
271
|
# Returns the standard \port number for this request's protocol.
|
289
272
|
#
|
290
|
-
#
|
291
|
-
# include ActionDispatch::Http::URL
|
292
|
-
# end
|
293
|
-
#
|
294
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
273
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
295
274
|
# req.standard_port # => 80
|
296
275
|
def standard_port
|
297
276
|
case protocol
|
298
|
-
|
277
|
+
when "https://" then 443
|
299
278
|
else 80
|
300
279
|
end
|
301
280
|
end
|
302
281
|
|
303
282
|
# Returns whether this request is using the standard port
|
304
283
|
#
|
305
|
-
#
|
306
|
-
# include ActionDispatch::Http::URL
|
307
|
-
# end
|
308
|
-
#
|
309
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:80'
|
284
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
310
285
|
# req.standard_port? # => true
|
311
286
|
#
|
312
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
287
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
313
288
|
# req.standard_port? # => false
|
314
289
|
def standard_port?
|
315
290
|
port == standard_port
|
@@ -318,14 +293,10 @@ module ActionDispatch
|
|
318
293
|
# Returns a number \port suffix like 8080 if the \port number of this request
|
319
294
|
# is not the default HTTP \port 80 or HTTPS \port 443.
|
320
295
|
#
|
321
|
-
#
|
322
|
-
# include ActionDispatch::Http::URL
|
323
|
-
# end
|
324
|
-
#
|
325
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:80'
|
296
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
326
297
|
# req.optional_port # => nil
|
327
298
|
#
|
328
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
299
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
329
300
|
# req.optional_port # => 8080
|
330
301
|
def optional_port
|
331
302
|
standard_port? ? nil : port
|
@@ -334,21 +305,24 @@ module ActionDispatch
|
|
334
305
|
# Returns a string \port suffix, including colon, like ":8080" if the \port
|
335
306
|
# number of this request is not the default HTTP \port 80 or HTTPS \port 443.
|
336
307
|
#
|
337
|
-
#
|
338
|
-
# include ActionDispatch::Http::URL
|
339
|
-
# end
|
340
|
-
#
|
341
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:80'
|
308
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
342
309
|
# req.port_string # => ""
|
343
310
|
#
|
344
|
-
# req = Request.new 'HTTP_HOST' => 'example.com:8080'
|
311
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
345
312
|
# req.port_string # => ":8080"
|
346
313
|
def port_string
|
347
|
-
standard_port? ?
|
314
|
+
standard_port? ? "" : ":#{port}"
|
348
315
|
end
|
349
316
|
|
317
|
+
# Returns the requested port, such as 8080, based on SERVER_PORT
|
318
|
+
#
|
319
|
+
# req = ActionDispatch::Request.new 'SERVER_PORT' => '80'
|
320
|
+
# req.server_port # => 80
|
321
|
+
#
|
322
|
+
# req = ActionDispatch::Request.new 'SERVER_PORT' => '8080'
|
323
|
+
# req.server_port # => 8080
|
350
324
|
def server_port
|
351
|
-
get_header(
|
325
|
+
get_header("SERVER_PORT").to_i
|
352
326
|
end
|
353
327
|
|
354
328
|
# Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "action_dispatch/journey/router"
|
2
|
+
require "action_dispatch/journey/gtg/builder"
|
3
|
+
require "action_dispatch/journey/gtg/simulator"
|
4
|
+
require "action_dispatch/journey/nfa/builder"
|
5
|
+
require "action_dispatch/journey/nfa/simulator"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "action_controller/metal/exceptions"
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
# :stopdoc:
|
@@ -45,8 +45,12 @@ module ActionDispatch
|
|
45
45
|
return [route.format(parameterized_parts), params]
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
unmatched_keys = (missing_keys || []) & constraints.keys
|
49
|
+
missing_keys = (missing_keys || []) - unmatched_keys
|
50
|
+
|
51
|
+
message = "No route matches #{Hash[constraints.sort_by { |k, v| k.to_s }].inspect}"
|
52
|
+
message << ", missing required keys: #{missing_keys.sort.inspect}" if missing_keys && !missing_keys.empty?
|
53
|
+
message << ", possible unmatched constraints: #{unmatched_keys.sort.inspect}" if unmatched_keys && !unmatched_keys.empty?
|
50
54
|
|
51
55
|
raise ActionController::UrlGenerationError, message
|
52
56
|
end
|
@@ -179,5 +183,5 @@ module ActionDispatch
|
|
179
183
|
end
|
180
184
|
end
|
181
185
|
end
|
182
|
-
# :
|
186
|
+
# :startdoc:
|
183
187
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "action_dispatch/journey/gtg/transition_table"
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Journey # :nodoc:
|
@@ -17,7 +17,7 @@ module ActionDispatch
|
|
17
17
|
def transition_table
|
18
18
|
dtrans = TransitionTable.new
|
19
19
|
marked = {}
|
20
|
-
state_id = Hash.new { |h,k| h[k] = h.length }
|
20
|
+
state_id = Hash.new { |h, k| h[k] = h.length }
|
21
21
|
|
22
22
|
start = firstpos(root)
|
23
23
|
dstates = [start]
|
@@ -75,7 +75,7 @@ module ActionDispatch
|
|
75
75
|
when Nodes::Unary
|
76
76
|
nullable?(node.left)
|
77
77
|
else
|
78
|
-
raise ArgumentError,
|
78
|
+
raise ArgumentError, "unknown nullable: %s" % node.class.name
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -96,7 +96,7 @@ module ActionDispatch
|
|
96
96
|
when Nodes::Terminal
|
97
97
|
nullable?(node) ? [] : [node]
|
98
98
|
else
|
99
|
-
raise ArgumentError,
|
99
|
+
raise ArgumentError, "unknown firstpos: %s" % node.class.name
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
@@ -117,7 +117,7 @@ module ActionDispatch
|
|
117
117
|
when Nodes::Unary
|
118
118
|
lastpos(node.left)
|
119
119
|
else
|
120
|
-
raise ArgumentError,
|
120
|
+
raise ArgumentError, "unknown lastpos: %s" % node.class.name
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "action_dispatch/journey/nfa/dot"
|
2
2
|
|
3
3
|
module ActionDispatch
|
4
4
|
module Journey # :nodoc:
|
@@ -12,7 +12,7 @@ module ActionDispatch
|
|
12
12
|
@regexp_states = {}
|
13
13
|
@string_states = {}
|
14
14
|
@accepting = {}
|
15
|
-
@memos = Hash.new { |h,k| h[k] = [] }
|
15
|
+
@memos = Hash.new { |h, k| h[k] = [] }
|
16
16
|
end
|
17
17
|
|
18
18
|
def add_accepting(state)
|
@@ -56,7 +56,7 @@ module ActionDispatch
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def as_json(options = nil)
|
59
|
-
simple_regexp = Hash.new { |h,k| h[k] = {} }
|
59
|
+
simple_regexp = Hash.new { |h, k| h[k] = {} }
|
60
60
|
|
61
61
|
@regexp_states.each do |from, hash|
|
62
62
|
hash.each do |re, to|
|
@@ -72,20 +72,20 @@ module ActionDispatch
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def to_svg
|
75
|
-
svg = IO.popen(
|
75
|
+
svg = IO.popen("dot -Tsvg", "w+") { |f|
|
76
76
|
f.write(to_dot)
|
77
77
|
f.close_write
|
78
78
|
f.readlines
|
79
79
|
}
|
80
80
|
3.times { svg.shift }
|
81
|
-
svg.join.sub(/width="[^"]*"/,
|
81
|
+
svg.join.sub(/width="[^"]*"/, "").sub(/height="[^"]*"/, "")
|
82
82
|
end
|
83
83
|
|
84
|
-
def visualizer(paths, title =
|
85
|
-
viz_dir = File.join File.dirname(__FILE__),
|
86
|
-
fsm_js = File.read File.join(viz_dir,
|
87
|
-
fsm_css = File.read File.join(viz_dir,
|
88
|
-
erb = File.read File.join(viz_dir,
|
84
|
+
def visualizer(paths, title = "FSM")
|
85
|
+
viz_dir = File.join File.dirname(__FILE__), "..", "visualizer"
|
86
|
+
fsm_js = File.read File.join(viz_dir, "fsm.js")
|
87
|
+
fsm_css = File.read File.join(viz_dir, "fsm.css")
|
88
|
+
erb = File.read File.join(viz_dir, "index.html.erb")
|
89
89
|
states = "function tt() { return #{to_json}; }"
|
90
90
|
|
91
91
|
fun_routes = paths.sample(3).map do |ast|
|
@@ -93,10 +93,10 @@ module ActionDispatch
|
|
93
93
|
case n
|
94
94
|
when Nodes::Symbol
|
95
95
|
case n.left
|
96
|
-
when
|
97
|
-
when
|
96
|
+
when ":id" then rand(100).to_s
|
97
|
+
when ":format" then %w{ xml json }.sample
|
98
98
|
else
|
99
|
-
|
99
|
+
"omg"
|
100
100
|
end
|
101
101
|
when Nodes::Terminal then n.symbol
|
102
102
|
else
|
@@ -115,7 +115,7 @@ module ActionDispatch
|
|
115
115
|
svg = svg
|
116
116
|
javascripts = javascripts
|
117
117
|
|
118
|
-
require
|
118
|
+
require "erb"
|
119
119
|
template = ERB.new erb
|
120
120
|
template.result(binding)
|
121
121
|
end
|
@@ -148,7 +148,7 @@ module ActionDispatch
|
|
148
148
|
when Regexp
|
149
149
|
@regexp_states
|
150
150
|
else
|
151
|
-
raise ArgumentError,
|
151
|
+
raise ArgumentError, "unknown symbol: %s" % sym.class
|
152
152
|
end
|
153
153
|
end
|
154
154
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "action_dispatch/journey/nfa/transition_table"
|
2
|
+
require "action_dispatch/journey/gtg/transition_table"
|
3
3
|
|
4
4
|
module ActionDispatch
|
5
5
|
module Journey # :nodoc:
|
@@ -36,7 +36,7 @@ module ActionDispatch
|
|
36
36
|
def visit_OR(node)
|
37
37
|
from = @i += 1
|
38
38
|
children = node.children.map { |c| visit(c) }
|
39
|
-
to
|
39
|
+
to = @i += 1
|
40
40
|
|
41
41
|
children.each do |child|
|
42
42
|
@tt[from, child.first] = nil
|
@@ -18,7 +18,7 @@ module ActionDispatch
|
|
18
18
|
# (memos || []).map { |v| " #{k} -> #{v.object_id};" }
|
19
19
|
#}.uniq
|
20
20
|
|
21
|
-
|
21
|
+
<<-eodot
|
22
22
|
digraph nfa {
|
23
23
|
rankdir=LR;
|
24
24
|
node [shape = doublecircle];
|
@@ -26,7 +26,7 @@ digraph nfa {
|
|
26
26
|
node [shape = circle];
|
27
27
|
#{edges.join "\n"}
|
28
28
|
}
|
29
|
-
|
29
|
+
eodot
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|