Permalink
Browse files

Run Rails through a RailsServer EM instead of by requiring files

  • Loading branch information...
1 parent d7a2731 commit f2f243db9afaad68743f89e1fe6807743bd1ad2f @mike-burns mike-burns committed with jyurek Jul 27, 2012
View
7 Gemfile.lock
@@ -69,8 +69,10 @@ GEM
diff-lcs (>= 1.1.3)
gherkin (~> 2.11.0)
json (>= 1.4.6)
+ daemons (1.1.8)
diff-lcs (1.1.3)
erubis (2.7.0)
+ eventmachine (0.12.10)
excon (0.16.7)
fakeweb (1.3.0)
ffi (1.0.11)
@@ -162,6 +164,10 @@ GEM
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6)
+ thin (1.3.1)
+ daemons (>= 1.0.9)
+ eventmachine (>= 0.12.6)
+ rack (>= 1.0.0)
thor (0.15.4)
tilt (1.3.3)
treetop (1.4.10)
@@ -198,3 +204,4 @@ DEPENDENCIES
rake
shoulda
sqlite3
+ thin
View
28 features/step_definitions/mvc_steps.rb
@@ -10,7 +10,7 @@
<% end %>
VIEW
write_file('app/views/users/show.html.erb', <<-VIEW)
- <p>Attachment: <%= image_tag @user.avatar.url(:thumbnail) %></p>
+ <p>Thumbnail attachment: <%= image_tag @user.avatar.url(:thumbnail) %></p>
VIEW
write_file('app/models/user.rb', <<-MODEL)
class User < ActiveRecord::Base
@@ -21,13 +21,15 @@ class User < ActiveRecord::Base
end
Given /^I upload an avatar to the user model$/ do
+ FakeWeb.allow_net_connect = true
+ in_current_dir { RailsServer.start_unless_started(ENV['PORT'], ENV['DEBUG']) }
+
+ Capybara.current_driver = :selenium
+ Capybara.app_host = RailsServer.app_host
+
visit '/users/new'
attach_file('Avatar', File.expand_path('test/fixtures/5k.png'))
click_button 'Submit'
-
- in_current_dir do
- puts `find public -type f`
- end
end
When /^I add the following style to the user avatar:$/ do |string|
@@ -41,7 +43,7 @@ class User < ActiveRecord::Base
When /^I change the user show page to show the large avatar$/ do
write_file('app/views/users/show.html.erb', <<-VIEW)
- <p>Attachment: <%= image_tag @user.avatar.url(:large) %></p>
+ <p>Large attachment: <%= image_tag @user.avatar.url(:large) %></p>
VIEW
end
@@ -50,16 +52,10 @@ class User < ActiveRecord::Base
user.should_not be_nil
visit "/users/#{user.to_param}"
- page.source =~ %r{img alt="5k" src="/([^"]+large[^"]+)\?.*"}
+ page.source =~ %r{img src="/([^"]+large[^"]+)\?.*"}
image_path = $1
image_path.should_not be_blank
- in_current_dir do
- puts `find public -type f`
- end
-
- p Rails.root.join('public',image_path)
- puts `ls -l #{Rails.root.join('public',image_path)}`
File.should_not be_exist(Rails.root.join('public',image_path))
end
@@ -90,13 +86,9 @@ class #{migration_name.classify} < ActiveRecord::Migration
user.should_not be_nil
visit "/users/#{user.to_param}"
- page.source =~ %r{img alt="5k" src="/([^"]+large[^"]+)\?.*"}
+ page.source =~ %r{img src="/([^"]+large[^"]+)\?.*"}
image_path = $1
image_path.should_not be_blank
- in_current_dir do
- puts `find public -type f`
- end
-
File.should be_exist(Rails.root.join('public',image_path))
end
View
11 features/step_definitions/rails_steps.rb
@@ -1,8 +1,4 @@
Given /^I generate a new rails application$/ do
- if defined?(Paperclip::Attachment)
- Paperclip::Attachment.reset
- end
-
steps %{
When I run `bundle exec #{new_application_command} #{APP_NAME} --skip-bundle`
And I cd to "#{APP_NAME}"
@@ -17,6 +13,7 @@
gem "capybara"
gem "gherkin"
gem "aws-sdk"
+ gem 'thin'
"""
And I configure the application to use "paperclip" from this project
And I reset Bundler environment variable
@@ -60,7 +57,7 @@
Given I overwrite "app/views/users/show.html.erb" with:
"""
<p>Name: <%= @user.name %></p>
- <p>Attachment: <%= image_tag @user.attachment.url %></p>
+ <p>Default attachment: <%= image_tag @user.attachment.url %></p>
"""
}
end
@@ -88,10 +85,6 @@
end
end
-Given /^I reload my application$/ do
- Rails::Application.reload!
-end
-
When /^I turn off class caching$/ do
in_current_dir do
file = "config/environments/test.rb"
View
130 features/support/rails_server.rb
@@ -0,0 +1,130 @@
+require 'net/http'
+
+# Starts a Rails application server in a fork and waits for it to be responsive
+class RailsServer
+ HOST = 'localhost'.freeze
+
+ class << self
+ attr_accessor :instance
+ end
+
+ def self.start_unless_started(*a)
+ start(*a) unless started?
+ end
+
+ def self.start(port = nil, debug = nil)
+ self.instance = new(port, debug)
+ self.instance.start
+ self.instance
+ end
+
+ def self.stop
+ self.instance.stop if started?
+ self.instance = nil
+ end
+
+ def self.get(path)
+ self.instance.get(path)
+ end
+
+ def self.post(path, data)
+ self.instance.post(path, data)
+ end
+
+ def self.run(port, silent)
+ if silent
+ require 'stringio'
+ $stdout = StringIO.new
+ $stderr = StringIO.new
+ end
+
+ require './config/environment'
+ require 'thin'
+
+ if Rails::VERSION::MAJOR == 3
+ rails = Rails.application
+ else
+ rails = ActionController::Dispatcher.new
+ end
+ app = Identify.new(rails)
+
+ Thin::Logging.silent = silent
+ Rack::Handler::Thin.run(app, :Port => port, :AccessLog => [])
+ end
+
+ def self.app_host
+ self.instance.app_host
+ end
+
+ def self.started?
+ !self.instance.nil?
+ end
+
+ def initialize(port, debug)
+ @port = (port || 3001).to_i
+ @debug = debug
+ end
+
+ def start
+ command = ['ruby', "-r#{__FILE__}", '-e', "RailsServer.run(#{@port},#{(!@debug).inspect})"]
+ puts command.join(' ') if @debug
+ @pid = spawn(*command)
+ wait_until_responsive
+ end
+
+ def stop
+ if @pid
+ Process.kill('INT', @pid)
+ Process.wait(@pid)
+ @pid = nil
+ end
+ end
+
+ def get(path)
+ puts "GET #{path}" if @debug
+ Net::HTTP.start(HOST, @port) { |http| http.get(path) }
+ end
+
+ def post(path, data)
+ puts "POST #{path}\n#{data}" if @debug
+ Net::HTTP.start(HOST, @port) { |http| http.post(path, data) }
+ end
+
+ def wait_until_responsive
+ 20.times do
+ if responsive?
+ return true
+ else
+ sleep(0.5)
+ end
+ end
+ raise "Couldn't connect to Rails application server at #{HOST}:#{@port}"
+ end
+
+ def responsive?
+ response = Net::HTTP.start(HOST, @port) { |http| http.get('/__identify__') }
+ response.is_a?(Net::HTTPSuccess)
+ rescue Errno::ECONNREFUSED, Errno::EBADF
+ return false
+ end
+
+ def app_host
+ "http://#{HOST}:#{@port}"
+ end
+
+ # From Capybara::Server
+
+ class Identify
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ if env["PATH_INFO"] == "/__identify__"
+ [200, {}, 'OK']
+ else
+ @app.call(env)
+ end
+ end
+ end
+end
View
1 paperclip.gemspec
@@ -50,4 +50,5 @@ Gem::Specification.new do |s|
s.add_development_dependency('fakeweb')
s.add_development_dependency('railties')
s.add_development_dependency('actionmailer')
+ s.add_development_dependency('thin')
end

0 comments on commit f2f243d

Please sign in to comment.