padrino-core 0.9.28 → 0.9.29

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,4 @@
1
1
  module Padrino
2
-
3
2
  ##
4
3
  # Run the Padrino apps as a self-hosted server using:
5
4
  # thin, mongrel, webrick in that order.
@@ -11,64 +10,61 @@ module Padrino
11
10
  #
12
11
  def self.run!(options={})
13
12
  Padrino.load!
14
- Server.build(options)
13
+ Server.start(Padrino.application, options)
15
14
  end
16
15
 
17
16
  ##
18
17
  # This module build a Padrino server
19
18
  #
20
- module Server
21
-
22
- class LoadError < RuntimeError; end
23
-
24
- Handlers = %w[thin mongrel webrick] unless const_defined?(:Handlers)
19
+ class Server < Rack::Server
20
+ # Server Handlers
21
+ Handlers = [:thin, :mongrel, :webrick]
25
22
 
26
- private
27
- def self.build(options={})
28
- host = options[:host] || "localhost"
29
- port = options[:port] || 3000
30
- adapter = options[:adapter]
23
+ def self.start(app, opts={})
24
+ options = {}.merge(opts) # We use a standard hash instead of Thor::CoreExt::HashWithIndifferentAccess
25
+ options.symbolize_keys!
26
+ options[:Host] = options.delete(:host)
27
+ options[:Port] = options.delete(:port)
28
+ options[:AccessLog] = []
29
+ if options[:daemonize]
30
+ options[:pid] = options[:pid].blank? ? File.expand_path('tmp/pids/server.pid') : opts[:pid]
31
+ FileUtils.mkdir_p(File.dirname(options[:pid]))
32
+ end
33
+ options[:server] = detect_rack_handler if options[:server].blank?
34
+ new(options, app).start
35
+ end
31
36
 
32
- handler_name = adapter ? adapter.to_s.capitalize : detect_handler.name.gsub(/.*::/, '')
37
+ def initialize(options, app)
38
+ @options, @app = options, app
39
+ end
33
40
 
34
- begin
35
- handler = Rack::Handler.get(handler_name.downcase)
36
- rescue
37
- raise LoadError, "#{handler_name} not supported yet, available adapters are: #{Handlers.inspect}"
38
- exit
39
- end
41
+ def start
42
+ puts "=> Padrino/#{Padrino.version} has taken the stage #{Padrino.env} at http://#{options[:Host]}:#{options[:Port]}"
43
+ [:INT, :TERM].each { |sig| trap(sig) { exit } }
44
+ super
45
+ ensure
46
+ puts "<= Padrino has ended his set (crowd applauds)" unless options[:daemonize]
47
+ end
40
48
 
41
- puts "=> Padrino/#{Padrino.version} has taken the stage #{Padrino.env} on #{port}"
49
+ def app
50
+ @app
51
+ end
52
+ alias :wrapped_app :app
42
53
 
43
- handler.run Padrino.application, :Host => host, :Port => port do |server|
44
- trap(:INT) do
45
- # Use thins' hard #stop! if available, otherwise just #stop
46
- server.respond_to?(:stop!) ? server.stop! : server.stop
47
- puts "<= Padrino has ended his set (crowd applauds)"
48
- end
49
- end
50
- rescue RuntimeError => e
51
- if e.message =~ /no acceptor/
52
- if port < 1024 && RUBY_PLATFORM !~ /mswin|win|mingw/ && Process.uid != 0
53
- puts "=> Only root may open a priviledged port #{port}!"
54
- else
55
- puts "=> Someone is already performing on port #{port}!"
56
- end
57
- else
58
- raise e
59
- end
60
- rescue Errno::EADDRINUSE
61
- puts "=> Someone is already performing on port #{port}!"
62
- end
54
+ def options
55
+ @options
56
+ end
63
57
 
64
- def self.detect_handler
65
- Handlers.each do |server_name|
58
+ private
59
+ def self.detect_rack_handler
60
+ Handlers.each do |handler|
66
61
  begin
67
- return Rack::Handler.get(server_name.downcase)
68
- rescue Exception
62
+ return handler if Rack::Handler.get(handler.to_s.downcase)
63
+ rescue LoadError
64
+ rescue NameError
69
65
  end
70
66
  end
71
- raise LoadError, "Server handler (#{servers.join(',')}) not found."
67
+ fail "Server handler (#{Handlers.join(', ')}) not found."
72
68
  end
73
69
  end # Server
74
70
  end # Padrino
@@ -1,95 +1,41 @@
1
1
  ##
2
2
  # This file loads certain extensions required by Padrino from ActiveSupport.
3
3
  #
4
- # Why use ActiveSupport and not our own library or extlib?
5
- #
6
- # 1) Rewriting custom method extensions required (i.e string inflectors) is not a good use of time.
7
- # 2) Loading custom method extensions or separate gems would conflict with AS when AR or MM has been loaded.
8
- # 3) Datamapper 1.0 supports ActiveSupport 3.0 and no longer requires extlib.
9
- #
10
-
11
- # ActiveSupport Required Extensions
12
- require 'active_support/core_ext/string/conversions' unless String.method_defined?(:to_date)
13
- require 'active_support/core_ext/kernel' unless Kernel.method_defined?(:silence_warnings)
14
- require 'active_support/core_ext/module' unless Module.method_defined?(:alias_method_chain)
4
+ require 'active_support/core_ext/string/conversions' unless String.method_defined?(:to_date)
5
+ require 'active_support/core_ext/kernel' unless Kernel.method_defined?(:silence_warnings)
6
+ require 'active_support/core_ext/module' unless Module.method_defined?(:alias_method_chain)
15
7
  require 'active_support/core_ext/class/attribute_accessors' unless Class.method_defined?(:cattr_reader)
16
- require 'active_support/core_ext/hash/keys' unless Hash.method_defined?(:symbolize_keys!)
17
- require 'active_support/core_ext/hash/deep_merge' unless Hash.method_defined?(:deep_merge)
18
- require 'active_support/core_ext/hash/reverse_merge' unless Hash.method_defined?(:reverse_merge)
19
- require 'active_support/core_ext/hash/slice' unless Hash.method_defined?(:slice)
20
- require 'active_support/core_ext/object/blank' unless Object.method_defined?(:present?)
21
- require 'active_support/core_ext/array' unless Array.method_defined?(:from)
22
- require 'active_support/ordered_hash' unless defined?(ActiveSupport::OrderedHash)
23
- require 'active_support/inflector' unless String.method_defined?(:humanize)
24
- require 'active_support/core_ext/float/rounding' unless Float.method_defined?(:round)
25
- require 'active_support/option_merger' unless defined?(ActiveSupport::OptionMerger)
26
-
27
- # Loads symbol to proc extensions
28
- begin
29
- require 'active_support/core_ext/symbol'
30
- rescue LoadError
31
- # AS 3.0 has been removed it because is now available in Ruby > 1.8.7 but we want keep Ruby 1.8.6 support.
32
- class Symbol
33
- # Turns the symbol into a simple proc, which is especially useful for enumerations like: people.map(&:name)
34
- def to_proc
35
- Proc.new { |*args| args.shift.__send__(self, *args) }
36
- end
37
- end unless :to_proc.respond_to?(:to_proc)
38
- end
39
-
40
- # On ActiveSupport < 3.0.0 this is called misc
41
- begin
42
- require 'active_support/core_ext/object/with_options'
43
- rescue LoadError
44
- require 'active_support/core_ext/object/misc'
45
- end unless Object.method_defined?(:with_options)
46
-
47
- if defined?(ActiveSupport::CoreExtensions::Hash) && !Hash.method_defined?(:slice)
48
- # This mean that we are using AS 2.3.x
49
- class Hash
50
- include ActiveSupport::CoreExtensions::Hash::Keys
51
- include ActiveSupport::CoreExtensions::Hash::DeepMerge
52
- include ActiveSupport::CoreExtensions::Hash::ReverseMerge
53
- include ActiveSupport::CoreExtensions::Hash::Slice
54
-
55
- def ordered_collect(&block)
56
- keys = self.stringify_keys.keys.sort
57
- keys.map { |key| block.call(key, self[key.to_sym]) }
58
- end
59
- end
60
- end
8
+ require 'active_support/core_ext/hash/keys' unless Hash.method_defined?(:symbolize_keys!)
9
+ require 'active_support/core_ext/hash/deep_merge' unless Hash.method_defined?(:deep_merge)
10
+ require 'active_support/core_ext/hash/reverse_merge' unless Hash.method_defined?(:reverse_merge)
11
+ require 'active_support/core_ext/hash/slice' unless Hash.method_defined?(:slice)
12
+ require 'active_support/core_ext/object/blank' unless Object.method_defined?(:present?)
13
+ require 'active_support/core_ext/array' unless Array.method_defined?(:from)
14
+ require 'active_support/ordered_hash' unless defined?(ActiveSupport::OrderedHash)
15
+ require 'active_support/inflector' unless String.method_defined?(:humanize)
16
+ require 'active_support/core_ext/float/rounding' unless Float.method_defined?(:round)
17
+ require 'active_support/option_merger' unless defined?(ActiveSupport::OptionMerger)
18
+ require 'active_support/core_ext/object/with_options' unless Object.method_defined?(:with_options)
61
19
 
62
20
  ##
63
21
  # Used to know if this file has already been required
64
22
  #
65
- module SupportLite; end unless defined?(SupportLite)
23
+ module SupportLite; end
66
24
 
67
25
  module ObjectSpace
68
26
  class << self
69
27
  # Returns all the classes in the object space.
70
28
  def classes
71
- klasses = []
72
- ObjectSpace.each_object(Class) { |o| klasses << o }
73
- klasses
29
+ ObjectSpace.each_object(Module).select do |klass|
30
+ Class.class_eval { klass } rescue false
31
+ end
74
32
  end
75
33
  end
76
- end unless ObjectSpace.respond_to?(:classes)
77
-
78
- class Object
79
- def full_const_get(name)
80
- list = name.split("::")
81
- list.shift if list.first.blank?
82
- obj = self
83
- list.each do |x|
84
- # This is required because const_get tries to look for constants in the
85
- # ancestor chain, but we only want constants that are HERE
86
- obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
87
- end
88
- obj
89
- end
90
- end unless Object.method_defined?(:full_const_get)
34
+ end
91
35
 
36
+ ##
92
37
  # FileSet helper method for iterating and interacting with files inside a directory
38
+ #
93
39
  class FileSet
94
40
  # Iterates over every file in the glob pattern and yields to a block
95
41
  # Returns the list of files matching the glob pattern
@@ -106,10 +52,12 @@ class FileSet
106
52
  def self.glob_require(glob_pattern, file_path=nil)
107
53
  self.glob(glob_pattern, file_path) { |f| require f }
108
54
  end
109
- end unless defined?(FileSet)
55
+ end
110
56
 
57
+ ##
111
58
  # YAML Engine Parsing Fix
112
59
  # https://github.com/padrino/padrino-framework/issues/424
60
+ #
113
61
  require 'yaml' unless defined?(YAML)
114
62
  YAML::ENGINE.yamler = "syck" if defined?(YAML::ENGINE)
115
63
 
@@ -5,7 +5,7 @@
5
5
  # without include full padrino core.
6
6
  #
7
7
  module Padrino
8
- VERSION = '0.9.28' unless defined?(Padrino::VERSION)
8
+ VERSION = '0.9.29' unless defined?(Padrino::VERSION)
9
9
  ##
10
10
  # Return the current Padrino version
11
11
  #
@@ -20,10 +20,14 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
  s.rdoc_options = ["--charset=UTF-8"]
22
22
 
23
+
24
+ # TODO remove after a couple versions
25
+ s.post_install_message = "\e[32m When upgrading, please 'enable :sessions' for each application"
26
+ s.post_install_message << " as shown here:\e[0m http://bit.ly/kODKMx"
27
+
23
28
  s.add_dependency("tilt", "~> 1.3.0")
24
29
  s.add_dependency("sinatra", "~> 1.2.6")
25
- s.add_dependency("http_router", "~> 0.7.5")
30
+ s.add_dependency("http_router", "~> 0.7.8")
26
31
  s.add_dependency("thor", ">=0.14.3")
27
32
  s.add_dependency("activesupport", ">= 3.0.0")
28
- s.add_dependency("tzinfo")
29
33
  end
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  SimpleDemo.controllers do
16
16
  get "/" do
17
- 'The magick number is: 4!' # Change only the number!!!
17
+ 'The magick number is: 72!' # Change only the number!!!
18
18
  end
19
19
 
20
20
  get "/rand" do
@@ -5,7 +5,7 @@ class PadrinoTestApp2 < Padrino::Application; end
5
5
 
6
6
  class TestApplication < Test::Unit::TestCase
7
7
  def setup
8
- Padrino.mounted_apps.clear
8
+ Padrino.clear!
9
9
  end
10
10
 
11
11
  def teardown
@@ -1,8 +1,8 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/helper')
2
2
 
3
3
  class TestCore < Test::Unit::TestCase
4
- def teardown
5
- Padrino.clear_middleware!
4
+ def setup
5
+ Padrino.clear!
6
6
  end
7
7
 
8
8
  context 'for core functionality' do
@@ -31,6 +31,9 @@ class TestCore < Test::Unit::TestCase
31
31
  Padrino.set_encoding
32
32
  if RUBY_VERSION <'1.9'
33
33
  assert_equal 'UTF8', $KCODE
34
+ else
35
+ assert_equal Encoding.default_external, Encoding::UTF_8
36
+ assert_equal Encoding.default_internal, Encoding::UTF_8
34
37
  end
35
38
  end
36
39
 
@@ -39,10 +42,18 @@ class TestCore < Test::Unit::TestCase
39
42
  end
40
43
 
41
44
  should 'raise application error if I instantiate a new padrino application without mounted apps' do
42
- Padrino.mounted_apps.clear
43
45
  assert_raise(Padrino::ApplicationLoadError) { Padrino.application.new }
44
46
  end
45
47
 
48
+ should "check before/after padrino load hooks" do
49
+ Padrino.before_load { @_foo = 1 }
50
+ Padrino.after_load { @_foo += 1 }
51
+ Padrino.load!
52
+ assert_equal 1, Padrino.before_load.size
53
+ assert_equal 1, Padrino.after_load.size
54
+ assert_equal 2, @_foo
55
+ end
56
+
46
57
  should "add middlewares in front if specified" do
47
58
  test = Class.new {
48
59
  def initialize(app)
@@ -56,10 +67,13 @@ class TestCore < Test::Unit::TestCase
56
67
  end
57
68
  }
58
69
 
70
+ class Foo < Padrino::Application; end
71
+
59
72
  Padrino.use(test)
73
+ Padrino.mount(Foo).to("/")
60
74
 
61
75
  res = Rack::MockRequest.new(Padrino.application).get("/")
62
76
  assert_equal "yes", res["Middleware-Called"]
63
77
  end
64
78
  end
65
- end
79
+ end
@@ -4,7 +4,7 @@ class TestMounter < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  $VERBOSE, @_verbose_was = nil, $VERBOSE
7
- Padrino.mounted_apps.clear
7
+ Padrino.clear!
8
8
  end
9
9
 
10
10
  def teardown
@@ -6,7 +6,7 @@ class TestComplexReloader < Test::Unit::TestCase
6
6
  context 'for complex reload functionality' do
7
7
 
8
8
  should 'correctly instantiate Complex(1-2)Demo fixture' do
9
- Padrino.mounted_apps.clear
9
+ Padrino.clear!
10
10
  Padrino.mount("complex_1_demo").to("/complex_1_demo")
11
11
  Padrino.mount("complex_2_demo").to("/complex_2_demo")
12
12
  assert_equal ["/complex_1_demo", "/complex_2_demo"], Padrino.mounted_apps.map(&:uri_root)
@@ -36,7 +36,7 @@ class TestComplexReloader < Test::Unit::TestCase
36
36
  get "/complex_2_demo/old"
37
37
  assert_equal 200, status
38
38
 
39
- new_phrase = "The magick number is: #{rand(100)}!"
39
+ new_phrase = "The magick number is: #{rand(2**255)}!"
40
40
  buffer = File.read(Complex1Demo.app_file)
41
41
  new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase)
42
42
  begin
@@ -45,7 +45,7 @@ class TestSimpleReloader < Test::Unit::TestCase
45
45
  context 'for simple reload functionality' do
46
46
 
47
47
  should 'correctly instantiate SimpleDemo fixture' do
48
- Padrino.mounted_apps.clear
48
+ Padrino.clear!
49
49
  Padrino.mount("simple_demo").to("/")
50
50
  assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
51
51
  assert SimpleDemo.reload?
@@ -56,7 +56,7 @@ class TestSimpleReloader < Test::Unit::TestCase
56
56
  @app = SimpleDemo
57
57
  get "/"
58
58
  assert ok?
59
- new_phrase = "The magick number is: #{rand(100)}!"
59
+ new_phrase = "The magick number is: #{rand(2**255)}!"
60
60
  buffer = File.read(SimpleDemo.app_file)
61
61
  new_buffer = buffer.gsub(/The magick number is: \d+!/, new_phrase)
62
62
  File.open(SimpleDemo.app_file, "w") { |f| f.write(new_buffer) }
@@ -204,6 +204,36 @@ class TestRendering < Test::Unit::TestCase
204
204
  assert_equal "3", body
205
205
  end
206
206
 
207
+ should "support passing locals into render" do
208
+ create_layout :application, "layout <%= yield %>"
209
+ create_view :index, "<%= foo %>"
210
+ mock_app do
211
+ get("/") { render "index", { :layout => true }, { :foo => "bar" } }
212
+ end
213
+ get "/"
214
+ assert_equal "layout bar", body
215
+ end
216
+
217
+ should "support passing locals into sinatra render" do
218
+ create_layout :application, "layout <%= yield %>"
219
+ create_view :index, "<%= foo %>"
220
+ mock_app do
221
+ get("/") { render :erb, :index, { :layout => true }, { :foo => "bar" } }
222
+ end
223
+ get "/"
224
+ assert_equal "layout bar", body
225
+ end
226
+
227
+ should "support passing locals into special nil engine render" do
228
+ create_layout :application, "layout <%= yield %>"
229
+ create_view :index, "<%= foo %>"
230
+ mock_app do
231
+ get("/") { render nil, :index, { :layout => true }, { :foo => "bar" } }
232
+ end
233
+ get "/"
234
+ assert_equal "layout bar", body
235
+ end
236
+
207
237
  should 'be compatible with sinatra views' do
208
238
  with_view :index, "<%= 1+2 %>" do
209
239
  mock_app do
@@ -3,6 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/simple')
3
3
 
4
4
  class TestRouter < Test::Unit::TestCase
5
5
 
6
+ def setup
7
+ Padrino.clear!
8
+ end
9
+
6
10
  should "dispatch paths correctly" do
7
11
  app = lambda { |env|
8
12
  [200, {
@@ -104,7 +108,6 @@ class TestRouter < Test::Unit::TestCase
104
108
  end
105
109
 
106
110
  should "works with padrino core applications" do
107
- Padrino.mounted_apps.clear
108
111
  Padrino.mount("simple_demo").host("padrino.org")
109
112
  assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
110
113
  assert_equal ["padrino.org"], Padrino.mounted_apps.map(&:app_host)
@@ -120,7 +123,6 @@ class TestRouter < Test::Unit::TestCase
120
123
  end
121
124
 
122
125
  should "works with padrino applications" do
123
- Padrino.mounted_apps.clear
124
126
  Padrino.mount("simple_demo").to("/foo").host(/.*\.padrino.org/)
125
127
 
126
128
  res = Rack::MockRequest.new(Padrino.application).get("/")