Skip to content
This repository
Browse code

Run Rails through a RailsServer EM instead of by requiring files

  • Loading branch information...
commit f2f243db9afaad68743f89e1fe6807743bd1ad2f 1 parent d7a2731
Mike Burns authored July 27, 2012 jyurek committed November 02, 2012
7  Gemfile.lock
@@ -69,8 +69,10 @@ GEM
69 69
       diff-lcs (>= 1.1.3)
70 70
       gherkin (~> 2.11.0)
71 71
       json (>= 1.4.6)
  72
+    daemons (1.1.8)
72 73
     diff-lcs (1.1.3)
73 74
     erubis (2.7.0)
  75
+    eventmachine (0.12.10)
74 76
     excon (0.16.7)
75 77
     fakeweb (1.3.0)
76 78
     ffi (1.0.11)
@@ -162,6 +164,10 @@ GEM
162 164
       rack (~> 1.0)
163 165
       tilt (~> 1.1, != 1.3.0)
164 166
     sqlite3 (1.3.6)
  167
+    thin (1.3.1)
  168
+      daemons (>= 1.0.9)
  169
+      eventmachine (>= 0.12.6)
  170
+      rack (>= 1.0.0)
165 171
     thor (0.15.4)
166 172
     tilt (1.3.3)
167 173
     treetop (1.4.10)
@@ -198,3 +204,4 @@ DEPENDENCIES
198 204
   rake
199 205
   shoulda
200 206
   sqlite3
  207
+  thin
28  features/step_definitions/mvc_steps.rb
@@ -10,7 +10,7 @@
10 10
     <% end %>
11 11
   VIEW
12 12
   write_file('app/views/users/show.html.erb', <<-VIEW)
13  
-    <p>Attachment: <%= image_tag @user.avatar.url(:thumbnail) %></p>
  13
+    <p>Thumbnail attachment: <%= image_tag @user.avatar.url(:thumbnail) %></p>
14 14
   VIEW
15 15
   write_file('app/models/user.rb', <<-MODEL)
16 16
     class User < ActiveRecord::Base
@@ -21,13 +21,15 @@ class User < ActiveRecord::Base
21 21
 end
22 22
 
23 23
 Given /^I upload an avatar to the user model$/ do
  24
+  FakeWeb.allow_net_connect = true
  25
+  in_current_dir { RailsServer.start_unless_started(ENV['PORT'], ENV['DEBUG']) }
  26
+
  27
+  Capybara.current_driver = :selenium
  28
+  Capybara.app_host = RailsServer.app_host
  29
+
24 30
   visit '/users/new'
25 31
   attach_file('Avatar', File.expand_path('test/fixtures/5k.png'))
26 32
   click_button 'Submit'
27  
-
28  
-  in_current_dir do
29  
-    puts `find public -type f`
30  
-  end
31 33
 end
32 34
 
33 35
 When /^I add the following style to the user avatar:$/ do |string|
@@ -41,7 +43,7 @@ class User < ActiveRecord::Base
41 43
 
42 44
 When /^I change the user show page to show the large avatar$/ do
43 45
   write_file('app/views/users/show.html.erb', <<-VIEW)
44  
-    <p>Attachment: <%= image_tag @user.avatar.url(:large) %></p>
  46
+    <p>Large attachment: <%= image_tag @user.avatar.url(:large) %></p>
45 47
   VIEW
46 48
 end
47 49
 
@@ -50,16 +52,10 @@ class User < ActiveRecord::Base
50 52
   user.should_not be_nil
51 53
   visit "/users/#{user.to_param}"
52 54
 
53  
-  page.source =~ %r{img alt="5k" src="/([^"]+large[^"]+)\?.*"}
  55
+  page.source =~ %r{img src="/([^"]+large[^"]+)\?.*"}
54 56
   image_path = $1
55 57
   image_path.should_not be_blank
56 58
 
57  
-  in_current_dir do
58  
-    puts `find public -type f`
59  
-  end
60  
-
61  
-  p Rails.root.join('public',image_path)
62  
-  puts `ls -l #{Rails.root.join('public',image_path)}`
63 59
   File.should_not be_exist(Rails.root.join('public',image_path))
64 60
 end
65 61
 
@@ -90,13 +86,9 @@ class #{migration_name.classify} < ActiveRecord::Migration
90 86
   user.should_not be_nil
91 87
   visit "/users/#{user.to_param}"
92 88
 
93  
-  page.source =~ %r{img alt="5k" src="/([^"]+large[^"]+)\?.*"}
  89
+  page.source =~ %r{img src="/([^"]+large[^"]+)\?.*"}
94 90
   image_path = $1
95 91
   image_path.should_not be_blank
96 92
 
97  
-  in_current_dir do
98  
-    puts `find public -type f`
99  
-  end
100  
-
101 93
   File.should be_exist(Rails.root.join('public',image_path))
102 94
 end
11  features/step_definitions/rails_steps.rb
... ...
@@ -1,8 +1,4 @@
1 1
 Given /^I generate a new rails application$/ do
2  
-  if defined?(Paperclip::Attachment)
3  
-    Paperclip::Attachment.reset
4  
-  end
5  
-
6 2
   steps %{
7 3
     When I run `bundle exec #{new_application_command} #{APP_NAME} --skip-bundle`
8 4
     And I cd to "#{APP_NAME}"
@@ -17,6 +13,7 @@
17 13
       gem "capybara"
18 14
       gem "gherkin"
19 15
       gem "aws-sdk"
  16
+      gem 'thin'
20 17
       """
21 18
     And I configure the application to use "paperclip" from this project
22 19
     And I reset Bundler environment variable
@@ -60,7 +57,7 @@
60 57
     Given I overwrite "app/views/users/show.html.erb" with:
61 58
       """
62 59
       <p>Name: <%= @user.name %></p>
63  
-      <p>Attachment: <%= image_tag @user.attachment.url %></p>
  60
+      <p>Default attachment: <%= image_tag @user.attachment.url %></p>
64 61
       """
65 62
   }
66 63
 end
@@ -88,10 +85,6 @@
88 85
   end
89 86
 end
90 87
 
91  
-Given /^I reload my application$/ do
92  
-  Rails::Application.reload!
93  
-end
94  
-
95 88
 When /^I turn off class caching$/ do
96 89
   in_current_dir do
97 90
     file = "config/environments/test.rb"
130  features/support/rails_server.rb
... ...
@@ -0,0 +1,130 @@
  1
+require 'net/http'
  2
+
  3
+# Starts a Rails application server in a fork and waits for it to be responsive
  4
+class RailsServer
  5
+  HOST = 'localhost'.freeze
  6
+
  7
+  class << self
  8
+    attr_accessor :instance
  9
+  end
  10
+
  11
+  def self.start_unless_started(*a)
  12
+    start(*a) unless started?
  13
+  end
  14
+
  15
+  def self.start(port = nil, debug = nil)
  16
+    self.instance = new(port, debug)
  17
+    self.instance.start
  18
+    self.instance
  19
+  end
  20
+
  21
+  def self.stop
  22
+    self.instance.stop if started?
  23
+    self.instance = nil
  24
+  end
  25
+
  26
+  def self.get(path)
  27
+    self.instance.get(path)
  28
+  end
  29
+
  30
+  def self.post(path, data)
  31
+    self.instance.post(path, data)
  32
+  end
  33
+
  34
+  def self.run(port, silent)
  35
+    if silent
  36
+      require 'stringio'
  37
+      $stdout = StringIO.new
  38
+      $stderr = StringIO.new
  39
+    end
  40
+
  41
+    require './config/environment'
  42
+    require 'thin'
  43
+
  44
+    if Rails::VERSION::MAJOR == 3
  45
+      rails = Rails.application
  46
+    else
  47
+      rails = ActionController::Dispatcher.new
  48
+    end
  49
+    app = Identify.new(rails)
  50
+
  51
+    Thin::Logging.silent = silent
  52
+    Rack::Handler::Thin.run(app, :Port => port, :AccessLog => [])
  53
+  end
  54
+
  55
+  def self.app_host
  56
+    self.instance.app_host
  57
+  end
  58
+
  59
+  def self.started?
  60
+    !self.instance.nil?
  61
+  end
  62
+
  63
+  def initialize(port, debug)
  64
+    @port = (port || 3001).to_i
  65
+    @debug = debug
  66
+  end
  67
+
  68
+  def start
  69
+    command = ['ruby', "-r#{__FILE__}", '-e', "RailsServer.run(#{@port},#{(!@debug).inspect})"]
  70
+    puts command.join(' ') if @debug
  71
+    @pid = spawn(*command)
  72
+    wait_until_responsive
  73
+  end
  74
+
  75
+  def stop
  76
+    if @pid
  77
+      Process.kill('INT', @pid)
  78
+      Process.wait(@pid)
  79
+      @pid = nil
  80
+    end
  81
+  end
  82
+
  83
+  def get(path)
  84
+    puts "GET #{path}" if @debug
  85
+    Net::HTTP.start(HOST, @port) { |http| http.get(path) }
  86
+  end
  87
+
  88
+  def post(path, data)
  89
+    puts "POST #{path}\n#{data}" if @debug
  90
+    Net::HTTP.start(HOST, @port) { |http| http.post(path, data) }
  91
+  end
  92
+
  93
+  def wait_until_responsive
  94
+    20.times do
  95
+      if responsive?
  96
+        return true
  97
+      else
  98
+        sleep(0.5)
  99
+      end
  100
+    end
  101
+    raise "Couldn't connect to Rails application server at #{HOST}:#{@port}"
  102
+  end
  103
+
  104
+  def responsive?
  105
+    response = Net::HTTP.start(HOST, @port) { |http| http.get('/__identify__') }
  106
+    response.is_a?(Net::HTTPSuccess)
  107
+  rescue Errno::ECONNREFUSED, Errno::EBADF
  108
+    return false
  109
+  end
  110
+
  111
+  def app_host
  112
+    "http://#{HOST}:#{@port}"
  113
+  end
  114
+
  115
+  # From Capybara::Server
  116
+
  117
+  class Identify
  118
+    def initialize(app)
  119
+      @app = app
  120
+    end
  121
+
  122
+    def call(env)
  123
+      if env["PATH_INFO"] == "/__identify__"
  124
+        [200, {}, 'OK']
  125
+      else
  126
+        @app.call(env)
  127
+      end
  128
+    end
  129
+  end
  130
+end
1  paperclip.gemspec
@@ -50,4 +50,5 @@ Gem::Specification.new do |s|
50 50
   s.add_development_dependency('fakeweb')
51 51
   s.add_development_dependency('railties')
52 52
   s.add_development_dependency('actionmailer')
  53
+  s.add_development_dependency('thin')
53 54
 end

0 notes on commit f2f243d

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