dchelimsky-rspec-rails 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +63 -0
- data/Manifest.txt +158 -0
- data/README.txt +81 -0
- data/Rakefile +38 -0
- data/UPGRADE +7 -0
- data/generators/rspec/CHANGES +1 -0
- data/generators/rspec/rspec_generator.rb +40 -0
- data/generators/rspec/templates/all_stories.rb +4 -0
- data/generators/rspec/templates/previous_failures.txt +0 -0
- data/generators/rspec/templates/rcov.opts +2 -0
- data/generators/rspec/templates/rspec.rake +132 -0
- data/generators/rspec/templates/script/autospec +3 -0
- data/generators/rspec/templates/script/spec +4 -0
- data/generators/rspec/templates/script/spec_server +116 -0
- data/generators/rspec/templates/spec.opts +4 -0
- data/generators/rspec/templates/spec_helper.rb +47 -0
- data/generators/rspec/templates/stories_helper.rb +3 -0
- data/generators/rspec_controller/USAGE +33 -0
- data/generators/rspec_controller/rspec_controller_generator.rb +49 -0
- data/generators/rspec_controller/templates/controller_spec.rb +25 -0
- data/generators/rspec_controller/templates/helper_spec.rb +11 -0
- data/generators/rspec_controller/templates/view_spec.rb +12 -0
- data/generators/rspec_default_values.rb +19 -0
- data/generators/rspec_model/USAGE +18 -0
- data/generators/rspec_model/rspec_model_generator.rb +35 -0
- data/generators/rspec_model/templates/model_spec.rb +15 -0
- data/generators/rspec_scaffold/rspec_scaffold_generator.rb +154 -0
- data/generators/rspec_scaffold/templates/controller_spec.rb +173 -0
- data/generators/rspec_scaffold/templates/edit_erb_spec.rb +26 -0
- data/generators/rspec_scaffold/templates/helper_spec.rb +11 -0
- data/generators/rspec_scaffold/templates/index_erb_spec.rb +27 -0
- data/generators/rspec_scaffold/templates/new_erb_spec.rb +26 -0
- data/generators/rspec_scaffold/templates/routing_spec.rb +59 -0
- data/generators/rspec_scaffold/templates/show_erb_spec.rb +23 -0
- data/init.rb +9 -0
- data/lib/autotest/discover.rb +1 -0
- data/lib/autotest/rails_rspec.rb +76 -0
- data/lib/spec/rails/example/assigns_hash_proxy.rb +37 -0
- data/lib/spec/rails/example/controller_example_group.rb +256 -0
- data/lib/spec/rails/example/cookies_proxy.rb +25 -0
- data/lib/spec/rails/example/functional_example_group.rb +87 -0
- data/lib/spec/rails/example/helper_example_group.rb +166 -0
- data/lib/spec/rails/example/model_example_group.rb +14 -0
- data/lib/spec/rails/example/rails_example_group.rb +33 -0
- data/lib/spec/rails/example/render_observer.rb +93 -0
- data/lib/spec/rails/example/view_example_group.rb +183 -0
- data/lib/spec/rails/example.rb +47 -0
- data/lib/spec/rails/extensions/action_controller/base.rb +14 -0
- data/lib/spec/rails/extensions/action_controller/rescue.rb +21 -0
- data/lib/spec/rails/extensions/action_controller/test_response.rb +11 -0
- data/lib/spec/rails/extensions/action_view/base.rb +31 -0
- data/lib/spec/rails/extensions/active_record/base.rb +30 -0
- data/lib/spec/rails/extensions/object.rb +5 -0
- data/lib/spec/rails/extensions/spec/example/configuration.rb +71 -0
- data/lib/spec/rails/extensions/spec/matchers/have.rb +21 -0
- data/lib/spec/rails/extensions.rb +12 -0
- data/lib/spec/rails/interop/testcase.rb +14 -0
- data/lib/spec/rails/matchers/assert_select.rb +131 -0
- data/lib/spec/rails/matchers/change.rb +11 -0
- data/lib/spec/rails/matchers/have_text.rb +57 -0
- data/lib/spec/rails/matchers/include_text.rb +54 -0
- data/lib/spec/rails/matchers/redirect_to.rb +113 -0
- data/lib/spec/rails/matchers/render_template.rb +90 -0
- data/lib/spec/rails/matchers.rb +31 -0
- data/lib/spec/rails/mocks.rb +132 -0
- data/lib/spec/rails/story_adapter.rb +79 -0
- data/lib/spec/rails/version.rb +15 -0
- data/lib/spec/rails.rb +15 -0
- data/spec/rails/autotest/mappings_spec.rb +36 -0
- data/spec/rails/example/assigns_hash_proxy_spec.rb +70 -0
- data/spec/rails/example/configuration_spec.rb +83 -0
- data/spec/rails/example/controller_isolation_spec.rb +62 -0
- data/spec/rails/example/controller_spec_spec.rb +272 -0
- data/spec/rails/example/cookies_proxy_spec.rb +74 -0
- data/spec/rails/example/example_group_factory_spec.rb +112 -0
- data/spec/rails/example/helper_spec_spec.rb +161 -0
- data/spec/rails/example/model_spec_spec.rb +18 -0
- data/spec/rails/example/shared_behaviour_spec.rb +16 -0
- data/spec/rails/example/test_unit_assertion_accessibility_spec.rb +33 -0
- data/spec/rails/example/view_spec_spec.rb +280 -0
- data/spec/rails/extensions/action_controller_rescue_action_spec.rb +54 -0
- data/spec/rails/extensions/action_view_base_spec.rb +48 -0
- data/spec/rails/extensions/active_record_spec.rb +14 -0
- data/spec/rails/interop/testcase_spec.rb +66 -0
- data/spec/rails/matchers/assert_select_spec.rb +814 -0
- data/spec/rails/matchers/description_generation_spec.rb +37 -0
- data/spec/rails/matchers/errors_on_spec.rb +13 -0
- data/spec/rails/matchers/have_text_spec.rb +62 -0
- data/spec/rails/matchers/include_text_spec.rb +64 -0
- data/spec/rails/matchers/redirect_to_spec.rb +209 -0
- data/spec/rails/matchers/render_template_spec.rb +176 -0
- data/spec/rails/matchers/should_change_spec.rb +15 -0
- data/spec/rails/mocks/ar_classes.rb +10 -0
- data/spec/rails/mocks/mock_model_spec.rb +106 -0
- data/spec/rails/mocks/stub_model_spec.rb +80 -0
- data/spec/rails/sample_modified_fixture.rb +8 -0
- data/spec/rails/sample_spec.rb +8 -0
- data/spec/rails/spec_server_spec.rb +96 -0
- data/spec/rails/spec_spec.rb +11 -0
- data/spec/rails_suite.rb +7 -0
- data/spec/spec_helper.rb +57 -0
- data/spec_resources/controllers/action_view_base_spec_controller.rb +2 -0
- data/spec_resources/controllers/controller_spec_controller.rb +94 -0
- data/spec_resources/controllers/redirect_spec_controller.rb +59 -0
- data/spec_resources/controllers/render_spec_controller.rb +30 -0
- data/spec_resources/controllers/rjs_spec_controller.rb +58 -0
- data/spec_resources/helpers/explicit_helper.rb +38 -0
- data/spec_resources/helpers/more_explicit_helper.rb +5 -0
- data/spec_resources/helpers/plugin_application_helper.rb +6 -0
- data/spec_resources/helpers/view_spec_helper.rb +13 -0
- data/spec_resources/views/controller_spec/_partial.rhtml +0 -0
- data/spec_resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml +1 -0
- data/spec_resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml +1 -0
- data/spec_resources/views/controller_spec/action_setting_the_assigns_hash.rhtml +0 -0
- data/spec_resources/views/controller_spec/action_with_errors_in_template.rhtml +1 -0
- data/spec_resources/views/controller_spec/action_with_template.rhtml +1 -0
- data/spec_resources/views/layouts/application.rhtml +0 -0
- data/spec_resources/views/layouts/simple.rhtml +0 -0
- data/spec_resources/views/objects/_object.html.erb +1 -0
- data/spec_resources/views/render_spec/_a_partial.rhtml +0 -0
- data/spec_resources/views/render_spec/action_with_alternate_layout.rhtml +0 -0
- data/spec_resources/views/render_spec/some_action.js.rjs +1 -0
- data/spec_resources/views/render_spec/some_action.rhtml +0 -0
- data/spec_resources/views/render_spec/some_action.rjs +1 -0
- data/spec_resources/views/rjs_spec/_replacement_partial.rhtml +1 -0
- data/spec_resources/views/rjs_spec/hide_div.rjs +1 -0
- data/spec_resources/views/rjs_spec/hide_page_element.rjs +1 -0
- data/spec_resources/views/rjs_spec/insert_html.rjs +1 -0
- data/spec_resources/views/rjs_spec/replace.rjs +1 -0
- data/spec_resources/views/rjs_spec/replace_html.rjs +1 -0
- data/spec_resources/views/rjs_spec/replace_html_with_partial.rjs +1 -0
- data/spec_resources/views/rjs_spec/visual_effect.rjs +1 -0
- data/spec_resources/views/rjs_spec/visual_toggle_effect.rjs +1 -0
- data/spec_resources/views/tag_spec/no_tags.rhtml +1 -0
- data/spec_resources/views/tag_spec/single_div_with_no_attributes.rhtml +1 -0
- data/spec_resources/views/tag_spec/single_div_with_one_attribute.rhtml +1 -0
- data/spec_resources/views/view_spec/_partial.rhtml +2 -0
- data/spec_resources/views/view_spec/_partial_used_twice.rhtml +0 -0
- data/spec_resources/views/view_spec/_partial_with_local_variable.rhtml +1 -0
- data/spec_resources/views/view_spec/_partial_with_sub_partial.rhtml +1 -0
- data/spec_resources/views/view_spec/_spacer.rhtml +1 -0
- data/spec_resources/views/view_spec/accessor.rhtml +5 -0
- data/spec_resources/views/view_spec/block_helper.rhtml +3 -0
- data/spec_resources/views/view_spec/entry_form.rhtml +2 -0
- data/spec_resources/views/view_spec/explicit_helper.rhtml +2 -0
- data/spec_resources/views/view_spec/foo/show.rhtml +1 -0
- data/spec_resources/views/view_spec/implicit_helper.rhtml +2 -0
- data/spec_resources/views/view_spec/multiple_helpers.rhtml +3 -0
- data/spec_resources/views/view_spec/should_not_receive.rhtml +3 -0
- data/spec_resources/views/view_spec/template_with_partial.rhtml +5 -0
- data/spec_resources/views/view_spec/template_with_partial_using_collection.rhtml +3 -0
- data/spec_resources/views/view_spec/template_with_partial_with_array.rhtml +1 -0
- data/stories/all.rb +10 -0
- data/stories/configuration/stories.rb +5 -0
- data/stories/helper.rb +6 -0
- data/stories/steps/people.rb +8 -0
- data/stories/transactions_should_rollback +15 -0
- data/stories/transactions_should_rollback.rb +25 -0
- metadata +232 -0
@@ -0,0 +1,166 @@
|
|
1
|
+
module Spec
|
2
|
+
module Rails
|
3
|
+
module Example
|
4
|
+
# Helper Specs live in $RAILS_ROOT/spec/helpers/.
|
5
|
+
#
|
6
|
+
# Helper Specs use Spec::Rails::Example::HelperExampleGroup, which allows you to
|
7
|
+
# include your Helper directly in the context and write specs directly
|
8
|
+
# against its methods.
|
9
|
+
#
|
10
|
+
# HelperExampleGroup also includes the standard lot of ActionView::Helpers in case your
|
11
|
+
# helpers rely on any of those.
|
12
|
+
#
|
13
|
+
# == Example
|
14
|
+
#
|
15
|
+
# class ThingHelper
|
16
|
+
# def number_of_things
|
17
|
+
# Thing.count
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# describe "ThingHelper example_group" do
|
22
|
+
# include ThingHelper
|
23
|
+
# it "should tell you the number of things" do
|
24
|
+
# Thing.should_receive(:count).and_return(37)
|
25
|
+
# number_of_things.should == 37
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
class HelperExampleGroup < FunctionalExampleGroup
|
29
|
+
class HelperObject < ActionView::Base
|
30
|
+
def protect_against_forgery?
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def session=(session)
|
35
|
+
@session = session
|
36
|
+
end
|
37
|
+
|
38
|
+
def request=(request)
|
39
|
+
@request = request
|
40
|
+
end
|
41
|
+
|
42
|
+
def flash=(flash)
|
43
|
+
@flash = flash
|
44
|
+
end
|
45
|
+
|
46
|
+
def params=(params)
|
47
|
+
@params = params
|
48
|
+
end
|
49
|
+
|
50
|
+
def controller=(controller)
|
51
|
+
@controller = controller
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
attr_reader :session, :request, :flash, :params, :controller
|
56
|
+
end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
# The helper name....
|
60
|
+
def helper_name(name=nil)
|
61
|
+
@helper_being_described = "#{name}_helper".camelize.constantize
|
62
|
+
send :include, @helper_being_described
|
63
|
+
end
|
64
|
+
|
65
|
+
def helper
|
66
|
+
@helper_object ||= returning HelperObject.new do |helper_object|
|
67
|
+
if @helper_being_described.nil?
|
68
|
+
if described_type.class == Module
|
69
|
+
helper_object.extend described_type
|
70
|
+
end
|
71
|
+
else
|
72
|
+
helper_object.extend @helper_being_described
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns an instance of ActionView::Base with the helper being spec'd
|
79
|
+
# included.
|
80
|
+
#
|
81
|
+
# == Example
|
82
|
+
#
|
83
|
+
# describe PersonHelper do
|
84
|
+
# it "should write a link to person with the name" do
|
85
|
+
# assigns[:person] = mock_model(Person, :full_name => "Full Name", :id => 37, :new_record? => false)
|
86
|
+
# helper.link_to_person.should == %{<a href="/people/37">Full Name</a>}
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# module PersonHelper
|
91
|
+
# def link_to_person
|
92
|
+
# link_to person.full_name, url_for(person)
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
def helper
|
97
|
+
self.class.helper
|
98
|
+
end
|
99
|
+
|
100
|
+
# Reverse the load order so that custom helpers which are defined last
|
101
|
+
# are also loaded last.
|
102
|
+
ActionView::Base.included_modules.reverse.each do |mod|
|
103
|
+
include mod if mod.parents.include?(ActionView::Helpers)
|
104
|
+
end
|
105
|
+
|
106
|
+
before(:all) do
|
107
|
+
@controller_class_name = 'Spec::Rails::Example::HelperExampleGroupController'
|
108
|
+
end
|
109
|
+
|
110
|
+
before(:each) do
|
111
|
+
@controller.request = @request
|
112
|
+
@controller.url = ActionController::UrlRewriter.new @request, {} # url_for
|
113
|
+
|
114
|
+
@flash = ActionController::Flash::FlashHash.new
|
115
|
+
session['flash'] = @flash
|
116
|
+
|
117
|
+
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
|
118
|
+
|
119
|
+
helper.session = session
|
120
|
+
helper.request = @request
|
121
|
+
helper.flash = flash
|
122
|
+
helper.params = params
|
123
|
+
helper.controller = @controller
|
124
|
+
end
|
125
|
+
|
126
|
+
def flash
|
127
|
+
@flash
|
128
|
+
end
|
129
|
+
|
130
|
+
def eval_erb(text)
|
131
|
+
erb_args = [text]
|
132
|
+
if helper.respond_to?(:output_buffer)
|
133
|
+
erb_args += [nil, nil, '@output_buffer']
|
134
|
+
end
|
135
|
+
|
136
|
+
helper.instance_eval do
|
137
|
+
ERB.new(*erb_args).result(binding)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# TODO: BT - Helper Examples should proxy method_missing to a Rails View instance.
|
142
|
+
# When that is done, remove this method
|
143
|
+
def protect_against_forgery?
|
144
|
+
false
|
145
|
+
end
|
146
|
+
|
147
|
+
Spec::Example::ExampleGroupFactory.register(:helper, self)
|
148
|
+
|
149
|
+
protected
|
150
|
+
def _assigns_hash_proxy
|
151
|
+
@_assigns_hash_proxy ||= AssignsHashProxy.new self do
|
152
|
+
helper
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
class HelperExampleGroupController < ApplicationController #:nodoc:
|
159
|
+
attr_accessor :request, :url
|
160
|
+
|
161
|
+
# Re-raise errors
|
162
|
+
def rescue_action(e); raise e; end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Spec
|
2
|
+
module Rails
|
3
|
+
module Example
|
4
|
+
# Model examples live in $RAILS_ROOT/spec/models/.
|
5
|
+
#
|
6
|
+
# Model examples use Spec::Rails::Example::ModelExampleGroup, which
|
7
|
+
# provides support for fixtures and some custom expectations via extensions
|
8
|
+
# to ActiveRecord::Base.
|
9
|
+
class ModelExampleGroup < RailsExampleGroup
|
10
|
+
Spec::Example::ExampleGroupFactory.register(:model, self)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec/interop/test'
|
2
|
+
|
3
|
+
if ActionView::Base.respond_to?(:cache_template_extension)
|
4
|
+
ActionView::Base.cache_template_extensions = false
|
5
|
+
end
|
6
|
+
|
7
|
+
module Spec
|
8
|
+
module Rails
|
9
|
+
|
10
|
+
module Example
|
11
|
+
class RailsExampleGroup < Test::Unit::TestCase
|
12
|
+
|
13
|
+
# Rails >= r8570 uses setup/teardown_fixtures explicitly
|
14
|
+
# However, Rails >= r8664 extracted these out to use ActiveSupport::Callbacks.
|
15
|
+
# The latter case is handled at the TestCase level, in interop/testcase.rb
|
16
|
+
unless ActiveSupport.const_defined?(:Callbacks) and self.include?(ActiveSupport::Callbacks)
|
17
|
+
before(:each) do
|
18
|
+
setup_fixtures if self.respond_to?(:setup_fixtures)
|
19
|
+
end
|
20
|
+
after(:each) do
|
21
|
+
teardown_fixtures if self.respond_to?(:teardown_fixtures)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
include Spec::Rails::Matchers
|
26
|
+
include Spec::Rails::Mocks
|
27
|
+
|
28
|
+
Spec::Example::ExampleGroupFactory.default(self)
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec/mocks/framework'
|
2
|
+
|
3
|
+
module Spec
|
4
|
+
module Rails
|
5
|
+
module Example
|
6
|
+
# Extends the #should_receive, #should_not_receive and #stub! methods in rspec's
|
7
|
+
# mocking framework to handle #render calls to controller in controller examples
|
8
|
+
# and template and view examples
|
9
|
+
module RenderObserver
|
10
|
+
|
11
|
+
# DEPRECATED
|
12
|
+
#
|
13
|
+
# Use should_receive(:render).with(opts) instead
|
14
|
+
def expect_render(opts={})
|
15
|
+
warn_deprecation("expect_render", "should_receive")
|
16
|
+
register_verify_after_each
|
17
|
+
render_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
# DEPRECATED
|
21
|
+
#
|
22
|
+
# Use stub!(:render).with(opts) instead
|
23
|
+
def stub_render(opts={})
|
24
|
+
warn_deprecation("stub_render", "stub!")
|
25
|
+
register_verify_after_each
|
26
|
+
render_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
def warn_deprecation(deprecated_method, new_method)
|
30
|
+
Kernel.warn <<-WARNING
|
31
|
+
#{deprecated_method} is deprecated and will be removed from a future version of rspec-rails.
|
32
|
+
|
33
|
+
Please just use object.#{new_method} instead.
|
34
|
+
WARNING
|
35
|
+
end
|
36
|
+
|
37
|
+
def verify_rendered # :nodoc:
|
38
|
+
render_proxy.rspec_verify
|
39
|
+
end
|
40
|
+
|
41
|
+
def unregister_verify_after_each #:nodoc:
|
42
|
+
proc = verify_rendered_proc
|
43
|
+
Spec::Example::ExampleGroup.remove_after(:each, &proc)
|
44
|
+
end
|
45
|
+
|
46
|
+
def should_receive(*args)
|
47
|
+
if args[0] == :render
|
48
|
+
register_verify_after_each
|
49
|
+
render_proxy.should_receive(:render, :expected_from => caller(1)[0])
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def should_not_receive(*args)
|
56
|
+
if args[0] == :render
|
57
|
+
register_verify_after_each
|
58
|
+
render_proxy.should_not_receive(:render)
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def stub!(*args)
|
65
|
+
if args[0] == :render
|
66
|
+
register_verify_after_each
|
67
|
+
render_proxy.stub!(:render, :expected_from => caller(1)[0])
|
68
|
+
else
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def verify_rendered_proc #:nodoc:
|
74
|
+
template = self
|
75
|
+
@verify_rendered_proc ||= Proc.new do
|
76
|
+
template.verify_rendered
|
77
|
+
template.unregister_verify_after_each
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def register_verify_after_each #:nodoc:
|
82
|
+
proc = verify_rendered_proc
|
83
|
+
Spec::Example::ExampleGroup.after(:each, &proc)
|
84
|
+
end
|
85
|
+
|
86
|
+
def render_proxy #:nodoc:
|
87
|
+
@render_proxy ||= Spec::Mocks::Mock.new("render_proxy")
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
module Spec
|
2
|
+
module Rails
|
3
|
+
module Example
|
4
|
+
# View Examples live in $RAILS_ROOT/spec/views/.
|
5
|
+
#
|
6
|
+
# View Specs use Spec::Rails::Example::ViewExampleGroup,
|
7
|
+
# which provides access to views without invoking any of your controllers.
|
8
|
+
# See Spec::Rails::Expectations::Matchers for information about specific
|
9
|
+
# expectations that you can set on views.
|
10
|
+
#
|
11
|
+
# == Example
|
12
|
+
#
|
13
|
+
# describe "login/login" do
|
14
|
+
# before do
|
15
|
+
# render 'login/login'
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# it "should display login form" do
|
19
|
+
# response.should have_tag("form[action=/login]") do
|
20
|
+
# with_tag("input[type=text][name=email]")
|
21
|
+
# with_tag("input[type=password][name=password]")
|
22
|
+
# with_tag("input[type=submit][value=Login]")
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
class ViewExampleGroup < FunctionalExampleGroup
|
27
|
+
before(:each) do
|
28
|
+
ensure_that_flash_and_session_work_properly
|
29
|
+
end
|
30
|
+
|
31
|
+
after(:each) do
|
32
|
+
ensure_that_base_view_path_is_not_set_across_example_groups
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(defined_description, &implementation) #:nodoc:
|
36
|
+
super
|
37
|
+
@controller_class_name = "Spec::Rails::Example::ViewExampleGroupController"
|
38
|
+
end
|
39
|
+
|
40
|
+
def ensure_that_flash_and_session_work_properly #:nodoc:
|
41
|
+
@controller.send :initialize_template_class, @response
|
42
|
+
@controller.send :assign_shortcuts, @request, @response
|
43
|
+
@session = @controller.session
|
44
|
+
@controller.class.send :public, :flash
|
45
|
+
end
|
46
|
+
|
47
|
+
def ensure_that_base_view_path_is_not_set_across_example_groups #:nodoc:
|
48
|
+
ActionView::Base.base_view_path = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_base_view_path(options) #:nodoc:
|
52
|
+
ActionView::Base.base_view_path = base_view_path(options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def base_view_path(options) #:nodoc:
|
56
|
+
"/#{derived_controller_name(options)}/"
|
57
|
+
end
|
58
|
+
|
59
|
+
def derived_controller_name(options) #:nodoc:
|
60
|
+
parts = subject_of_render(options).split('/').reject { |part| part.empty? }
|
61
|
+
"#{parts[0..-2].join('/')}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def derived_action_name(options) #:nodoc:
|
65
|
+
parts = subject_of_render(options).split('/').reject { |part| part.empty? }
|
66
|
+
"#{parts.last}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def subject_of_render(options) #:nodoc:
|
70
|
+
[:template, :partial, :file].each do |render_type|
|
71
|
+
if options.has_key?(render_type)
|
72
|
+
return options[render_type]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
return ""
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_helpers(options) #:nodoc:
|
79
|
+
@controller.add_helper("application")
|
80
|
+
@controller.add_helper(derived_controller_name(options))
|
81
|
+
@controller.add_helper(options[:helper]) if options[:helper]
|
82
|
+
options[:helpers].each { |helper| @controller.add_helper(helper) } if options[:helpers]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Renders a template for a View Spec, which then provides access to the result
|
86
|
+
# through the +response+. Also supports render with :inline, which you can
|
87
|
+
# use to spec custom form builders, helpers, etc, in the context of a view.
|
88
|
+
#
|
89
|
+
# == Examples
|
90
|
+
#
|
91
|
+
# render('/people/list')
|
92
|
+
# render('/people/list', :helper => MyHelper)
|
93
|
+
# render('/people/list', :helpers => [MyHelper, MyOtherHelper])
|
94
|
+
# render(:partial => '/people/_address')
|
95
|
+
# render(:inline => "<% custom_helper 'argument', 'another argument' %>")
|
96
|
+
#
|
97
|
+
# See Spec::Rails::Example::ViewExampleGroup for more information.
|
98
|
+
def render(*args)
|
99
|
+
options = Hash === args.last ? args.pop : {}
|
100
|
+
options[:template] = args.first.to_s unless args.empty?
|
101
|
+
|
102
|
+
set_base_view_path(options)
|
103
|
+
add_helpers(options)
|
104
|
+
|
105
|
+
assigns[:action_name] = @action_name
|
106
|
+
|
107
|
+
@request.path_parameters = {
|
108
|
+
:controller => derived_controller_name(options),
|
109
|
+
:action => derived_action_name(options)
|
110
|
+
}
|
111
|
+
|
112
|
+
defaults = { :layout => false }
|
113
|
+
options = defaults.merge options
|
114
|
+
|
115
|
+
@controller.send(:params).reverse_merge! @request.parameters
|
116
|
+
|
117
|
+
@controller.send :initialize_current_url
|
118
|
+
|
119
|
+
@controller.class.instance_eval %{
|
120
|
+
def controller_path
|
121
|
+
"#{derived_controller_name(options)}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def controller_name
|
125
|
+
"#{derived_controller_name(options).split('/').last}"
|
126
|
+
end
|
127
|
+
}
|
128
|
+
|
129
|
+
@controller.send :forget_variables_added_to_assigns
|
130
|
+
@controller.send :render, options
|
131
|
+
@controller.send :process_cleanup
|
132
|
+
end
|
133
|
+
|
134
|
+
# This provides the template. Use this to set mock
|
135
|
+
# expectations for dealing with partials
|
136
|
+
#
|
137
|
+
# == Example
|
138
|
+
#
|
139
|
+
# describe "/person/new" do
|
140
|
+
# it "should use the form partial" do
|
141
|
+
# template.should_receive(:render).with(:partial => 'form')
|
142
|
+
# render "/person/new"
|
143
|
+
# end
|
144
|
+
# end
|
145
|
+
def template
|
146
|
+
@controller.template
|
147
|
+
end
|
148
|
+
|
149
|
+
Spec::Example::ExampleGroupFactory.register(:view, self)
|
150
|
+
|
151
|
+
protected
|
152
|
+
def _assigns_hash_proxy
|
153
|
+
@_assigns_hash_proxy ||= AssignsHashProxy.new self do
|
154
|
+
@response.template
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class ViewExampleGroupController < ApplicationController #:nodoc:
|
160
|
+
include Spec::Rails::Example::RenderObserver
|
161
|
+
attr_reader :template
|
162
|
+
|
163
|
+
def add_helper_for(template_path)
|
164
|
+
add_helper(template_path.split('/')[0])
|
165
|
+
end
|
166
|
+
|
167
|
+
def add_helper(name)
|
168
|
+
begin
|
169
|
+
helper_module = "#{name}_helper".camelize.constantize
|
170
|
+
rescue
|
171
|
+
return
|
172
|
+
end
|
173
|
+
(class << template; self; end).class_eval do
|
174
|
+
include helper_module
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def forget_variables_added_to_assigns
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'spec/rails/example/assigns_hash_proxy'
|
4
|
+
|
5
|
+
require "spec/rails/example/render_observer"
|
6
|
+
require "spec/rails/example/rails_example_group"
|
7
|
+
require "spec/rails/example/model_example_group"
|
8
|
+
require "spec/rails/example/functional_example_group"
|
9
|
+
require "spec/rails/example/controller_example_group"
|
10
|
+
require "spec/rails/example/helper_example_group"
|
11
|
+
require "spec/rails/example/view_example_group"
|
12
|
+
require "spec/rails/example/cookies_proxy"
|
13
|
+
|
14
|
+
module Spec
|
15
|
+
module Rails
|
16
|
+
# Spec::Rails::Example extends Spec::Example (RSpec's core Example module) to provide
|
17
|
+
# Rails-specific contexts for describing Rails Models, Views, Controllers and Helpers.
|
18
|
+
#
|
19
|
+
# == Model Examples
|
20
|
+
#
|
21
|
+
# These are the equivalent of unit tests in Rails' built in testing. Ironically (for the traditional TDD'er) these are the only specs that we feel should actually interact with the database.
|
22
|
+
#
|
23
|
+
# See Spec::Rails::Example::ModelExampleGroup
|
24
|
+
#
|
25
|
+
# == Controller Examples
|
26
|
+
#
|
27
|
+
# These align somewhat with functional tests in rails, except that they do not actually render views (though you can force rendering of views if you prefer). Instead of setting expectations about what goes on a page, you set expectations about what templates get rendered.
|
28
|
+
#
|
29
|
+
# See Spec::Rails::Example::ControllerExampleGroup
|
30
|
+
#
|
31
|
+
# == View Examples
|
32
|
+
#
|
33
|
+
# This is the other half of Rails functional testing. View specs allow you to set up assigns and render
|
34
|
+
# a template. By assigning mock model data, you can specify view behaviour with no dependency on a database
|
35
|
+
# or your real models.
|
36
|
+
#
|
37
|
+
# See Spec::Rails::Example::ViewExampleGroup
|
38
|
+
#
|
39
|
+
# == Helper Examples
|
40
|
+
#
|
41
|
+
# These let you specify directly methods that live in your helpers.
|
42
|
+
#
|
43
|
+
# See Spec::Rails::Example::HelperExampleGroup
|
44
|
+
module Example
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActionController
|
2
|
+
module Rescue
|
3
|
+
def use_rails_error_handling!
|
4
|
+
@use_rails_error_handling = true
|
5
|
+
end
|
6
|
+
|
7
|
+
def use_rails_error_handling?
|
8
|
+
@use_rails_error_handling ||= false
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
def rescue_action_with_fast_errors(exception)
|
13
|
+
if use_rails_error_handling?
|
14
|
+
rescue_action_without_fast_errors exception
|
15
|
+
else
|
16
|
+
raise exception
|
17
|
+
end
|
18
|
+
end
|
19
|
+
alias_method_chain :rescue_action, :fast_errors
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActionView #:nodoc:
|
2
|
+
class Base #:nodoc:
|
3
|
+
include Spec::Rails::Example::RenderObserver
|
4
|
+
cattr_accessor :base_view_path
|
5
|
+
def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
|
6
|
+
if partial_path.is_a?(String)
|
7
|
+
unless partial_path.include?("/")
|
8
|
+
unless self.class.base_view_path.nil?
|
9
|
+
partial_path = "#{self.class.base_view_path}/#{partial_path}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
begin
|
14
|
+
super(partial_path, local_assigns, deprecated_local_assigns)
|
15
|
+
rescue ArgumentError # edge rails > 2.1 changed render_partial to accept only one arg
|
16
|
+
super(partial_path)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :orig_render, :render
|
21
|
+
def render(options = {}, old_local_assigns = {}, &block)
|
22
|
+
if render_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options)
|
23
|
+
render_proxy.render(options)
|
24
|
+
else
|
25
|
+
unless render_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options)
|
26
|
+
orig_render(options, old_local_assigns, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
if defined?(ActiveRecord::Base)
|
2
|
+
module ActiveRecord #:nodoc:
|
3
|
+
class Base
|
4
|
+
|
5
|
+
(class << self; self; end).class_eval do
|
6
|
+
# Extension for <tt>should have</tt> on AR Model classes
|
7
|
+
#
|
8
|
+
# ModelClass.should have(:no).records
|
9
|
+
# ModelClass.should have(1).record
|
10
|
+
# ModelClass.should have(n).records
|
11
|
+
def records
|
12
|
+
find(:all)
|
13
|
+
end
|
14
|
+
alias :record :records
|
15
|
+
end
|
16
|
+
|
17
|
+
# Extension for <tt>should have</tt> on AR Model instances
|
18
|
+
#
|
19
|
+
# model.should have(:no).errors_on(:attribute)
|
20
|
+
# model.should have(1).error_on(:attribute)
|
21
|
+
# model.should have(n).errors_on(:attribute)
|
22
|
+
def errors_on(attribute)
|
23
|
+
self.valid?
|
24
|
+
[self.errors.on(attribute)].flatten.compact
|
25
|
+
end
|
26
|
+
alias :error_on :errors_on
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|