1
0
Fork 0
mirror of https://github.com/drapergem/draper synced 2023-03-27 23:21:17 -04:00

Integration tests for all environments

The problem with using Cucumber is that it runs the dummy app in the
test environment. Because the view context behaviour is dependent on
environment, we need to test it running on an actual server.
This commit is contained in:
Andrew Haines 2012-11-12 07:01:49 +00:00
parent b4a5839345
commit cef5e628be
23 changed files with 276 additions and 96 deletions

View file

@ -7,3 +7,7 @@ rvm:
matrix:
allow_failures:
- rvm: ruby-head
before_script:
- sudo ci/install_phantomjs
- "export PATH=phantomjs/bin:$PATH"
- phantomjs --version

View file

@ -1,22 +1,66 @@
require 'rake'
# These tasks help build and release the gem
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new
require 'cucumber/rake/task'
Cucumber::Rake::Task.new
file "spec/dummy/db/test.sqlite3" do
system "cd spec/dummy &&
RAILS_ENV=test rake db:migrate"
def run_in_dummy_app(command)
success = system("cd spec/dummy && #{command}")
raise "#{command} failed" unless success
end
task :cucumber => :"spec/dummy/db/test.sqlite3"
task "default" => "ci"
desc "Run all tests for CI"
task "ci" => ["spec", "cucumber"]
task "ci" => "spec:integration" #"spec"
task "default" => "ci"
desc "Run all specs"
task "spec" => "spec:all"
namespace "spec" do
task "all" => ["draper", "generators", "minitest-rails", "integration"]
def spec_task(name)
desc "Run #{name} specs"
RSpec::Core::RakeTask.new(name) do |t|
t.pattern = "spec/#{name}/**/*_spec.rb"
end
end
spec_task "draper"
spec_task "generators"
spec_task "minitest-rails"
desc "Run integration specs"
task "integration" => ["db:setup", "integration:all"]
namespace "integration" do
task "all" => ["development", "production", "test"]
["development", "production"].each do |environment|
task environment do
Rake::Task["spec:integration:run"].execute environment
end
end
task "run" do |t, environment|
puts "Running integration specs in #{environment}"
ENV["RAILS_ENV"] = environment
success = system("rspec spec/integration")
raise "Integration specs failed in #{environment}" unless success
end
task "test" do
run_in_dummy_app "rake"
end
end
end
namespace "db" do
desc "Set up databases for integration testing"
task "setup" do
run_in_dummy_app "rm -f db/*.sqlite3"
run_in_dummy_app "RAILS_ENV=development rake db:schema:load db:seed db:test:prepare"
run_in_dummy_app "RAILS_ENV=production rake db:schema:load db:seed"
end
end

6
ci/install_phantomjs Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
version=phantomjs-1.7.0-linux-i686
wget http://phantomjs.googlecode.com/files/$version.tar.bz2
tar xjf $version.tar.bz2
mv $version phantomjs

View file

@ -1 +0,0 @@
default: --format=progress

View file

@ -22,8 +22,9 @@ Gem::Specification.new do |s|
s.add_development_dependency 'ammeter'
s.add_development_dependency 'rake', '~> 0.9.2'
s.add_development_dependency 'rspec', '~> 2.10'
s.add_development_dependency 'cucumber-rails'
s.add_development_dependency 'yard'
s.add_development_dependency 'minitest-rails', '~> 0.2'
s.add_development_dependency 'minitest', '~> 3.0' if RUBY_PLATFORM == "java"
s.add_development_dependency 'capybara'
s.add_development_dependency 'poltergeist'
end

View file

@ -1,6 +0,0 @@
Feature: Blog posts
Scenario: A post exists with the correct time
Given a blog post exists that was posted today
When I visit the page for that post
Then I should see that it was posted today

View file

@ -1,17 +0,0 @@
Feature: Route helpers should work in decorators
Background:
Given a post exists
Scenario:
Then a _path helper with the underlying model works
Scenario:
Then a _path helper with the underlying model's id works
Scenario:
Then a _url helper with the underlying model works
Scenario:
Then a _url helper with the underlying model's id works

View file

@ -1,11 +0,0 @@
Given /^a blog post exists that was posted today$/ do
@post = Post.create
end
When /^I visit the page for that post$/ do
visit post_path(@post)
end
Then /^I should see that it was posted today$/ do
page.should have_content("Posted: Today")
end

View file

@ -1,20 +0,0 @@
Given /^a post exists$/ do
@post = Post.create
@decorator = PostDecorator.decorate(@post)
end
Then /^a _path helper with the underlying model works$/ do
@decorator.path_helper_with_model.should == {:post_path => "/posts/#{@post.id}"}
end
Then /^a _path helper with the underlying model's id works$/ do
@decorator.path_helper_with_model_id.should == {:post_path => "/posts/#{@post.id}"}
end
Then /^a _url helper with the underlying model works$/ do
@decorator.url_helper_with_model.should == {:post_url => "http://www.example.com/posts/#{@post.id}"}
end
Then /^a _url helper with the underlying model's id works$/ do
@decorator.url_helper_with_model_id.should == {:post_url => "http://www.example.com/posts/#{@post.id}"}
end

View file

@ -1,8 +0,0 @@
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../../spec/dummy/config/environment.rb", __FILE__)
ENV["RAILS_ROOT"] = File.expand_path("../../../spec/dummy", __FILE__)
require 'cucumber/rails'
Rails.backtrace_cleaner.remove_silencers!

2
spec/dummy/.rspec Normal file
View file

@ -0,0 +1,2 @@
--color
--format progress

View file

@ -1,3 +1,7 @@
class ApplicationController < ActionController::Base
protect_from_forgery
def default_url_options(options = {})
{locale: I18n.locale, host: "www.example.com", port: nil}
end
end

View file

@ -7,19 +7,19 @@ class PostDecorator < Draper::Decorator
end
end
def path_helper_with_model
{:post_path => h.post_path(self.model)}
def path_with_model
h.post_path(source)
end
def path_helper_with_model_id
{:post_path => h.post_path(:id => self.model.id)}
def path_with_id
h.post_path(id: id)
end
def url_helper_with_model
{:post_url => h.post_url(self.model)}
def url_with_model
h.post_url(source)
end
def url_helper_with_model_id
{:post_url => h.post_url(:id => self.model.id)}
def url_with_id
h.post_url(id: id)
end
end

View file

@ -1 +1,19 @@
Posted: <%= @post.posted_date %>
<dl>
<dt>Environment:</dt>
<dd id="environment"><%= Rails.env %></dd>
<dt>Posted:</dt>
<dd id="posted_date"><%= @post.posted_date %></dd>
<dt>Path with model:</dt>
<dd id="path_with_model"><%= @post.path_with_model %></dd>
<dt>Path with id:</dt>
<dd id="path_with_id"><%= @post.path_with_id %></dd>
<dt>URL with model:</dt>
<dd id="url_with_model"><%= @post.url_with_model %></dd>
<dt>URL with id:</dt>
<dd id="url_with_id"><%= @post.url_with_id %></dd>
</dl>

View file

@ -11,15 +11,6 @@ Dummy::Application.configure do
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to nil and saved in location specified by config.assets.prefix
# config.assets.manifest = YOUR_PATH

View file

@ -1,3 +1,5 @@
Dummy::Application.routes.draw do
resources :posts, :only => [:show]
scope "(:locale)", locale: /en|zh/ do
resources :posts, only: [:show]
end
end

2
spec/dummy/db/seeds.rb Normal file
View file

@ -0,0 +1,2 @@
Post.delete_all
Post.create id: 1

View file

@ -0,0 +1,5 @@
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new
task "default" => "spec"

View file

@ -0,0 +1,23 @@
require 'spec_helper'
describe PostDecorator do
subject { PostDecorator.new(source) }
let(:source) { Post.create }
it "can use path helpers with its model" do
subject.path_with_model.should == "/en/posts/#{source.id}"
end
it "can use path helpers with its id" do
subject.path_with_id.should == "/en/posts/#{source.id}"
end
it "can use url helpers with its model" do
subject.url_with_model.should == "http://www.example.com/en/posts/#{source.id}"
end
it "can use url helpers with its id" do
subject.url_with_id.should == "http://www.example.com/en/posts/#{source.id}"
end
end

View file

@ -0,0 +1,9 @@
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'draper/test/rspec_integration'
RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.order = :random
end

View file

@ -0,0 +1,49 @@
require 'spec_helper'
require 'support/dummy_app'
describe "integration" do
include Capybara::DSL
environment = ENV["RAILS_ENV"].to_s
raise ArgumentError, "RAILS_ENV must be development or production" unless ["development", "production"].include?(environment)
app = DummyApp.new(environment)
app.start_server do
describe "in #{environment}" do
before { Capybara.app_host = app.url }
it "runs in the correct environment" do
visit("/posts/1")
page.should have_css "#environment", text: environment
end
it "decorates" do
visit("/posts/1")
page.should have_content "Today"
end
it "can use path helpers with a model" do
visit("/posts/1")
page.should have_css "#path_with_model", text: "/en/posts/1"
end
it "can use path helpers with an id" do
visit("/posts/1")
page.should have_css "#path_with_id", text: "/en/posts/1"
end
it "can use url helpers with a model" do
visit("/posts/1")
page.should have_css "#url_with_model", text: "http://www.example.com/en/posts/1"
end
it "can use url helpers with an id" do
visit("/posts/1")
page.should have_css "#url_with_id", text: "http://www.example.com/en/posts/1"
end
end
end
end

83
spec/support/dummy_app.rb Normal file
View file

@ -0,0 +1,83 @@
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
require 'singleton'
require 'socket'
# Adapted from code by Jon Leighton
# https://github.com/jonleighton/focused_controller/blob/ec7ccf1/test/acceptance/app_test.rb
Capybara.run_server = false
Capybara.default_driver = :poltergeist
class DummyApp
def initialize(environment)
@environment = environment
end
def url
"http://#{localhost}:#{port}"
end
def within_app(&block)
Dir.chdir(root, &block)
end
def start_server
within_app do
IO.popen("bundle exec rails s -e #{@environment} -p #{port} 2>&1") do |out|
start = Time.now
started = false
output = ""
timeout = 60.0
while !started && !out.eof? && Time.now - start <= timeout
output << read_output(out)
sleep 0.1
begin
TCPSocket.new(localhost, port)
rescue Errno::ECONNREFUSED
else
started = true
end
end
raise "Server failed to start:\n#{output}" unless started
yield
Process.kill('KILL', out.pid)
end
end
end
private
def root
File.expand_path('../../dummy', __FILE__)
end
def localhost
'127.0.0.1'
end
def port
@port ||= begin
server = TCPServer.new(localhost, 0)
port = server.addr[1]
ensure
server.close if server
end
end
def read_output(stream)
read = IO.select([stream], [], [stream], 0.1)
output = ""
loop { output << stream.read_nonblock(1024) } if read
output
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, EOFError
output
end
end