Skip to content

Commit

Permalink
Add an rspec unit test helper
Browse files Browse the repository at this point in the history
  • Loading branch information
jonleighton committed Feb 20, 2012
1 parent 7959074 commit 28bef0e
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 5 deletions.
4 changes: 2 additions & 2 deletions focused_controller.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Gem::Specification.new do |s|

s.add_dependency 'actionpack', '~> 3.2'

# specify any dependencies here; for example:
s.add_development_dependency 'minitest', '~> 2.11.2'
s.add_development_dependency 'capybara', '~> 1.1.2'
s.add_development_dependency 'capybara_minitest_spec', '~> 0.2.1'
s.add_development_dependency 'poltergeist', '~> 0.4.0'
# s.add_runtime_dependency "rest-client"
s.add_development_dependency 'rspec', '~> 2.8.0'
s.add_development_dependency 'rspec-rails', '~> 2.8.0'
end
47 changes: 47 additions & 0 deletions lib/focused_controller/rspec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'focused_controller/test_helper'

begin
# Requiring specific files rather than just 'rspec/rails' because I don't
# want to force the configuration that 'rspec/rails' adds on people if they
# haven't specifically chosen to receive it.
require 'rspec/rails/matchers'
require 'rspec/rails/adapters'
require 'rspec/rails/example/rails_example_group'
rescue LoadError
end

module FocusedController
module RSpecHelper
def self.append_features(base)
base.class_eval do
# This must get included higher in the ancestor chain than
# this module so that inheritance works as desired
include FocusedController::TestHelper

extend ClassMethods

subject { controller }
end

super
end

if defined?(RSpec::Rails)
include RSpec::Rails::RailsExampleGroup
include RSpec::Rails::Matchers::RedirectTo
include RSpec::Rails::Matchers::RenderTemplate
end

module ClassMethods
def controller
controller = metadata[:example_group][:description_args].first

if controller.respond_to?(:new)
controller
else
super
end
end
end
end
end
7 changes: 4 additions & 3 deletions lib/focused_controller/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require 'action_dispatch/testing/test_request'
require 'action_dispatch/testing/test_response'
require 'action_dispatch'
require 'active_support/concern'
require 'active_support/core_ext/class/attribute'
require 'active_support/hash_with_indifferent_access'
Expand Down Expand Up @@ -50,7 +49,9 @@ def controller
end

def include_routes
include controller._routes.named_routes.module
if controller.respond_to?(:_routes) && controller._routes
include controller._routes.named_routes.module
end
end
end

Expand Down
3 changes: 3 additions & 0 deletions test/app/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ gem 'jquery-rails'

gem 'focused_controller', :path => '../..'

gem 'rspec'
gem 'rspec-rails'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

Expand Down
4 changes: 4 additions & 0 deletions test/app/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require 'rails/application'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec'
require 'focused_controller/rspec_helper'
59 changes: 59 additions & 0 deletions test/app/spec/unit/controllers/posts_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'spec_helper'

describe PostsController do
include FocusedController::RSpecHelper

before do
@post = Post.create(:title => 'Hello', :body => 'Omg')
end

describe PostsController::Index do
it "should get index" do
req
response.should be_success
subject.posts.should_not be(:nil)
end
end

describe PostsController::New do
it "should get new" do
req
response.should be_success
end
end

describe PostsController::Create do
it "should create post" do
expect { req :post => @post.attributes }.to change(Post, :count).by(1)
response.should redirect_to(post_path(subject.post))
end
end

describe PostsController::Show do
it "should show post" do
req :id => @post.id
response.should be_success
end
end

describe PostsController::Edit do
it "should get edit" do
req :id => @post.id
response.should be_success
end
end

describe PostsController::Update do
it "should update post" do
req :id => @post.id
response.should redirect_to(post_path(subject.post))
end
end

describe PostsController::Destroy do
it "should destroy post" do
expect { req :id => @post.id }.to change(Post, :count).by(-1)
response.should redirect_to(posts_path)
end
end
end
7 changes: 7 additions & 0 deletions test/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@
require 'minitest/autorun'
require 'focused_controller'

require 'rspec/core'

# Don't want to actually use RSpec to run our tests
module RSpec::Core::DSL
remove_method :describe
end

TEST_ROOT = File.expand_path('..', __FILE__)
83 changes: 83 additions & 0 deletions test/unit/rspec_helper_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require 'helper'
require 'action_controller'
require 'focused_controller/rspec_helper'

module FocusedController
module RSpecHelper
module FakePostsController
class Action < ActionController::Base
end

class Index < Action
end

class Show < Action
end

class Edit < Action
end
end

index_spec = RSpec::Core::ExampleGroup.describe FakePostsController::Index do
include FocusedController::RSpecHelper
end

show_spec = nil
RSpec::Core::ExampleGroup.describe FakePostsController do
show_spec = describe FakePostsController::Show do
include FocusedController::RSpecHelper
end
end

edit_spec = RSpec::Core::ExampleGroup.describe "the edit action" do
include FocusedController::RSpecHelper
self.controller = FakePostsController::Edit
end

describe RSpecHelper do
it 'finds the correct controller class' do
index_spec.controller.must_equal FakePostsController::Index
show_spec.controller.must_equal FakePostsController::Show
edit_spec.controller.must_equal FakePostsController::Edit
end

subject { index_spec.new }

def must_fail(&block)
block.must_raise RSpec::Expectations::ExpectationNotMetError
end

def must_succeed(&block)
block.call
true.must_equal true # to count the assertion
end

it 'has a redirect_to matcher' do
must_fail { subject.should subject.redirect_to('/foo') }
subject.controller.redirect_to('/foo')
must_succeed { subject.should subject.redirect_to('/foo') }
end

it 'matches response type' do
must_succeed { subject.response.should subject.be_success }
must_fail { subject.response.should subject.be_error }

subject.controller.render :status => :not_found

must_fail { subject.response.should subject.be_success }
must_succeed { subject.response.should subject.be_missing }
end

it 'has a render_template matcher' do
subject.controller.render :foo

must_succeed { subject.response.should subject.render_template(:foo) }
must_fail { subject.response.should subject.render_template(:bar) }
end

it 'sets the subject to be the controller instance' do
subject.subject.must_equal subject.controller
end
end
end
end

0 comments on commit 28bef0e

Please sign in to comment.