padrino-core 0.1.5 → 0.2.0
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.
- data/VERSION +1 -1
- data/lib/padrino-core.rb +3 -3
- data/lib/padrino-core/application.rb +28 -54
- data/lib/padrino-core/caller.rb +18 -12
- data/lib/padrino-core/loader.rb +43 -21
- data/lib/padrino-core/logger.rb +204 -0
- data/lib/padrino-core/mounter.rb +28 -10
- data/lib/padrino-core/reloader.rb +1 -1
- data/lib/padrino-core/stat.rb +12 -4
- data/lib/padrino-core/support_lite.rb +1 -0
- data/lib/padrino-core/support_lite/as_support.rb +1 -1
- data/lib/padrino-core/support_lite/extlib_support.rb +12 -0
- data/lib/padrino-core/tasks.rb +6 -5
- data/lib/padrino-core/tasks/console.rb +3 -3
- data/padrino-core.gemspec +9 -5
- data/test/fixtures/apps/complex.rb +29 -0
- data/test/fixtures/apps/simple.rb +23 -0
- data/test/helper.rb +29 -28
- data/test/test_application.rb +30 -0
- data/test/test_padrino_core.rb +1 -1
- data/test/test_padrino_mounter.rb +15 -8
- data/test/test_reloader_complex.rb +59 -0
- data/test/test_reloader_simple.rb +48 -0
- metadata +8 -4
- data/test/fixtures/apps/app.rb +0 -15
- data/test/fixtures/apps/multi.rb +0 -27
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/padrino-core.rb
CHANGED
@@ -13,17 +13,17 @@ module Padrino
|
|
13
13
|
# Padrino.root("config", "settings.yml")
|
14
14
|
# # returns PADRINO_ROOT + "/config/setting.yml"
|
15
15
|
def self.root(*args)
|
16
|
-
File.join(PADRINO_ROOT, *args)
|
16
|
+
File.expand_path(File.join(PADRINO_ROOT, *args))
|
17
17
|
end
|
18
18
|
|
19
19
|
# Helper method that return PADRINO_ENV
|
20
20
|
def self.env
|
21
|
-
PADRINO_ENV.to_s
|
21
|
+
PADRINO_ENV.to_s.downcase.to_sym
|
22
22
|
end
|
23
23
|
|
24
24
|
# Returns the resulting rack builder mapping each 'mounted' application
|
25
25
|
def self.application
|
26
|
-
raise ApplicationLoadError.new("At least one
|
26
|
+
raise ApplicationLoadError.new("At least one app must be mounted!") unless self.mounted_apps && self.mounted_apps.any?
|
27
27
|
builder = Rack::Builder.new
|
28
28
|
self.mounted_apps.each { |app| app.map_onto(builder) }
|
29
29
|
builder
|
@@ -4,18 +4,12 @@ module Padrino
|
|
4
4
|
# These subclassed applications can be easily mounted into other Padrino applications as well.
|
5
5
|
class Application < Sinatra::Application
|
6
6
|
|
7
|
-
def logger
|
8
|
-
@log_stream ||= self.class.log_to_file? ? Padrino.root("log/#{PADRINO_ENV.downcase}.log") : $stdout
|
9
|
-
@logger ||= Logger.new(@log_stream)
|
10
|
-
end
|
11
|
-
|
12
7
|
class << self
|
13
8
|
def inherited(subclass)
|
14
9
|
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
15
10
|
subclass.default_configuration!
|
16
11
|
super # Loading the subclass
|
17
12
|
subclass.register Padrino::Routing if defined?(Padrino::Routing)
|
18
|
-
subclass.check_single_app
|
19
13
|
end
|
20
14
|
|
21
15
|
# Hooks into when a new instance of the application is created
|
@@ -30,19 +24,21 @@ module Padrino
|
|
30
24
|
# Makes the routes defined in the block and in the Modules given
|
31
25
|
# in `extensions` available to the application
|
32
26
|
def controllers(*extensions, &block)
|
33
|
-
self.reset_routes! if reload?
|
34
27
|
instance_eval(&block) if block_given?
|
35
28
|
include(*extensions) if extensions.any?
|
36
29
|
end
|
37
30
|
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
31
|
+
# Reloads the application files from all defined load paths
|
32
|
+
def reload!
|
33
|
+
reset_routes! # remove all existing user-defined application routes
|
34
|
+
Padrino.load_dependency(self.app_file) # reload the app file
|
35
|
+
load_paths.each { |path| Padrino.load_dependencies(File.join(self.root, path)) }
|
43
36
|
end
|
44
37
|
|
45
|
-
|
38
|
+
# Resets application routes to only routes not defined by the user
|
39
|
+
def reset_routes!
|
40
|
+
@routes = Padrino::Application.dupe_routes
|
41
|
+
end
|
46
42
|
|
47
43
|
# Setup the application by registering initializers, load paths and logger
|
48
44
|
# Invoked automatically when an application is first instantiated
|
@@ -52,33 +48,28 @@ module Padrino
|
|
52
48
|
self.calculate_paths
|
53
49
|
self.register_initializers
|
54
50
|
self.require_load_paths
|
55
|
-
self.
|
51
|
+
self.disable :logging # We need do that as default because Sinatra use commonlogger.
|
56
52
|
@_configured = true
|
57
53
|
end
|
58
54
|
|
55
|
+
protected
|
56
|
+
|
59
57
|
# Defines default settings for Padrino application
|
60
58
|
def default_configuration!
|
61
59
|
# Overwriting Sinatra defaults
|
62
60
|
set :app_file, caller_files.first || $0 # Assume app file is first caller
|
63
61
|
set :environment, PADRINO_ENV.to_sym
|
64
62
|
set :raise_errors, true if development?
|
65
|
-
set :logging,
|
63
|
+
set :logging, false#!test?
|
66
64
|
set :sessions, true
|
67
|
-
set :log_to_file, !development?
|
68
|
-
set :reload, development?
|
69
65
|
# Padrino specific
|
66
|
+
set :reload, development?
|
70
67
|
set :app_name, self.to_s.underscore.to_sym
|
71
68
|
set :default_builder, 'StandardFormBuilder'
|
72
|
-
|
69
|
+
set :flash, defined?(Rack::Flash)
|
73
70
|
# Plugin specific
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
def check_single_app
|
79
|
-
@_single_app = File.identical?(self.app_file, Padrino.called_from.to_s)
|
80
|
-
single_message = "=> Instantiated #{File.basename(self.app_file)} in single app mode, reload is not available"
|
81
|
-
puts single_message if @_single_app && logging?
|
71
|
+
set :padrino_mailer, defined?(Padrino::Mailer)
|
72
|
+
set :padrino_helpers, defined?(Padrino::Helpers)
|
82
73
|
end
|
83
74
|
|
84
75
|
# Calculates any required paths after app_file and root have been properly configured
|
@@ -91,32 +82,23 @@ module Padrino
|
|
91
82
|
|
92
83
|
# Requires the middleware and initializer modules to configure components
|
93
84
|
def register_initializers
|
94
|
-
use
|
95
|
-
use
|
96
|
-
use
|
97
|
-
register DatabaseSetup
|
85
|
+
use Padrino::RackLogger
|
86
|
+
use Padrino::Reloader if reload?
|
87
|
+
use Rack::Flash if flash?
|
88
|
+
register DatabaseSetup if defined?(DatabaseSetup)
|
98
89
|
@initializer_path ||= Padrino.root + '/config/initializers/*.rb'
|
99
90
|
Dir[@initializer_path].each { |file| register_initializer(file) }
|
100
91
|
end
|
101
92
|
|
102
93
|
# Registers all desired padrino extension helpers/routing
|
103
94
|
def register_framework_extensions
|
104
|
-
register Padrino::Mailer if padrino_mailer?
|
105
|
-
register Padrino::Helpers if padrino_helpers?
|
95
|
+
register Padrino::Mailer if padrino_mailer?
|
96
|
+
register Padrino::Helpers if padrino_helpers?
|
106
97
|
end
|
107
98
|
|
108
|
-
#
|
99
|
+
# Requires all files within the application load paths
|
109
100
|
def require_load_paths
|
110
|
-
load_paths.each { |path| Padrino.
|
111
|
-
end
|
112
|
-
|
113
|
-
# Creates the log directory and redirects output to file if needed
|
114
|
-
def setup_logger
|
115
|
-
return unless logging? && log_to_file?
|
116
|
-
FileUtils.mkdir_p("#{Padrino.root}/log") unless File.exists?("#{Padrino.root}/log")
|
117
|
-
log = File.new("#{Padrino.root}/log/#{PADRINO_ENV.downcase}.log", "a+")
|
118
|
-
$stdout.reopen(log)
|
119
|
-
$stderr.reopen(log)
|
101
|
+
load_paths.each { |path| Padrino.require_dependencies(File.join(self.root, path)) }
|
120
102
|
end
|
121
103
|
|
122
104
|
# Returns the load_paths for the application (relative to the application root)
|
@@ -132,23 +114,15 @@ module Padrino
|
|
132
114
|
@view_paths.find { |path| Dir[File.join(path, '/**/*')].any? }
|
133
115
|
end
|
134
116
|
|
135
|
-
# Resets application routes for use in reloading the application
|
136
|
-
# This performs a basic routes reload (compatible with sinatra edge)
|
137
|
-
def reset_routes!
|
138
|
-
return if single_app? # Don't reset routes for single app
|
139
|
-
@routes = Padrino::Application.dupe_routes
|
140
|
-
load(self.app_file)
|
141
|
-
end
|
142
|
-
|
143
117
|
# Registers an initializer with the application
|
144
118
|
# register_initializer('/path/to/initializer')
|
145
119
|
def register_initializer(file_path)
|
146
|
-
Padrino.
|
120
|
+
Padrino.require_dependencies(file_path)
|
147
121
|
file_class = File.basename(file_path, '.rb').camelize
|
148
122
|
register "#{file_class}Initializer".constantize
|
149
123
|
rescue NameError => e
|
150
|
-
|
151
|
-
|
124
|
+
logger.error "The module '#{file_class}Initializer' (#{file_path}) didn't loaded properly!"
|
125
|
+
logger.error " Initializer error was '#{e.message}'"
|
152
126
|
end
|
153
127
|
end
|
154
128
|
end
|
data/lib/padrino-core/caller.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
module Padrino
|
2
2
|
PADRINO_IGNORE_CALLERS = [
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
%r{lib/padrino-.*$}, # all padrino code
|
4
|
+
%r{/padrino-.*/(lib|bin)}, # all padrino code
|
5
|
+
%r{/bin/padrino$}, # all padrino code
|
6
|
+
%r{/sinatra}, # all sinatra code
|
7
|
+
%r{lib/tilt.*\.rb$}, # all tilt code
|
8
|
+
%r{lib/rack.*\.rb$}, # all rack code
|
9
|
+
%r{lib/mongrel.*\.rb$}, # all mongrel code
|
10
|
+
%r{lib/shotgun.*\.rb$}, # all shotgun lib
|
11
|
+
%r{bin/shotgun$}, # shotgun binary
|
12
|
+
%r{\(.*\)}, # generated code
|
13
|
+
%r{shoulda/context\.rb$}, # shoulda hacks
|
14
|
+
%r{mocha/integration}, # mocha hacks
|
15
|
+
%r{test/unit}, # test unit hacks
|
16
|
+
%r{rake_test_loader\.rb}, # rake hacks
|
17
|
+
%r{custom_require\.rb$}, # rubygems require hacks
|
18
|
+
%r{active_support}, # active_support require hacks
|
19
|
+
%r{/thor}, # thor require hacks
|
20
|
+
] unless defined?(PADRINO_IGNORE_CALLERS)
|
15
21
|
|
16
22
|
# add rubinius (and hopefully other VM impls) ignore patterns ...
|
17
23
|
PADRINO_IGNORE_CALLERS.concat(RUBY_IGNORE_CALLERS) if defined?(RUBY_IGNORE_CALLERS)
|
data/lib/padrino-core/loader.rb
CHANGED
@@ -2,13 +2,20 @@ module Padrino
|
|
2
2
|
class << self
|
3
3
|
# Requires necessary dependencies as well as application files from root lib and models
|
4
4
|
def load!
|
5
|
-
return if loaded?
|
5
|
+
return false if loaded?
|
6
6
|
@_called_from = first_caller
|
7
7
|
load_required_gems # load bundler gems
|
8
|
-
|
9
|
-
|
10
|
-
reload! # We need to fill our Stat::CACHE but we do that only for development
|
11
|
-
|
8
|
+
require_dependencies("#{root}/config/apps.rb", "#{root}/config/database.rb") # load configuration
|
9
|
+
require_dependencies("#{root}/lib/**/*.rb", "#{root}/models/*.rb") # load root app dependencies
|
10
|
+
Stat.reload! # We need to fill our Stat::CACHE but we do that only for development
|
11
|
+
Thread.current[:padrino_loaded] = true
|
12
|
+
end
|
13
|
+
|
14
|
+
# Method for reloading required applications and their files
|
15
|
+
def reload!
|
16
|
+
return unless Stat.changed?
|
17
|
+
Stat.reload! # detects the modified files
|
18
|
+
Padrino.mounted_apps.each { |m| m.app_object.reload! } # finally we reload all files for each app
|
12
19
|
end
|
13
20
|
|
14
21
|
# This adds the ablity to instantiate Padrino.load! after Padrino::Application definition.
|
@@ -18,7 +25,7 @@ module Padrino
|
|
18
25
|
|
19
26
|
# Return true if Padrino was loaded with Padrino.load!
|
20
27
|
def loaded?
|
21
|
-
|
28
|
+
Thread.current[:padrino_loaded]
|
22
29
|
end
|
23
30
|
|
24
31
|
# Attempts to require all dependencies with bundler; if this fails, uses system wide gems
|
@@ -27,23 +34,33 @@ module Padrino
|
|
27
34
|
require_vendored_gems
|
28
35
|
end
|
29
36
|
|
30
|
-
# Attempts to
|
37
|
+
# Attempts to require all dependency libs that we need.
|
31
38
|
# If you use this method we can perform correctly a Padrino.reload!
|
32
39
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
|
40
|
+
# ==== Parameters
|
41
|
+
# paths:: Path where is necessary require a dependency
|
42
|
+
#
|
43
|
+
# Example:
|
44
|
+
# # For require all our app libs we need to do:
|
45
|
+
# require_dependencies("#{Padrino.root}/lib/**/*.rb")
|
46
|
+
def require_dependencies(*paths)
|
37
47
|
paths.each do |path|
|
38
48
|
Dir[path].each { |file| require(file) }
|
39
49
|
end
|
40
50
|
end
|
41
|
-
|
51
|
+
alias :require_dependency :require_dependencies
|
42
52
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
53
|
+
# Attempts to load all dependency libs that we need.
|
54
|
+
# If you use this method we can perform correctly a Padrino.reload!
|
55
|
+
#
|
56
|
+
# ==== Parameters
|
57
|
+
# paths:: Path where is necessary to load a dependency
|
58
|
+
def load_dependencies(*paths)
|
59
|
+
paths.each do |path|
|
60
|
+
Dir[path].each { |file| load(file) }
|
61
|
+
end
|
46
62
|
end
|
63
|
+
alias :load_dependency :load_dependencies
|
47
64
|
|
48
65
|
protected
|
49
66
|
|
@@ -57,17 +74,22 @@ module Padrino
|
|
57
74
|
say " ... Not Found"
|
58
75
|
end
|
59
76
|
|
60
|
-
#
|
77
|
+
# Require bundled gems if they exist
|
61
78
|
def require_vendored_gems
|
62
|
-
|
63
|
-
say " (Loading bundled gems)
|
79
|
+
require_dependencies(root('/../vendor', 'gems', PADRINO_ENV))
|
80
|
+
say! " (Loading bundled gems)"
|
64
81
|
rescue LoadError => e
|
65
|
-
say " (Loading system gems)
|
82
|
+
say! " (Loading system gems)"
|
66
83
|
end
|
67
84
|
|
68
85
|
# Prints out a message to the stdout if not in test environment
|
69
86
|
def say(text)
|
70
|
-
print text if Padrino.env !=
|
87
|
+
print text if Padrino.env != :test
|
88
|
+
end
|
89
|
+
|
90
|
+
# Puts out a message to the stdout if not in test environment
|
91
|
+
def say!(text)
|
92
|
+
puts text if Padrino.env != :test
|
71
93
|
end
|
72
94
|
end
|
73
|
-
end
|
95
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
module Padrino
|
2
|
+
|
3
|
+
# Setup a new logger
|
4
|
+
def self.setup_logger!
|
5
|
+
case Padrino.env
|
6
|
+
when :production
|
7
|
+
FileUtils.mkdir_p("#{Padrino.root}/log") unless File.exists?("#{Padrino.root}/log")
|
8
|
+
log = File.new("#{Padrino.root}/log/#{PADRINO_ENV.downcase}.log", "a+")
|
9
|
+
Thread.current[:padrino_logger] = Padrino::Logger.new(:log_level => :error, :stream => log)
|
10
|
+
when :development
|
11
|
+
Thread.current[:padrino_logger] = Padrino::Logger.new
|
12
|
+
when :test
|
13
|
+
Thread.current[:padrino_logger] = Padrino::Logger.new(:stream => StringIO.new)
|
14
|
+
end
|
15
|
+
Thread.current[:padrino_logger]
|
16
|
+
end
|
17
|
+
|
18
|
+
class Logger
|
19
|
+
|
20
|
+
attr_accessor :level
|
21
|
+
attr_accessor :auto_flush
|
22
|
+
attr_reader :buffer
|
23
|
+
attr_reader :log
|
24
|
+
attr_reader :init_args
|
25
|
+
|
26
|
+
# ==== Notes
|
27
|
+
# Ruby (standard) logger levels:
|
28
|
+
#
|
29
|
+
# :fatal:: An unhandleable error that results in a program crash
|
30
|
+
# :error:: A handleable error condition
|
31
|
+
# :warn:: A warning
|
32
|
+
# :info:: generic (useful) information about system operation
|
33
|
+
# :debug:: low-level information for developers
|
34
|
+
Levels = {
|
35
|
+
:fatal => 7,
|
36
|
+
:error => 6,
|
37
|
+
:warn => 4,
|
38
|
+
:info => 3,
|
39
|
+
:debug => 0
|
40
|
+
} unless const_defined?(:Levels)
|
41
|
+
|
42
|
+
@@mutex = {}
|
43
|
+
|
44
|
+
public
|
45
|
+
|
46
|
+
# To initialize the logger you create a new object, proxies to set_log.
|
47
|
+
#
|
48
|
+
# ==== Options can be:
|
49
|
+
#
|
50
|
+
# :stream:: Either an IO object or a name of a logfile. Defaults to $stdout
|
51
|
+
# :log_level::
|
52
|
+
# The log level from, e.g. :fatal or :info. Defaults to :debug in the
|
53
|
+
# production environment and :debug otherwise.
|
54
|
+
# :auto_flush::
|
55
|
+
# Whether the log should automatically flush after new messages are
|
56
|
+
# added. Defaults to true.
|
57
|
+
# :format_datetime:: Format of datetime. Defaults to: "%d/%b/%Y %H:%M:%S"
|
58
|
+
# :format_message:: Format of message. Defaults to: ""%s - - [%s] \"%s\"""
|
59
|
+
def initialize(options={})
|
60
|
+
@buffer = []
|
61
|
+
@auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true
|
62
|
+
@level = options[:log_level] ? Levels[options[:log_level]] : Levels[:debug]
|
63
|
+
@log = options[:stream] || $stdout
|
64
|
+
@log.sync = true
|
65
|
+
@mutex = @@mutex[@log] ||= Mutex.new
|
66
|
+
@format_datetime = options[:format_datetime] || "%d/%b/%Y %H:%M:%S"
|
67
|
+
@format_message = options[:format_message] || "%s - [%s] \"%s\""
|
68
|
+
end
|
69
|
+
|
70
|
+
# Flush the entire buffer to the log object.
|
71
|
+
def flush
|
72
|
+
return unless @buffer.size > 0
|
73
|
+
@mutex.synchronize do
|
74
|
+
@log.write(@buffer.slice!(0..-1).join(''))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Close and remove the current log object.
|
79
|
+
def close
|
80
|
+
flush
|
81
|
+
@log.close if @log.respond_to?(:close) && !@log.tty?
|
82
|
+
@log = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
# Appends a message to the log. The methods yield to an optional block and
|
86
|
+
# the output of this block will be appended to the message.
|
87
|
+
#
|
88
|
+
# ==== Parameters
|
89
|
+
# message:: The message to be logged. Defaults to nil.
|
90
|
+
#
|
91
|
+
# ==== Returns
|
92
|
+
# message:: The resulting message added to the log file.
|
93
|
+
def push(message = nil, level = nil)
|
94
|
+
self << @format_message % [level.to_s.upcase, Time.now.strftime(@format_datetime), message.to_s]
|
95
|
+
end
|
96
|
+
|
97
|
+
def <<(message = nil)
|
98
|
+
message << "\n" unless message[-1] == ?\n
|
99
|
+
@buffer << message
|
100
|
+
flush if @auto_flush
|
101
|
+
message
|
102
|
+
end
|
103
|
+
|
104
|
+
# Generate the logging methods for Padrino.logger for each log level.
|
105
|
+
Levels.each_pair do |name, number|
|
106
|
+
class_eval <<-LEVELMETHODS, __FILE__, __LINE__
|
107
|
+
|
108
|
+
# Appends a message to the log if the log level is at least as high as
|
109
|
+
# the log level of the logger.
|
110
|
+
#
|
111
|
+
# ==== Parameters
|
112
|
+
# message:: The message to be logged. Defaults to nil.
|
113
|
+
#
|
114
|
+
# ==== Returns
|
115
|
+
# self:: The logger object for chaining.
|
116
|
+
def #{name}(message = nil)
|
117
|
+
if #{number} >= level
|
118
|
+
message = block_given? ? yield : message
|
119
|
+
self.push(message, :#{name}) if #{number} >= level
|
120
|
+
end
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
# Appends a message to the log if the log level is at least as high as
|
125
|
+
# the log level of the logger. The bang! version of the method also auto
|
126
|
+
# flushes the log buffer to disk.
|
127
|
+
#
|
128
|
+
# ==== Parameters
|
129
|
+
# message:: The message to be logged. Defaults to nil.
|
130
|
+
#
|
131
|
+
# ==== Returns
|
132
|
+
# self:: The logger object for chaining.
|
133
|
+
def #{name}!(message = nil)
|
134
|
+
if #{number} >= level
|
135
|
+
message = block_given? ? yield : message
|
136
|
+
self.push(message, :#{name}) if #{number} >= level
|
137
|
+
flush if #{number} >= level
|
138
|
+
end
|
139
|
+
self
|
140
|
+
end
|
141
|
+
|
142
|
+
# ==== Returns
|
143
|
+
# Boolean:: True if this level will be logged by this logger.
|
144
|
+
def #{name}?
|
145
|
+
#{number} >= level
|
146
|
+
end
|
147
|
+
LEVELMETHODS
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
# RackLogger forwards every request to an +app+ given, and
|
153
|
+
# logs a line in the Apache common log format to the +logger+, or
|
154
|
+
# rack.errors by default.
|
155
|
+
class RackLogger
|
156
|
+
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
157
|
+
# "lilith.local - - GET / HTTP/1.1 500 -"
|
158
|
+
# %{%s - %s %s %s%s %s - %d %s %0.4f}
|
159
|
+
FORMAT = %{%s - %s %s %s%s %s - %d %s %0.4f}
|
160
|
+
|
161
|
+
def initialize(app)
|
162
|
+
@app = app
|
163
|
+
end
|
164
|
+
|
165
|
+
def call(env)
|
166
|
+
began_at = Time.now
|
167
|
+
status, header, body = @app.call(env)
|
168
|
+
log(env, status, header, began_at)
|
169
|
+
[status, header, body]
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
def log(env, status, header, began_at)
|
175
|
+
now = Time.now
|
176
|
+
length = extract_content_length(header)
|
177
|
+
|
178
|
+
logger.debug FORMAT % [
|
179
|
+
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
|
180
|
+
env["REMOTE_USER"] || "-",
|
181
|
+
env["REQUEST_METHOD"],
|
182
|
+
env["PATH_INFO"],
|
183
|
+
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
|
184
|
+
env["HTTP_VERSION"],
|
185
|
+
status.to_s[0..3],
|
186
|
+
length,
|
187
|
+
now - began_at ]
|
188
|
+
end
|
189
|
+
|
190
|
+
def extract_content_length(headers)
|
191
|
+
headers.each do |key, value|
|
192
|
+
if key.downcase == 'content-length'
|
193
|
+
return value.to_s == '0' ? '-' : value
|
194
|
+
end
|
195
|
+
end
|
196
|
+
'-'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# Define a logger available every where in our app
|
202
|
+
def logger
|
203
|
+
Thread.current[:padrino_logger] ||= Padrino::setup_logger!
|
204
|
+
end
|
data/lib/padrino-core/mounter.rb
CHANGED
@@ -4,19 +4,21 @@ module Padrino
|
|
4
4
|
# @example Mounter.new("blog_app", :app_class => "Blog").to("/blog")
|
5
5
|
# @example Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog")
|
6
6
|
class Mounter
|
7
|
-
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root
|
7
|
+
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj
|
8
|
+
|
8
9
|
def initialize(name, options={})
|
9
10
|
@name = name.downcase
|
10
11
|
@app_class = options[:app_class] || name.classify
|
11
12
|
@app_file = options[:app_file] || locate_app_file
|
12
13
|
@app_root = options[:app_root]
|
14
|
+
@app_obj = self.app_object
|
13
15
|
end
|
14
16
|
|
15
17
|
# Registers the mounted application onto Padrino
|
16
18
|
# @example Mounter.new("blog_app").to("/blog")
|
17
19
|
def to(mount_url)
|
18
|
-
@uri_root
|
19
|
-
Padrino.
|
20
|
+
@uri_root = mount_url
|
21
|
+
Padrino.insert_mounted_app(self)
|
20
22
|
self
|
21
23
|
end
|
22
24
|
|
@@ -24,22 +26,32 @@ module Padrino
|
|
24
26
|
# For use in constructing a Rack application
|
25
27
|
# @example @app.map_onto(@builder)
|
26
28
|
def map_onto(builder)
|
27
|
-
|
28
|
-
app_data, app_class = self, self.app_class.constantize
|
29
|
+
app_data, app_obj = self, @app_obj
|
29
30
|
builder.map self.uri_root do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
run
|
31
|
+
app_obj.set :uri_root, app_data.uri_root
|
32
|
+
app_obj.set :app_name, app_data.name
|
33
|
+
app_obj.set :app_file, app_data.app_file unless File.exist?(app_obj.app_file)
|
34
|
+
app_obj.set :root, app_data.app_root unless app_data.app_root.blank?
|
35
|
+
run app_obj
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
39
|
+
# Return the class for the app
|
40
|
+
def app_object
|
41
|
+
app_class.constantize rescue Padrino.require_dependency(app_file)
|
42
|
+
app_class.constantize
|
43
|
+
end
|
44
|
+
|
38
45
|
# Returns the determined location of the mounted application main file
|
39
46
|
def locate_app_file
|
40
47
|
callers_are_identical = File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
|
41
48
|
callers_are_identical ? Padrino.first_caller : Padrino.mounted_root(name, "app.rb")
|
42
49
|
end
|
50
|
+
|
51
|
+
# Makes two Mounters equal if they have the same name and uri_root
|
52
|
+
def ==(other)
|
53
|
+
other.is_a?(Mounter) && self.name == other.name && self.uri_root == other.uri_root
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
class << self
|
@@ -55,6 +67,12 @@ module Padrino
|
|
55
67
|
@mounted_apps ||= []
|
56
68
|
end
|
57
69
|
|
70
|
+
# Inserts a Mounter object into the mounted applications (avoids duplicates)
|
71
|
+
def insert_mounted_app(mounter)
|
72
|
+
return false if Padrino.mounted_apps.include?(mounter)
|
73
|
+
Padrino.mounted_apps << mounter
|
74
|
+
end
|
75
|
+
|
58
76
|
# Mounts the core application onto Padrino project with given app settings (file, class, root)
|
59
77
|
# @example Padrino.mount_core("Blog")
|
60
78
|
# @example Padrino.mount_core(:app_file => "/path/to/file", :app_class => "Blog")
|
@@ -7,7 +7,7 @@ module Padrino
|
|
7
7
|
# also respects a cool down time, during which nothing will be done.
|
8
8
|
class Reloader
|
9
9
|
|
10
|
-
def initialize(app, cooldown = 1
|
10
|
+
def initialize(app, cooldown = 1)
|
11
11
|
@app = app
|
12
12
|
@cooldown = cooldown
|
13
13
|
@last = (Time.now - cooldown)
|
data/lib/padrino-core/stat.rb
CHANGED
@@ -17,9 +17,18 @@ module Padrino
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def changed?
|
21
|
+
changed = false
|
22
|
+
rotation do |file, mtime|
|
23
|
+
previous_mtime = MTIMES[file] ||= mtime
|
24
|
+
changed = true if mtime > MTIMES[file]
|
25
|
+
end
|
26
|
+
changed
|
27
|
+
end
|
28
|
+
|
20
29
|
# A safe Kernel::load, issuing the hooks depending on the results
|
21
30
|
def safe_load(file, mtime)
|
22
|
-
|
31
|
+
Padrino.say! "=> Reloading #{file}"
|
23
32
|
load(file)
|
24
33
|
file
|
25
34
|
rescue LoadError, SyntaxError => ex
|
@@ -32,9 +41,8 @@ module Padrino
|
|
32
41
|
files = [$0, *$LOADED_FEATURES].uniq
|
33
42
|
paths = ['./', *$LOAD_PATH].uniq
|
34
43
|
|
35
|
-
files.map{|file|
|
36
|
-
next if file =~ /\.(so|bundle)$/
|
37
|
-
|
44
|
+
files.map{ |file|
|
45
|
+
next if file =~ /\.(so|bundle)$/ # cannot reload compiled files
|
38
46
|
found, stat = figure_path(file, paths)
|
39
47
|
next unless found && stat && mtime = stat.mtime
|
40
48
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Class#cattr_accessor
|
4
4
|
require 'active_support/core_ext/class/attribute_accessors' unless Class.method_defined?(:cattr_accessor)
|
5
|
-
## Hash#symbolize_keys, Hash#reverse_merge, Hash#reverse_merge!, Hash#extract_options!
|
5
|
+
## Hash#symbolize_keys, Hash#reverse_merge, Hash#reverse_merge!, Hash#extract_options!, Hash#slice!
|
6
6
|
require 'active_support/core_ext/hash' unless Hash.method_defined?(:reverse_merge)
|
7
7
|
## String#inflectors
|
8
8
|
require 'active_support/inflector' unless String.method_defined?(:constantize)
|
@@ -24,6 +24,18 @@ unless Hash.method_defined?(:symbolize_keys)
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
## Hash#slice, Hash#slice!
|
28
|
+
unless Hash.method_defined?(:slice)
|
29
|
+
require 'extlib/hash'
|
30
|
+
class Hash
|
31
|
+
def slice(*keys)
|
32
|
+
keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
33
|
+
hash = self.class.new
|
34
|
+
keys.each { |k| hash[k] = self[k] if has_key?(k) }
|
35
|
+
hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
27
39
|
|
28
40
|
## Hash#reverse_merge, Hash#reverse_merge!
|
29
41
|
unless Hash.method_defined?(:present?)
|
data/lib/padrino-core/tasks.rb
CHANGED
@@ -16,6 +16,7 @@ module Padrino
|
|
16
16
|
method_option :port, :type => :numeric, :aliases => "-p", :required => true, :default => 3000
|
17
17
|
method_option :boot, :type => :string, :aliases => "-b", :required => true, :default => "config/boot.rb"
|
18
18
|
method_option :daemonize, :type => :boolean, :aliases => "-d"
|
19
|
+
|
19
20
|
def start
|
20
21
|
require File.dirname(__FILE__) + "/tasks/adapter"
|
21
22
|
chdir(options.chdir)
|
@@ -47,11 +48,11 @@ module Padrino
|
|
47
48
|
end
|
48
49
|
ENV["PADRINO_ENV"] ||= environment
|
49
50
|
puts "=> Loading #{environment} console (Padrino v.#{Padrino.version})"
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
require 'irb'
|
52
|
+
require "irb/completion"
|
53
|
+
require boot
|
54
|
+
require File.dirname(__FILE__) + '/tasks/console'
|
55
|
+
IRB.start
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# Reloads classes
|
2
2
|
def reload!
|
3
3
|
Padrino.reload!
|
4
|
-
true
|
5
4
|
end
|
6
5
|
|
7
6
|
# Show applications
|
@@ -17,5 +16,6 @@ end
|
|
17
16
|
# Load apps
|
18
17
|
Padrino.mounted_apps.each do |app|
|
19
18
|
puts "=> Loading Application #{app.name}"
|
20
|
-
Padrino.
|
21
|
-
|
19
|
+
Padrino.require_dependency(app.app_file)
|
20
|
+
app.app_object.setup_application!
|
21
|
+
end
|
data/padrino-core.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{padrino-core}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-24}
|
13
13
|
s.default_executable = %q{padrino}
|
14
14
|
s.description = %q{The Padrino core gem required for use of this framework}
|
15
15
|
s.email = %q{nesquena@gmail.com}
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
"lib/padrino-core/application.rb",
|
30
30
|
"lib/padrino-core/caller.rb",
|
31
31
|
"lib/padrino-core/loader.rb",
|
32
|
+
"lib/padrino-core/logger.rb",
|
32
33
|
"lib/padrino-core/mounter.rb",
|
33
34
|
"lib/padrino-core/reloader.rb",
|
34
35
|
"lib/padrino-core/stat.rb",
|
@@ -44,11 +45,14 @@ Gem::Specification.new do |s|
|
|
44
45
|
"padrino-core.gemspec",
|
45
46
|
"test/fixtures/apps/.components",
|
46
47
|
"test/fixtures/apps/.gitignore",
|
47
|
-
"test/fixtures/apps/
|
48
|
-
"test/fixtures/apps/
|
48
|
+
"test/fixtures/apps/complex.rb",
|
49
|
+
"test/fixtures/apps/simple.rb",
|
49
50
|
"test/helper.rb",
|
51
|
+
"test/test_application.rb",
|
50
52
|
"test/test_padrino_core.rb",
|
51
|
-
"test/test_padrino_mounter.rb"
|
53
|
+
"test/test_padrino_mounter.rb",
|
54
|
+
"test/test_reloader_complex.rb",
|
55
|
+
"test/test_reloader_simple.rb"
|
52
56
|
]
|
53
57
|
s.homepage = %q{http://github.com/padrino/padrino-framework/tree/master/padrino-core}
|
54
58
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -0,0 +1,29 @@
|
|
1
|
+
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
2
|
+
|
3
|
+
module LibDemo
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def give_me_a_random
|
7
|
+
@rand ||= rand(100)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Complex1Demo < Padrino::Application
|
12
|
+
set :reload, true
|
13
|
+
get("/old"){ "Old Sinatra Way" }
|
14
|
+
end
|
15
|
+
|
16
|
+
class Complex2Demo < Padrino::Application
|
17
|
+
set :reload, true
|
18
|
+
get("/old"){ "Old Sinatra Way" }
|
19
|
+
end
|
20
|
+
|
21
|
+
Complex1Demo.controllers do
|
22
|
+
get(""){ "Given random #{LibDemo.give_me_a_random}" }
|
23
|
+
end
|
24
|
+
|
25
|
+
Complex2Demo.controllers do
|
26
|
+
get(""){ "The magick number is: 88!" } # Change only the number!!!
|
27
|
+
end
|
28
|
+
|
29
|
+
Padrino.load!
|
@@ -0,0 +1,23 @@
|
|
1
|
+
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
2
|
+
# Remove this comment if you want do some like this: ruby PADRINO_ENV=test app.rb
|
3
|
+
#
|
4
|
+
# require 'rubygems'
|
5
|
+
# require 'lib/padrino-core'
|
6
|
+
#
|
7
|
+
# Use this for prevent (when reload is in use) to re run the server.
|
8
|
+
#
|
9
|
+
# if Padrino.load!
|
10
|
+
# SingleDemo.run!
|
11
|
+
# end
|
12
|
+
|
13
|
+
class SimpleDemo < Padrino::Application
|
14
|
+
set :reload, true
|
15
|
+
end
|
16
|
+
|
17
|
+
SimpleDemo.controllers do
|
18
|
+
get "/" do
|
19
|
+
'The magick number is: 66!' # Change only the number!!!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Padrino.load! # Remove this if you will run the app standalone
|
data/test/helper.rb
CHANGED
@@ -7,19 +7,17 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
7
7
|
require 'rubygems'
|
8
8
|
require 'padrino-core'
|
9
9
|
require 'test/unit'
|
10
|
-
require 'shoulda'
|
11
|
-
require 'mocha'
|
12
10
|
require 'rack/test'
|
13
|
-
require '
|
11
|
+
require 'rack'
|
12
|
+
require 'shoulda'
|
13
|
+
|
14
|
+
class Padrino::Application
|
15
|
+
# Allow assertions in request context
|
16
|
+
include Test::Unit::Assertions
|
17
|
+
end
|
14
18
|
|
15
19
|
class Test::Unit::TestCase
|
16
20
|
include Rack::Test::Methods
|
17
|
-
include Webrat::Methods
|
18
|
-
include Webrat::Matchers
|
19
|
-
|
20
|
-
Webrat.configure do |config|
|
21
|
-
config.mode = :rack
|
22
|
-
end
|
23
21
|
|
24
22
|
# Test App
|
25
23
|
class PadrinoTestApp < Padrino::Application; end
|
@@ -46,24 +44,27 @@ class Test::Unit::TestCase
|
|
46
44
|
assert File.exist?(file), "File '#{file}' does not exist!"
|
47
45
|
assert_match pattern, File.read(file)
|
48
46
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
$stdout = log_buffer = StringIO.new
|
57
|
-
block.call
|
58
|
-
$stdout = orig_stdout
|
59
|
-
log_buffer.rewind && log_buffer.read
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
module Webrat
|
64
|
-
module Logging
|
65
|
-
def logger # :nodoc:
|
66
|
-
@logger = nil
|
47
|
+
|
48
|
+
# Delegate other missing methods to response.
|
49
|
+
def method_missing(name, *args, &block)
|
50
|
+
if response && response.respond_to?(name)
|
51
|
+
response.send(name, *args, &block)
|
52
|
+
else
|
53
|
+
super
|
67
54
|
end
|
68
55
|
end
|
69
|
-
|
56
|
+
|
57
|
+
alias :response :last_response
|
58
|
+
end
|
59
|
+
#
|
60
|
+
# class Object
|
61
|
+
# # Silences the output by redirecting to stringIO
|
62
|
+
# # silence_logger { ...commands... } => "...output..."
|
63
|
+
# def silence_logger(&block)
|
64
|
+
# orig_stdout = $stdout
|
65
|
+
# $stdout = log_buffer = StringIO.new
|
66
|
+
# block.call
|
67
|
+
# $stdout = orig_stdout
|
68
|
+
# log_buffer.rewind && log_buffer.read
|
69
|
+
# end
|
70
|
+
# end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestApplication < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context 'for application functionality' do
|
6
|
+
|
7
|
+
should 'check default options' do
|
8
|
+
assert_match %r{test/helper.rb}, PadrinoTestApp.app_file
|
9
|
+
assert_equal :test, PadrinoTestApp.environment
|
10
|
+
assert_equal Padrino.root("views"), PadrinoTestApp.views
|
11
|
+
assert PadrinoTestApp.raise_errors
|
12
|
+
assert !PadrinoTestApp.logging
|
13
|
+
assert PadrinoTestApp.sessions
|
14
|
+
assert 'PadrinoTestApp', PadrinoTestApp.app_name
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'check padrino specific options' do
|
18
|
+
assert !PadrinoTestApp.instance_variable_get(:@_configured)
|
19
|
+
PadrinoTestApp.send(:setup_application!)
|
20
|
+
assert PadrinoTestApp.instance_variable_get(:@_configured)
|
21
|
+
assert !PadrinoTestApp.send(:find_view_path)
|
22
|
+
assert !PadrinoTestApp.reload?
|
23
|
+
assert 'padrino_test_app', PadrinoTestApp.app_name
|
24
|
+
assert 'StandardFormBuilder', PadrinoTestApp.default_builder
|
25
|
+
assert !PadrinoTestApp.flash
|
26
|
+
assert !PadrinoTestApp.padrino_mailer
|
27
|
+
assert !PadrinoTestApp.padrino_helpers
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/test/test_padrino_core.rb
CHANGED
@@ -27,15 +27,15 @@ class TestPadrinoMounter < Test::Unit::TestCase
|
|
27
27
|
mounter.to("/test")
|
28
28
|
assert_equal "test", mounter.name
|
29
29
|
assert_equal "Test", mounter.app_class
|
30
|
-
|
30
|
+
assert_match %r{test/apps/test/app.rb}, mounter.app_file
|
31
31
|
assert_equal "/test", mounter.uri_root
|
32
32
|
assert_nil mounter.app_root
|
33
33
|
end
|
34
34
|
|
35
35
|
should 'mount an app' do
|
36
|
-
class AnApp < Padrino::Application; end
|
37
|
-
|
36
|
+
class ::AnApp < Padrino::Application; end
|
38
37
|
Padrino.mount_core("an_app")
|
38
|
+
assert_equal AnApp, Padrino.mounted_apps.first.app_obj
|
39
39
|
assert_equal ["core"], Padrino.mounted_apps.collect(&:name)
|
40
40
|
end
|
41
41
|
|
@@ -43,18 +43,25 @@ class TestPadrinoMounter < Test::Unit::TestCase
|
|
43
43
|
mounter = Padrino.mount_core("test")
|
44
44
|
assert_equal "core", mounter.name
|
45
45
|
assert_equal "Test", mounter.app_class
|
46
|
+
assert_equal Test, mounter.app_obj
|
46
47
|
assert_equal Padrino.root('app/app.rb'), mounter.app_file
|
47
48
|
assert_equal "/", mounter.uri_root
|
48
49
|
assert_equal Padrino.root, mounter.app_root
|
49
50
|
end
|
50
51
|
|
51
52
|
should 'mount multiple apps' do
|
52
|
-
class OneApp < Padrino::Application; end
|
53
|
-
class TwoApp < Padrino::Application; end
|
53
|
+
class ::OneApp < Padrino::Application; end
|
54
|
+
class ::TwoApp < Padrino::Application; end
|
54
55
|
|
56
|
+
Padrino.mount("one_app").to("/one_app")
|
57
|
+
Padrino.mount("two_app").to("/two_app")
|
58
|
+
# And testing no duplicates
|
55
59
|
Padrino.mount("one_app").to("/one_app")
|
56
60
|
Padrino.mount("two_app").to("/two_app")
|
57
61
|
|
62
|
+
assert_equal OneApp, Padrino.mounted_apps[0].app_obj
|
63
|
+
assert_equal TwoApp, Padrino.mounted_apps[1].app_obj
|
64
|
+
assert_equal 2, Padrino.mounted_apps.size, "should not mount duplicate apps"
|
58
65
|
assert_equal ["one_app", "two_app"], Padrino.mounted_apps.collect(&:name)
|
59
66
|
end
|
60
67
|
|
@@ -74,9 +81,9 @@ class TestPadrinoMounter < Test::Unit::TestCase
|
|
74
81
|
end
|
75
82
|
|
76
83
|
get '/demo_1'
|
77
|
-
|
78
|
-
|
79
|
-
|
84
|
+
assert_equal "Im Demo 1", body
|
85
|
+
get '/demo_2'
|
86
|
+
assert_equal "Im Demo 2", body
|
80
87
|
end
|
81
88
|
end
|
82
89
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
require 'fixtures/apps/complex'
|
3
|
+
|
4
|
+
class TestComplexReloader < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context 'for complex reload functionality' do
|
7
|
+
|
8
|
+
should 'correctly instantiate Complex(1-2)Demo fixture' do
|
9
|
+
Padrino.mounted_apps.clear
|
10
|
+
Padrino.mount("complex_1_demo").to("/complex_1_demo")
|
11
|
+
Padrino.mount("complex_2_demo").to("/complex_2_demo")
|
12
|
+
assert_equal ["complex_1_demo", "complex_2_demo"], Padrino.mounted_apps.collect(&:name)
|
13
|
+
assert Complex1Demo.reload?
|
14
|
+
assert Complex2Demo.reload?
|
15
|
+
assert_match %r{fixtures/apps/complex.rb}, Complex1Demo.app_file
|
16
|
+
assert_match %r{fixtures/apps/complex.rb}, Complex2Demo.app_file
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'correctly reload Complex(1-2)Demo fixture' do
|
20
|
+
assert_match %r{fixtures/apps/complex.rb}, Complex1Demo.app_file
|
21
|
+
@app = Padrino.application
|
22
|
+
|
23
|
+
get "/"
|
24
|
+
assert_equal 404, status
|
25
|
+
|
26
|
+
get "/complex_1_demo"
|
27
|
+
assert_equal "Given random #{LibDemo.give_me_a_random}", body
|
28
|
+
|
29
|
+
get "/complex_2_demo"
|
30
|
+
assert_equal 200, status
|
31
|
+
|
32
|
+
get "/complex_1_demo/old"
|
33
|
+
assert_equal 200, status
|
34
|
+
|
35
|
+
get "/complex_2_demo/old"
|
36
|
+
assert_equal 200, status
|
37
|
+
|
38
|
+
new_phrase = "The magick number is: #{rand(100)}!"
|
39
|
+
buffer = File.read(Complex1Demo.app_file).gsub!(/The magick number is: \d+!/, new_phrase)
|
40
|
+
File.open(Complex1Demo.app_file, "w") { |f| f.write(buffer) }
|
41
|
+
sleep 1.2 # We need at least a cooldown of 1 sec.
|
42
|
+
get "/complex_2_demo"
|
43
|
+
assert_equal new_phrase, body
|
44
|
+
|
45
|
+
# Re-Check that we didn't forget any route
|
46
|
+
get "/complex_1_demo"
|
47
|
+
assert_equal "Given random #{LibDemo.give_me_a_random}", body
|
48
|
+
|
49
|
+
get "/complex_2_demo"
|
50
|
+
assert_equal 200, status
|
51
|
+
|
52
|
+
get "/complex_1_demo/old"
|
53
|
+
assert_equal 200, status
|
54
|
+
|
55
|
+
get "/complex_2_demo/old"
|
56
|
+
assert_equal 200, status
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
require 'fixtures/apps/simple'
|
3
|
+
|
4
|
+
class TestSimpleReloader < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context 'for simple reset functionality' do
|
7
|
+
|
8
|
+
should 'reset routes' do
|
9
|
+
mock_app do
|
10
|
+
1.step(10).each do |i|
|
11
|
+
get("/#{i}") { "Foo #{i}" }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
1.step(10).each do |i|
|
15
|
+
get "/#{i}"
|
16
|
+
assert_equal "Foo #{i}", body
|
17
|
+
end
|
18
|
+
@app.reset_routes!
|
19
|
+
1.step(10).each do |i|
|
20
|
+
get "/#{i}"
|
21
|
+
assert_equal 404, status
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'for simple reload functionality' do
|
27
|
+
|
28
|
+
should 'correctly instantiate SimpleDemo fixture' do
|
29
|
+
Padrino.mounted_apps.clear
|
30
|
+
Padrino.mount_core("simple_demo")
|
31
|
+
assert_equal ["core"], Padrino.mounted_apps.collect(&:name)
|
32
|
+
assert SimpleDemo.reload?
|
33
|
+
assert_match %r{fixtures/apps/simple.rb}, SimpleDemo.app_file
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'correctly reload SimpleDemo fixture' do
|
37
|
+
@app = SimpleDemo
|
38
|
+
get "/"
|
39
|
+
assert_equal 200, status
|
40
|
+
new_phrase = "The magick number is: #{rand(100)}!"
|
41
|
+
buffer = File.read(SimpleDemo.app_file).gsub!(/The magick number is: \d+!/, new_phrase)
|
42
|
+
File.open(SimpleDemo.app_file, "w") { |f| f.write(buffer) }
|
43
|
+
sleep 1.2 # We need at least a cooldown of 1 sec.
|
44
|
+
get "/"
|
45
|
+
assert_equal new_phrase, body
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Padrino Team
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2009-11-
|
15
|
+
date: 2009-11-24 00:00:00 -08:00
|
16
16
|
default_executable: padrino
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/padrino-core/application.rb
|
116
116
|
- lib/padrino-core/caller.rb
|
117
117
|
- lib/padrino-core/loader.rb
|
118
|
+
- lib/padrino-core/logger.rb
|
118
119
|
- lib/padrino-core/mounter.rb
|
119
120
|
- lib/padrino-core/reloader.rb
|
120
121
|
- lib/padrino-core/stat.rb
|
@@ -130,11 +131,14 @@ files:
|
|
130
131
|
- padrino-core.gemspec
|
131
132
|
- test/fixtures/apps/.components
|
132
133
|
- test/fixtures/apps/.gitignore
|
133
|
-
- test/fixtures/apps/
|
134
|
-
- test/fixtures/apps/
|
134
|
+
- test/fixtures/apps/complex.rb
|
135
|
+
- test/fixtures/apps/simple.rb
|
135
136
|
- test/helper.rb
|
137
|
+
- test/test_application.rb
|
136
138
|
- test/test_padrino_core.rb
|
137
139
|
- test/test_padrino_mounter.rb
|
140
|
+
- test/test_reloader_complex.rb
|
141
|
+
- test/test_reloader_simple.rb
|
138
142
|
has_rdoc: true
|
139
143
|
homepage: http://github.com/padrino/padrino-framework/tree/master/padrino-core
|
140
144
|
licenses: []
|
data/test/fixtures/apps/app.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
2
|
-
require 'rubygems'
|
3
|
-
require 'sinatra/base'
|
4
|
-
require 'lib/padrino-core'
|
5
|
-
|
6
|
-
class SingleDemo < Padrino::Application; end
|
7
|
-
|
8
|
-
SingleDemo.controllers do
|
9
|
-
get "/test" do
|
10
|
-
'This should work'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
Padrino.mount_core("single_demo")
|
15
|
-
Padrino.load!
|
data/test/fixtures/apps/multi.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
2
|
-
require 'sinatra/base'
|
3
|
-
require 'padrino-core'
|
4
|
-
|
5
|
-
class Multi1Demo < Padrino::Application
|
6
|
-
disable :padrino_routing
|
7
|
-
disable :padrino_mailer
|
8
|
-
disable :padrino_helpers
|
9
|
-
|
10
|
-
get "" do
|
11
|
-
"Im Core1Demo"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class Mutli2Demo < Padrino::Application
|
16
|
-
disable :padrino_routing
|
17
|
-
disable :padrino_mailer
|
18
|
-
disable :padrino_helpers
|
19
|
-
|
20
|
-
get "" do
|
21
|
-
"Im Core2Demo"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
Padrino.mount("multi_1_demo").to("/multi_1_demo")
|
26
|
-
Padrino.mount("multi_2_demo").to("/multi_2_demo")
|
27
|
-
Padrino.load!
|