padrino-core 0.12.2 → 0.12.3

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.
@@ -87,7 +87,7 @@ module Padrino
87
87
  began_at = Time.now
88
88
  file = figure_path(file)
89
89
  return unless options[:force] || file_changed?(file)
90
- return require(file) if external_feature?(file)
90
+ return require(file) if feature_excluded?(file)
91
91
 
92
92
  Storage.prepare(file) # might call #safe_load recursively
93
93
  logger.devel(file_new?(file) ? :loading : :reload, began_at, file)
@@ -95,13 +95,13 @@ module Padrino
95
95
  with_silence{ require(file) }
96
96
  Storage.commit(file)
97
97
  update_modification_time(file)
98
- rescue Exception => e
98
+ rescue Exception => exception
99
99
  unless options[:cyclic]
100
- logger.exception e, :short
100
+ logger.exception exception, :short
101
101
  logger.error "Failed to load #{file}; removing partially defined constants"
102
102
  end
103
103
  Storage.rollback(file)
104
- raise e
104
+ raise
105
105
  end
106
106
  end
107
107
 
@@ -121,7 +121,7 @@ module Padrino
121
121
  # Remove a feature from $LOADED_FEATURES so it can be required again.
122
122
  #
123
123
  def remove_feature(file)
124
- $LOADED_FEATURES.delete(file) unless external_feature?(file)
124
+ $LOADED_FEATURES.delete(file) unless feature_excluded?(file)
125
125
  end
126
126
 
127
127
  ##
@@ -156,7 +156,7 @@ module Padrino
156
156
  # Reloads the file if it's special. For now it's only I18n locale files.
157
157
  #
158
158
  def reload_special(file)
159
- return unless special_files.any?{ |f| File.identical?(f, file) }
159
+ return unless special_files.any?{ |special_file| File.identical?(special_file, file) }
160
160
  if defined?(I18n)
161
161
  began_at = Time.now
162
162
  I18n.reload!
@@ -171,14 +171,14 @@ module Padrino
171
171
  #
172
172
  def reload_regular(file)
173
173
  apps = mounted_apps_of(file)
174
- if apps.present?
175
- apps.each { |app| app.app_obj.reload! }
176
- update_modification_time(file)
177
- else
174
+ if apps.empty?
178
175
  reloadable_apps.each do |app|
179
176
  app.app_obj.reload! if app.app_obj.dependencies.include?(file)
180
177
  end
181
178
  safe_load(file)
179
+ else
180
+ apps.each { |app| app.app_obj.reload! }
181
+ update_modification_time(file)
182
182
  end
183
183
  end
184
184
 
@@ -203,14 +203,6 @@ module Padrino
203
203
  MTIMES[file].nil?
204
204
  end
205
205
 
206
- ##
207
- # Return the mounted_apps providing the app location.
208
- # Can be an array because in one app.rb we can define multiple Padrino::Application.
209
- #
210
- def mounted_apps_of(file)
211
- Padrino.mounted_apps.select { |app| File.identical?(file, app.app_file) }
212
- end
213
-
214
206
  ##
215
207
  # Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths
216
208
  # and monitors them for any changes.
@@ -229,25 +221,73 @@ module Padrino
229
221
  #
230
222
  def files_for_rotation
231
223
  files = Set.new
232
- Padrino.load_paths.each{ |path| files += Dir.glob("#{path}/**/*.rb") }
224
+ files += Dir.glob("#{Padrino.root}/{lib,models,shared}/**/*.rb")
233
225
  reloadable_apps.each do |app|
234
226
  files << app.app_file
227
+ files += Dir.glob(app.app_obj.prerequisites)
235
228
  files += app.app_obj.dependencies
236
229
  end
237
230
  files + special_files
238
231
  end
239
232
 
240
233
  ##
241
- # Tells if a feature is internal or external for Padrino project.
234
+ # Tells if a feature should be excluded from Reloader tracking.
242
235
  #
243
- def external_feature?(file)
244
- !file.start_with?(Padrino.root)
236
+ def feature_excluded?(file)
237
+ !file.start_with?(Padrino.root) || exclude.any?{ |excluded_path| file.start_with?(excluded_path) }
245
238
  end
246
239
 
240
+ ##
241
+ # Tells if a constant should be excluded from Reloader routines.
242
+ #
247
243
  def constant_excluded?(const)
248
- (exclude_constants - include_constants).any?{ |c| const._orig_klass_name.start_with?(c) }
244
+ external_constant?(const) || (exclude_constants - include_constants).any?{ |excluded_constant| const._orig_klass_name.start_with?(excluded_constant) }
245
+ end
246
+
247
+ ##
248
+ # Tells if a constant is defined only outside of Padrino project path.
249
+ # If a constant has any methods defined inside of the project path it's
250
+ # considered internal and will be included in further testing.
251
+ #
252
+ def external_constant?(const)
253
+ sources = object_sources(const)
254
+ begin
255
+ if sample = ObjectSpace.each_object(const).first
256
+ sources += object_sources(sample)
257
+ end
258
+ rescue RuntimeError => error # JRuby 1.7.12 fails to ObjectSpace.each_object
259
+ raise unless RUBY_PLATFORM =='java' && error.message.start_with?("ObjectSpace is disabled")
260
+ end
261
+ !sources.any?{ |source| source.start_with?(Padrino.root) }
262
+ end
263
+
264
+ ##
265
+ # Gets all the sources in which target's class or instance methods are defined.
266
+ #
267
+ # Note: Method#source_location is for Ruby 1.9.3+ only.
268
+ #
269
+ def object_sources(target)
270
+ sources = Set.new
271
+ target.methods.each do |method_name|
272
+ method_object = target.method(method_name)
273
+ if method_object.owner == (target.class == Class ? target.singleton_class : target.class)
274
+ sources << method_object.source_location.first
275
+ end
276
+ end
277
+ sources
249
278
  end
250
279
 
280
+ ##
281
+ # Return the mounted_apps providing the app location.
282
+ # Can be an array because in one app.rb we can define multiple Padrino::Application.
283
+ #
284
+ def mounted_apps_of(file)
285
+ Padrino.mounted_apps.select { |app| File.identical?(file, app.app_file) }
286
+ end
287
+
288
+ ##
289
+ # Return the apps that allow reloading.
290
+ #
251
291
  def reloadable_apps
252
292
  Padrino.mounted_apps.select{ |app| app.app_obj.respond_to?(:reload) && app.app_obj.reload? }
253
293
  end
@@ -57,7 +57,9 @@ module Padrino
57
57
  def start
58
58
  puts "=> Padrino/#{Padrino.version} has taken the stage #{Padrino.env} at http://#{options[:Host]}:#{options[:Port]}"
59
59
  [:INT, :TERM].each { |sig| trap(sig) { exit } }
60
- super
60
+ super do |server|
61
+ server.threaded = true if server.respond_to?(:threaded=)
62
+ end
61
63
  ensure
62
64
  puts "<= Padrino leaves the gun, takes the cannoli" unless options[:daemonize]
63
65
  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.12.2' unless defined?(Padrino::VERSION)
9
+ VERSION = '0.12.3' unless defined?(Padrino::VERSION)
10
10
 
11
11
  #
12
12
  # The current Padrino version.
data/padrino-core.gemspec CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  s.add_dependency("sinatra", "~> 1.4.2")
31
31
  end
32
32
  s.add_dependency("http_router", "~> 0.11.0")
33
- s.add_dependency("thor", "~> 0.18.0")
33
+ s.add_dependency("thor", "~> 0.18")
34
34
  s.add_dependency("activesupport", ">= 3.1")
35
35
  s.add_dependency("rack-protection", ">= 1.5.0")
36
36
  end
@@ -0,0 +1,4 @@
1
+ begin
2
+ require '/tmp/padrino_class_demo'
3
+ rescue LoadError
4
+ end
@@ -0,0 +1,4 @@
1
+ begin
2
+ require '/tmp/padrino_instance_demo'
3
+ rescue LoadError
4
+ end
@@ -0,0 +1,7 @@
1
+ PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
2
+
3
+ class SystemClassMethodsDemo < Padrino::Application
4
+ set :reload, true
5
+ end
6
+
7
+ Padrino.load!
@@ -0,0 +1,7 @@
1
+ PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
2
+
3
+ class SystemInstanceMethodsDemo < Padrino::Application
4
+ set :reload, true
5
+ end
6
+
7
+ Padrino.load!
data/test/test_core.rb CHANGED
@@ -30,6 +30,7 @@ describe "Core" do
30
30
  end
31
31
 
32
32
  it 'should have load paths' do
33
+ skip
33
34
  assert_equal [Padrino.root('lib'), Padrino.root('models'), Padrino.root('shared')], Padrino.load_paths
34
35
  end
35
36
 
data/test/test_logger.rb CHANGED
@@ -2,9 +2,14 @@ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
2
  require 'logger'
3
3
 
4
4
  describe "PadrinoLogger" do
5
+ before do
6
+ @save_config = Padrino::Logger::Config[:test].dup
7
+ Padrino::Logger::Config[:test][:stream] = :null
8
+ Padrino::Logger.setup!
9
+ end
5
10
 
6
- def setup
7
- Padrino::Logger::Config[:test][:stream] = :null # The default
11
+ after do
12
+ Padrino::Logger::Config[:test] = @save_config
8
13
  Padrino::Logger.setup!
9
14
  end
10
15
 
@@ -14,9 +19,7 @@ describe "PadrinoLogger" do
14
19
  end
15
20
 
16
21
  describe 'for logger functionality' do
17
-
18
22
  describe 'check stream config' do
19
-
20
23
  it 'should use stdout if stream is nil' do
21
24
  Padrino::Logger::Config[:test][:stream] = nil
22
25
  Padrino::Logger.setup!
@@ -116,6 +119,7 @@ describe "PadrinoLogger" do
116
119
  access_to_mock_app
117
120
  assert_match /\e\[0;36m DEBUG\e\[0m/, Padrino.logger.log.string
118
121
  end
122
+
119
123
  it 'should not output over debug level' do
120
124
  Padrino.logger.instance_eval{ @level = Padrino::Logger::Levels[:info] }
121
125
  access_to_mock_app
@@ -141,13 +145,17 @@ describe "alternate logger" do
141
145
  end
142
146
  end
143
147
 
144
- def setup_logger
148
+ before do
149
+ @save_logger = Padrino.logger
145
150
  @log = StringIO.new
146
151
  Padrino.logger = FancyLogger.new(@log)
147
152
  end
148
153
 
154
+ after do
155
+ Padrino.logger = @save_logger
156
+ end
157
+
149
158
  it 'should annotate the logger to support additional Padrino fancyness' do
150
- setup_logger
151
159
  Padrino.logger.debug("Debug message")
152
160
  assert_match(/Debug message/, @log.string)
153
161
  Padrino.logger.exception(Exception.new 'scary message')
@@ -155,7 +163,6 @@ describe "alternate logger" do
155
163
  end
156
164
 
157
165
  it 'should colorize log output after colorize! is called' do
158
- setup_logger
159
166
  Padrino.logger.colorize!
160
167
 
161
168
  mock_app do
@@ -169,19 +176,22 @@ describe "alternate logger" do
169
176
  end
170
177
 
171
178
  describe "alternate logger: stdlib logger" do
172
- def setup_logger
179
+ before do
173
180
  @log = StringIO.new
181
+ @save_logger = Padrino.logger
174
182
  Padrino.logger = Logger.new(@log)
175
183
  end
176
184
 
185
+ after do
186
+ Padrino.logger = @save_logger
187
+ end
188
+
177
189
  it 'should annotate the logger to support additional Padrino fancyness' do
178
- setup_logger
179
190
  Padrino.logger.debug("Debug message")
180
191
  assert_match(/Debug message/, @log.string)
181
192
  end
182
193
 
183
194
  it 'should colorize log output after colorize! is called' do
184
- setup_logger
185
195
  Padrino.logger.colorize!
186
196
 
187
197
  mock_app do
@@ -202,7 +212,22 @@ describe "options :colorize_logging" do
202
212
  end
203
213
  get "/"
204
214
  end
215
+
216
+ before do
217
+ @save_config = Padrino::Logger::Config[:test].dup
218
+ end
219
+
220
+ after do
221
+ Padrino::Logger::Config[:test] = @save_config
222
+ Padrino::Logger.setup!
223
+ end
224
+
205
225
  describe 'default' do
226
+ before do
227
+ Padrino::Logger::Config[:test][:colorize_logging] = true
228
+ Padrino::Logger.setup!
229
+ end
230
+
206
231
  it 'should use colorize logging' do
207
232
  Padrino::Logger.setup!
208
233
 
@@ -210,11 +235,14 @@ describe "options :colorize_logging" do
210
235
  assert_match /\e\[1;9m200\e\[0m OK/, Padrino.logger.log.string
211
236
  end
212
237
  end
238
+
213
239
  describe 'set value is false' do
214
- it 'should not use colorize logging' do
240
+ before do
215
241
  Padrino::Logger::Config[:test][:colorize_logging] = false
216
242
  Padrino::Logger.setup!
243
+ end
217
244
 
245
+ it 'should not use colorize logging' do
218
246
  access_to_mock_app
219
247
  assert_match /200 OK/, Padrino.logger.log.string
220
248
  end
@@ -17,6 +17,7 @@ describe "SystemReloader" do
17
17
  end
18
18
 
19
19
  it 'should reload children on parent change' do
20
+ Padrino.mount(SystemDemo).to("/")
20
21
  assert_equal Child.new.family, 'Danes'
21
22
  parent_file = File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/models/parent.rb')
22
23
  new_class = <<-DOC
@@ -46,10 +47,11 @@ describe "SystemReloader" do
46
47
  end
47
48
 
48
49
  it 'should tamper with LOAD_PATH' do
50
+ skip
49
51
  SystemDemo.load_paths.each do |lib_dir|
50
52
  assert_includes $LOAD_PATH, lib_dir
51
53
  end
52
- Padrino.send(:load_paths_was).each do |lib_dir|
54
+ Padrino.send(:default_load_paths).each do |lib_dir|
53
55
  assert_includes $LOAD_PATH, lib_dir
54
56
  end
55
57
  end
@@ -64,4 +66,58 @@ describe "SystemReloader" do
64
66
  Padrino.reload!
65
67
  end
66
68
  end
69
+
70
+ describe 'reloading external constants' do
71
+ it 'should not touch external constants defining singleton methods' do
72
+ new_class = <<-DOC
73
+ class SingletonClassTest
74
+ def self.external_test
75
+ end
76
+ end
77
+ DOC
78
+ tmp_file = '/tmp/padrino_class_demo.rb'
79
+ begin
80
+ File.open(tmp_file, "w") { |f| f.write(new_class) }
81
+ Padrino.clear!
82
+ require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/system_class_methods_demo.rb')
83
+ @app = SystemClassMethodsDemo
84
+ Padrino.mount(SystemClassMethodsDemo).to("/")
85
+ get '/'
86
+ assert defined?(SingletonClassTest), 'SingletonClassTest undefined'
87
+ assert_includes SingletonClassTest.singleton_methods, :external_test
88
+ FileUtils.touch File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/helpers/class_methods_helpers.rb')
89
+ Padrino.reload!
90
+ assert defined?(SingletonClassTest), 'SingletonClassTest undefined'
91
+ assert_includes SingletonClassTest.singleton_methods, :external_test
92
+ ensure
93
+ FileUtils.rm tmp_file
94
+ end
95
+ end
96
+
97
+ it 'should not touch external constants defining instance methods' do
98
+ new_class = <<-DOC
99
+ class InstanceTest
100
+ def instance_test
101
+ end
102
+ end
103
+ DOC
104
+ tmp_file = '/tmp/padrino_instance_demo.rb'
105
+ begin
106
+ File.open(tmp_file, "w") { |f| f.write(new_class) }
107
+ Padrino.clear!
108
+ require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/system_instance_methods_demo.rb')
109
+ @app = SystemInstanceMethodsDemo
110
+ Padrino.mount(SystemInstanceMethodsDemo).to("/")
111
+ get '/'
112
+ assert defined?(InstanceTest), 'InstanceTest undefined'
113
+ assert_includes InstanceTest.new.methods, :instance_test
114
+ FileUtils.touch File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/helpers/instance_methods_helpers.rb')
115
+ Padrino.reload!
116
+ assert defined?(InstanceTest), 'InstanceTest undefined'
117
+ assert_includes InstanceTest.new.methods, :instance_test
118
+ ensure
119
+ FileUtils.rm tmp_file
120
+ end
121
+ end
122
+ end
67
123
  end
data/test/test_routing.rb CHANGED
@@ -228,6 +228,10 @@ describe "Routing" do
228
228
  get("/old-bar/:id"){ params[:id] }
229
229
  post(:mix, :map => "/mix-bar/:id"){ params[:id] }
230
230
  get(:mix, :map => "/mix-bar/:id"){ params[:id] }
231
+ get(:foo, '', :with => :id){ |id| "/#{id}" }
232
+ post(:foo, '', :with => :id){ |id| "/#{id}" }
233
+ delete(:drugs, :with => [:id, 'destroy']){ |id| "/drugs/#{id}/destroy" }
234
+ delete(:drugs, '', :with => [:id, 'destroy']){ |id| "/#{id}/destroy" }
231
235
  end
232
236
  get "/foo"
233
237
  assert_equal "/foo", body
@@ -251,6 +255,14 @@ describe "Routing" do
251
255
  assert_equal "4", body
252
256
  get "/mix-bar/4"
253
257
  assert_equal "4", body
258
+ get "/123"
259
+ assert_equal "/123", body
260
+ post "/123"
261
+ assert_equal "/123", body
262
+ delete "/drugs/123/destroy"
263
+ assert_equal "/drugs/123/destroy", body
264
+ delete "/123/destroy"
265
+ assert_equal "/123/destroy", body
254
266
  end
255
267
 
256
268
  it 'should generate url with format' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: padrino-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Padrino Team
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-05-12 00:00:00.000000000 Z
14
+ date: 2014-08-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: padrino-support
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - '='
21
21
  - !ruby/object:Gem::Version
22
- version: 0.12.2
22
+ version: 0.12.3
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.12.2
29
+ version: 0.12.3
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: sinatra
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -61,14 +61,14 @@ dependencies:
61
61
  requirements:
62
62
  - - ~>
63
63
  - !ruby/object:Gem::Version
64
- version: 0.18.0
64
+ version: '0.18'
65
65
  type: :runtime
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
69
  - - ~>
70
70
  - !ruby/object:Gem::Version
71
- version: 0.18.0
71
+ version: '0.18'
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: activesupport
74
74
  requirement: !ruby/object:Gem::Requirement
@@ -124,9 +124,13 @@ files:
124
124
  - lib/padrino-core/cli/adapter.rb
125
125
  - lib/padrino-core/cli/base.rb
126
126
  - lib/padrino-core/cli/console.rb
127
+ - lib/padrino-core/cli/launcher.rb
127
128
  - lib/padrino-core/cli/rake.rb
128
129
  - lib/padrino-core/cli/rake_tasks.rb
129
130
  - lib/padrino-core/command.rb
131
+ - lib/padrino-core/ext/http_router.rb
132
+ - lib/padrino-core/ext/sinatra.rb
133
+ - lib/padrino-core/filter.rb
130
134
  - lib/padrino-core/images/404.png
131
135
  - lib/padrino-core/images/500.png
132
136
  - lib/padrino-core/loader.rb
@@ -149,6 +153,8 @@ files:
149
153
  - test/fixtures/apps/complex.rb
150
154
  - test/fixtures/apps/demo_app.rb
151
155
  - test/fixtures/apps/demo_demo.rb
156
+ - test/fixtures/apps/helpers/class_methods_helpers.rb
157
+ - test/fixtures/apps/helpers/instance_methods_helpers.rb
152
158
  - test/fixtures/apps/helpers/support.rb
153
159
  - test/fixtures/apps/helpers/system_helpers.rb
154
160
  - test/fixtures/apps/kiq.rb
@@ -159,6 +165,8 @@ files:
159
165
  - test/fixtures/apps/simple.rb
160
166
  - test/fixtures/apps/static.rb
161
167
  - test/fixtures/apps/system.rb
168
+ - test/fixtures/apps/system_class_methods_demo.rb
169
+ - test/fixtures/apps/system_instance_methods_demo.rb
162
170
  - test/fixtures/dependencies/a.rb
163
171
  - test/fixtures/dependencies/b.rb
164
172
  - test/fixtures/dependencies/c.rb
@@ -217,6 +225,8 @@ test_files:
217
225
  - test/fixtures/apps/complex.rb
218
226
  - test/fixtures/apps/demo_app.rb
219
227
  - test/fixtures/apps/demo_demo.rb
228
+ - test/fixtures/apps/helpers/class_methods_helpers.rb
229
+ - test/fixtures/apps/helpers/instance_methods_helpers.rb
220
230
  - test/fixtures/apps/helpers/support.rb
221
231
  - test/fixtures/apps/helpers/system_helpers.rb
222
232
  - test/fixtures/apps/kiq.rb
@@ -227,6 +237,8 @@ test_files:
227
237
  - test/fixtures/apps/simple.rb
228
238
  - test/fixtures/apps/static.rb
229
239
  - test/fixtures/apps/system.rb
240
+ - test/fixtures/apps/system_class_methods_demo.rb
241
+ - test/fixtures/apps/system_instance_methods_demo.rb
230
242
  - test/fixtures/dependencies/a.rb
231
243
  - test/fixtures/dependencies/b.rb
232
244
  - test/fixtures/dependencies/c.rb