rspec-rails 2.99.0 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +40 -68
  5. data/License.txt +1 -0
  6. data/README.md +6 -4
  7. data/features/Generators.md +24 -0
  8. data/features/GettingStarted.md +84 -0
  9. data/features/README.md +56 -0
  10. data/features/RailsVersions.md +4 -0
  11. data/features/Transactions.md +84 -0
  12. data/features/Upgrade.md +121 -0
  13. data/features/controller_specs/Cookies.md +57 -0
  14. data/features/controller_specs/README.md +45 -0
  15. data/features/controller_specs/anonymous_controller.feature +378 -0
  16. data/features/controller_specs/bypass_rescue.feature +75 -0
  17. data/features/controller_specs/controller_spec.feature +58 -0
  18. data/features/controller_specs/engine_routes.feature +51 -0
  19. data/features/controller_specs/isolation_from_views.feature +87 -0
  20. data/features/controller_specs/render_views.feature +114 -0
  21. data/features/directory_structure.feature +71 -0
  22. data/features/feature_specs/feature_spec.feature +35 -0
  23. data/features/helper_specs/helper_spec.feature +122 -0
  24. data/features/mailer_specs/url_helpers.feature +38 -0
  25. data/features/matchers/README.md +18 -0
  26. data/features/matchers/new_record_matcher.feature +41 -0
  27. data/features/matchers/redirect_to_matcher.feature +40 -0
  28. data/features/matchers/relation_match_array.feature +27 -0
  29. data/features/matchers/render_template_matcher.feature +49 -0
  30. data/features/mocks/mock_model.feature +147 -0
  31. data/features/mocks/stub_model.feature +58 -0
  32. data/features/model_specs/README.md +21 -0
  33. data/features/model_specs/errors_on.feature +51 -0
  34. data/features/model_specs/records.feature +27 -0
  35. data/features/model_specs/transactional_examples.feature +109 -0
  36. data/features/request_specs/request_spec.feature +49 -0
  37. data/features/routing_specs/README.md +16 -0
  38. data/features/routing_specs/be_routable_matcher.feature +80 -0
  39. data/features/routing_specs/engine_routes.feature +38 -0
  40. data/features/routing_specs/named_routes.feature +18 -0
  41. data/features/routing_specs/route_to_matcher.feature +90 -0
  42. data/features/step_definitions/additional_cli_steps.rb +4 -0
  43. data/features/step_definitions/model_steps.rb +3 -0
  44. data/features/support/capybara.rb +7 -0
  45. data/features/support/env.rb +53 -0
  46. data/features/support/rails_versions.rb +4 -0
  47. data/features/support/rubinius.rb +6 -0
  48. data/features/view_specs/inferred_controller_path.feature +45 -0
  49. data/features/view_specs/stub_template.feature +51 -0
  50. data/features/view_specs/view_spec.feature +206 -0
  51. data/lib/generators/rspec/controller/templates/controller_spec.rb +1 -1
  52. data/lib/generators/rspec/install/templates/spec/spec_helper.rb.tt +2 -21
  53. data/lib/generators/rspec/integration/integration_generator.rb +2 -3
  54. data/lib/generators/rspec/integration/templates/request_spec.rb +1 -1
  55. data/lib/generators/rspec/mailer/templates/mailer_spec.rb +4 -4
  56. data/lib/generators/rspec/scaffold/scaffold_generator.rb +2 -3
  57. data/lib/generators/rspec/scaffold/templates/controller_spec.rb +16 -16
  58. data/lib/generators/rspec/scaffold/templates/edit_spec.rb +2 -2
  59. data/lib/generators/rspec/scaffold/templates/index_spec.rb +1 -1
  60. data/lib/generators/rspec/scaffold/templates/new_spec.rb +2 -2
  61. data/lib/generators/rspec/scaffold/templates/routing_spec.rb +7 -7
  62. data/lib/generators/rspec/scaffold/templates/show_spec.rb +2 -2
  63. data/lib/rspec/rails.rb +0 -5
  64. data/lib/rspec/rails/adapters.rb +5 -12
  65. data/lib/rspec/rails/example.rb +55 -24
  66. data/lib/rspec/rails/example/controller_example_group.rb +7 -31
  67. data/lib/rspec/rails/example/view_example_group.rb +0 -3
  68. data/lib/rspec/rails/matchers.rb +1 -2
  69. data/lib/rspec/rails/matchers/be_a_new.rb +1 -1
  70. data/lib/rspec/rails/matchers/be_new_record.rb +1 -1
  71. data/lib/rspec/rails/matchers/be_valid.rb +1 -1
  72. data/lib/rspec/rails/matchers/have_rendered.rb +1 -1
  73. data/lib/rspec/rails/matchers/redirect_to.rb +1 -1
  74. data/lib/rspec/rails/matchers/relation_match_array.rb +1 -1
  75. data/lib/rspec/rails/matchers/routing_matchers.rb +6 -10
  76. data/lib/rspec/rails/mocks.rb +5 -41
  77. data/lib/rspec/rails/tasks/rspec.rake +5 -12
  78. data/lib/rspec/rails/vendor/capybara.rb +4 -35
  79. data/lib/rspec/rails/version.rb +1 -1
  80. data/spec/generators/rspec/controller/controller_generator_spec.rb +97 -0
  81. data/spec/generators/rspec/helper/helper_generator_spec.rb +30 -0
  82. data/spec/generators/rspec/install/install_generator_spec.rb +30 -0
  83. data/spec/generators/rspec/integration/integration_generator_spec.rb +44 -0
  84. data/spec/generators/rspec/mailer/mailer_generator_spec.rb +48 -0
  85. data/spec/generators/rspec/model/model_generator_spec.rb +52 -0
  86. data/spec/generators/rspec/observer/observer_generator_spec.rb +21 -0
  87. data/spec/generators/rspec/scaffold/scaffold_generator_spec.rb +138 -0
  88. data/spec/generators/rspec/view/view_generator_spec.rb +41 -0
  89. data/spec/rspec/rails/assertion_adapter_spec.rb +28 -0
  90. data/spec/rspec/rails/assertion_delegator_spec.rb +43 -0
  91. data/spec/rspec/rails/configuration_spec.rb +26 -0
  92. data/spec/rspec/rails/deprecations_spec.rb +18 -0
  93. data/spec/rspec/rails/example/controller_example_group_spec.rb +100 -0
  94. data/spec/rspec/rails/example/feature_example_group_spec.rb +56 -0
  95. data/spec/rspec/rails/example/helper_example_group_spec.rb +66 -0
  96. data/spec/rspec/rails/example/mailer_example_group_spec.rb +21 -0
  97. data/spec/rspec/rails/example/model_example_group_spec.rb +15 -0
  98. data/spec/rspec/rails/example/request_example_group_spec.rb +17 -0
  99. data/spec/rspec/rails/example/routing_example_group_spec.rb +32 -0
  100. data/spec/rspec/rails/example/view_example_group_spec.rb +220 -0
  101. data/spec/rspec/rails/extensions/active_model/errors_on_spec.rb +23 -0
  102. data/spec/rspec/rails/extensions/active_record/base_spec.rb +42 -0
  103. data/spec/rspec/rails/fixture_support_spec.rb +17 -0
  104. data/spec/rspec/rails/matchers/be_a_new_spec.rb +142 -0
  105. data/spec/rspec/rails/matchers/be_new_record_spec.rb +33 -0
  106. data/spec/rspec/rails/matchers/be_routable_spec.rb +41 -0
  107. data/spec/rspec/rails/matchers/be_valid_spec.rb +44 -0
  108. data/spec/rspec/rails/matchers/has_spec.rb +29 -0
  109. data/spec/rspec/rails/matchers/have_rendered_spec.rb +93 -0
  110. data/spec/rspec/rails/matchers/redirect_to_spec.rb +80 -0
  111. data/spec/rspec/rails/matchers/relation_match_array_spec.rb +31 -0
  112. data/spec/rspec/rails/matchers/route_to_spec.rb +151 -0
  113. data/spec/rspec/rails/minitest_lifecycle_adapter_spec.rb +22 -0
  114. data/spec/rspec/rails/mocks/mock_model_spec.rb +378 -0
  115. data/spec/rspec/rails/mocks/stub_model_spec.rb +154 -0
  116. data/spec/rspec/rails/setup_and_teardown_adapter_spec.rb +32 -0
  117. data/spec/rspec/rails/view_rendering_spec.rb +111 -0
  118. data/spec/spec_helper.rb +35 -0
  119. data/spec/support/ar_classes.rb +42 -0
  120. data/spec/support/helpers.rb +20 -0
  121. data/spec/support/matchers.rb +9 -0
  122. data/spec/support/null_object.rb +6 -0
  123. metadata +229 -42
  124. metadata.gz.sig +0 -0
  125. data/lib/autotest/rails_rspec2.rb +0 -91
  126. data/lib/rspec/rails/infer_type_configuration.rb +0 -26
  127. data/lib/rspec/rails/matchers/have_extension.rb +0 -36
  128. 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