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.
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