tpitale-shoulda 2.11.0

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 (170) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +10 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +171 -0
  4. data/Rakefile +71 -0
  5. data/bin/convert_to_should_syntax +42 -0
  6. data/lib/shoulda.rb +11 -0
  7. data/lib/shoulda/action_controller.rb +26 -0
  8. data/lib/shoulda/action_controller/macros.rb +240 -0
  9. data/lib/shoulda/action_controller/matchers.rb +37 -0
  10. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  11. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  12. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  13. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +74 -0
  14. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +81 -0
  15. data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  16. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +87 -0
  17. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  18. data/lib/shoulda/action_mailer.rb +10 -0
  19. data/lib/shoulda/action_mailer/assertions.rb +38 -0
  20. data/lib/shoulda/action_view.rb +10 -0
  21. data/lib/shoulda/action_view/macros.rb +61 -0
  22. data/lib/shoulda/active_record.rb +16 -0
  23. data/lib/shoulda/active_record/assertions.rb +69 -0
  24. data/lib/shoulda/active_record/helpers.rb +27 -0
  25. data/lib/shoulda/active_record/macros.rb +512 -0
  26. data/lib/shoulda/active_record/matchers.rb +43 -0
  27. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  28. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
  29. data/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
  30. data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  31. data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  32. data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  33. data/lib/shoulda/active_record/matchers/have_db_index_matcher.rb +112 -0
  34. data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +128 -0
  35. data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  36. data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  37. data/lib/shoulda/active_record/matchers/validate_format_of_matcher.rb +67 -0
  38. data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  39. data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  40. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  41. data/lib/shoulda/active_record/matchers/validation_matcher.rb +57 -0
  42. data/lib/shoulda/assertions.rb +71 -0
  43. data/lib/shoulda/autoload_macros.rb +46 -0
  44. data/lib/shoulda/context.rb +413 -0
  45. data/lib/shoulda/helpers.rb +8 -0
  46. data/lib/shoulda/macros.rb +133 -0
  47. data/lib/shoulda/minitest.rb +24 -0
  48. data/lib/shoulda/private_helpers.rb +13 -0
  49. data/lib/shoulda/proc_extensions.rb +14 -0
  50. data/lib/shoulda/rails.rb +13 -0
  51. data/lib/shoulda/rspec.rb +11 -0
  52. data/lib/shoulda/tasks.rb +3 -0
  53. data/lib/shoulda/tasks/list_tests.rake +29 -0
  54. data/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  55. data/lib/shoulda/test_unit.rb +22 -0
  56. data/rails/init.rb +7 -0
  57. data/test/README +36 -0
  58. data/test/fail_macros.rb +39 -0
  59. data/test/fixtures/addresses.yml +3 -0
  60. data/test/fixtures/friendships.yml +0 -0
  61. data/test/fixtures/posts.yml +5 -0
  62. data/test/fixtures/products.yml +0 -0
  63. data/test/fixtures/taggings.yml +0 -0
  64. data/test/fixtures/tags.yml +9 -0
  65. data/test/fixtures/users.yml +6 -0
  66. data/test/functional/posts_controller_test.rb +121 -0
  67. data/test/functional/users_controller_test.rb +19 -0
  68. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +68 -0
  69. data/test/matchers/active_record/allow_value_matcher_test.rb +64 -0
  70. data/test/matchers/active_record/association_matcher_test.rb +263 -0
  71. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +80 -0
  72. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +158 -0
  73. data/test/matchers/active_record/have_db_column_matcher_test.rb +169 -0
  74. data/test/matchers/active_record/have_db_index_matcher_test.rb +91 -0
  75. data/test/matchers/active_record/have_named_scope_matcher_test.rb +65 -0
  76. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +29 -0
  77. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +44 -0
  78. data/test/matchers/active_record/validate_format_of_matcher_test.rb +39 -0
  79. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +52 -0
  80. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +86 -0
  81. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +147 -0
  82. data/test/matchers/controller/assign_to_matcher_test.rb +35 -0
  83. data/test/matchers/controller/filter_param_matcher_test.rb +32 -0
  84. data/test/matchers/controller/render_with_layout_matcher_test.rb +33 -0
  85. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +32 -0
  86. data/test/matchers/controller/respond_with_matcher_test.rb +106 -0
  87. data/test/matchers/controller/route_matcher_test.rb +58 -0
  88. data/test/matchers/controller/set_session_matcher_test.rb +38 -0
  89. data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
  90. data/test/model_builder.rb +106 -0
  91. data/test/other/autoload_macro_test.rb +18 -0
  92. data/test/other/context_test.rb +203 -0
  93. data/test/other/convert_to_should_syntax_test.rb +63 -0
  94. data/test/other/helpers_test.rb +340 -0
  95. data/test/other/private_helpers_test.rb +32 -0
  96. data/test/other/should_test.rb +271 -0
  97. data/test/rails_root/app/controllers/application_controller.rb +25 -0
  98. data/test/rails_root/app/controllers/posts_controller.rb +87 -0
  99. data/test/rails_root/app/controllers/users_controller.rb +84 -0
  100. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  101. data/test/rails_root/app/helpers/posts_helper.rb +2 -0
  102. data/test/rails_root/app/helpers/users_helper.rb +2 -0
  103. data/test/rails_root/app/models/address.rb +7 -0
  104. data/test/rails_root/app/models/flea.rb +3 -0
  105. data/test/rails_root/app/models/friendship.rb +4 -0
  106. data/test/rails_root/app/models/pets/cat.rb +7 -0
  107. data/test/rails_root/app/models/pets/dog.rb +10 -0
  108. data/test/rails_root/app/models/post.rb +12 -0
  109. data/test/rails_root/app/models/product.rb +12 -0
  110. data/test/rails_root/app/models/profile.rb +2 -0
  111. data/test/rails_root/app/models/registration.rb +2 -0
  112. data/test/rails_root/app/models/tag.rb +8 -0
  113. data/test/rails_root/app/models/tagging.rb +4 -0
  114. data/test/rails_root/app/models/treat.rb +3 -0
  115. data/test/rails_root/app/models/user.rb +32 -0
  116. data/test/rails_root/app/views/layouts/posts.rhtml +19 -0
  117. data/test/rails_root/app/views/layouts/users.rhtml +17 -0
  118. data/test/rails_root/app/views/layouts/wide.html.erb +1 -0
  119. data/test/rails_root/app/views/posts/edit.rhtml +27 -0
  120. data/test/rails_root/app/views/posts/index.rhtml +25 -0
  121. data/test/rails_root/app/views/posts/new.rhtml +26 -0
  122. data/test/rails_root/app/views/posts/show.rhtml +18 -0
  123. data/test/rails_root/app/views/users/edit.rhtml +22 -0
  124. data/test/rails_root/app/views/users/index.rhtml +22 -0
  125. data/test/rails_root/app/views/users/new.rhtml +21 -0
  126. data/test/rails_root/app/views/users/show.rhtml +13 -0
  127. data/test/rails_root/config/boot.rb +110 -0
  128. data/test/rails_root/config/database.yml +4 -0
  129. data/test/rails_root/config/environment.rb +18 -0
  130. data/test/rails_root/config/environments/test.rb +0 -0
  131. data/test/rails_root/config/initializers/new_rails_defaults.rb +15 -0
  132. data/test/rails_root/config/initializers/shoulda.rb +8 -0
  133. data/test/rails_root/config/routes.rb +6 -0
  134. data/test/rails_root/db/migrate/001_create_users.rb +19 -0
  135. data/test/rails_root/db/migrate/002_create_posts.rb +13 -0
  136. data/test/rails_root/db/migrate/003_create_taggings.rb +12 -0
  137. data/test/rails_root/db/migrate/004_create_tags.rb +11 -0
  138. data/test/rails_root/db/migrate/005_create_dogs.rb +12 -0
  139. data/test/rails_root/db/migrate/006_create_addresses.rb +14 -0
  140. data/test/rails_root/db/migrate/007_create_fleas.rb +11 -0
  141. data/test/rails_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  142. data/test/rails_root/db/migrate/009_create_products.rb +17 -0
  143. data/test/rails_root/db/migrate/010_create_friendships.rb +14 -0
  144. data/test/rails_root/db/migrate/011_create_treats.rb +12 -0
  145. data/test/rails_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  146. data/test/rails_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  147. data/test/rails_root/db/migrate/20090513104502_create_cats.rb +12 -0
  148. data/test/rails_root/db/schema.rb +0 -0
  149. data/test/rails_root/log/test.log +1 -0
  150. data/test/rails_root/public/404.html +30 -0
  151. data/test/rails_root/public/422.html +30 -0
  152. data/test/rails_root/public/500.html +30 -0
  153. data/test/rails_root/script/console +3 -0
  154. data/test/rails_root/script/generate +3 -0
  155. data/test/rails_root/test/shoulda_macros/custom_macro.rb +6 -0
  156. data/test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
  157. data/test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
  158. data/test/rspec_test.rb +207 -0
  159. data/test/test_helper.rb +28 -0
  160. data/test/unit/address_test.rb +10 -0
  161. data/test/unit/cat_test.rb +7 -0
  162. data/test/unit/dog_test.rb +9 -0
  163. data/test/unit/flea_test.rb +6 -0
  164. data/test/unit/friendship_test.rb +6 -0
  165. data/test/unit/post_test.rb +19 -0
  166. data/test/unit/product_test.rb +23 -0
  167. data/test/unit/tag_test.rb +15 -0
  168. data/test/unit/tagging_test.rb +6 -0
  169. data/test/unit/user_test.rb +80 -0
  170. metadata +226 -0
@@ -0,0 +1,80 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class EnsureInclusionOfMatcherTest < ActiveSupport::TestCase # :nodoc:
4
+
5
+ context "an attribute which must be included in a range" do
6
+ setup do
7
+ @model = define_model(:example, :attr => :integer) do
8
+ validates_inclusion_of :attr, :in => 2..5
9
+ end.new
10
+ end
11
+
12
+ should "accept ensuring the correct range" do
13
+ assert_accepts ensure_inclusion_of(:attr).in_range(2..5), @model
14
+ end
15
+
16
+ should "reject ensuring a lower minimum value" do
17
+ assert_rejects ensure_inclusion_of(:attr).in_range(1..5), @model
18
+ end
19
+
20
+ should "reject ensuring a higher minimum value" do
21
+ assert_rejects ensure_inclusion_of(:attr).in_range(3..5), @model
22
+ end
23
+
24
+ should "reject ensuring a lower maximum value" do
25
+ assert_rejects ensure_inclusion_of(:attr).in_range(2..4), @model
26
+ end
27
+
28
+ should "reject ensuring a higher maximum value" do
29
+ assert_rejects ensure_inclusion_of(:attr).in_range(2..6), @model
30
+ end
31
+
32
+ should "not override the default message with a blank" do
33
+ assert_accepts ensure_inclusion_of(:attr).
34
+ in_range(2..5).
35
+ with_message(nil),
36
+ @model
37
+ end
38
+ end
39
+
40
+ context "an attribute with a custom ranged value validation" do
41
+ setup do
42
+ @model = define_model(:example, :attr => :string) do
43
+ validates_inclusion_of :attr, :in => 2..4, :message => 'not good'
44
+
45
+ end.new
46
+ end
47
+
48
+ should "accept ensuring the correct range" do
49
+ assert_accepts ensure_inclusion_of(:attr).
50
+ in_range(2..4).
51
+ with_message(/not good/),
52
+ @model
53
+ end
54
+ end
55
+
56
+ context "an attribute with custom range validations" do
57
+ setup do
58
+ define_model :example, :attr => :integer do
59
+ def validate
60
+ if attr < 2
61
+ errors.add(:attr, 'too low')
62
+ elsif attr > 5
63
+ errors.add(:attr, 'too high')
64
+ end
65
+ end
66
+ end
67
+ @model = Example.new
68
+ end
69
+
70
+ should "accept ensuring the correct range and messages" do
71
+ assert_accepts ensure_inclusion_of(:attr).
72
+ in_range(2..5).
73
+ with_low_message(/low/).
74
+ with_high_message(/high/),
75
+ @model
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,158 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class EnsureLengthOfMatcher < ActiveSupport::TestCase # :nodoc:
4
+
5
+ context "an attribute with a non-zero minimum length validation" do
6
+ setup do
7
+ @model = define_model(:example, :attr => :string) do
8
+ validates_length_of :attr, :minimum => 4
9
+ end.new
10
+ end
11
+
12
+ should "accept ensuring the correct minimum length" do
13
+ assert_accepts ensure_length_of(:attr).is_at_least(4), @model
14
+ end
15
+
16
+ should "reject ensuring a lower minimum length with any message" do
17
+ assert_rejects ensure_length_of(:attr).
18
+ is_at_least(3).
19
+ with_short_message(/.*/),
20
+ @model
21
+ end
22
+
23
+ should "reject ensuring a higher minimum length with any message" do
24
+ assert_rejects ensure_length_of(:attr).
25
+ is_at_least(5).
26
+ with_short_message(/.*/),
27
+ @model
28
+ end
29
+
30
+ should "not override the default message with a blank" do
31
+ assert_accepts ensure_length_of(:attr).
32
+ is_at_least(4).
33
+ with_short_message(nil),
34
+ @model
35
+ end
36
+ end
37
+
38
+ context "an attribute with a minimum length validation of 0" do
39
+ setup do
40
+ @model = define_model(:example, :attr => :string) do
41
+ validates_length_of :attr, :minimum => 0
42
+ end.new
43
+ end
44
+
45
+ should "accept ensuring the correct minimum length" do
46
+ assert_accepts ensure_length_of(:attr).is_at_least(0), @model
47
+ end
48
+ end
49
+
50
+ context "an attribute with a maximum length" do
51
+ setup do
52
+ @model = define_model(:example, :attr => :string) do
53
+ validates_length_of :attr, :maximum => 4
54
+ end.new
55
+ end
56
+
57
+ should "accept ensuring the correct maximum length" do
58
+ assert_accepts ensure_length_of(:attr).is_at_most(4), @model
59
+ end
60
+
61
+ should "reject ensuring a lower maximum length with any message" do
62
+ assert_rejects ensure_length_of(:attr).
63
+ is_at_most(3).
64
+ with_long_message(/.*/),
65
+ @model
66
+ end
67
+
68
+ should "reject ensuring a higher maximum length with any message" do
69
+ assert_rejects ensure_length_of(:attr).
70
+ is_at_most(5).
71
+ with_long_message(/.*/),
72
+ @model
73
+ end
74
+
75
+ should "not override the default message with a blank" do
76
+ assert_accepts ensure_length_of(:attr).
77
+ is_at_most(4).
78
+ with_long_message(nil),
79
+ @model
80
+ end
81
+ end
82
+
83
+ context "an attribute with a required exact length" do
84
+ setup do
85
+ @model = define_model(:example, :attr => :string) do
86
+ validates_length_of :attr, :is => 4
87
+ end.new
88
+ end
89
+
90
+ should "accept ensuring the correct length" do
91
+ assert_accepts ensure_length_of(:attr).is_equal_to(4), @model
92
+ end
93
+
94
+ should "reject ensuring a lower maximum length with any message" do
95
+ assert_rejects ensure_length_of(:attr).
96
+ is_equal_to(3).
97
+ with_message(/.*/),
98
+ @model
99
+ end
100
+
101
+ should "reject ensuring a higher maximum length with any message" do
102
+ assert_rejects ensure_length_of(:attr).
103
+ is_equal_to(5).
104
+ with_message(/.*/),
105
+ @model
106
+ end
107
+
108
+ should "not override the default message with a blank" do
109
+ assert_accepts ensure_length_of(:attr).
110
+ is_equal_to(4).
111
+ with_message(nil),
112
+ @model
113
+ end
114
+ end
115
+
116
+ context "an attribute with a custom minimum length validation" do
117
+ setup do
118
+ @model = define_model(:example, :attr => :string) do
119
+ validates_length_of :attr, :minimum => 4, :too_short => 'short'
120
+ end.new
121
+ end
122
+
123
+ should "accept ensuring the correct minimum length" do
124
+ assert_accepts ensure_length_of(:attr).
125
+ is_at_least(4).
126
+ with_short_message(/short/),
127
+ @model
128
+ end
129
+
130
+ end
131
+
132
+ context "an attribute with a custom maximum length validation" do
133
+ setup do
134
+ @model = define_model(:example, :attr => :string) do
135
+ validates_length_of :attr, :maximum => 4, :too_long => 'long'
136
+ end.new
137
+ end
138
+
139
+ should "accept ensuring the correct minimum length" do
140
+ assert_accepts ensure_length_of(:attr).
141
+ is_at_most(4).
142
+ with_long_message(/long/),
143
+ @model
144
+ end
145
+
146
+ end
147
+
148
+ context "an attribute without a length validation" do
149
+ setup do
150
+ @model = define_model(:example, :attr => :string).new
151
+ end
152
+
153
+ should "reject ensuring a minimum length" do
154
+ assert_rejects ensure_length_of(:attr).is_at_least(1), @model
155
+ end
156
+ end
157
+
158
+ end
@@ -0,0 +1,169 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class HaveDbColumnMatcherTest < ActiveSupport::TestCase # :nodoc:
4
+
5
+ context "have_db_column" do
6
+ setup do
7
+ @matcher = have_db_column(:nickname)
8
+ end
9
+
10
+ should "accept an existing database column" do
11
+ create_table 'superheros' do |table|
12
+ table.string :nickname
13
+ end
14
+ define_model_class 'Superhero'
15
+ assert_accepts @matcher, Superhero.new
16
+ end
17
+
18
+ should "reject a nonexistent database column" do
19
+ define_model :superhero
20
+ assert_rejects @matcher, Superhero.new
21
+ end
22
+ end
23
+
24
+ context "have_db_column of type string" do
25
+ setup do
26
+ @matcher = have_db_column(:nickname).of_type(:string)
27
+ end
28
+
29
+ should "accept a column of correct type" do
30
+ create_table 'superheros' do |table|
31
+ table.string :nickname
32
+ end
33
+ define_model_class 'Superhero'
34
+ assert_accepts @matcher, Superhero.new
35
+ end
36
+
37
+ should "reject a nonexistent database column" do
38
+ define_model :superhero
39
+ assert_rejects @matcher, Superhero.new
40
+ end
41
+
42
+ should "reject a column of wrong type" do
43
+ create_table 'superheros' do |table|
44
+ table.integer :nickname
45
+ end
46
+ define_model_class 'Superhero'
47
+ assert_rejects @matcher, Superhero.new
48
+ end
49
+ end
50
+
51
+ context "have_db_column with precision option" do
52
+ setup do
53
+ @matcher = have_db_column(:salary).with_options(:precision => 5)
54
+ end
55
+
56
+ should "accept a column of correct precision" do
57
+ create_table 'superheros' do |table|
58
+ table.decimal :salary, :precision => 5
59
+ end
60
+ define_model_class 'Superhero'
61
+ assert_accepts @matcher, Superhero.new
62
+ end
63
+
64
+ should "reject a column of wrong precision" do
65
+ create_table 'superheros' do |table|
66
+ table.decimal :salary, :precision => 15
67
+ end
68
+ define_model_class 'Superhero'
69
+ assert_rejects @matcher, Superhero.new
70
+ end
71
+ end
72
+
73
+ context "have_db_column with limit option" do
74
+ setup do
75
+ @matcher = have_db_column(:email).
76
+ of_type(:string).
77
+ with_options(:limit => 255)
78
+ end
79
+
80
+ should "accept a column of correct limit" do
81
+ create_table 'superheros' do |table|
82
+ table.string :email, :limit => 255
83
+ end
84
+ define_model_class 'Superhero'
85
+ assert_accepts @matcher, Superhero.new
86
+ end
87
+
88
+ should "reject a column of wrong limit" do
89
+ create_table 'superheros' do |table|
90
+ table.string :email, :limit => 500
91
+ end
92
+ define_model_class 'Superhero'
93
+ assert_rejects @matcher, Superhero.new
94
+ end
95
+ end
96
+
97
+ context "have_db_column with default option" do
98
+ setup do
99
+ @matcher = have_db_column(:admin).
100
+ of_type(:boolean).
101
+ with_options(:default => false)
102
+ end
103
+
104
+ should "accept a column of correct default" do
105
+ create_table 'superheros' do |table|
106
+ table.boolean :admin, :default => false
107
+ end
108
+ define_model_class 'Superhero'
109
+ assert_accepts @matcher, Superhero.new
110
+ end
111
+
112
+ should "reject a column of wrong default" do
113
+ create_table 'superheros' do |table|
114
+ table.boolean :admin, :default => true
115
+ end
116
+ define_model_class 'Superhero'
117
+ assert_rejects @matcher, Superhero.new
118
+ end
119
+ end
120
+
121
+ context "have_db_column with null option" do
122
+ setup do
123
+ @matcher = have_db_column(:admin).
124
+ of_type(:boolean).
125
+ with_options(:null => false)
126
+ end
127
+
128
+ should "accept a column of correct null" do
129
+ create_table 'superheros' do |table|
130
+ table.boolean :admin, :null => false
131
+ end
132
+ define_model_class 'Superhero'
133
+ assert_accepts @matcher, Superhero.new
134
+ end
135
+
136
+ should "reject a column of wrong null" do
137
+ create_table 'superheros' do |table|
138
+ table.boolean :admin, :null => true
139
+ end
140
+ define_model_class 'Superhero'
141
+ assert_rejects @matcher, Superhero.new
142
+ end
143
+ end
144
+
145
+ context "have_db_column with scale option" do
146
+ setup do
147
+ @matcher = have_db_column(:salary).
148
+ of_type(:decimal).
149
+ with_options(:scale => 2)
150
+ end
151
+
152
+ should "accept a column of correct scale" do
153
+ create_table 'superheros' do |table|
154
+ table.decimal :salary, :precision => 10, :scale => 2
155
+ end
156
+ define_model_class 'Superhero'
157
+ assert_accepts @matcher, Superhero.new
158
+ end
159
+
160
+ should "reject a column of wrong scale" do
161
+ create_table 'superheros' do |table|
162
+ table.decimal :salary, :precision => 10, :scale => 4
163
+ end
164
+ define_model_class 'Superhero'
165
+ assert_rejects @matcher, Superhero.new
166
+ end
167
+ end
168
+
169
+ end
@@ -0,0 +1,91 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class HaveDbIndexMatcherTest < ActiveSupport::TestCase # :nodoc:
4
+
5
+ context "have_db_index" do
6
+ setup do
7
+ @matcher = have_db_index(:age)
8
+ end
9
+
10
+ should "accept an existing index" do
11
+ db_connection = create_table 'superheros' do |table|
12
+ table.integer :age
13
+ end
14
+ db_connection.add_index :superheros, :age
15
+ define_model_class 'Superhero'
16
+ assert_accepts @matcher, Superhero.new
17
+ end
18
+
19
+ should "reject a nonexistent index" do
20
+ define_model :superhero
21
+ assert_rejects @matcher, Superhero.new
22
+ end
23
+ end
24
+
25
+ context "have_db_index with unique option" do
26
+ setup do
27
+ @matcher = have_db_index(:ssn).unique(true)
28
+ end
29
+
30
+ should "accept an index of correct unique" do
31
+ db_connection = create_table 'superheros' do |table|
32
+ table.integer :ssn
33
+ end
34
+ db_connection.add_index :superheros, :ssn, :unique => true
35
+ define_model_class 'Superhero'
36
+ assert_accepts @matcher, Superhero.new
37
+ end
38
+
39
+ should "reject an index of wrong unique" do
40
+ db_connection = create_table 'superheros' do |table|
41
+ table.integer :ssn
42
+ end
43
+ db_connection.add_index :superheros, :ssn, :unique => false
44
+ define_model_class 'Superhero'
45
+ assert_rejects @matcher, Superhero.new
46
+ end
47
+ end
48
+
49
+ context "have_db_index on multiple columns" do
50
+ setup do
51
+ @matcher = have_db_index([:geocodable_type, :geocodable_id])
52
+ end
53
+
54
+ should "accept an existing index" do
55
+ db_connection = create_table 'geocodings' do |table|
56
+ table.integer :geocodable_id
57
+ table.string :geocodable_type
58
+ end
59
+ db_connection.add_index :geocodings, [:geocodable_type, :geocodable_id]
60
+ define_model_class 'Geocoding'
61
+ assert_accepts @matcher, Geocoding.new
62
+ end
63
+
64
+ should "reject a nonexistant index" do
65
+ db_connection = create_table 'geocodings' do |table|
66
+ table.integer :geocodable_id
67
+ table.string :geocodable_type
68
+ end
69
+ define_model_class 'Geocoding'
70
+ assert_rejects @matcher, Geocoding.new
71
+ end
72
+ end
73
+
74
+ should "join columns with and describing multiple columns" do
75
+ assert_match /on columns user_id and post_id/,
76
+ have_db_index([:user_id, :post_id]).description
77
+ end
78
+
79
+ should "describe a unique index as unique" do
80
+ assert_match /a unique index/, have_db_index(:user_id).unique(true).description
81
+ end
82
+
83
+ should "describe a non-unique index as non-unique" do
84
+ assert_match /a non-unique index/, have_db_index(:user_id).unique(false).description
85
+ end
86
+
87
+ should "not describe an index's uniqueness when it isn't important" do
88
+ assert_no_match /unique/, have_db_index(:user_id).description
89
+ end
90
+
91
+ end