francois-shoulda 2.0.5.4 → 2.10.1

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 (109) hide show
  1. data/README.rdoc +60 -10
  2. data/Rakefile +7 -7
  3. data/lib/shoulda.rb +7 -15
  4. data/lib/shoulda/action_controller.rb +28 -0
  5. data/lib/shoulda/action_controller/helpers.rb +47 -0
  6. data/lib/shoulda/action_controller/macros.rb +277 -0
  7. data/lib/shoulda/action_controller/matchers.rb +37 -0
  8. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  9. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  10. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  11. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
  12. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +81 -0
  13. data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  14. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +87 -0
  15. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  16. data/lib/shoulda/action_mailer.rb +1 -1
  17. data/lib/shoulda/action_mailer/assertions.rb +32 -33
  18. data/lib/shoulda/action_view.rb +10 -0
  19. data/lib/shoulda/action_view/macros.rb +56 -0
  20. data/lib/shoulda/active_record.rb +6 -2
  21. data/lib/shoulda/active_record/assertions.rb +62 -89
  22. data/lib/shoulda/active_record/helpers.rb +40 -0
  23. data/lib/shoulda/active_record/macros.rb +520 -684
  24. data/lib/shoulda/active_record/matchers.rb +42 -0
  25. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  26. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
  27. data/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
  28. data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  29. data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  30. data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  31. data/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
  32. data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
  33. data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  34. data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  35. data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  36. data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  37. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  38. data/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
  39. data/lib/shoulda/assertions.rb +50 -40
  40. data/lib/shoulda/autoload_macros.rb +46 -0
  41. data/lib/shoulda/context.rb +124 -126
  42. data/lib/shoulda/helpers.rb +5 -7
  43. data/lib/shoulda/macros.rb +63 -64
  44. data/lib/shoulda/private_helpers.rb +16 -18
  45. data/lib/shoulda/rails.rb +5 -11
  46. data/lib/shoulda/rspec.rb +11 -0
  47. data/lib/shoulda/tasks/list_tests.rake +6 -1
  48. data/lib/shoulda/test_unit.rb +19 -0
  49. data/rails/init.rb +7 -1
  50. data/test/README +2 -2
  51. data/test/fail_macros.rb +15 -15
  52. data/test/fixtures/tags.yml +1 -1
  53. data/test/functional/posts_controller_test.rb +46 -26
  54. data/test/functional/users_controller_test.rb +0 -19
  55. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +68 -0
  56. data/test/matchers/active_record/allow_value_matcher_test.rb +41 -0
  57. data/test/matchers/active_record/association_matcher_test.rb +258 -0
  58. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +80 -0
  59. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +158 -0
  60. data/test/matchers/active_record/have_db_column_matcher_test.rb +169 -0
  61. data/test/matchers/active_record/have_index_matcher_test.rb +74 -0
  62. data/test/matchers/active_record/have_named_scope_matcher_test.rb +65 -0
  63. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +29 -0
  64. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +44 -0
  65. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +52 -0
  66. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +86 -0
  67. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +147 -0
  68. data/test/matchers/controller/assign_to_matcher_test.rb +35 -0
  69. data/test/matchers/controller/filter_param_matcher_test.rb +32 -0
  70. data/test/matchers/controller/render_with_layout_matcher_test.rb +33 -0
  71. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +27 -0
  72. data/test/matchers/controller/respond_with_matcher_test.rb +106 -0
  73. data/test/matchers/controller/route_matcher_test.rb +58 -0
  74. data/test/matchers/controller/set_session_matcher_test.rb +31 -0
  75. data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
  76. data/test/model_builder.rb +106 -0
  77. data/test/other/autoload_macro_test.rb +18 -0
  78. data/test/other/helpers_test.rb +58 -0
  79. data/test/other/private_helpers_test.rb +1 -1
  80. data/test/other/should_test.rb +16 -16
  81. data/test/rails_root/app/controllers/posts_controller.rb +6 -5
  82. data/test/rails_root/app/models/pets/dog.rb +10 -0
  83. data/test/rails_root/app/models/treat.rb +3 -0
  84. data/test/rails_root/app/models/user.rb +4 -3
  85. data/test/rails_root/app/views/layouts/posts.rhtml +2 -0
  86. data/test/rails_root/config/database.yml +1 -1
  87. data/test/rails_root/config/environment.rb +1 -1
  88. data/test/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
  89. data/test/rails_root/db/migrate/001_create_users.rb +3 -2
  90. data/test/rails_root/db/migrate/011_create_treats.rb +12 -0
  91. data/test/rails_root/test/shoulda_macros/custom_macro.rb +6 -0
  92. data/test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
  93. data/test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
  94. data/test/rspec_test.rb +207 -0
  95. data/test/test_helper.rb +3 -1
  96. data/test/unit/address_test.rb +1 -23
  97. data/test/unit/dog_test.rb +5 -2
  98. data/test/unit/post_test.rb +7 -3
  99. data/test/unit/product_test.rb +2 -2
  100. data/test/unit/tag_test.rb +2 -1
  101. data/test/unit/user_test.rb +25 -9
  102. metadata +84 -23
  103. data/lib/shoulda/controller.rb +0 -30
  104. data/lib/shoulda/controller/formats/html.rb +0 -201
  105. data/lib/shoulda/controller/formats/xml.rb +0 -170
  106. data/lib/shoulda/controller/helpers.rb +0 -64
  107. data/lib/shoulda/controller/macros.rb +0 -316
  108. data/lib/shoulda/controller/resource_options.rb +0 -236
  109. data/test/rails_root/app/models/dog.rb +0 -5
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class RespondWithContentTypeMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller responding with content type :xml" do
6
+ setup do
7
+ @controller = build_response { render :xml => { :user => "thoughtbot" }.to_xml }
8
+ end
9
+
10
+ should "accept responding with content type :xml" do
11
+ assert_accepts respond_with_content_type(:xml), @controller
12
+ end
13
+
14
+ should "accept responding with content type 'application/xml'" do
15
+ assert_accepts respond_with_content_type('application/xml'), @controller
16
+ end
17
+
18
+ should "accept responding with content type /xml/" do
19
+ assert_accepts respond_with_content_type(/xml/), @controller
20
+ end
21
+
22
+ should "reject responding with another content type" do
23
+ assert_rejects respond_with_content_type(:json), @controller
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,106 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class RespondWithMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller responding with success" do
6
+ setup do
7
+ @controller = build_response { render :text => "text", :status => 200 }
8
+ end
9
+
10
+ should "accept responding with 200" do
11
+ assert_accepts respond_with(200), @controller
12
+ end
13
+
14
+ should "accept responding with :success" do
15
+ assert_accepts respond_with(:success), @controller
16
+ end
17
+
18
+ should "reject responding with another status" do
19
+ assert_rejects respond_with(:error), @controller
20
+ end
21
+ end
22
+
23
+ context "a controller responding with redirect" do
24
+ setup do
25
+ @controller = build_response { render :text => "text", :status => 301 }
26
+ end
27
+
28
+ should "accept responding with 301" do
29
+ assert_accepts respond_with(301), @controller
30
+ end
31
+
32
+ should "accept responding with :redirect" do
33
+ assert_accepts respond_with(:redirect), @controller
34
+ end
35
+
36
+ should "reject responding with another status" do
37
+ assert_rejects respond_with(:error), @controller
38
+ end
39
+ end
40
+
41
+ context "a controller responding with missing" do
42
+ setup do
43
+ @controller = build_response { render :text => "text", :status => 404 }
44
+ end
45
+
46
+ should "accept responding with 404" do
47
+ assert_accepts respond_with(404), @controller
48
+ end
49
+
50
+ should "accept responding with :missing" do
51
+ assert_accepts respond_with(:missing), @controller
52
+ end
53
+
54
+ should "reject responding with another status" do
55
+ assert_rejects respond_with(:success), @controller
56
+ end
57
+ end
58
+
59
+ context "a controller responding with error" do
60
+ setup do
61
+ @controller = build_response { render :text => "text", :status => 500 }
62
+ end
63
+
64
+ should "accept responding with 500" do
65
+ assert_accepts respond_with(500), @controller
66
+ end
67
+
68
+ should "accept responding with :error" do
69
+ assert_accepts respond_with(:error), @controller
70
+ end
71
+
72
+ should "reject responding with another status" do
73
+ assert_rejects respond_with(:success), @controller
74
+ end
75
+ end
76
+
77
+ context "a controller responding with not implemented" do
78
+ setup do
79
+ @controller = build_response { render :text => "text", :status => 501 }
80
+ end
81
+
82
+ should "accept responding with 501" do
83
+ assert_accepts respond_with(501), @controller
84
+ end
85
+
86
+ should "accept responding with :not_implemented" do
87
+ assert_accepts respond_with(:not_implemented), @controller
88
+ end
89
+
90
+ should "reject responding with another status" do
91
+ assert_rejects respond_with(:success), @controller
92
+ end
93
+ end
94
+
95
+ context "a controller raising an error" do
96
+ setup do
97
+ @controller = build_response { raise RailsError }
98
+ end
99
+
100
+ should "reject responding with any status" do
101
+ assert_rejects respond_with(:success), @controller
102
+ end
103
+ end
104
+
105
+ end
106
+
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class RouteToMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "given a controller with a defined route" do
6
+ setup do
7
+ @controller = define_controller('Examples').new
8
+ define_routes do |map|
9
+ map.connect 'examples/:id', :controller => 'examples',
10
+ :action => 'example'
11
+ end
12
+ end
13
+
14
+ should "accept routing the correct path to the correct parameters" do
15
+ assert_accepts route(:get, '/examples/1').
16
+ to(:action => 'example', :id => '1'),
17
+ @controller
18
+ end
19
+
20
+ should "accept a symbol controller" do
21
+ assert_accepts route(:get, '/examples/1').
22
+ to(:controller => :examples,
23
+ :action => 'example',
24
+ :id => '1'),
25
+ self
26
+ end
27
+
28
+ should "accept a symbol action" do
29
+ assert_accepts route(:get, '/examples/1').
30
+ to(:action => :example, :id => '1'),
31
+ @controller
32
+ end
33
+
34
+ should "accept a non-string parameter" do
35
+ assert_accepts route(:get, '/examples/1').
36
+ to(:action => 'example', :id => 1),
37
+ @controller
38
+ end
39
+
40
+ should "reject an undefined route" do
41
+ assert_rejects route(:get, '/bad_route').to(:var => 'value'), @controller
42
+ end
43
+
44
+ should "reject a route for another controller" do
45
+ @other = define_controller('Other').new
46
+ assert_rejects route(:get, '/examples/1').
47
+ to(:action => 'example', :id => '1'),
48
+ @other
49
+ end
50
+
51
+ should "reject a route for different parameters" do
52
+ assert_rejects route(:get, '/examples/1').
53
+ to(:action => 'other', :id => '1'),
54
+ @controller
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,31 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class SetSessionMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller that sets a session variable" do
6
+ setup do
7
+ @controller = build_response { session[:var] = 'value' }
8
+ end
9
+
10
+ should "accept assigning to that variable" do
11
+ assert_accepts set_session(:var), @controller
12
+ end
13
+
14
+ should "accept assigning the correct value to that variable" do
15
+ assert_accepts set_session(:var).to('value'), @controller
16
+ end
17
+
18
+ should "reject assigning another value to that variable" do
19
+ assert_rejects set_session(:var).to('other'), @controller
20
+ end
21
+
22
+ should "reject assigning to another variable" do
23
+ assert_rejects set_session(:other), @controller
24
+ end
25
+
26
+ should "accept assigning nil to another variable" do
27
+ assert_accepts set_session(:other).to(nil), @controller
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class SetTheFlashMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller that sets a flash message" do
6
+ setup do
7
+ @controller = build_response { flash[:notice] = 'value' }
8
+ end
9
+
10
+ should "accept setting any flash message" do
11
+ assert_accepts set_the_flash, @controller
12
+ end
13
+
14
+ should "accept setting the exact flash message" do
15
+ assert_accepts set_the_flash.to('value'), @controller
16
+ end
17
+
18
+ should "accept setting a matched flash message" do
19
+ assert_accepts set_the_flash.to(/value/), @controller
20
+ end
21
+
22
+ should "reject setting a different flash message" do
23
+ assert_rejects set_the_flash.to('other'), @controller
24
+ end
25
+
26
+ should "reject setting a different pattern" do
27
+ assert_rejects set_the_flash.to(/other/), @controller
28
+ end
29
+ end
30
+
31
+ context "a controller that doesn't set a flash message" do
32
+ setup do
33
+ @controller = build_response
34
+ end
35
+
36
+ should "reject setting any flash message" do
37
+ assert_rejects set_the_flash, @controller
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,106 @@
1
+ class Test::Unit::TestCase
2
+ def create_table(table_name, &block)
3
+ connection = ActiveRecord::Base.connection
4
+
5
+ begin
6
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
7
+ connection.create_table(table_name, &block)
8
+ @created_tables ||= []
9
+ @created_tables << table_name
10
+ connection
11
+ rescue Exception => e
12
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
13
+ raise e
14
+ end
15
+ end
16
+
17
+ def define_constant(class_name, base, &block)
18
+ class_name = class_name.to_s.camelize
19
+
20
+ klass = Class.new(base)
21
+ Object.const_set(class_name, klass)
22
+
23
+ klass.class_eval(&block) if block_given?
24
+
25
+ @defined_constants ||= []
26
+ @defined_constants << class_name
27
+
28
+ klass
29
+ end
30
+
31
+ def define_model_class(class_name, &block)
32
+ define_constant(class_name, ActiveRecord::Base, &block)
33
+ end
34
+
35
+ def define_model(name, columns = {}, &block)
36
+ class_name = name.to_s.pluralize.classify
37
+ table_name = class_name.tableize
38
+
39
+ create_table(table_name) do |table|
40
+ columns.each do |name, type|
41
+ table.column name, type
42
+ end
43
+ end
44
+
45
+ define_model_class(class_name, &block)
46
+ end
47
+
48
+ def define_controller(class_name, &block)
49
+ class_name = class_name.to_s
50
+ class_name << 'Controller' unless class_name =~ /Controller$/
51
+ define_constant(class_name, ActionController::Base, &block)
52
+ end
53
+
54
+ def define_routes(&block)
55
+ @replaced_routes = ActionController::Routing::Routes
56
+ new_routes = ActionController::Routing::RouteSet.new
57
+ silence_warnings do
58
+ ActionController::Routing.const_set('Routes', new_routes)
59
+ end
60
+ new_routes.draw(&block)
61
+ end
62
+
63
+ def build_response(&block)
64
+ klass = define_controller('Examples')
65
+ block ||= lambda { render :nothing => true }
66
+ klass.class_eval { define_method(:example, &block) }
67
+ define_routes do |map|
68
+ map.connect 'examples', :controller => 'examples', :action => 'example'
69
+ end
70
+
71
+ @controller = klass.new
72
+ @request = ActionController::TestRequest.new
73
+ @response = ActionController::TestResponse.new
74
+ get :example
75
+
76
+ @controller
77
+ end
78
+
79
+ def teardown_with_models
80
+ if @defined_constants
81
+ @defined_constants.each do |class_name|
82
+ Object.send(:remove_const, class_name)
83
+ end
84
+ end
85
+
86
+ if @created_tables
87
+ @created_tables.each do |table_name|
88
+ ActiveRecord::Base.
89
+ connection.
90
+ execute("DROP TABLE IF EXISTS #{table_name}")
91
+ end
92
+ end
93
+
94
+ if @replaced_routes
95
+ ActionController::Routing::Routes.clear!
96
+ silence_warnings do
97
+ ActionController::Routing.const_set('Routes', @replaced_routes)
98
+ end
99
+ @replaced_routes.reload!
100
+ end
101
+
102
+ teardown_without_models
103
+ end
104
+ alias_method :teardown_without_models, :teardown
105
+ alias_method :teardown, :teardown_with_models
106
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class AutoloadMacroTest < Test::Unit::TestCase # :nodoc:
4
+ context "The macro auto-loader" do
5
+ should "load macros from the plugins" do
6
+ assert self.class.respond_to?('plugin_macro')
7
+ end
8
+
9
+ should "load macros from the gems" do
10
+ assert self.class.respond_to?('gem_macro')
11
+ end
12
+
13
+ should "load custom macros from ROOT/test/shoulda_macros" do
14
+ assert self.class.respond_to?('custom_macro')
15
+ end
16
+ end
17
+ end
18
+
@@ -180,4 +180,62 @@ class HelpersTest < Test::Unit::TestCase # :nodoc:
180
180
  end
181
181
  end
182
182
  end
183
+
184
+ context "a matching matcher" do
185
+ setup do
186
+ @matcher = stub('matcher', :matches? => true,
187
+ :failure_message => 'bad failure message',
188
+ :negative_failure_message => 'big time failure')
189
+ end
190
+
191
+ should "pass when given to assert_accepts" do
192
+ assert_accepts @matcher, 'target'
193
+ end
194
+
195
+ context "when given to assert_rejects" do
196
+ setup do
197
+ begin
198
+ assert_rejects @matcher, 'target'
199
+ rescue Test::Unit::AssertionFailedError => @error
200
+ end
201
+ end
202
+
203
+ should "fail" do
204
+ assert_not_nil @error
205
+ end
206
+
207
+ should "use the error message from the matcher" do
208
+ assert_equal 'big time failure', @error.message
209
+ end
210
+ end
211
+ end
212
+
213
+ context "a non-matching matcher" do
214
+ setup do
215
+ @matcher = stub('matcher', :matches? => false,
216
+ :failure_message => 'big time failure',
217
+ :negative_failure_message => 'bad failure message')
218
+ end
219
+
220
+ should "pass when given to assert_rejects" do
221
+ assert_rejects @matcher, 'target'
222
+ end
223
+
224
+ context "when given to assert_accepts" do
225
+ setup do
226
+ begin
227
+ assert_accepts @matcher, 'target'
228
+ rescue Test::Unit::AssertionFailedError => @error
229
+ end
230
+ end
231
+
232
+ should "fail" do
233
+ assert_not_nil @error
234
+ end
235
+
236
+ should "use the error message from the matcher" do
237
+ assert_equal 'big time failure', @error.message
238
+ end
239
+ end
240
+ end
183
241
  end