padrino-core 0.12.9 → 0.13.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +5 -13
  2. data/bin/padrino +1 -2
  3. data/lib/padrino-core/application/application_setup.rb +10 -6
  4. data/lib/padrino-core/application/params_protection.rb +7 -1
  5. data/lib/padrino-core/application/routing.rb +88 -50
  6. data/lib/padrino-core/application/show_exceptions.rb +29 -0
  7. data/lib/padrino-core/application.rb +0 -19
  8. data/lib/padrino-core/caller.rb +1 -2
  9. data/lib/padrino-core/cli/base.rb +7 -11
  10. data/lib/padrino-core/cli/rake_tasks.rb +8 -21
  11. data/lib/padrino-core/loader.rb +13 -12
  12. data/lib/padrino-core/logger.rb +4 -32
  13. data/lib/padrino-core/mounter.rb +62 -21
  14. data/lib/padrino-core/path_router/compiler.rb +110 -0
  15. data/lib/padrino-core/path_router/error_handler.rb +8 -0
  16. data/lib/padrino-core/path_router/matcher.rb +123 -0
  17. data/lib/padrino-core/path_router/route.rb +169 -0
  18. data/lib/padrino-core/path_router.rb +119 -0
  19. data/lib/padrino-core/reloader/rack.rb +1 -4
  20. data/lib/padrino-core/reloader/storage.rb +3 -31
  21. data/lib/padrino-core/reloader.rb +12 -17
  22. data/lib/padrino-core/version.rb +1 -1
  23. data/lib/padrino-core.rb +0 -2
  24. data/padrino-core.gemspec +8 -2
  25. data/test/fixtures/apps/helpers/support.rb +1 -0
  26. data/test/fixtures/apps/{rack_apps.rb → mountable_apps/rack_apps.rb} +0 -4
  27. data/test/fixtures/apps/{static.html → mountable_apps/static.html} +0 -0
  28. data/test/fixtures/apps/precompiled_app.rb +19 -0
  29. data/test/fixtures/apps/system.rb +0 -2
  30. data/test/helper.rb +1 -1
  31. data/test/test_application.rb +18 -6
  32. data/test/test_csrf_protection.rb +6 -7
  33. data/test/test_filters.rb +18 -1
  34. data/test/test_logger.rb +1 -49
  35. data/test/test_mounter.rb +2 -4
  36. data/test/test_params_protection.rb +15 -15
  37. data/test/test_reloader_simple.rb +2 -2
  38. data/test/test_reloader_system.rb +0 -30
  39. data/test/test_restful_routing.rb +4 -4
  40. data/test/test_routing.rb +176 -54
  41. metadata +109 -49
  42. data/lib/padrino-core/cli/binstub.rb +0 -27
  43. data/lib/padrino-core/configuration.rb +0 -40
  44. data/lib/padrino-core/ext/http_router.rb +0 -201
  45. data/lib/padrino-core/mounter/application_extension.rb +0 -55
  46. data/test/fixtures/apps/custom_dependencies/custom_dependencies.rb +0 -11
  47. data/test/fixtures/apps/custom_dependencies/my_dependencies/my_dependency.rb +0 -0
  48. data/test/fixtures/apps/stealthy/app.rb +0 -7
  49. data/test/fixtures/apps/stealthy/helpers/stealthy_class_helpers.rb +0 -13
  50. data/test/test_configuration.rb +0 -29
  51. data/test/test_reloader_storage.rb +0 -51
@@ -1,27 +0,0 @@
1
- module Padrino
2
- ##
3
- # Replaces the current process with it's binstub.
4
- #
5
- def self.replace_with_binstub(executable)
6
- begin
7
- return if Bundler.definition.missing_specs.empty?
8
- rescue NameError, NoMethodError, Bundler::GemfileNotFound
9
- end
10
-
11
- project_root = Dir.pwd
12
- until project_root.empty?
13
- break if File.file?(File.join(project_root, 'Gemfile'))
14
- project_root = project_root.rpartition('/').first
15
- end
16
-
17
- if %w(Gemfile .components).all? { |file| File.file?(File.join(project_root, file)) }
18
- binstub = File.join(project_root, 'bin', executable)
19
- if File.file?(binstub)
20
- exec Gem.ruby, binstub, *ARGV
21
- else
22
- puts 'Please run `bundler install --binstubs` from your project root to generate bundle-specific executables'
23
- exit!
24
- end
25
- end
26
- end
27
- end
@@ -1,40 +0,0 @@
1
- require 'ostruct'
2
-
3
- module Padrino
4
- ##
5
- # Padrino simple configuration module
6
- #
7
- module Configuration
8
- ##
9
- # Returns the configuration structure allowing to get and set it's values.
10
- # Padrino.config is a simple Ruby OpenStruct object with no additional magic.
11
- #
12
- # Example:
13
- #
14
- # Padrino.config.value1 = 42
15
- # exit if Padrino.config.exiting
16
- #
17
- def config
18
- @config ||= OpenStruct.new
19
- end
20
-
21
- ##
22
- # Allows to configure different environments differently. Requires a block.
23
- #
24
- # Example:
25
- #
26
- # Padrino.configure :development do |config|
27
- # config.value2 = 'only development'
28
- # end
29
- # Padrino.configure :development, :production do |config|
30
- # config.value2 = 'both development and production'
31
- # end
32
- # Padrino.configure do |config|
33
- # config.value2 = 'any environment'
34
- # end
35
- #
36
- def configure(*environments)
37
- yield(config) if environments.empty? || environments.include?(Padrino.env)
38
- end
39
- end
40
- end
@@ -1,201 +0,0 @@
1
- require 'http_router' unless defined?(HttpRouter)
2
-
3
- class HttpRouter
4
- def rewrite_partial_path_info(env, request); end
5
- def rewrite_path_info(env, request); end
6
-
7
- def process_destination_path(path, env)
8
- Thread.current['padrino.instance'].instance_eval do
9
- request.route_obj = path.route
10
- @_response_buffer = nil
11
- @route = path.route
12
- @params ||= {}
13
- @params.update(env['router.params'])
14
- @block_params = if match_data = env['router.request'].extra_env['router.regex_match']
15
- params_list = match_data.to_a
16
- params_list.shift
17
- @params[:captures] = params_list
18
- params_list
19
- else
20
- env['router.request'].params
21
- end
22
- # Provide access to the current controller to the request
23
- # Now we can eval route, but because we have "throw halt" we need to be
24
- # (en)sure to reset old layout and run controller after filters.
25
- original_params = @params
26
- parent_layout = @layout
27
- successful = false
28
- begin
29
- filter! :before
30
- (@route.before_filters - settings.filters[:before]).each { |block| instance_eval(&block) }
31
- @layout = path.route.use_layout if path.route.use_layout
32
- @route.custom_conditions.each { |block| pass if block.bind(self).call == false }
33
- halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
34
- @_response_buffer = halt_response.is_a?(Array) ? halt_response.last : halt_response
35
- successful = true
36
- halt halt_response
37
- ensure
38
- (@route.after_filters - settings.filters[:after]).each { |block| instance_eval(&block) } if successful
39
- @layout = parent_layout
40
- @params = original_params
41
- end
42
- end
43
- end
44
-
45
- class Route
46
- VALID_HTTP_VERBS.replace %w[GET POST PUT PATCH DELETE HEAD OPTIONS LINK UNLINK]
47
-
48
- attr_accessor :use_layout, :controller, :action, :cache, :cache_key, :cache_expires, :parent
49
-
50
- def before_filters(&block)
51
- @_before_filters ||= []
52
- @_before_filters << block if block_given?
53
-
54
- @_before_filters
55
- end
56
-
57
- def after_filters(&block)
58
- @_after_filters ||= []
59
- @_after_filters << block if block_given?
60
-
61
- @_after_filters
62
- end
63
-
64
- def custom_conditions(&block)
65
- @_custom_conditions ||= []
66
- @_custom_conditions << block if block_given?
67
-
68
- @_custom_conditions
69
- end
70
-
71
- def significant_variable_names
72
- @significant_variable_names ||= if @original_path.is_a?(String)
73
- @original_path.scan(/(^|[^\\])[:\*]([a-zA-Z0-9_]+)/).map{|p| p.last.to_sym}
74
- elsif @original_path.is_a?(Regexp) and @original_path.respond_to?(:named_captures)
75
- @original_path.named_captures.keys.map(&:to_sym)
76
- else
77
- []
78
- end
79
- end
80
-
81
- def to(dest = nil, &dest_block)
82
- @dest = dest || dest_block || raise("you didn't specify a destination")
83
-
84
- @router.current_order ||= 0
85
- @order = @router.current_order
86
- @router.current_order += 1
87
-
88
- if @dest.respond_to?(:url_mount=)
89
- urlmount = UrlMount.new(@path_for_generation, @default_values || {}) # TODO url mount should accept nil here.
90
- urlmount.url_mount = @router.url_mount if @router.url_mount
91
- @dest.url_mount = urlmount
92
- end
93
- self
94
- end
95
-
96
- attr_accessor :order
97
-
98
- end
99
-
100
- attr_accessor :current_order
101
-
102
- def sort!
103
- @routes.sort!{ |a, b| a.order <=> b.order }
104
- end
105
-
106
- class Node::Glob
107
- def to_code
108
- id = root.next_counter
109
- "request.params << (globbed_params#{id} = [])
110
- until request.path.empty?
111
- globbed_params#{id} << request.path.shift
112
- #{super}
113
- end
114
- request.path[0,0] = globbed_params#{id}
115
- request.params.pop"
116
- end
117
- end
118
-
119
- class Node::SpanningRegex
120
- def to_code
121
- params_count = @ordered_indicies.size
122
- whole_path_var = "whole_path#{root.next_counter}"
123
- "#{whole_path_var} = request.joined_path
124
- if match = #{@matcher.inspect}.match(#{whole_path_var}) and match.begin(0).zero?
125
- _#{whole_path_var} = request.path.dup
126
- " << param_capturing_code << "
127
- remaining_path = #{whole_path_var}[match[0].size + (#{whole_path_var}[match[0].size] == ?/ ? 1 : 0), #{whole_path_var}.size]
128
- request.path = remaining_path.split('/')
129
- #{node_to_code}
130
- request.path = _#{whole_path_var}
131
- request.params.slice!(#{-params_count}, #{params_count})
132
- end
133
- "
134
- end
135
- end
136
-
137
- # Monkey patching the Request class. Using Rack::Utils.unescape rather than
138
- # URI.unescape which can't handle utf-8 chars
139
- class Request
140
- def initialize(path, rack_request)
141
- @rack_request = rack_request
142
- @path = path.split(/\//).map{|part| Rack::Utils.unescape(part) }
143
- @path.shift if @path.first == ''
144
- @path.push('') if path[-1] == ?/
145
- @extra_env = {}
146
- @params = []
147
- @acceptable_methods = Set.new
148
- end
149
- end
150
-
151
- class Node::Path
152
- def to_code
153
- path_ivar = inject_root_ivar(self)
154
- "#{"if !callback && request.path.size == 1 && request.path.first == '' && (request.rack_request.head? || request.rack_request.get?) && request.rack_request.path_info[-1] == ?/
155
- catch(:pass) do
156
- response = ::Rack::Response.new
157
- response.redirect(request.rack_request.path_info[0, request.rack_request.path_info.size - 1], 302)
158
- return response.finish
159
- end
160
- end" if router.redirect_trailing_slash?}
161
-
162
- #{"if request.#{router.ignore_trailing_slash? ? 'path_finished?' : 'path.empty?'}" unless route.match_partially}
163
- catch(:pass) do
164
- if callback
165
- request.called = true
166
- callback.call(Response.new(request, #{path_ivar}))
167
- else
168
- env = request.rack_request.dup.env
169
- env['router.request'] = request
170
- env['router.params'] ||= {}
171
- #{"env['router.params'].merge!(Hash[#{param_names.inspect}.zip(request.params)])" if dynamic?}
172
- env['router.params'] = env['router.params'].with_indifferent_access
173
- @router.rewrite#{"_partial" if route.match_partially}_path_info(env, request)
174
- response = @router.process_destination_path(#{path_ivar}, env)
175
- return response unless router.pass_on_response(response)
176
- end
177
- end
178
- #{"end" unless route.match_partially}"
179
- end
180
- end
181
-
182
- class Node::FreeRegex
183
- def to_code
184
- id = root.next_counter
185
- "whole_path#{id} = \"/\#{request.joined_path}\"
186
- if match = #{matcher.inspect}.match(whole_path#{id}) and match[0].size == whole_path#{id}.size
187
- request.extra_env['router.regex_match'] = match
188
- old_path = request.path
189
- request.path = ['']
190
- " << (use_named_captures? ?
191
- "match.names.size.times{|i| request.params << match[i + 1]} if match.respond_to?(:names) && match.names" : "") << "
192
- #{super}
193
- request.path = old_path
194
- request.extra_env.delete('router.regex_match')
195
- " << (use_named_captures? ?
196
- "request.params.slice!(-match.names.size, match.names.size)" : ""
197
- ) << "
198
- end"
199
- end
200
- end
201
- end
@@ -1,55 +0,0 @@
1
- module Padrino
2
- class Mounter
3
- module ApplicationExtension
4
- attr_accessor :uri_root, :mounter_options
5
- attr_writer :public_folder
6
-
7
- def dependencies
8
- @__dependencies ||= Dir.glob("#{root}/**/*.rb").delete_if { |path| path == app_file }
9
- end
10
-
11
- def prerequisites
12
- @__prerequisites ||= []
13
- end
14
-
15
- def app_file
16
- @__app_file ||= trace_method(:app_file) { mounter_options[:app_file] }
17
- end
18
-
19
- def root
20
- @__root ||= trace_method(:root) { File.expand_path("#{app_file}/../") }
21
- end
22
-
23
- def public_folder
24
- @public_folder ||= trace_method(:public_folder) { "" }
25
- end
26
-
27
- def app_name
28
- @__app_name ||= mounter_options[:app_name] || self.to_s.underscore.to_sym
29
- end
30
-
31
- def setup_application!
32
- @configured ||= trace_method(:setup_application!) do
33
- $LOAD_PATH.concat(prerequisites)
34
- require_dependencies if root.start_with?(Padrino.root)
35
- true
36
- end
37
- end
38
-
39
- private
40
-
41
- def require_dependencies
42
- Padrino.require_dependencies(dependencies, :force => true)
43
- end
44
-
45
- def trace_method(method_name)
46
- value = baseclass.send(method_name) if baseclass != self && baseclass.respond_to?(method_name)
47
- value || yield
48
- end
49
-
50
- def baseclass
51
- @__baseclass ||= respond_to?(:superclass) ? superclass : self
52
- end
53
- end
54
- end
55
- end
@@ -1,11 +0,0 @@
1
- PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
2
-
3
- class CustomDependencies < Padrino::Application
4
- set :reload, true
5
- end
6
-
7
- CustomDependencies.controllers do
8
- get "/" do
9
- "foo"
10
- end
11
- end
@@ -1,7 +0,0 @@
1
- PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
2
-
3
- class SystemStealthyClassDemo < Padrino::Application
4
- set :reload, true
5
- end
6
-
7
- Padrino.load!
@@ -1,13 +0,0 @@
1
- class Boo
2
- def self.class_method
3
- "BooClass"
4
- end
5
- end
6
-
7
- class Woo < Boo
8
- def poo
9
- end
10
- end
11
-
12
- class Soo < Boo
13
- end
@@ -1,29 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/helper')
2
-
3
- describe "PadrinoConfiguration" do
4
- it 'should be able to store values' do
5
- Padrino.config.val1 = 12345
6
- assert_equal 12345, Padrino.config.val1
7
- end
8
-
9
- it 'should be able to configure with block' do
10
- Padrino.configure do |config|
11
- config.val2 = 54321
12
- end
13
- assert_equal 54321, Padrino.config.val2
14
- end
15
-
16
- it 'should be able to configure with block' do
17
- Padrino.configure :test do |config|
18
- config.test1 = 54321
19
- end
20
- Padrino.configure :development do |config|
21
- config.test1 = 12345
22
- end
23
- Padrino.configure :test, :development do |config|
24
- config.both1 = 54321
25
- end
26
- assert_equal 54321, Padrino.config.test1
27
- assert_equal 54321, Padrino.config.both1
28
- end
29
- end
@@ -1,51 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/helper')
2
-
3
- describe "Padrino::Reloader::Storage" do
4
- describe "#classes" do
5
- it 'should take an snapshot of the current loaded classes' do
6
- snapshot = Padrino::Reloader::Storage.send(:object_classes)
7
- assert_equal snapshot.include?(Padrino::Logger), true
8
- end
9
-
10
- it 'should return a Set object' do
11
- snapshot = Padrino::Reloader::Storage.send(:object_classes)
12
- assert_equal snapshot.kind_of?(Set), true
13
- end
14
-
15
- it 'should be able to process a the class name given a block' do
16
- klasses = Padrino::Reloader::Storage.send(:object_classes) do |klass|
17
- next unless klass.respond_to?(:name) # fix JRuby < 1.7.22
18
- if klass.name =~ /^Padrino::/
19
- klass
20
- end
21
- end
22
-
23
- assert_equal (klasses.size > 1), true
24
- klasses.each do |klass|
25
- assert_match /^Padrino::/, klass.to_s
26
- end
27
- end
28
- end
29
-
30
- describe "#new_classes" do
31
- before do
32
- @snapshot = Padrino::Reloader::Storage.send(:object_classes)
33
- end
34
-
35
- it 'should return list of new classes' do
36
- class OSTest; end
37
- module OSTestModule; class B; end; end
38
-
39
- new_classes = Padrino::Reloader::Storage.send(:new_classes, @snapshot)
40
-
41
- assert_equal new_classes.size, 2
42
- assert_equal new_classes.include?(OSTest), true
43
- assert_equal new_classes.include?(OSTestModule::B), true
44
- end
45
-
46
- it 'should return a Set object' do
47
- new_classes = Padrino::Reloader::Storage.send(:new_classes, @snapshot)
48
- assert_equal new_classes.kind_of?(Set), true
49
- end
50
- end
51
- end