Skip to content
This repository
Browse code

Start Rails::Application object

  • Loading branch information...
commit 4129449594ad3d8ff2f8fb4836104f25406a104f 1 parent 088ce29
authored September 25, 2009
1  .gitignore
@@ -31,3 +31,4 @@ actionpack/bin
31 31
 vendor/gems/
32 32
 */vendor/gems/
33 33
 bin/
  34
+railties/tmp
2  railties/lib/rails.rb
... ...
@@ -0,0 +1,2 @@
  1
+require "rails/application"
  2
+require "rails/initializer"
58  railties/lib/rails/application.rb
... ...
@@ -0,0 +1,58 @@
  1
+require 'action_controller'
  2
+
  3
+module Rails
  4
+  class Application
  5
+    # Loads a Rails application from a directory and returns a Rails
  6
+    # Application object that responds to #call(env)
  7
+    def self.load(path, options = {})
  8
+      require "#{path}/config/environment"
  9
+      new(path, options)
  10
+    end
  11
+
  12
+    def initialize(path, options)
  13
+      @path = path
  14
+
  15
+      ensure_tmp_dirs
  16
+
  17
+      if options[:config]
  18
+        config = File.join(path, options[:config])
  19
+        config = nil unless File.exist?(config)
  20
+      end
  21
+
  22
+      @app = ::Rack::Builder.new {
  23
+        use Rails::Rack::LogTailer unless options[:detach]
  24
+        use Rails::Rack::Debugger if options[:debugger]
  25
+        if options[:path]
  26
+          base = options[:path]
  27
+          ActionController::Base.relative_url_root = base
  28
+        end
  29
+
  30
+        map base || "/" do
  31
+          use Rails::Rack::Static 
  32
+
  33
+          if config && config =~ /\.ru$/
  34
+            instance_eval(File.read(config), config)
  35
+          elsif config
  36
+            require config
  37
+            run Object.const_get(File.basename(config, '.rb').capitalize)
  38
+          else
  39
+            run ActionController::Dispatcher.new
  40
+          end
  41
+        end
  42
+      }.to_app
  43
+    end
  44
+
  45
+    def call(env)
  46
+      @app.call(env)
  47
+    end
  48
+
  49
+  private
  50
+
  51
+    def ensure_tmp_dirs
  52
+      %w(cache pids sessions sockets).each do |dir_to_make|
  53
+        FileUtils.mkdir_p(File.join(@path, 'tmp', dir_to_make))
  54
+      end
  55
+    end
  56
+
  57
+  end
  58
+end
40  railties/lib/rails/commands/server.rb
... ...
@@ -1,7 +1,6 @@
1  
-require 'action_controller'
2  
-
3 1
 require 'fileutils'
4 2
 require 'optparse'
  3
+require 'rails'
5 4
 
6 5
 options = {
7 6
   :Port        => 3000,
@@ -46,10 +45,6 @@
46 45
 puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
47 46
 puts "=> Rails #{Rails.version} application starting on http://#{options[:Host]}:#{options[:Port]}#{options[:path]}"
48 47
 
49  
-%w(cache pids sessions sockets).each do |dir_to_make|
50  
-  FileUtils.mkdir_p(File.join(RAILS_ROOT, 'tmp', dir_to_make))
51  
-end
52  
-
53 48
 if options[:detach]
54 49
   Process.daemon
55 50
   pid = "#{RAILS_ROOT}/tmp/pids/server.pid"
@@ -60,38 +55,7 @@
60 55
 ENV["RAILS_ENV"] = options[:environment]
61 56
 RAILS_ENV.replace(options[:environment]) if defined?(RAILS_ENV)
62 57
 
63  
-if File.exist?(options[:config])
64  
-  config = options[:config]
65  
-  if config =~ /\.ru$/
66  
-    cfgfile = File.read(config)
67  
-    if cfgfile[/^#\\(.*)/]
68  
-      opts.parse!($1.split(/\s+/))
69  
-    end
70  
-    inner_app = eval("Rack::Builder.new {( " + cfgfile + "\n )}.to_app", nil, config)
71  
-  else
72  
-    require config
73  
-    inner_app = Object.const_get(File.basename(config, '.rb').capitalize)
74  
-  end
75  
-else
76  
-  require RAILS_ROOT + "/config/environment"
77  
-  inner_app = ActionController::Dispatcher.new
78  
-end
79  
-
80  
-if options[:path].nil?
81  
-  map_path = "/"
82  
-else
83  
-  ActionController::Base.relative_url_root = options[:path]
84  
-  map_path = options[:path]
85  
-end
86  
-
87  
-app = Rack::Builder.new {
88  
-  use Rails::Rack::LogTailer unless options[:detach]
89  
-  use Rails::Rack::Debugger if options[:debugger]
90  
-  map map_path do
91  
-    use Rails::Rack::Static 
92  
-    run inner_app
93  
-  end
94  
-}.to_app
  58
+app = Rails::Application.load(RAILS_ROOT, options)
95 59
 
96 60
 puts "=> Call with -d to detach"
97 61
 
98  railties/test/application/load_test.rb
... ...
@@ -0,0 +1,98 @@
  1
+require "isolation/abstract_unit"
  2
+require "rails"
  3
+require "rack"
  4
+
  5
+module ApplicationTests
  6
+  class LoadTest < Test::Unit::TestCase
  7
+    include ActiveSupport::Testing::Isolation
  8
+
  9
+    def setup
  10
+      build_app
  11
+    end
  12
+
  13
+    test "rails app is present" do
  14
+      assert File.exist?(app_path("config"))
  15
+    end
  16
+
  17
+    test "running Rails::Application.load on the path returns a (vaguely) useful application" do
  18
+      @app = Rails::Application.load app_path
  19
+      assert_welcome get("/")
  20
+    end
  21
+
  22
+    test "setting the map_path of the application" do
  23
+      controller "says", <<-CONTROLLER
  24
+        class SaysController < ActionController::Base
  25
+          def index ; render :text => "MOO!" ; end
  26
+        end
  27
+      CONTROLLER
  28
+
  29
+      @app = Rails::Application.load app_path, :path => "/the/cow"
  30
+
  31
+      assert_missing get("/")
  32
+      assert_welcome get("/the/cow")
  33
+      assert_body    "MOO!", get("/the/cow/says")
  34
+    end
  35
+
  36
+    test "url generation with a base path" do
  37
+      controller "generatin", <<-CONTROLLER
  38
+        class GeneratinController < ActionController::Base
  39
+          def index ; render :text => url_for(:action => "index", :only_path => true) ; end
  40
+        end
  41
+      CONTROLLER
  42
+
  43
+      @app = Rails::Application.load app_path, :path => "/base"
  44
+
  45
+      assert_body "/base/generatin", get("/base/generatin")
  46
+    end
  47
+    
  48
+    test "config.ru is used" do
  49
+      app_file "config.ru", <<-CONFIG
  50
+        class MyMiddleware
  51
+          def initialize(app)
  52
+            @app = app
  53
+          end
  54
+          
  55
+          def call(env)
  56
+            status, headers, body = @app.call(env)
  57
+            headers["Config-Ru-Test"] = "TESTING"
  58
+            [status, headers, body]
  59
+          end
  60
+        end
  61
+        
  62
+        use MyMiddleware
  63
+        run proc {|env| [200, {"Content-Type" => "text/html"}, ["VICTORY"]] }
  64
+      CONFIG
  65
+      
  66
+      @app = Rails::Application.load app_path, :config => "config.ru"
  67
+
  68
+      assert_body    "VICTORY", get("/omg")
  69
+      assert_header  "Config-Ru-Test", "TESTING", get("/omg")
  70
+    end
  71
+    
  72
+    test "arbitrary.rb can be used as a config" do
  73
+      app_file "myapp.rb", <<-CONFIG
  74
+        Myapp = proc {|env| [200, {"Content-Type" => "text/html"}, ["OMG ROBOTS"]] }
  75
+      CONFIG
  76
+      
  77
+      @app = Rails::Application.load app_path, :config => "myapp.rb"
  78
+      
  79
+      assert_body "OMG ROBOTS", get("/omg")
  80
+    end
  81
+
  82
+    %w(cache pids sessions sockets).each do |dir|
  83
+      test "creating tmp/#{dir} if it does not exist" do
  84
+        FileUtils.rm_r(app_path("tmp/#{dir}"))
  85
+        Rails::Application.load app_path
  86
+        assert File.exist?(app_path("tmp/#{dir}"))
  87
+      end
  88
+    end
  89
+
  90
+    test "LogTailer middleware is present when not detached" do
  91
+      
  92
+    end
  93
+
  94
+    test "Debugger middleware is present when using debugger option" do
  95
+      
  96
+    end
  97
+  end
  98
+end
107  railties/test/isolation/abstract_unit.rb
... ...
@@ -0,0 +1,107 @@
  1
+# Note:
  2
+# It is important to keep this file as light as possible
  3
+# the goal for tests that require this is to test booting up
  4
+# rails from an empty state, so anything added here could
  5
+# hide potential failures
  6
+#
  7
+# It is also good to know what is the bare minimum to get
  8
+# Rails booted up.
  9
+
  10
+# TODO: Remove rubygems when possible
  11
+require 'rubygems'
  12
+require 'test/unit'
  13
+
  14
+# TODO: Remove setting this magic constant
  15
+RAILS_FRAMEWORK_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../..")
  16
+
  17
+# These load paths usually get set inside of boot.rb
  18
+$:.unshift "#{RAILS_FRAMEWORK_ROOT}/railties/lib"
  19
+$:.unshift "#{RAILS_FRAMEWORK_ROOT}/actionpack/lib"
  20
+
  21
+# These files do not require any others and are needed
  22
+# to run the tests
  23
+require "#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/testing/isolation"
  24
+require "#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/testing/declarative"
  25
+
  26
+module TestHelpers
  27
+  module Paths
  28
+    module_function
  29
+
  30
+    def tmp_path(*args)
  31
+      File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp] + args))
  32
+    end
  33
+
  34
+    def app_path(*args)
  35
+      tmp_path(*%w[app] + args)
  36
+    end
  37
+  end
  38
+
  39
+  module Rack
  40
+    def extract_body(response)
  41
+      "".tap do |body|
  42
+        response[2].each {|chunk| body << chunk }
  43
+      end
  44
+    end
  45
+
  46
+    def get(path)
  47
+      @app.call(::Rack::MockRequest.env_for(path))
  48
+    end
  49
+
  50
+    def assert_welcome(resp)
  51
+      assert_equal 200, resp[0]
  52
+      assert resp[1]["Content-Type"] = "text/html"
  53
+      assert extract_body(resp).match(/Welcome aboard/)
  54
+    end
  55
+
  56
+    def assert_success(resp)
  57
+      assert_equal 202, resp[0]
  58
+    end
  59
+
  60
+    def assert_missing(resp)
  61
+      assert_equal 404, resp[0]
  62
+    end
  63
+
  64
+    def assert_header(key, value, resp)
  65
+      assert_equal value, resp[1][key.to_s]
  66
+    end
  67
+
  68
+    def assert_body(expected, resp)
  69
+      assert_equal expected, extract_body(resp)
  70
+    end
  71
+  end
  72
+
  73
+  module Generation
  74
+    def build_app
  75
+      FileUtils.cp_r(tmp_path('app_template'), app_path)
  76
+    end
  77
+
  78
+    def app_file(path, contents)
  79
+      File.open(app_path(path), 'w') do |f|
  80
+        f.puts contents
  81
+      end
  82
+    end
  83
+
  84
+    def controller(name, contents)
  85
+      app_file("app/controllers/#{name}_controller.rb", contents)
  86
+    end
  87
+  end
  88
+end
  89
+
  90
+class Test::Unit::TestCase
  91
+  include TestHelpers::Paths
  92
+  include TestHelpers::Rack
  93
+  include TestHelpers::Generation
  94
+  extend  ActiveSupport::Testing::Declarative
  95
+end
  96
+
  97
+# Create a scope and build a fixture rails app
  98
+Module.new do
  99
+  extend TestHelpers::Paths
  100
+  # Build a rails app
  101
+  if File.exist?(tmp_path)
  102
+    FileUtils.rm_rf(tmp_path)
  103
+  end
  104
+
  105
+  FileUtils.mkdir(tmp_path)
  106
+  `#{Gem.ruby} #{RAILS_FRAMEWORK_ROOT}/railties/bin/rails #{tmp_path('app_template')}`
  107
+end

0 notes on commit 4129449

Please sign in to comment.
Something went wrong with that request. Please try again.