francois-shoulda 2.0.5.4 → 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
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,29 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class HaveReadonlyAttributesMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "an attribute that cannot be set after being saved" do
6
+ setup do
7
+ define_model :example, :attr => :string do
8
+ attr_readonly :attr
9
+ end
10
+ @model = Example.new
11
+ end
12
+
13
+ should "accept being read-only" do
14
+ assert_accepts have_readonly_attribute(:attr), @model
15
+ end
16
+ end
17
+
18
+ context "an attribute that can be set after being saved" do
19
+ setup do
20
+ define_model :example, :attr => :string
21
+ @model = Example.new
22
+ end
23
+
24
+ should "accept being read-only" do
25
+ assert_rejects have_readonly_attribute(:attr), @model
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,44 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ValidateAcceptanceOfMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "an attribute which must be accepted" do
6
+ setup do
7
+ @model = define_model(:example) do
8
+ validates_acceptance_of :attr
9
+ end.new
10
+ end
11
+
12
+ should "require that attribute to be accepted" do
13
+ assert_accepts validate_acceptance_of(:attr), @model
14
+ end
15
+
16
+ should "not overwrite the default message with nil" do
17
+ assert_accepts validate_acceptance_of(:attr).with_message(nil), @model
18
+ end
19
+ end
20
+
21
+ context "an attribute that does not need to be accepted" do
22
+ setup do
23
+ @model = define_model(:example, :attr => :string).new
24
+ end
25
+
26
+ should "not require that attribute to be accepted" do
27
+ assert_rejects validate_acceptance_of(:attr), @model
28
+ end
29
+ end
30
+
31
+ context "an attribute which must be accepted with a custom message" do
32
+ setup do
33
+ @model = define_model(:example) do
34
+ validates_acceptance_of :attr, :message => 'custom'
35
+ end.new
36
+ end
37
+
38
+ should "require that attribute to be accepted with that message" do
39
+ assert_accepts validate_acceptance_of(:attr).with_message(/custom/),
40
+ @model
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,52 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ValidateNumericalityOfMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a numeric attribute" do
6
+ setup do
7
+ define_model :example, :attr => :string do
8
+ validates_numericality_of :attr
9
+ end
10
+ @model = Example.new
11
+ end
12
+
13
+ should "only allow numeric values for that attribute" do
14
+ assert_accepts validate_numericality_of(:attr), @model
15
+ end
16
+
17
+ should "not override the default message with a blank" do
18
+ assert_accepts validate_numericality_of(:attr).with_message(nil),
19
+ @model
20
+ end
21
+ end
22
+
23
+ context "a numeric attribute with a custom validation message" do
24
+ setup do
25
+ define_model :example, :attr => :string do
26
+ validates_numericality_of :attr, :message => 'custom'
27
+ end
28
+ @model = Example.new
29
+ end
30
+
31
+ should "only allow numeric values for that attribute with that message" do
32
+ assert_accepts validate_numericality_of(:attr).
33
+ with_message(/custom/),
34
+ @model
35
+ end
36
+
37
+ should "not allow numeric values for that attribute with another message" do
38
+ assert_rejects validate_numericality_of(:attr), @model
39
+ end
40
+ end
41
+
42
+ context "a non-numeric attribute" do
43
+ setup do
44
+ @model = define_model(:example, :attr => :string).new
45
+ end
46
+
47
+ should "not only allow numeric values for that attribute" do
48
+ assert_rejects validate_numericality_of(:attr), @model
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,86 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ValidatePresenceOfMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a required attribute" do
6
+ setup do
7
+ define_model :example, :attr => :string do
8
+ validates_presence_of :attr
9
+ end
10
+ @model = Example.new
11
+ end
12
+
13
+ should "require a value" do
14
+ assert_accepts validate_presence_of(:attr), @model
15
+ end
16
+
17
+ should "not override the default message with a blank" do
18
+ assert_accepts validate_presence_of(:attr).with_message(nil), @model
19
+ end
20
+ end
21
+
22
+ context "an optional attribute" do
23
+ setup do
24
+ @model = define_model(:example, :attr => :string).new
25
+ end
26
+
27
+ should "not require a value" do
28
+ assert_rejects validate_presence_of(:attr), @model
29
+ end
30
+ end
31
+
32
+ context "a required has_many association" do
33
+ setup do
34
+ define_model :child
35
+ @model = define_model :parent do
36
+ has_many :children
37
+ validates_presence_of :children
38
+ end.new
39
+ end
40
+
41
+ should "require the attribute to be set" do
42
+ assert_accepts validate_presence_of(:children), @model
43
+ end
44
+ end
45
+
46
+ context "an optional has_many association" do
47
+ setup do
48
+ define_model :child
49
+ @model = define_model :parent do
50
+ has_many :children
51
+ end.new
52
+ end
53
+
54
+ should "not require the attribute to be set" do
55
+ assert_rejects validate_presence_of(:children), @model
56
+ end
57
+ end
58
+
59
+ context "a required has_and_belongs_to_many association" do
60
+ setup do
61
+ define_model :child
62
+ @model = define_model :parent do
63
+ has_and_belongs_to_many :children
64
+ validates_presence_of :children
65
+ end.new
66
+ end
67
+
68
+ should "require the attribute to be set" do
69
+ assert_accepts validate_presence_of(:children), @model
70
+ end
71
+ end
72
+
73
+ context "an optional has_and_belongs_to_many association" do
74
+ setup do
75
+ define_model :child
76
+ @model = define_model :parent do
77
+ has_and_belongs_to_many :children
78
+ end.new
79
+ end
80
+
81
+ should "not require the attribute to be set" do
82
+ assert_rejects validate_presence_of(:children), @model
83
+ end
84
+ end
85
+
86
+ end
@@ -0,0 +1,147 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ValidateUniquenessOfMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a unique attribute" do
6
+ setup do
7
+ @model = define_model(:example, :attr => :string,
8
+ :other => :integer) do
9
+ validates_uniqueness_of :attr
10
+ end.new
11
+ end
12
+
13
+ context "with an existing value" do
14
+ setup do
15
+ @existing = Example.create!(:attr => 'value', :other => 1)
16
+ end
17
+
18
+ should "require a unique value for that attribute" do
19
+ assert_accepts validate_uniqueness_of(:attr), @model
20
+ end
21
+
22
+ should "pass when the subject is an existing record" do
23
+ assert_accepts validate_uniqueness_of(:attr), @existing
24
+ end
25
+
26
+ should "fail when a scope is specified" do
27
+ assert_rejects validate_uniqueness_of(:attr).scoped_to(:other), @model
28
+ end
29
+ end
30
+
31
+ context "without an existing value" do
32
+ setup do
33
+ assert_nil Example.find(:first)
34
+ @matcher = validate_uniqueness_of(:attr)
35
+ end
36
+
37
+ should "fail to require a unique value" do
38
+ assert_rejects @matcher, @model
39
+ end
40
+
41
+ should "alert the tester that an existing value is not present" do
42
+ @matcher.matches?(@model)
43
+ assert @matcher.negative_failure_message =~ /^Can't find first .*/
44
+ end
45
+ end
46
+ end
47
+
48
+ context "a unique attribute with a custom error and an existing value" do
49
+ setup do
50
+ @model = define_model(:example, :attr => :string) do
51
+ validates_uniqueness_of :attr, :message => 'Bad value'
52
+ end.new
53
+ Example.create!
54
+ end
55
+
56
+ should "fail when checking the default message" do
57
+ assert_rejects validate_uniqueness_of(:attr), @model
58
+ end
59
+
60
+ should "fail when checking a message that doesn't match" do
61
+ assert_rejects validate_uniqueness_of(:attr).with_message(/abc/i), @model
62
+ end
63
+
64
+ should "pass when checking a message that matches" do
65
+ assert_accepts validate_uniqueness_of(:attr).with_message(/bad/i), @model
66
+ end
67
+ end
68
+
69
+ context "a scoped unique attribute with an existing value" do
70
+ setup do
71
+ @model = define_model(:example, :attr => :string,
72
+ :scope1 => :integer,
73
+ :scope2 => :integer) do
74
+ validates_uniqueness_of :attr, :scope => [:scope1, :scope2]
75
+ end.new
76
+ @existing = Example.create!(:attr => 'value', :scope1 => 1, :scope2 => 2)
77
+ end
78
+
79
+ should "pass when the correct scope is specified" do
80
+ assert_accepts validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2),
81
+ @model
82
+ end
83
+
84
+ should "pass when the subject is an existing record" do
85
+ assert_accepts validate_uniqueness_of(:attr).scoped_to(:scope1, :scope2),
86
+ @existing
87
+ end
88
+
89
+ should "fail when a different scope is specified" do
90
+ assert_rejects validate_uniqueness_of(:attr).scoped_to(:scope1), @model
91
+ end
92
+
93
+ should "fail when no scope is specified" do
94
+ assert_rejects validate_uniqueness_of(:attr), @model
95
+ end
96
+
97
+ should "fail when a non-existent attribute is specified as a scope" do
98
+ assert_rejects validate_uniqueness_of(:attr).scoped_to(:fake), @model
99
+ end
100
+ end
101
+
102
+ context "a non-unique attribute with an existing value" do
103
+ setup do
104
+ @model = define_model(:example, :attr => :string).new
105
+ Example.create!(:attr => 'value')
106
+ end
107
+
108
+ should "not require a unique value for that attribute" do
109
+ assert_rejects validate_uniqueness_of(:attr), @model
110
+ end
111
+ end
112
+
113
+ context "a case sensitive unique attribute with an existing value" do
114
+ setup do
115
+ @model = define_model(:example, :attr => :string) do
116
+ validates_uniqueness_of :attr, :case_sensitive => true
117
+ end.new
118
+ Example.create!(:attr => 'value')
119
+ end
120
+
121
+ should "not require a unique, case-insensitive value for that attribute" do
122
+ assert_rejects validate_uniqueness_of(:attr).case_insensitive, @model
123
+ end
124
+
125
+ should "require a unique, case-sensitive value for that attribute" do
126
+ assert_accepts validate_uniqueness_of(:attr), @model
127
+ end
128
+ end
129
+
130
+ context "a case sensitive unique integer attribute with an existing value" do
131
+ setup do
132
+ @model = define_model(:example, :attr => :integer) do
133
+ validates_uniqueness_of :attr, :case_sensitive => true
134
+ end.new
135
+ Example.create!(:attr => 'value')
136
+ end
137
+
138
+ should "require a unique, case-insensitive value for that attribute" do
139
+ assert_accepts validate_uniqueness_of(:attr).case_insensitive, @model
140
+ end
141
+
142
+ should "require a unique, case-sensitive value for that attribute" do
143
+ assert_accepts validate_uniqueness_of(:attr), @model
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class AssignToMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller that assigns to an instance variable" do
6
+ setup do
7
+ @controller = build_response { @var = 'value' }
8
+ end
9
+
10
+ should "accept assigning to that variable" do
11
+ assert_accepts assign_to(:var), @controller
12
+ end
13
+
14
+ should "accept assigning to that variable with the correct class" do
15
+ assert_accepts assign_to(:var).with_kind_of(String), @controller
16
+ end
17
+
18
+ should "reject assigning to that variable with another class" do
19
+ assert_rejects assign_to(:var).with_kind_of(Fixnum), @controller
20
+ end
21
+
22
+ should "accept assigning the correct value to that variable" do
23
+ assert_accepts assign_to(:var).with('value'), @controller
24
+ end
25
+
26
+ should "reject assigning another value to that variable" do
27
+ assert_rejects assign_to(:var).with('other'), @controller
28
+ end
29
+
30
+ should "reject assigning to another variable" do
31
+ assert_rejects assign_to(:other), @controller
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class FilterParamMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller that filters no parameters" do
6
+ setup do
7
+ @controller = define_controller(:examples).new
8
+ end
9
+
10
+ should "reject filtering any parameter" do
11
+ assert_rejects filter_param(:any), @controller
12
+ end
13
+ end
14
+
15
+ context "a controller that filters a parameter" do
16
+ setup do
17
+ @controller = define_controller :examples do
18
+ filter_parameter_logging :password
19
+ end.new
20
+ end
21
+
22
+ should "accept filtering that parameter" do
23
+ assert_accepts filter_param(:password), @controller
24
+ end
25
+
26
+ should "reject filtering another parameter" do
27
+ assert_rejects filter_param(:other), @controller
28
+ end
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class RenderWithLayoutMatcherTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "a controller that renders with a layout" do
6
+ setup do
7
+ @controller = build_response { render :layout => 'wide' }
8
+ end
9
+
10
+ should "accept rendering with any layout" do
11
+ assert_accepts render_with_layout, @controller
12
+ end
13
+
14
+ should "accept rendering with that layout" do
15
+ assert_accepts render_with_layout(:wide), @controller
16
+ end
17
+
18
+ should "reject rendering with another layout" do
19
+ assert_rejects render_with_layout(:other), @controller
20
+ end
21
+ end
22
+
23
+ context "a controller that renders without a layout" do
24
+ setup do
25
+ @controller = build_response { render :layout => false }
26
+ end
27
+
28
+ should "reject rendering with a layout" do
29
+ assert_rejects render_with_layout, @controller
30
+ end
31
+ end
32
+
33
+ end