rspec-rails 2.99.0 → 3.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +40 -68
- data/License.txt +1 -0
- data/README.md +6 -4
- data/features/Generators.md +24 -0
- data/features/GettingStarted.md +84 -0
- data/features/README.md +56 -0
- data/features/RailsVersions.md +4 -0
- data/features/Transactions.md +84 -0
- data/features/Upgrade.md +121 -0
- data/features/controller_specs/Cookies.md +57 -0
- data/features/controller_specs/README.md +45 -0
- data/features/controller_specs/anonymous_controller.feature +378 -0
- data/features/controller_specs/bypass_rescue.feature +75 -0
- data/features/controller_specs/controller_spec.feature +58 -0
- data/features/controller_specs/engine_routes.feature +51 -0
- data/features/controller_specs/isolation_from_views.feature +87 -0
- data/features/controller_specs/render_views.feature +114 -0
- data/features/directory_structure.feature +71 -0
- data/features/feature_specs/feature_spec.feature +35 -0
- data/features/helper_specs/helper_spec.feature +122 -0
- data/features/mailer_specs/url_helpers.feature +38 -0
- data/features/matchers/README.md +18 -0
- data/features/matchers/new_record_matcher.feature +41 -0
- data/features/matchers/redirect_to_matcher.feature +40 -0
- data/features/matchers/relation_match_array.feature +27 -0
- data/features/matchers/render_template_matcher.feature +49 -0
- data/features/mocks/mock_model.feature +147 -0
- data/features/mocks/stub_model.feature +58 -0
- data/features/model_specs/README.md +21 -0
- data/features/model_specs/errors_on.feature +51 -0
- data/features/model_specs/records.feature +27 -0
- data/features/model_specs/transactional_examples.feature +109 -0
- data/features/request_specs/request_spec.feature +49 -0
- data/features/routing_specs/README.md +16 -0
- data/features/routing_specs/be_routable_matcher.feature +80 -0
- data/features/routing_specs/engine_routes.feature +38 -0
- data/features/routing_specs/named_routes.feature +18 -0
- data/features/routing_specs/route_to_matcher.feature +90 -0
- data/features/step_definitions/additional_cli_steps.rb +4 -0
- data/features/step_definitions/model_steps.rb +3 -0
- data/features/support/capybara.rb +7 -0
- data/features/support/env.rb +53 -0
- data/features/support/rails_versions.rb +4 -0
- data/features/support/rubinius.rb +6 -0
- data/features/view_specs/inferred_controller_path.feature +45 -0
- data/features/view_specs/stub_template.feature +51 -0
- data/features/view_specs/view_spec.feature +206 -0
- data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
- data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +2 -21
- data/lib/generators/rspec/integration/integration_generator.rb +2 -3
- data/lib/generators/rspec/integration/templates/request_spec.rb +1 -1
- data/lib/generators/rspec/mailer/templates/mailer_spec.rb +4 -4
- data/lib/generators/rspec/scaffold/scaffold_generator.rb +2 -3
- data/lib/generators/rspec/scaffold/templates/controller_spec.rb +16 -16
- data/lib/generators/rspec/scaffold/templates/edit_spec.rb +2 -2
- data/lib/generators/rspec/scaffold/templates/index_spec.rb +1 -1
- data/lib/generators/rspec/scaffold/templates/new_spec.rb +2 -2
- data/lib/generators/rspec/scaffold/templates/routing_spec.rb +7 -7
- data/lib/generators/rspec/scaffold/templates/show_spec.rb +2 -2
- data/lib/rspec/rails.rb +0 -5
- data/lib/rspec/rails/adapters.rb +5 -12
- data/lib/rspec/rails/example.rb +55 -24
- data/lib/rspec/rails/example/controller_example_group.rb +7 -31
- data/lib/rspec/rails/example/view_example_group.rb +0 -3
- data/lib/rspec/rails/matchers.rb +1 -2
- data/lib/rspec/rails/matchers/be_a_new.rb +1 -1
- data/lib/rspec/rails/matchers/be_new_record.rb +1 -1
- data/lib/rspec/rails/matchers/be_valid.rb +1 -1
- data/lib/rspec/rails/matchers/have_rendered.rb +1 -1
- data/lib/rspec/rails/matchers/redirect_to.rb +1 -1
- data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
- data/lib/rspec/rails/matchers/routing_matchers.rb +6 -10
- data/lib/rspec/rails/mocks.rb +5 -41
- data/lib/rspec/rails/tasks/rspec.rake +5 -12
- data/lib/rspec/rails/vendor/capybara.rb +4 -35
- data/lib/rspec/rails/version.rb +1 -1
- data/spec/generators/rspec/controller/controller_generator_spec.rb +97 -0
- data/spec/generators/rspec/helper/helper_generator_spec.rb +30 -0
- data/spec/generators/rspec/install/install_generator_spec.rb +30 -0
- data/spec/generators/rspec/integration/integration_generator_spec.rb +44 -0
- data/spec/generators/rspec/mailer/mailer_generator_spec.rb +48 -0
- data/spec/generators/rspec/model/model_generator_spec.rb +52 -0
- data/spec/generators/rspec/observer/observer_generator_spec.rb +21 -0
- data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +138 -0
- data/spec/generators/rspec/view/view_generator_spec.rb +41 -0
- data/spec/rspec/rails/assertion_adapter_spec.rb +28 -0
- data/spec/rspec/rails/assertion_delegator_spec.rb +43 -0
- data/spec/rspec/rails/configuration_spec.rb +26 -0
- data/spec/rspec/rails/deprecations_spec.rb +18 -0
- data/spec/rspec/rails/example/controller_example_group_spec.rb +100 -0
- data/spec/rspec/rails/example/feature_example_group_spec.rb +56 -0
- data/spec/rspec/rails/example/helper_example_group_spec.rb +66 -0
- data/spec/rspec/rails/example/mailer_example_group_spec.rb +21 -0
- data/spec/rspec/rails/example/model_example_group_spec.rb +15 -0
- data/spec/rspec/rails/example/request_example_group_spec.rb +17 -0
- data/spec/rspec/rails/example/routing_example_group_spec.rb +32 -0
- data/spec/rspec/rails/example/view_example_group_spec.rb +220 -0
- data/spec/rspec/rails/extensions/active_model/errors_on_spec.rb +23 -0
- data/spec/rspec/rails/extensions/active_record/base_spec.rb +42 -0
- data/spec/rspec/rails/fixture_support_spec.rb +17 -0
- data/spec/rspec/rails/matchers/be_a_new_spec.rb +142 -0
- data/spec/rspec/rails/matchers/be_new_record_spec.rb +33 -0
- data/spec/rspec/rails/matchers/be_routable_spec.rb +41 -0
- data/spec/rspec/rails/matchers/be_valid_spec.rb +44 -0
- data/spec/rspec/rails/matchers/has_spec.rb +29 -0
- data/spec/rspec/rails/matchers/have_rendered_spec.rb +93 -0
- data/spec/rspec/rails/matchers/redirect_to_spec.rb +80 -0
- data/spec/rspec/rails/matchers/relation_match_array_spec.rb +31 -0
- data/spec/rspec/rails/matchers/route_to_spec.rb +151 -0
- data/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb +22 -0
- data/spec/rspec/rails/mocks/mock_model_spec.rb +378 -0
- data/spec/rspec/rails/mocks/stub_model_spec.rb +154 -0
- data/spec/rspec/rails/setup_and_teardown_adapter_spec.rb +32 -0
- data/spec/rspec/rails/view_rendering_spec.rb +111 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/support/ar_classes.rb +42 -0
- data/spec/support/helpers.rb +20 -0
- data/spec/support/matchers.rb +9 -0
- data/spec/support/null_object.rb +6 -0
- metadata +229 -42
- metadata.gz.sig +0 -0
- data/lib/autotest/rails_rspec2.rb +0 -91
- data/lib/rspec/rails/infer_type_configuration.rb +0 -26
- data/lib/rspec/rails/matchers/have_extension.rb +0 -36
- data/lib/rspec/rails/module_inclusion.rb +0 -19
@@ -0,0 +1,80 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "active_support/test_case"
|
3
|
+
|
4
|
+
describe "redirect_to" do
|
5
|
+
include RSpec::Rails::Matchers::RedirectTo
|
6
|
+
|
7
|
+
let(:response) { ActionController::TestResponse.new }
|
8
|
+
|
9
|
+
context "with should" do
|
10
|
+
context "when assert_redirected_to passes" do
|
11
|
+
def assert_redirected_to(*); end
|
12
|
+
|
13
|
+
it "passes" do
|
14
|
+
expect do
|
15
|
+
response.should redirect_to("destination")
|
16
|
+
end.to_not raise_exception
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when assert_redirected_to fails" do
|
21
|
+
def assert_redirected_to(*)
|
22
|
+
raise ActiveSupport::TestCase::Assertion.new("this message")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "uses failure message from assert_redirected_to" do
|
26
|
+
expect do
|
27
|
+
response.should redirect_to("destination")
|
28
|
+
end.to raise_exception("this message")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when fails due to some other exception" do
|
33
|
+
def assert_redirected_to(*)
|
34
|
+
raise "oops"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises that exception" do
|
38
|
+
expect do
|
39
|
+
response.should redirect_to("destination")
|
40
|
+
end.to raise_exception("oops")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with should_not" do
|
46
|
+
context "when assert_redirected_to fails" do
|
47
|
+
def assert_redirected_to(*)
|
48
|
+
raise ActiveSupport::TestCase::Assertion.new("this message")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "passes" do
|
52
|
+
expect do
|
53
|
+
response.should_not redirect_to("destination")
|
54
|
+
end.to_not raise_exception
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when assert_redirected_to passes" do
|
59
|
+
def assert_redirected_to(*); end
|
60
|
+
|
61
|
+
it "fails with custom failure message" do
|
62
|
+
expect do
|
63
|
+
response.should_not redirect_to("destination")
|
64
|
+
end.to raise_exception(/expected not to redirect to \"destination\", but did/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when fails due to some other exception" do
|
69
|
+
def assert_redirected_to(*)
|
70
|
+
raise "oops"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "raises that exception" do
|
74
|
+
expect do
|
75
|
+
response.should_not redirect_to("destination")
|
76
|
+
end.to raise_exception("oops")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "ActiveSupport::Relation =~ matcher" do
|
4
|
+
before { MockableModel.delete_all }
|
5
|
+
|
6
|
+
let!(:models) { Array.new(3) { MockableModel.create } }
|
7
|
+
|
8
|
+
if ::Rails::VERSION::STRING >= '4'
|
9
|
+
it "verifies that the scope returns the records on the right hand side, regardless of order" do
|
10
|
+
MockableModel.all.should =~ models.reverse
|
11
|
+
end
|
12
|
+
|
13
|
+
it "fails if the scope encompasses more records than on the right hand side" do
|
14
|
+
MockableModel.create
|
15
|
+
MockableModel.all.should_not =~ models.reverse
|
16
|
+
end
|
17
|
+
else
|
18
|
+
it "verifies that the scope returns the records on the right hand side, regardless of order" do
|
19
|
+
MockableModel.scoped.should =~ models.reverse
|
20
|
+
end
|
21
|
+
|
22
|
+
it "fails if the scope encompasses more records than on the right hand side" do
|
23
|
+
MockableModel.create
|
24
|
+
MockableModel.scoped.should_not =~ models.reverse
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "fails if the scope encompasses fewer records than on the right hand side" do
|
29
|
+
MockableModel.limit(models.length - 1).should_not =~ models.reverse
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "route_to" do
|
4
|
+
include RSpec::Rails::Matchers::RoutingMatchers
|
5
|
+
include RSpec::Rails::Matchers::RoutingMatchers::RouteHelpers
|
6
|
+
|
7
|
+
def assert_recognizes(*)
|
8
|
+
# no-op
|
9
|
+
end
|
10
|
+
|
11
|
+
it "provides a description" do
|
12
|
+
matcher = route_to("these" => "options")
|
13
|
+
matcher.matches?(:get => "path")
|
14
|
+
matcher.description.should == "route {:get=>\"path\"} to {\"these\"=>\"options\"}"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "delegates to assert_recognizes" do
|
18
|
+
self.should_receive(:assert_recognizes).with({ "these" => "options" }, { :method=> :get, :path=>"path" }, {})
|
19
|
+
{:get => "path"}.should route_to("these" => "options")
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with shortcut syntax" do
|
23
|
+
it "routes with extra options" do
|
24
|
+
self.should_receive(:assert_recognizes).with({ :controller => "controller", :action => "action", :extra => "options"}, { :method=> :get, :path=>"path" }, {})
|
25
|
+
get("path").should route_to("controller#action", :extra => "options")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "routes without extra options" do
|
29
|
+
self.should_receive(:assert_recognizes).with(
|
30
|
+
{:controller => "controller", :action => "action"},
|
31
|
+
{:method=> :get, :path=>"path" },
|
32
|
+
{}
|
33
|
+
)
|
34
|
+
get("path").should route_to("controller#action")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "routes with one query parameter" do
|
38
|
+
self.should_receive(:assert_recognizes).with(
|
39
|
+
{:controller => "controller", :action => "action", :queryitem => "queryvalue"},
|
40
|
+
{:method=> :get, :path=>"path" },
|
41
|
+
{'queryitem' => 'queryvalue' }
|
42
|
+
)
|
43
|
+
get("path?queryitem=queryvalue").should route_to("controller#action", :queryitem => 'queryvalue')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "routes with multiple query parameters" do
|
47
|
+
self.should_receive(:assert_recognizes).with(
|
48
|
+
{:controller => "controller", :action => "action", :queryitem => "queryvalue", :qi2 => 'qv2'},
|
49
|
+
{:method=> :get, :path=>"path"},
|
50
|
+
{'queryitem' => 'queryvalue', 'qi2' => 'qv2'}
|
51
|
+
)
|
52
|
+
get("path?queryitem=queryvalue&qi2=qv2").should route_to("controller#action", :queryitem => 'queryvalue', :qi2 => 'qv2')
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with should" do
|
58
|
+
context "when assert_recognizes passes" do
|
59
|
+
it "passes" do
|
60
|
+
expect do
|
61
|
+
{:get => "path"}.should route_to("these" => "options")
|
62
|
+
end.to_not raise_exception
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when assert_recognizes fails with an assertion failure" do
|
67
|
+
it "fails with message from assert_recognizes" do
|
68
|
+
def assert_recognizes(*)
|
69
|
+
raise ActiveSupport::TestCase::Assertion.new("this message")
|
70
|
+
end
|
71
|
+
expect do
|
72
|
+
{:get => "path"}.should route_to("these" => "options")
|
73
|
+
end.to raise_error(RSpec::Expectations::ExpectationNotMetError, "this message")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when assert_recognizes fails with a routing error" do
|
78
|
+
it "fails with message from assert_recognizes" do
|
79
|
+
def assert_recognizes(*)
|
80
|
+
raise ActionController::RoutingError.new("this message")
|
81
|
+
end
|
82
|
+
expect do
|
83
|
+
{:get => "path"}.should route_to("these" => "options")
|
84
|
+
end.to raise_error(RSpec::Expectations::ExpectationNotMetError, "this message")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when an exception is raised" do
|
89
|
+
it "raises that exception" do
|
90
|
+
def assert_recognizes(*)
|
91
|
+
raise "oops"
|
92
|
+
end
|
93
|
+
expect do
|
94
|
+
{:get => "path"}.should route_to("these" => "options")
|
95
|
+
end.to raise_exception("oops")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "with should_not" do
|
101
|
+
context "when assert_recognizes passes" do
|
102
|
+
it "fails with custom message" do
|
103
|
+
expect do
|
104
|
+
{:get => "path"}.should_not route_to("these" => "options")
|
105
|
+
end.to raise_error(/expected .* not to route to .*/)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when assert_recognizes fails with an assertion failure" do
|
110
|
+
it "passes" do
|
111
|
+
def assert_recognizes(*)
|
112
|
+
raise ActiveSupport::TestCase::Assertion.new("this message")
|
113
|
+
end
|
114
|
+
expect do
|
115
|
+
{:get => "path"}.should_not route_to("these" => "options")
|
116
|
+
end.to_not raise_error
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "when assert_recognizes fails with a routing error" do
|
121
|
+
it "passes" do
|
122
|
+
def assert_recognizes(*)
|
123
|
+
raise ActionController::RoutingError.new("this message")
|
124
|
+
end
|
125
|
+
expect do
|
126
|
+
{:get => "path"}.should_not route_to("these" => "options")
|
127
|
+
end.to_not raise_error
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when an exception is raised" do
|
132
|
+
it "raises that exception" do
|
133
|
+
def assert_recognizes(*)
|
134
|
+
raise "oops"
|
135
|
+
end
|
136
|
+
expect do
|
137
|
+
{:get => "path"}.should_not route_to("these" => "options")
|
138
|
+
end.to raise_exception("oops")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it "uses failure message from assert_recognizes" do
|
144
|
+
def assert_recognizes(*)
|
145
|
+
raise ActiveSupport::TestCase::Assertion, "this message"
|
146
|
+
end
|
147
|
+
expect do
|
148
|
+
{"this" => "path"}.should route_to("these" => "options")
|
149
|
+
end.to raise_error("this message")
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe RSpec::Rails::MinitestLifecycleAdapter do
|
4
|
+
it "invokes minitest lifecycle hooks at the appropriate times" do
|
5
|
+
invocations = []
|
6
|
+
example_group = RSpec::Core::ExampleGroup.describe("MinitestHooks") do
|
7
|
+
include RSpec::Rails::MinitestLifecycleAdapter
|
8
|
+
|
9
|
+
define_method(:before_setup) { invocations << :before_setup }
|
10
|
+
define_method(:after_setup) { invocations << :after_setup }
|
11
|
+
define_method(:before_teardown) { invocations << :before_teardown }
|
12
|
+
define_method(:after_teardown) { invocations << :after_teardown }
|
13
|
+
end
|
14
|
+
|
15
|
+
example = example_group.example("foo") { invocations << :example }
|
16
|
+
example_group.run(NullObject.new)
|
17
|
+
|
18
|
+
expect(invocations).to eq([
|
19
|
+
:before_setup, :after_setup, :example, :before_teardown, :after_teardown
|
20
|
+
])
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,378 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "mock_model(RealModel)" do
|
4
|
+
|
5
|
+
context "given a String" do
|
6
|
+
context "that does not represent an existing constant" do
|
7
|
+
it "class says it's name" do
|
8
|
+
model = mock_model("Foo")
|
9
|
+
model.class.name.should eq("Foo")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "that represents an existing constant" do
|
14
|
+
context "that extends ActiveModel::Naming" do
|
15
|
+
it "treats the constant as the class" do
|
16
|
+
model = mock_model("MockableModel")
|
17
|
+
model.class.name.should eq("MockableModel")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "that does not extend ActiveModel::Naming" do
|
22
|
+
it "raises with a helpful message" do
|
23
|
+
expect do
|
24
|
+
mock_model("String")
|
25
|
+
end.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "given a class that does not extend ActiveModel::Naming" do
|
32
|
+
it "raises with a helpful message" do
|
33
|
+
expect do
|
34
|
+
mock_model(String)
|
35
|
+
end.to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "with #id stubbed" do
|
40
|
+
before(:each) do
|
41
|
+
@model = mock_model(MockableModel, :id => 1)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "is named using the stubbed id value" do
|
45
|
+
@model.instance_variable_get(:@name).should == "MockableModel_1"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "destroy" do
|
50
|
+
it "sets persisted to false" do
|
51
|
+
model = mock_model(MockableModel)
|
52
|
+
model.destroy
|
53
|
+
model.should_not be_persisted
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "errors" do
|
58
|
+
context "default" do
|
59
|
+
it "is empty" do
|
60
|
+
model = mock_model(MockableModel)
|
61
|
+
model.errors.should be_empty
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with :save => false" do
|
66
|
+
it "is not empty" do
|
67
|
+
model = mock_model(MockableModel, :save => false)
|
68
|
+
model.errors.should_not be_empty
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with :update_attributes => false" do
|
73
|
+
it "is not empty" do
|
74
|
+
model = mock_model(MockableModel, :save => false)
|
75
|
+
model.errors.should_not be_empty
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "with params" do
|
81
|
+
it "does not mutate its parameters" do
|
82
|
+
params = {:a => 'b'}
|
83
|
+
mock_model(MockableModel, params)
|
84
|
+
params.should == {:a => 'b'}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "as association" do
|
89
|
+
before(:each) do
|
90
|
+
@real = AssociatedModel.create!
|
91
|
+
@mock_model = mock_model(MockableModel)
|
92
|
+
@real.mockable_model = @mock_model
|
93
|
+
end
|
94
|
+
|
95
|
+
it "passes: associated_model == mock" do
|
96
|
+
@mock_model.should == @real.mockable_model
|
97
|
+
end
|
98
|
+
|
99
|
+
it "passes: mock == associated_model" do
|
100
|
+
@real.mockable_model.should == @mock_model
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "as association that doesn't exist yet" do
|
105
|
+
before(:each) do
|
106
|
+
@real = AssociatedModel.create!
|
107
|
+
@mock_model = mock_model("Other")
|
108
|
+
@real.nonexistent_model = @mock_model
|
109
|
+
end
|
110
|
+
|
111
|
+
it "passes: associated_model == mock" do
|
112
|
+
@mock_model.should == @real.nonexistent_model
|
113
|
+
end
|
114
|
+
|
115
|
+
it "passes: mock == associated_model" do
|
116
|
+
@real.nonexistent_model.should == @mock_model
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#is_a?" do
|
121
|
+
before(:each) do
|
122
|
+
@model = mock_model(SubMockableModel)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "says it is_a?(RealModel)" do
|
126
|
+
@model.is_a?(SubMockableModel).should be(true)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "says it is_a?(OtherModel) if RealModel is an ancestors" do
|
130
|
+
@model.is_a?(MockableModel).should be(true)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "can be stubbed" do
|
134
|
+
mock_model(MockableModel, :is_a? => true).is_a?(:Foo).should be_truthy
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#kind_of?" do
|
139
|
+
before(:each) do
|
140
|
+
@model = mock_model(SubMockableModel)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "says it is kind_of? if RealModel is" do
|
144
|
+
@model.kind_of?(SubMockableModel).should be(true)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "says it is kind_of? if RealModel's ancestor is" do
|
148
|
+
@model.kind_of?(MockableModel).should be(true)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "can be stubbed" do
|
152
|
+
mock_model(MockableModel, :kind_of? => true).kind_of?(:Foo).should be_truthy
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "#instance_of?" do
|
157
|
+
before(:each) do
|
158
|
+
@model = mock_model(SubMockableModel)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "says it is instance_of? if RealModel is" do
|
162
|
+
@model.instance_of?(SubMockableModel).should be(true)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "does not say it instance_of? if RealModel isn't, even if it's ancestor is" do
|
166
|
+
@model.instance_of?(MockableModel).should be(false)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "can be stubbed" do
|
170
|
+
mock_model(MockableModel, :instance_of? => true).instance_of?(:Foo).should be_truthy
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#respond_to?" do
|
175
|
+
context "with an ActiveRecord model" do
|
176
|
+
before(:each) do
|
177
|
+
MockableModel.stub(:column_names).and_return(["column_a", "column_b"])
|
178
|
+
@model = mock_model(MockableModel)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "accepts two arguments" do
|
182
|
+
expect do
|
183
|
+
@model.respond_to?("title_before_type_cast", false)
|
184
|
+
end.to_not raise_exception
|
185
|
+
end
|
186
|
+
|
187
|
+
context "without as_null_object" do
|
188
|
+
it "says it will respond_to?(key) if RealModel has the attribute 'key'" do
|
189
|
+
@model.respond_to?("column_a").should be(true)
|
190
|
+
end
|
191
|
+
it "stubs column accessor (with string)" do
|
192
|
+
@model.respond_to?("column_a")
|
193
|
+
@model.column_a.should be_nil
|
194
|
+
end
|
195
|
+
it "stubs column accessor (with symbol)" do
|
196
|
+
@model.respond_to?(:column_a)
|
197
|
+
@model.column_a.should be_nil
|
198
|
+
end
|
199
|
+
it "does not stub column accessor if already stubbed in declaration (with string)" do
|
200
|
+
model = mock_model(MockableModel, "column_a" => "a")
|
201
|
+
model.respond_to?("column_a")
|
202
|
+
model.column_a.should eq("a")
|
203
|
+
end
|
204
|
+
it "does not stub column accessor if already stubbed in declaration (with symbol)" do
|
205
|
+
model = mock_model(MockableModel, :column_a => "a")
|
206
|
+
model.respond_to?("column_a")
|
207
|
+
model.column_a.should eq("a")
|
208
|
+
end
|
209
|
+
it "does not stub column accessor if already stubbed after declaration (with string)" do
|
210
|
+
@model.stub("column_a" => "a")
|
211
|
+
@model.respond_to?("column_a")
|
212
|
+
@model.column_a.should eq("a")
|
213
|
+
end
|
214
|
+
it "does not stub column accessor if already stubbed after declaration (with symbol)" do
|
215
|
+
@model.stub(:column_a => "a")
|
216
|
+
@model.respond_to?("column_a")
|
217
|
+
@model.column_a.should eq("a")
|
218
|
+
end
|
219
|
+
it "says it will not respond_to?(key) if RealModel does not have the attribute 'key'" do
|
220
|
+
@model.respond_to?("column_c").should be(false)
|
221
|
+
end
|
222
|
+
it "says it will not respond_to?(xxx_before_type_cast)" do
|
223
|
+
@model.respond_to?("title_before_type_cast").should be(false)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context "with as_null_object" do
|
228
|
+
it "says it will respond_to?(key) if RealModel has the attribute 'key'" do
|
229
|
+
@model.as_null_object.respond_to?("column_a").should be(true)
|
230
|
+
end
|
231
|
+
it "says it will respond_to?(key) even if RealModel does not have the attribute 'key'" do
|
232
|
+
@model.as_null_object.respond_to?("column_c").should be(true)
|
233
|
+
end
|
234
|
+
it "says it will not respond_to?(xxx_before_type_cast)" do
|
235
|
+
@model.as_null_object.respond_to?("title_before_type_cast").should be(false)
|
236
|
+
end
|
237
|
+
it "returns self for any unprepared message" do
|
238
|
+
@model.as_null_object.tap do |x|
|
239
|
+
x.non_existant_message.should be(@model)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context "with a non-ActiveRecord model" do
|
246
|
+
it "responds as normal" do
|
247
|
+
model = NonActiveRecordModel.new
|
248
|
+
model.should respond_to(:to_param)
|
249
|
+
end
|
250
|
+
|
251
|
+
context "with as_null_object" do
|
252
|
+
it "says it will not respond_to?(xxx_before_type_cast)" do
|
253
|
+
model = NonActiveRecordModel.new.as_null_object
|
254
|
+
model.respond_to?("title_before_type_cast").should be(false)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
it "can be stubbed" do
|
260
|
+
mock_model(MockableModel, :respond_to? => true).respond_to?(:foo).should be_truthy
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
describe "#class" do
|
265
|
+
it "returns the mocked model" do
|
266
|
+
mock_model(MockableModel).class.should eq(MockableModel)
|
267
|
+
end
|
268
|
+
|
269
|
+
it "can be stubbed" do
|
270
|
+
mock_model(MockableModel, :class => String).class.should be(String)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "#to_s" do
|
275
|
+
it "returns (model.name)_(model#to_param)" do
|
276
|
+
mock_model(MockableModel).to_s.should == "MockableModel_#{to_param}"
|
277
|
+
end
|
278
|
+
|
279
|
+
it "can be stubbed" do
|
280
|
+
mock_model(MockableModel, :to_s => "this string").to_s.should == "this string"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
describe "#destroyed?" do
|
285
|
+
context "default" do
|
286
|
+
it "returns false" do
|
287
|
+
@model = mock_model(SubMockableModel)
|
288
|
+
@model.destroyed?.should be(false)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "#marked_for_destruction?" do
|
294
|
+
context "default" do
|
295
|
+
it "returns false" do
|
296
|
+
@model = mock_model(SubMockableModel)
|
297
|
+
@model.marked_for_destruction?.should be(false)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe "#persisted?" do
|
303
|
+
context "with default identifier" do
|
304
|
+
it "returns true" do
|
305
|
+
mock_model(MockableModel).should be_persisted
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "with explicit identifier via :id" do
|
310
|
+
it "returns true" do
|
311
|
+
mock_model(MockableModel, :id => 37).should be_persisted
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context "with id => nil" do
|
316
|
+
it "returns false" do
|
317
|
+
mock_model(MockableModel, :id => nil).should_not be_persisted
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
describe "#valid?" do
|
323
|
+
context "default" do
|
324
|
+
it "returns true" do
|
325
|
+
mock_model(MockableModel).should be_valid
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context "stubbed with false" do
|
330
|
+
it "returns false" do
|
331
|
+
mock_model(MockableModel, :valid? => false).should_not be_valid
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
describe "#as_new_record" do
|
337
|
+
it "says it is a new record" do
|
338
|
+
m = mock_model(MockableModel)
|
339
|
+
m.as_new_record.should be_new_record
|
340
|
+
end
|
341
|
+
|
342
|
+
it "says it is not persisted" do
|
343
|
+
m = mock_model(MockableModel)
|
344
|
+
m.as_new_record.should_not be_persisted
|
345
|
+
end
|
346
|
+
|
347
|
+
it "has a nil id" do
|
348
|
+
mock_model(MockableModel).as_new_record.id.should be(nil)
|
349
|
+
end
|
350
|
+
|
351
|
+
it "returns nil for #to_param" do
|
352
|
+
mock_model(MockableModel).as_new_record.to_param.should be(nil)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe "#blank?" do
|
357
|
+
it "is false" do
|
358
|
+
mock_model(MockableModel).should_not be_blank
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
describe "ActiveModel Lint tests" do
|
363
|
+
require 'active_model/lint'
|
364
|
+
include RSpec::Rails::MinitestAssertionAdapter
|
365
|
+
include ActiveModel::Lint::Tests
|
366
|
+
|
367
|
+
# to_s is to support ruby-1.9
|
368
|
+
ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
|
369
|
+
example m.gsub('_',' ') do
|
370
|
+
send m
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
def model
|
375
|
+
mock_model(MockableModel, :id => nil)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|