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:
parent
b4a5839345
commit
cef5e628be
23 changed files with 276 additions and 96 deletions
|
@ -7,3 +7,7 @@ rvm:
|
|||
matrix:
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
before_script:
|
||||
- sudo ci/install_phantomjs
|
||||
- "export PATH=phantomjs/bin:$PATH"
|
||||
- phantomjs --version
|
||||
|
|
70
Rakefile
70
Rakefile
|
@ -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
6
ci/install_phantomjs
Executable 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
|
|
@ -1 +0,0 @@
|
|||
default: --format=progress
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
2
spec/dummy/.rspec
Normal file
|
@ -0,0 +1,2 @@
|
|||
--color
|
||||
--format progress
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
2
spec/dummy/db/seeds.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
Post.delete_all
|
||||
Post.create id: 1
|
5
spec/dummy/lib/tasks/spec.rake
Normal file
5
spec/dummy/lib/tasks/spec.rake
Normal file
|
@ -0,0 +1,5 @@
|
|||
require 'rspec/core/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new
|
||||
|
||||
task "default" => "spec"
|
23
spec/dummy/spec/decorators/post_decorator_spec.rb
Normal file
23
spec/dummy/spec/decorators/post_decorator_spec.rb
Normal 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
|
9
spec/dummy/spec/spec_helper.rb
Normal file
9
spec/dummy/spec/spec_helper.rb
Normal 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
|
49
spec/integration/integration_spec.rb
Normal file
49
spec/integration/integration_spec.rb
Normal 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
83
spec/support/dummy_app.rb
Normal 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
|
Loading…
Add table
Reference in a new issue