mcmire-shoulda-matchers 2.5.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 (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +32 -0
  4. data/.yardopts +7 -0
  5. data/Appraisals +45 -0
  6. data/CONTRIBUTING.md +41 -0
  7. data/Gemfile +31 -0
  8. data/Gemfile.lock +166 -0
  9. data/MIT-LICENSE +22 -0
  10. data/NEWS.md +299 -0
  11. data/README.md +163 -0
  12. data/Rakefile +116 -0
  13. data/doc_config/gh-pages/index.html.erb +9 -0
  14. data/doc_config/yard/setup.rb +22 -0
  15. data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +5967 -0
  16. data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +12 -0
  17. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +45 -0
  18. data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +69 -0
  19. data/doc_config/yard/templates/default/fulldoc/html/css/style.css +283 -0
  20. data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +32 -0
  21. data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +1 -0
  22. data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +8 -0
  23. data/doc_config/yard/templates/default/fulldoc/html/js/app.js +300 -0
  24. data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +1 -0
  25. data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +289 -0
  26. data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +6 -0
  27. data/doc_config/yard/templates/default/fulldoc/html/setup.rb +8 -0
  28. data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +14 -0
  29. data/doc_config/yard/templates/default/layout/html/fonts.erb +1 -0
  30. data/doc_config/yard/templates/default/layout/html/layout.erb +23 -0
  31. data/doc_config/yard/templates/default/layout/html/search.erb +13 -0
  32. data/doc_config/yard/templates/default/layout/html/setup.rb +8 -0
  33. data/doc_config/yard/templates/default/method_details/html/source.erb +10 -0
  34. data/doc_config/yard/templates/default/module/html/box_info.erb +31 -0
  35. data/features/rails_integration.feature +113 -0
  36. data/features/step_definitions/rails_steps.rb +162 -0
  37. data/features/support/env.rb +5 -0
  38. data/gemfiles/3.0.gemfile +24 -0
  39. data/gemfiles/3.0.gemfile.lock +150 -0
  40. data/gemfiles/3.1.gemfile +27 -0
  41. data/gemfiles/3.1.gemfile.lock +173 -0
  42. data/gemfiles/3.2.gemfile +27 -0
  43. data/gemfiles/3.2.gemfile.lock +171 -0
  44. data/gemfiles/4.0.0.gemfile +28 -0
  45. data/gemfiles/4.0.0.gemfile.lock +172 -0
  46. data/gemfiles/4.0.1.gemfile +28 -0
  47. data/gemfiles/4.0.1.gemfile.lock +172 -0
  48. data/lib/shoulda-matchers.rb +1 -0
  49. data/lib/shoulda/matchers.rb +11 -0
  50. data/lib/shoulda/matchers/action_controller.rb +17 -0
  51. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +64 -0
  52. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +97 -0
  53. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +81 -0
  54. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +117 -0
  55. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +114 -0
  56. data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +154 -0
  57. data/lib/shoulda/matchers/action_controller/route_matcher.rb +116 -0
  58. data/lib/shoulda/matchers/action_controller/route_params.rb +48 -0
  59. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +164 -0
  60. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +296 -0
  61. data/lib/shoulda/matchers/active_model.rb +30 -0
  62. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +167 -0
  63. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +314 -0
  64. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +46 -0
  65. data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +160 -0
  66. data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +417 -0
  67. data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +337 -0
  68. data/lib/shoulda/matchers/active_model/errors.rb +10 -0
  69. data/lib/shoulda/matchers/active_model/exception_message_finder.rb +58 -0
  70. data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +92 -0
  71. data/lib/shoulda/matchers/active_model/helpers.rb +46 -0
  72. data/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
  73. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +75 -0
  74. data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +27 -0
  75. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +41 -0
  76. data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +27 -0
  77. data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +26 -0
  78. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +112 -0
  79. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +77 -0
  80. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +121 -0
  81. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +380 -0
  82. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +89 -0
  83. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +372 -0
  84. data/lib/shoulda/matchers/active_model/validation_matcher.rb +97 -0
  85. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +69 -0
  86. data/lib/shoulda/matchers/active_record.rb +22 -0
  87. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +204 -0
  88. data/lib/shoulda/matchers/active_record/association_matcher.rb +901 -0
  89. data/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
  90. data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +41 -0
  91. data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +41 -0
  92. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +81 -0
  93. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +65 -0
  94. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +94 -0
  95. data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
  96. data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +41 -0
  97. data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +63 -0
  98. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +261 -0
  99. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +149 -0
  100. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +72 -0
  101. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +181 -0
  102. data/lib/shoulda/matchers/assertion_error.rb +19 -0
  103. data/lib/shoulda/matchers/error.rb +6 -0
  104. data/lib/shoulda/matchers/integrations/rspec.rb +20 -0
  105. data/lib/shoulda/matchers/integrations/test_unit.rb +30 -0
  106. data/lib/shoulda/matchers/rails_shim.rb +50 -0
  107. data/lib/shoulda/matchers/version.rb +6 -0
  108. data/lib/shoulda/matchers/warn.rb +8 -0
  109. data/shoulda-matchers.gemspec +23 -0
  110. data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
  111. data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
  112. data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
  113. data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +63 -0
  114. data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +63 -0
  115. data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
  116. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +70 -0
  117. data/spec/shoulda/matchers/action_controller/route_params_spec.rb +30 -0
  118. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
  119. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
  120. data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
  121. data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +170 -0
  122. data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +81 -0
  123. data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +95 -0
  124. data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +320 -0
  125. data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +166 -0
  126. data/spec/shoulda/matchers/active_model/exception_message_finder_spec.rb +111 -0
  127. data/spec/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +20 -0
  128. data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
  129. data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +169 -0
  130. data/spec/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +59 -0
  131. data/spec/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +59 -0
  132. data/spec/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +57 -0
  133. data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +139 -0
  134. data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
  135. data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +47 -0
  136. data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +331 -0
  137. data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +180 -0
  138. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +398 -0
  139. data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +127 -0
  140. data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +107 -0
  141. data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +860 -0
  142. data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +247 -0
  143. data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
  144. data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
  145. data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
  146. data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
  147. data/spec/spec_helper.rb +26 -0
  148. data/spec/support/active_model_versions.rb +13 -0
  149. data/spec/support/active_resource_builder.rb +29 -0
  150. data/spec/support/activemodel_helpers.rb +19 -0
  151. data/spec/support/capture_helpers.rb +19 -0
  152. data/spec/support/class_builder.rb +42 -0
  153. data/spec/support/controller_builder.rb +74 -0
  154. data/spec/support/fail_with_message_including_matcher.rb +33 -0
  155. data/spec/support/fail_with_message_matcher.rb +32 -0
  156. data/spec/support/i18n_faker.rb +10 -0
  157. data/spec/support/mailer_builder.rb +10 -0
  158. data/spec/support/model_builder.rb +81 -0
  159. data/spec/support/rails_versions.rb +18 -0
  160. data/spec/support/shared_examples/numerical_submatcher.rb +19 -0
  161. data/spec/support/shared_examples/numerical_type_submatcher.rb +17 -0
  162. data/spec/support/test_application.rb +120 -0
  163. data/yard.watchr +5 -0
  164. metadata +281 -0
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveModel::ExceptionMessageFinder do
4
+ if active_model_3_2?
5
+ context '#allow_description' do
6
+ it 'describes its attribute' do
7
+ finder = build_finder(attribute: :attr)
8
+
9
+ description = finder.allow_description('allowed values')
10
+
11
+ expect(description).to eq %q(doesn't raise when attr is set to allowed values)
12
+ end
13
+ end
14
+
15
+ context '#expected_message_from' do
16
+ it 'returns the message with the attribute name prefixed' do
17
+ finder = build_finder(attribute: :attr)
18
+
19
+ message = finder.expected_message_from('some message')
20
+
21
+ expect(message).to eq 'Attr some message'
22
+ end
23
+ end
24
+
25
+ context '#has_messages?' do
26
+ it 'has messages when some validations fail' do
27
+ finder = build_finder(format: /abc/, value: 'xyz')
28
+
29
+ result = finder.has_messages?
30
+
31
+ expect(result).to eq true
32
+ end
33
+
34
+ it 'has no messages when all validations pass' do
35
+ finder = build_finder(format: /abc/, value: 'abc')
36
+
37
+ result = finder.has_messages?
38
+
39
+ expect(result).to eq false
40
+ end
41
+ end
42
+
43
+ context '#messages' do
44
+ it 'returns errors for the given attribute' do
45
+ finder = build_finder(
46
+ attribute: :attr,
47
+ format: /abc/,
48
+ value: 'xyz'
49
+ )
50
+
51
+ messages = finder.messages
52
+
53
+ expect(messages).to eq ['Attr is invalid']
54
+ end
55
+ end
56
+
57
+ context '#messages_description' do
58
+ it 'describes errors for the given attribute' do
59
+ finder = build_finder(
60
+ attribute: :attr,
61
+ format: /abc/,
62
+ value: 'xyz'
63
+ )
64
+
65
+ description = finder.messages_description
66
+
67
+ expect(description).to eq 'Attr is invalid'
68
+ end
69
+
70
+ it 'describes errors when there are none' do
71
+ finder = build_finder(format: /abc/, value: 'abc')
72
+
73
+ description = finder.messages_description
74
+
75
+ expect(description).to eq 'no exception'
76
+ end
77
+ end
78
+
79
+ context '#source_description' do
80
+ it 'describes the source of its messages' do
81
+ finder = build_finder
82
+
83
+ description = finder.source_description
84
+
85
+ expect(description).to eq 'exception'
86
+ end
87
+ end
88
+ end
89
+
90
+ def build_finder(arguments = {})
91
+ arguments[:attribute] ||= :attr
92
+ instance = build_instance_validating(
93
+ arguments[:attribute],
94
+ arguments[:format] || /abc/,
95
+ arguments[:value] || 'abc'
96
+ )
97
+ Shoulda::Matchers::ActiveModel::ExceptionMessageFinder.new(
98
+ instance,
99
+ arguments[:attribute]
100
+ )
101
+ end
102
+
103
+ def build_instance_validating(attribute, format, value)
104
+ model_class = define_model(:example, attribute => :string) do
105
+ attr_accessible attribute
106
+ validates_format_of attribute, with: format, strict: true
107
+ end
108
+
109
+ model_class.new(attribute => value)
110
+ end
111
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveModel::HaveSecurePasswordMatcher do
4
+ if active_model_3_1?
5
+ it 'matches when the subject configures has_secure_password with default options' do
6
+ working_model = define_model(:example, password_digest: :string) { has_secure_password }
7
+ expect(working_model.new).to have_secure_password
8
+ end
9
+
10
+ it 'does not match when the subject does not authenticate a password' do
11
+ no_secure_password = define_model(:example)
12
+ expect(no_secure_password.new).not_to have_secure_password
13
+ end
14
+
15
+ it 'does not match when the subject is missing the password_digest attribute' do
16
+ no_digest_column = define_model(:example) { has_secure_password }
17
+ expect(no_digest_column.new).not_to have_secure_password
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,158 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe Shoulda::Matchers::ActiveModel::Helpers do
5
+ include Shoulda::Matchers::ActiveModel
6
+ after { I18n.backend.reload! }
7
+
8
+ describe 'default_error_message' do
9
+ context 'if the translation for the model attribute’s error exists' do
10
+ it 'provides the right error message for validate_presence_of' do
11
+ store_translations
12
+
13
+ assert_presence_validation_has_correct_message
14
+ end
15
+
16
+ it 'provides the right error message for validates_length_of' do
17
+ store_translations
18
+
19
+ assert_length_validation_has_correct_message
20
+ end
21
+ end
22
+
23
+ context 'if no translation for the model attribute’s error exists' do
24
+ context 'and the translation for the model’s error exists' do
25
+ it 'provides the right error message for validate_presence_of' do
26
+ store_translations(without: :model_attribute)
27
+
28
+ assert_presence_validation_has_correct_message
29
+ end
30
+
31
+ it 'provides the right error message for validates_length_of' do
32
+ store_translations(without: :model_attribute)
33
+
34
+ assert_length_validation_has_correct_message
35
+ end
36
+ end
37
+
38
+ context 'and no translation for the model’s error exists' do
39
+ context 'and the translation for the message exists' do
40
+ it 'provides the right error message for validate_presence_of' do
41
+ store_translations(without: [:model_attribute, :model])
42
+
43
+ assert_presence_validation_has_correct_message
44
+ end
45
+
46
+ it 'provides the right error message for validates_length_of' do
47
+ store_translations(without: [:model_attribute, :model])
48
+
49
+ assert_length_validation_has_correct_message
50
+ end
51
+ end
52
+
53
+ context 'and no translation for the message exists' do
54
+ context 'and the translation for the attribute exists' do
55
+ it 'provides the right error message for validate_presence_of' do
56
+ store_translations(without: [:model_attribute, :model, :message])
57
+
58
+ assert_presence_validation_has_correct_message
59
+ end
60
+
61
+ it 'provides the right error message for validates_length_of' do
62
+ store_translations(without: [:model_attribute, :model, :message])
63
+
64
+ assert_length_validation_has_correct_message
65
+ end
66
+ end
67
+
68
+ context 'and no translation for the attribute exists' do
69
+ it 'provides the general error message for validate_presence_of' do
70
+ assert_presence_validation_has_correct_message
71
+ end
72
+
73
+ it 'provides the general error message for validates_length_of' do
74
+ assert_length_validation_has_correct_message
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'if ActiveModel::Errors#generate_message behavior has changed' do
82
+ it 'provides the right error message for validate_presence_of' do
83
+ stub_active_model_message_generation(type: :blank,
84
+ message: 'Behavior has diverged.')
85
+ assert_presence_validation_has_correct_message
86
+ end
87
+ end
88
+ end
89
+
90
+ def assert_presence_validation_has_correct_message
91
+ record = define_model :example, attr: :string do
92
+ validates_presence_of :attr
93
+ end.new
94
+ expect(record).to validate_presence_of(:attr)
95
+ end
96
+
97
+ def assert_length_validation_has_correct_message
98
+ record = define_model :example, attr: :string do
99
+ validates_length_of :attr, is: 40, allow_blank: true
100
+ end.new
101
+ expect(record).to ensure_length_of(:attr).is_equal_to(40)
102
+ end
103
+
104
+ def store_translations(options = {without: []})
105
+ options[:without] = Array.wrap(options[:without] || [])
106
+
107
+ translations = {
108
+ activerecord: {
109
+ errors: {
110
+ models: {
111
+ example: {
112
+ attributes: {
113
+ attr: {}
114
+ }
115
+ }
116
+ },
117
+ messages: {}
118
+ }
119
+ },
120
+ errors: {
121
+ attributes: {
122
+ attr: {}
123
+ },
124
+ messages: {}
125
+ }
126
+ }
127
+
128
+ unless options[:without].include?(:model_attribute)
129
+ translations[:activerecord][:errors][:models][:example][:attributes][:attr][:blank] = "Don't you do that to me!"
130
+ translations[:activerecord][:errors][:models][:example][:attributes][:attr][:wrong_length] = "Don't you do that to me!"
131
+ end
132
+
133
+ unless options[:without].include?(:model)
134
+ translations[:activerecord][:errors][:models][:example][:blank] = 'Give it one more try!'
135
+ translations[:activerecord][:errors][:models][:example][:wrong_length] = 'Give it one more try!'
136
+ end
137
+
138
+ unless options[:without].include?(:message)
139
+ translations[:activerecord][:errors][:messages][:blank] = 'Oh no!'
140
+ translations[:activerecord][:errors][:messages][:wrong_length] = 'Oh no!'
141
+ end
142
+
143
+ unless options[:without].include?(:attribute)
144
+ translations[:errors][:attributes][:attr][:blank] = 'Seriously?'
145
+ translations[:errors][:attributes][:attr][:wrong_length] = 'Seriously?'
146
+ end
147
+
148
+ I18n.backend.store_translations(:en, translations)
149
+ end
150
+
151
+ def stub_active_model_message_generation(options = {})
152
+ attribute = options.delete(:attribute) || :attr
153
+ message = options.delete(:message)
154
+ type = options.delete(:type)
155
+
156
+ ActiveModel::Errors.any_instance.expects(:generate_message).with(attribute, type, {}).at_least_once.returns(message)
157
+ end
158
+ end
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher do
4
+ subject { described_class.new(matcher, 0, :>) }
5
+
6
+ it_behaves_like 'a numerical submatcher'
7
+
8
+ context 'when initialized without correct numerical matcher' do
9
+ it 'raises an argument error' do
10
+ fake_matcher = matcher
11
+ class << fake_matcher
12
+ undef_method :diff_to_compare
13
+ end
14
+ expect do
15
+ described_class.new(fake_matcher, 0, :>)
16
+ end.to raise_error ArgumentError
17
+ end
18
+ end
19
+
20
+ context 'is_greater_than' do
21
+ it do
22
+ expect(instance_with_validations(greater_than: 2))
23
+ .to matcher.is_greater_than(2)
24
+ end
25
+
26
+ it do
27
+ expect(instance_with_validations(greater_than: 1.5))
28
+ .not_to matcher.is_greater_than(2)
29
+ end
30
+
31
+ it do
32
+ expect(instance_with_validations(greater_than: 2.5))
33
+ .not_to matcher.is_greater_than(2)
34
+ end
35
+
36
+ it do
37
+ expect(instance_without_validations).not_to matcher.is_greater_than(2)
38
+ end
39
+ end
40
+
41
+ context 'greater_than_or_equal_to' do
42
+ it do
43
+ expect(instance_with_validations(greater_than_or_equal_to: 2))
44
+ .to matcher.is_greater_than_or_equal_to(2)
45
+ end
46
+
47
+ it do
48
+ expect(instance_with_validations(greater_than_or_equal_to: 1.5))
49
+ .not_to matcher.is_greater_than_or_equal_to(2)
50
+ end
51
+
52
+ it do
53
+ expect(instance_with_validations(greater_than_or_equal_to: 2.5))
54
+ .not_to matcher.is_greater_than_or_equal_to(2)
55
+ end
56
+
57
+ it do
58
+ expect(instance_without_validations)
59
+ .not_to matcher.is_greater_than_or_equal_to(2)
60
+ end
61
+ end
62
+
63
+ context 'less_than' do
64
+ it do
65
+ expect(instance_with_validations(less_than: 2))
66
+ .to matcher.is_less_than(2)
67
+ end
68
+
69
+ it do
70
+ expect(instance_with_validations(less_than: 1.5))
71
+ .not_to matcher.is_less_than(2)
72
+ end
73
+
74
+ it do
75
+ expect(instance_with_validations(less_than: 2.5))
76
+ .not_to matcher.is_less_than(2)
77
+ end
78
+
79
+ it do
80
+ expect(instance_without_validations)
81
+ .not_to matcher.is_less_than(2)
82
+ end
83
+ end
84
+
85
+ context 'less_than_or_equal_to' do
86
+ it do
87
+ expect(instance_with_validations(less_than_or_equal_to: 2))
88
+ .to matcher.is_less_than_or_equal_to(2)
89
+ end
90
+
91
+ it do
92
+ expect(instance_with_validations(less_than_or_equal_to: 1.5))
93
+ .not_to matcher.is_less_than_or_equal_to(2)
94
+ end
95
+
96
+ it do
97
+ expect(instance_with_validations(less_than_or_equal_to: 2.5))
98
+ .not_to matcher.is_less_than_or_equal_to(2)
99
+ end
100
+
101
+ it do
102
+ expect(instance_without_validations)
103
+ .not_to matcher.is_less_than_or_equal_to(2)
104
+ end
105
+ end
106
+
107
+ context 'is_equal_to' do
108
+ it do
109
+ expect(instance_with_validations(equal_to: 0))
110
+ .to matcher.is_equal_to(0)
111
+ end
112
+
113
+ it do
114
+ expect(instance_with_validations(equal_to: -0.5))
115
+ .not_to matcher.is_equal_to(0)
116
+ end
117
+
118
+ it do
119
+ expect(instance_with_validations(equal_to: 0.5))
120
+ .not_to matcher.is_equal_to(0)
121
+ end
122
+
123
+ it do
124
+ expect(instance_without_validations)
125
+ .not_to matcher.is_equal_to(0)
126
+ end
127
+ end
128
+
129
+ context 'with_message' do
130
+ it 'verifies the message for the validation' do
131
+ instance = instance_with_validations(equal_to: 0, message: 'Must be zero')
132
+ expect(instance).to matcher.is_equal_to(0).with_message('Must be zero')
133
+ end
134
+ end
135
+
136
+ describe '#comparison_description' do
137
+ [{ operator: :>, value: 0, expectation: 'greater than 0' },
138
+ { operator: :>=, value: -1.0, expectation: 'greater than or equal to -1.0' },
139
+ { operator: :==, value: 2.2, expectation: 'equal to 2.2' },
140
+ { operator: :<, value: -3, expectation: 'less than -3' },
141
+ { operator: :<=, value: 4, expectation: 'less than or equal to 4' },
142
+ ].each do |h|
143
+ context "with :#{h[:operator]} as operator and #{h[:value]} as value" do
144
+ subject do
145
+ described_class.new(matcher, h[:value], h[:operator])
146
+ .comparison_description
147
+ end
148
+ it { should eq h[:expectation] }
149
+ end
150
+ end
151
+ end
152
+
153
+ def instance_with_validations(options = {})
154
+ define_model :example, attr: :string do
155
+ validates_numericality_of :attr, options
156
+ attr_accessible :attr
157
+ end.new
158
+ end
159
+
160
+ def instance_without_validations
161
+ define_model :example, attr: :string do
162
+ attr_accessible :attr
163
+ end.new
164
+ end
165
+
166
+ def matcher
167
+ validate_numericality_of(:attr)
168
+ end
169
+ end