padrino-core 0.11.3 → 0.11.4

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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +5 -5
  3. data/lib/padrino-core.rb +3 -9
  4. data/lib/padrino-core/application.rb +39 -35
  5. data/lib/padrino-core/application/flash.rb +7 -7
  6. data/lib/padrino-core/application/rendering.rb +136 -139
  7. data/lib/padrino-core/application/rendering/extensions/erubis.rb +15 -6
  8. data/lib/padrino-core/application/routing.rb +371 -369
  9. data/lib/padrino-core/application/showexceptions.rb +13 -12
  10. data/lib/padrino-core/caller.rb +40 -40
  11. data/lib/padrino-core/cli/adapter.rb +4 -4
  12. data/lib/padrino-core/cli/base.rb +40 -39
  13. data/lib/padrino-core/cli/rake.rb +2 -2
  14. data/lib/padrino-core/cli/rake_tasks.rb +2 -4
  15. data/lib/padrino-core/command.rb +2 -2
  16. data/lib/padrino-core/loader.rb +14 -15
  17. data/lib/padrino-core/locale/cs.yml +0 -1
  18. data/lib/padrino-core/locale/da.yml +0 -1
  19. data/lib/padrino-core/locale/de.yml +0 -1
  20. data/lib/padrino-core/locale/en.yml +0 -1
  21. data/lib/padrino-core/locale/es.yml +1 -2
  22. data/lib/padrino-core/locale/fr.yml +2 -3
  23. data/lib/padrino-core/locale/hu.yml +1 -2
  24. data/lib/padrino-core/locale/it.yml +0 -1
  25. data/lib/padrino-core/locale/ja.yml +1 -2
  26. data/lib/padrino-core/locale/lv.yml +0 -1
  27. data/lib/padrino-core/locale/nl.yml +0 -1
  28. data/lib/padrino-core/locale/no.yml +0 -2
  29. data/lib/padrino-core/locale/pl.yml +0 -1
  30. data/lib/padrino-core/locale/pt_br.yml +0 -1
  31. data/lib/padrino-core/locale/ro.yml +0 -1
  32. data/lib/padrino-core/locale/ru.yml +0 -1
  33. data/lib/padrino-core/locale/sv.yml +0 -1
  34. data/lib/padrino-core/locale/tr.yml +0 -1
  35. data/lib/padrino-core/locale/uk.yml +0 -1
  36. data/lib/padrino-core/locale/zh_cn.yml +0 -1
  37. data/lib/padrino-core/locale/zh_tw.yml +0 -1
  38. data/lib/padrino-core/logger.rb +26 -27
  39. data/lib/padrino-core/module.rb +3 -3
  40. data/lib/padrino-core/mounter.rb +59 -59
  41. data/lib/padrino-core/reloader.rb +23 -23
  42. data/lib/padrino-core/router.rb +10 -13
  43. data/lib/padrino-core/server.rb +17 -19
  44. data/lib/padrino-core/tasks.rb +3 -3
  45. data/lib/padrino-core/version.rb +1 -1
  46. data/padrino-core.gemspec +1 -1
  47. data/test/test_application.rb +7 -7
  48. data/test/test_rendering.rb +15 -2
  49. data/test/test_routing.rb +34 -10
  50. metadata +13 -27
@@ -143,8 +143,8 @@ module Padrino
143
143
  Padrino::Utils.unsilence_output
144
144
  new_constants = ObjectSpace.new_classes(klasses)
145
145
  if loaded
146
- process_loaded_file(:file => file,
147
- :constants => new_constants,
146
+ process_loaded_file(:file => file,
147
+ :constants => new_constants,
148
148
  :files => files)
149
149
  else
150
150
  logger.devel "Failed to load #{file}; removing partially defined constants"
@@ -154,7 +154,7 @@ module Padrino
154
154
  end
155
155
 
156
156
  ##
157
- # Returns true if the file is defined in our padrino root
157
+ # Returns true if the file is defined in our padrino root.
158
158
  #
159
159
  def figure_path(file)
160
160
  return file if Pathname.new(file).absolute?
@@ -183,13 +183,12 @@ module Padrino
183
183
  private
184
184
 
185
185
  ###
186
- # Clear instance variables that keep track of
187
- # loaded features/files/mtimes
186
+ # Clear instance variables that keep track of # loaded features/files/mtimes.
188
187
  #
189
188
  def clear_modification_times
190
189
  MTIMES.clear
191
190
  end
192
-
191
+
193
192
  def clear_loaded_classes
194
193
  LOADED_CLASSES.each do |file, klasses|
195
194
  klasses.each { |klass| remove_constant(klass) }
@@ -205,21 +204,21 @@ module Padrino
205
204
  end
206
205
 
207
206
  ###
208
- # Macro for mtime query
207
+ # Macro for mtime query.
209
208
  #
210
209
  def modification_time(file)
211
210
  MTIMES[file]
212
211
  end
213
212
 
214
213
  ###
215
- # Macro for mtime update
214
+ # Macro for mtime update.
216
215
  #
217
216
  def update_modification_time(file)
218
217
  MTIMES[file] = File.mtime(file)
219
218
  end
220
219
 
221
220
  ###
222
- # Tracks loaded file features/classes/constants
221
+ # Tracks loaded file features/classes/constants:
223
222
  #
224
223
  def process_loaded_file(*args)
225
224
  options = args.extract_options!
@@ -236,14 +235,14 @@ module Padrino
236
235
  end
237
236
 
238
237
  ###
239
- # Unloads all constants in new_constants
238
+ # Unloads all constants in new_constants.
240
239
  #
241
240
  def unload_constants(new_constants)
242
241
  new_constants.each { |klass| remove_constant(klass) }
243
242
  end
244
243
 
245
244
  ###
246
- # Safe load dependencies of a file
245
+ # Safe load dependencies of a file.
247
246
  #
248
247
  def reload_deps_of_file(file)
249
248
  if features = LOADED_FILES.delete(file)
@@ -252,23 +251,23 @@ module Padrino
252
251
  end
253
252
 
254
253
  ##
255
- # Check if file was changed or if force a reload
254
+ # Check if file was changed or if force a reload.
256
255
  #
257
256
  def should_reload?(file)
258
257
  MTIMES[file] && File.mtime(file) > MTIMES[file]
259
258
  end
260
259
 
261
260
  ##
262
- # Removes all classes declared in the specified file
261
+ # Removes all classes declared in the specified file.
263
262
  #
264
263
  def remove_loaded_file_classes(file)
265
264
  if klasses = LOADED_CLASSES.delete(file)
266
265
  klasses.each { |klass| remove_constant(klass) }
267
- end
266
+ end
268
267
  end
269
268
 
270
269
  ##
271
- # Remove all loaded fatures with our file
270
+ # Remove all loaded fatures with our file.
272
271
  #
273
272
  def remove_loaded_file_features(file)
274
273
  if features = LOADED_FILES[file]
@@ -277,8 +276,8 @@ module Padrino
277
276
  end
278
277
 
279
278
  ##
280
- # Return the mounted_apps providing the app location
281
- # Can be an array because in one app.rb we can define multiple Padrino::Appplications
279
+ # Return the mounted_apps providing the app location.
280
+ # Can be an array because in one app.rb we can define multiple Padrino::Application.
282
281
  #
283
282
  def mounted_apps_of(file)
284
283
  file = figure_path(file)
@@ -286,7 +285,7 @@ module Padrino
286
285
  end
287
286
 
288
287
  ##
289
- # Returns true if file is in our Padrino.root
288
+ # Returns true if file is in our Padrino.root.
290
289
  #
291
290
  def in_root?(file)
292
291
  # This is better but slow:
@@ -307,7 +306,7 @@ module Padrino
307
306
  end
308
307
 
309
308
  ##
310
- # Creates an array of paths for use in #rotation
309
+ # Creates an array of paths for use in #rotation.
311
310
  #
312
311
  def files_for_rotation
313
312
  files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
@@ -317,8 +316,9 @@ module Padrino
317
316
  end # self
318
317
 
319
318
  ##
320
- # This class acts as a Rack middleware to be added to the application stack. This middleware performs a
321
- # check and reload for source files at the start of each request, but also respects a specified cool down time
319
+ # This class acts as a Rack middleware to be added to the application stack.
320
+ # This middleware performs a check and reload for source files at the start
321
+ # of each request, but also respects a specified cool down time
322
322
  # during which no further action will be taken.
323
323
  #
324
324
  class Rack
@@ -337,5 +337,5 @@ module Padrino
337
337
  @app.call(env)
338
338
  end
339
339
  end
340
- end # Reloader
341
- end # Padrino
340
+ end
341
+ end
@@ -1,6 +1,6 @@
1
1
  module Padrino
2
2
  ##
3
- # This class is an extended version of Rack::URLMap
3
+ # This class is an extended version of Rack::URLMap.
4
4
  #
5
5
  # Padrino::Router like Rack::URLMap dispatches in such a way that the
6
6
  # longest paths are tried first, since they are most specific.
@@ -9,7 +9,7 @@ module Padrino
9
9
  #
10
10
  # * Map a path to the specified App
11
11
  # * Ignore server names (this solve issues with vhost and domain aliases)
12
- # * Use hosts instead of server name for mappings (this help us with our vhost and doman aliases)
12
+ # * Use hosts instead of server name for mappings (this help us with our vhost and domain aliases)
13
13
  #
14
14
  # @example
15
15
  #
@@ -26,8 +26,6 @@ module Padrino
26
26
  #
27
27
  # @api semipublic
28
28
  class Router
29
-
30
- # Constructs a new route mapper instance
31
29
  def initialize(*mapping, &block)
32
30
  @mapping = []
33
31
  mapping.each { |m| map(m) }
@@ -68,14 +66,14 @@ module Padrino
68
66
  end
69
67
 
70
68
  # The call handler setup to route a request given the mappings specified.
71
- # @api private
72
69
  def call(env)
73
- rPath = env["PATH_INFO"].to_s
70
+ path_info = env["PATH_INFO"].to_s
74
71
  script_name = env['SCRIPT_NAME']
75
- hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
72
+ http_host = env['HTTP_HOST']
73
+
76
74
  @mapping.each do |host, path, match, app|
77
- next unless host.nil? || hHost =~ host
78
- next unless rPath =~ match && rest = $1
75
+ next unless host.nil? || http_host =~ host
76
+ next unless path_info =~ match && rest = $1
79
77
  next unless rest.empty? || rest[0] == ?/
80
78
 
81
79
  rest = "/" if rest.empty?
@@ -85,14 +83,13 @@ module Padrino
85
83
  'SCRIPT_NAME' => (script_name + path),
86
84
  'PATH_INFO' => rest))
87
85
  end
88
- [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{rPath}"]]
86
+ [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path_info}"]]
89
87
  end
90
88
 
91
89
  private
92
90
 
93
- # Sorts the mapped routes in consistent order
94
91
  def sort!
95
92
  @mapping = @mapping.sort_by { |h, p, m, a| -p.size }
96
93
  end
97
- end # Router
98
- end # Padrino
94
+ end
95
+ end
@@ -1,7 +1,7 @@
1
1
  module Padrino
2
2
  ##
3
3
  # Runs the Padrino apps as a self-hosted server using:
4
- # thin, mongrel, or webrick in that order.
4
+ # thin, mongrel, or WEBrick in that order.
5
5
  #
6
6
  # @example
7
7
  # Padrino.run! # with these defaults => host: "127.0.0.1", port: "3000", adapter: the first found
@@ -23,7 +23,7 @@ module Padrino
23
23
  def self.start(app, opts={})
24
24
  options = {}.merge(opts) # We use a standard hash instead of Thor::CoreExt::HashWithIndifferentAccess
25
25
  options.symbolize_keys!
26
- options[:Host] = options.delete(:host) || '127.0.0.1'
26
+ options[:Host] = options.delete(:host) || '127.0.0.1'
27
27
  options[:Port] = options.delete(:port) || 3000
28
28
  options[:AccessLog] = []
29
29
  if options[:daemonize]
@@ -53,27 +53,25 @@ module Padrino
53
53
  end
54
54
  alias :wrapped_app :app
55
55
 
56
- # The options specified to the server.
57
56
  def options
58
57
  @options
59
58
  end
60
59
 
61
60
  private
62
-
63
- # Detects the supported handler to use.
64
- #
65
- # @example
66
- # detect_rack_handler => <ThinHandler>
67
- #
68
- def self.detect_rack_handler
69
- Handlers.each do |handler|
70
- begin
71
- return handler if Rack::Handler.get(handler.to_s.downcase)
72
- rescue LoadError
73
- rescue NameError
74
- end
61
+ # Detects the supported handler to use.
62
+ #
63
+ # @example
64
+ # detect_rack_handler => <ThinHandler>
65
+ #
66
+ def self.detect_rack_handler
67
+ Handlers.each do |handler|
68
+ begin
69
+ return handler if Rack::Handler.get(handler.to_s.downcase)
70
+ rescue LoadError
71
+ rescue NameError
75
72
  end
76
- fail "Server handler (#{Handlers.join(', ')}) not found."
77
73
  end
78
- end # Server
79
- end # Padrino
74
+ fail "Server handler (#{Handlers.join(', ')}) not found."
75
+ end
76
+ end
77
+ end
@@ -1,7 +1,7 @@
1
1
  module Padrino
2
2
  ##
3
3
  # This module it's used for bootstrap with padrino rake
4
- # thirdy party tasks, in your gem/plugin/extension you
4
+ # third party tasks, in your gem/plugin/extension you
5
5
  # need only do this:
6
6
  #
7
7
  # @example
@@ -17,5 +17,5 @@ module Padrino
17
17
  def self.files
18
18
  @files ||= []
19
19
  end
20
- end # Tasks
21
- end # Padrino
20
+ end
21
+ end
@@ -6,7 +6,7 @@
6
6
  #
7
7
  module Padrino
8
8
  # The version constant for the current version of Padrino.
9
- VERSION = '0.11.3' unless defined?(Padrino::VERSION)
9
+ VERSION = '0.11.4' unless defined?(Padrino::VERSION)
10
10
 
11
11
  #
12
12
  # The current Padrino version.
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  # s.post_install_message << " as shown here:\e[0m https://gist.github.com/1d36a35794dbbd664ea4"
31
31
  # s.post_install_message << "\n\e[32m" + ("*" * 20) + "\n\e[0m"
32
32
 
33
- s.add_dependency("tilt", "~> 1.3.7")
33
+ s.add_dependency("tilt", "~> 1.4.1")
34
34
  if ENV["SINATRA_EDGE"]
35
35
  s.add_dependency("sinatra")
36
36
  else
@@ -80,22 +80,22 @@ describe "Application" do
80
80
  end
81
81
 
82
82
  # compare to: test_routing: allow global provides
83
- should "set content_type to :html if none can be determined" do
83
+ should "set content_type to nil if none can be determined" do
84
84
  mock_app do
85
85
  provides :xml
86
86
 
87
- get("/foo"){ "Foo in #{content_type}" }
88
- get("/bar"){ "Foo in #{content_type}" }
87
+ get("/foo"){ "Foo in #{content_type.inspect}" }
88
+ get("/bar"){ "Foo in #{content_type.inspect}" }
89
89
  end
90
90
 
91
91
  get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
92
- assert_equal 'Foo in xml', body
92
+ assert_equal 'Foo in :xml', body
93
93
  get '/foo'
94
- assert_equal 'Foo in xml', body
94
+ assert_equal 'Foo in :xml', body
95
95
 
96
96
  get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
97
- assert_equal "Foo in html", body
98
- end # content_type to :html
97
+ assert_equal "Foo in nil", body
98
+ end
99
99
 
100
100
  context "errors" do
101
101
  should "haven't mapped errors on development" do
@@ -60,14 +60,14 @@ describe "Rendering" do
60
60
  end
61
61
 
62
62
  should 'not use layout' do
63
- with_layout :application, "this is a <%= yield %>" do
63
+ with_layout :application, "this is an <%= yield %>" do
64
64
  with_view :index, "index" do
65
65
  mock_app do
66
66
  get("/with/layout"){ render :index }
67
67
  get("/without/layout"){ render :index, :layout => false }
68
68
  end
69
69
  get "/with/layout"
70
- assert_equal "this is a index", body
70
+ assert_equal "this is an index", body
71
71
  get "/without/layout"
72
72
  assert_equal "index", body
73
73
  end
@@ -528,5 +528,18 @@ describe "Rendering" do
528
528
  assert ok?
529
529
  assert_equal '<p><div>foo</div></p>', body.strip
530
530
  end
531
+
532
+ should "render correct erb when use sinatra as middleware" do
533
+ class Bar < Sinatra::Base
534
+ get "/" do
535
+ render :erb, "<&'>"
536
+ end
537
+ end
538
+ mock_app do
539
+ use Bar
540
+ end
541
+ get "/"
542
+ assert_equal "<&'>", body
543
+ end
531
544
  end
532
545
  end
@@ -109,6 +109,16 @@ describe "Routing" do
109
109
  assert_equal 'success!', body
110
110
  end
111
111
 
112
+ should 'parse routes that include encoded slash' do
113
+ mock_app do
114
+ get('/:drive_alias/:path', :path => /.*/){
115
+ "Show #{params[:drive_alias]} and #{params[:path]}"
116
+ }
117
+ end
118
+ get("/drive%2Ffoo/some/path")
119
+ assert_equal "Show drive/foo and some/path", body
120
+ end
121
+
112
122
  should 'encode params using UTF-8' do
113
123
  skip unless ''.respond_to?(:encoding) # for 1.8.7
114
124
 
@@ -151,6 +161,20 @@ describe "Routing" do
151
161
  assert_equal 404, status
152
162
  end
153
163
 
164
+ should "parse params when use regex for parts of a route" do
165
+ mock_app do
166
+ post :index, :with => [:foo, :bar], :bar => /.+/ do
167
+ "show #{params[:foo]}"
168
+ end
169
+
170
+ get :index, :map => '/mystuff/:a_id/boing/:boing_id' do
171
+ "show #{params[:a_id]} and #{params[:boing_id]}"
172
+ end
173
+ end
174
+ get "/mystuff/5/boing/2"
175
+ assert_equal "show 5 and 2", body
176
+ end
177
+
154
178
  should "not generate overlapping head urls" do
155
179
  app = mock_app do
156
180
  get("/main"){ "hello" }
@@ -1096,17 +1120,17 @@ describe "Routing" do
1096
1120
  mock_app do
1097
1121
  provides :xml
1098
1122
 
1099
- get("/foo"){ "Foo in #{content_type}" }
1100
- get("/bar"){ "Bar in #{content_type}" }
1123
+ get("/foo"){ "Foo in #{content_type.inspect}" }
1124
+ get("/bar"){ "Bar in #{content_type.inspect}" }
1101
1125
  end
1102
1126
 
1103
1127
  get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
1104
- assert_equal 'Foo in xml', body
1128
+ assert_equal 'Foo in :xml', body
1105
1129
  get '/foo'
1106
- assert_equal 'Foo in xml', body
1130
+ assert_equal 'Foo in :xml', body
1107
1131
 
1108
1132
  get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
1109
- assert_equal 'Bar in html', body
1133
+ assert_equal 'Bar in nil', body
1110
1134
  end
1111
1135
 
1112
1136
  should "does not allow global provides in controller" do
@@ -1114,18 +1138,18 @@ describe "Routing" do
1114
1138
  controller :base do
1115
1139
  provides :xml
1116
1140
 
1117
- get(:foo, "/foo"){ "Foo in #{content_type}" }
1118
- get(:bar, "/bar"){ "Bar in #{content_type}" }
1141
+ get(:foo, "/foo"){ "Foo in #{content_type.inspect}" }
1142
+ get(:bar, "/bar"){ "Bar in #{content_type.inspect}" }
1119
1143
  end
1120
1144
  end
1121
1145
 
1122
1146
  get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
1123
- assert_equal 'Foo in xml', body
1147
+ assert_equal 'Foo in :xml', body
1124
1148
  get '/foo'
1125
- assert_equal 'Foo in xml', body
1149
+ assert_equal 'Foo in :xml', body
1126
1150
 
1127
1151
  get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
1128
- assert_equal 'Bar in html', body
1152
+ assert_equal 'Bar in nil', body
1129
1153
  end
1130
1154
 
1131
1155
  should "map non named routes in controllers" do