padrino-core 0.11.3 → 0.11.4

Sign up to get free protection for your applications and to get access to all the features.
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