warp 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +4 -0
- data/README.md +99 -2
- data/gemfiles/rails_3.2_rspec_2.14.gemfile +3 -0
- data/gemfiles/rails_3.2_rspec_2.99.0.beta1.gemfile +3 -0
- data/gemfiles/rails_3.2_rspec_3.0.0.beta1.gemfile +3 -0
- data/gemfiles/rails_3.2_rspec_master.gemfile +3 -0
- data/gemfiles/rails_4.0_rspec_2.14.gemfile +3 -0
- data/gemfiles/rails_4.0_rspec_2.99.0.beta1.gemfile +3 -0
- data/gemfiles/rails_4.0_rspec_3.0.0.beta1.gemfile +3 -0
- data/gemfiles/rails_4.0_rspec_master.gemfile +3 -0
- data/gemfiles/rails_4.1.0.beta1_rspec_2.14.gemfile +3 -0
- data/gemfiles/rails_4.1.0.beta1_rspec_2.99.0.beta1.gemfile +3 -0
- data/gemfiles/rails_4.1.0.beta1_rspec_3.0.0.beta1.gemfile +3 -0
- data/gemfiles/rails_4.1.0.beta1_rspec_master.gemfile +3 -0
- data/lib/warp/controller_matchers.rb +4 -0
- data/lib/warp/matcher.rb +1 -1
- data/lib/warp/model_matchers/association_matcher.rb +27 -19
- data/lib/warp/model_matchers/attribute_matcher.rb +20 -13
- data/lib/warp/model_matchers/matcher.rb +7 -1
- data/lib/warp/model_matchers/validation_matcher.rb +88 -2
- data/lib/warp/model_matchers.rb +10 -3
- data/lib/warp/version.rb +1 -1
- data/spec/spec_helper.rb +8 -0
- data/spec/support/match_helpers.rb +1 -1
- data/spec/support/model_helpers.rb +5 -0
- data/spec/support/with_contexts_helpers.rb +12 -2
- data/spec/warp/model_helpers/association_matcher_spec.rb +3 -3
- data/spec/warp/model_helpers/attribute_matcher_spec.rb +2 -2
- data/spec/warp/model_helpers/validation_matcher_spec.rb +172 -0
- data/warp.gemspec +1 -7
- metadata +8 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c7c3c6f9e427418e76e0be7e7a5f14fe6cc669b
|
4
|
+
data.tar.gz: 1ce6c0bf3dec5650c89f3016f27bd3735840808b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f53d6173f69d9da373f3632bb406a002ff55417ef7f1adba46eb01e5c6ff2576f6eb9d7101d2a9388ec2c2652d65166b09c2d2d2cf2941c659e17ce1a04ecc31
|
7
|
+
data.tar.gz: 6a9eaf01f40faf8866608e8f03c1b0579702f8f92f18fbe3d1e5d82caeac436b57aaa1a325a9e89cbc3284000fe738dce3d2e72a87138afec123ed8a21e8bc25
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -21,7 +21,7 @@ And then execute:
|
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
24
|
-
###
|
24
|
+
### Assign Matchers
|
25
25
|
|
26
26
|
#### assigns(key)
|
27
27
|
|
@@ -55,6 +55,8 @@ Ensures that the specific assign is set with a instance of the specified class t
|
|
55
55
|
specify { expect(controller).to assign(:post).with_a_new(Post) }
|
56
56
|
```
|
57
57
|
|
58
|
+
### Flash Matchers
|
59
|
+
|
58
60
|
#### set_flash(key)
|
59
61
|
|
60
62
|
Ensure that the specific flash key is set:
|
@@ -70,7 +72,7 @@ Ensure that the specific flash key is set:
|
|
70
72
|
specify { expect(controller).to set_flash(:notice).to("Your order has been processed.") }
|
71
73
|
```
|
72
74
|
|
73
|
-
###
|
75
|
+
### Association Matchers
|
74
76
|
|
75
77
|
#### belongs_to(association)
|
76
78
|
|
@@ -108,6 +110,8 @@ specify { expect(group).to have_and_belong_to_many(:users) }
|
|
108
110
|
|
109
111
|
This matcher is not avaliable on Rails 4.1+, as these versions of Rails will create a `has_many :though` association instead of a 'has_and_belongs_to_many' association.
|
110
112
|
|
113
|
+
### Attribute Matchers
|
114
|
+
|
111
115
|
#### have_attribute(attribute)
|
112
116
|
|
113
117
|
Checks if a certain attribute is present on a model. Works against models or model instances.
|
@@ -116,6 +120,99 @@ Checks if a certain attribute is present on a model. Works against models or mod
|
|
116
120
|
specify { expect(user).to have_attribute(:name) }
|
117
121
|
```
|
118
122
|
|
123
|
+
### Validation Matchers
|
124
|
+
|
125
|
+
All validation matchers can be specified with, or without options to verify.
|
126
|
+
|
127
|
+
#### validate_acceptance_of
|
128
|
+
|
129
|
+
Ensures that a `validates_acceptance_of` validator is present on the attribute.
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
specify { expect(user).to validate_acceptance_of(:terms) }
|
133
|
+
```
|
134
|
+
|
135
|
+
#### validate_absence_of
|
136
|
+
|
137
|
+
Ensures that a `validates_absence_of` validator is present on the attribute.
|
138
|
+
Only avaliable on Rails 4+.
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
specify { expect(user).to validate_absence_of(:postcode, if: :non_us_address) }
|
142
|
+
```
|
143
|
+
|
144
|
+
#### validate_confirmation_of
|
145
|
+
|
146
|
+
Ensures that a `validates_confirmation_of` validator is present on the attribute.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
specify { expect(user).to validate_confirmation_of(:password) }
|
150
|
+
```
|
151
|
+
|
152
|
+
#### validate_exclusion_of
|
153
|
+
|
154
|
+
Ensures that a `validates_exclusion_of` validator is present on the attribute.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
specify { expect(user).to validate_exclusion_of(:age, in: 0..17) }
|
158
|
+
```
|
159
|
+
|
160
|
+
#### validate_format_of
|
161
|
+
|
162
|
+
Ensures that a `validates_format_of` validator is present on the attribute.
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
specify { expect(user).to validate_format_of(:postcode, with: /\d{5,8}/) }
|
166
|
+
```
|
167
|
+
|
168
|
+
#### validate_inclusion_of
|
169
|
+
|
170
|
+
Ensures that a `validates_inclusion_of` validator is present on the attribute.
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
specify { expect(user).to validate_inclusion_of(:role, in: ["develop", "design"]) }
|
174
|
+
```
|
175
|
+
|
176
|
+
#### validate_length_of
|
177
|
+
|
178
|
+
Ensures that a `validates_length_of` validator is present on the attribute.
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
specify { expect(user).to validate_length_of(:name, in: 5..25) }
|
182
|
+
```
|
183
|
+
|
184
|
+
#### validate_numericality_of
|
185
|
+
|
186
|
+
Ensures that a `validates_numericality_of` validator is present on the attribute.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
specify { expect(user).to validate_numericality_of(:age) }
|
190
|
+
```
|
191
|
+
|
192
|
+
#### validate_presence_of
|
193
|
+
|
194
|
+
Ensures that a `validates_presence_of` validator is present on the attribute.
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
specify { expect(user).to validate_presence_of(:name) }
|
198
|
+
```
|
199
|
+
|
200
|
+
#### validate_association_of
|
201
|
+
|
202
|
+
Ensures that a `validates_association_of` validator is present on the attribute.
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
specify { expect(user).to validate_association_of(:profile) }
|
206
|
+
```
|
207
|
+
|
208
|
+
#### validate_uniqueness_of
|
209
|
+
|
210
|
+
Ensures that a `validates_uniqueness_of` validator is present on the attribute.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
specify { expect(user).to validate_uniqueness_of(:email, scope: :company) }
|
214
|
+
```
|
215
|
+
|
119
216
|
## Contributing
|
120
217
|
|
121
218
|
1. Fork it
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "bundler", "~> 1.5.1"
|
5
6
|
gem "appraisal", "1.0.0.beta2"
|
7
|
+
gem "rake"
|
8
|
+
gem "fuubar"
|
6
9
|
gem "simplecov", :require=>false
|
7
10
|
gem "coveralls", :require=>false
|
8
11
|
gem "activesupport", "4.1.0.beta1", :require=>"active_support/all"
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "bundler", "~> 1.5.1"
|
5
6
|
gem "appraisal", "1.0.0.beta2"
|
7
|
+
gem "rake"
|
8
|
+
gem "fuubar"
|
6
9
|
gem "simplecov", :require=>false
|
7
10
|
gem "coveralls", :require=>false
|
8
11
|
gem "activesupport", "4.1.0.beta1", :require=>"active_support/all"
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "bundler", "~> 1.5.1"
|
5
6
|
gem "appraisal", "1.0.0.beta2"
|
7
|
+
gem "rake"
|
8
|
+
gem "fuubar"
|
6
9
|
gem "simplecov", :require=>false
|
7
10
|
gem "coveralls", :require=>false
|
8
11
|
gem "activesupport", "4.1.0.beta1", :require=>"active_support/all"
|
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "bundler", "~> 1.5.1"
|
5
6
|
gem "appraisal", "1.0.0.beta2"
|
7
|
+
gem "rake"
|
8
|
+
gem "fuubar"
|
6
9
|
gem "simplecov", :require=>false
|
7
10
|
gem "coveralls", :require=>false
|
8
11
|
gem "activesupport", "4.1.0.beta1", :require=>"active_support/all"
|
data/lib/warp/matcher.rb
CHANGED
@@ -17,7 +17,7 @@ module Warp
|
|
17
17
|
# RSpec 2 and 3 have different methods
|
18
18
|
# that they call on matcher to get the
|
19
19
|
# failure messages.
|
20
|
-
if RSpec::Version::STRING[0] == "2"
|
20
|
+
if RSpec::Version::STRING[0] == "2" || RSpec::Version::STRING == "3.0.0.beta1"
|
21
21
|
def failure_message_for_should
|
22
22
|
failure_message
|
23
23
|
end
|
@@ -1,35 +1,43 @@
|
|
1
1
|
module Warp
|
2
2
|
module ModelMatchers
|
3
3
|
class AssociationMatcher < Warp::ModelMatchers::Matcher
|
4
|
-
attr_reader :
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@macro = macro
|
4
|
+
attr_reader :expected_macro, :key
|
5
|
+
|
6
|
+
def initialize(expected_macro, key)
|
7
|
+
@expected_macro = expected_macro
|
9
8
|
@key = key
|
10
9
|
end
|
11
10
|
|
12
11
|
def matches?(model_or_instance)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
@model_or_instance = model_or_instance
|
13
|
+
|
14
|
+
association && values_match?(expected_macro, assocation_macro)
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
"have a #{expected_macro} association with :#{key}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message
|
22
|
+
if association
|
23
|
+
"expected #{model_name} to #{description}, but had a #{assocation_macro} association with :#{key}"
|
18
24
|
else
|
19
|
-
|
20
|
-
@failure_message_when_negated = "expected to not have association #{macro} :#{key}"
|
21
|
-
false
|
25
|
+
"expected #{model_name} to #{description}"
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
29
|
+
def failure_message_when_negated
|
30
|
+
"expected #{model_name} to not #{description}"
|
31
|
+
end
|
32
|
+
|
25
33
|
private
|
26
34
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
35
|
+
def association
|
36
|
+
model.reflect_on_association(key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assocation_macro
|
40
|
+
association.macro
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
@@ -1,27 +1,34 @@
|
|
1
|
-
module Warp
|
1
|
+
module Warp
|
2
2
|
module ModelMatchers
|
3
3
|
class AttributeMatcher < Warp::ModelMatchers::Matcher
|
4
4
|
attr_reader :attr_name
|
5
|
-
attr_reader :failure_message, :failure_message_when_negated, :description
|
6
5
|
|
7
6
|
def initialize(attr_name)
|
8
7
|
@attr_name = attr_name.to_sym
|
9
8
|
end
|
10
9
|
|
11
10
|
def matches?(model_or_instance)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
@model_or_instance = model_or_instance
|
12
|
+
|
13
|
+
attributes.any? {|actual| values_match?(attr_name, actual) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def description
|
17
|
+
"have attribute #{description_of(attr_name)}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message
|
21
|
+
"expected #{model_name} to #{description}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def failure_message_when_negated
|
25
|
+
"expected #{model_name} to not #{description}"
|
21
26
|
end
|
27
|
+
|
28
|
+
private
|
22
29
|
|
23
|
-
def attributes
|
24
|
-
model
|
30
|
+
def attributes
|
31
|
+
model.column_names.map(&:to_sym)
|
25
32
|
end
|
26
33
|
end
|
27
34
|
|
@@ -1,15 +1,21 @@
|
|
1
1
|
module Warp
|
2
2
|
module ModelMatchers
|
3
3
|
class Matcher < Warp::Matcher
|
4
|
+
attr_reader :model_or_instance
|
5
|
+
|
4
6
|
private
|
5
7
|
|
6
|
-
def model
|
8
|
+
def model
|
7
9
|
if model_or_instance.is_a? Class
|
8
10
|
model_or_instance
|
9
11
|
else
|
10
12
|
model_or_instance.class
|
11
13
|
end
|
12
14
|
end
|
15
|
+
|
16
|
+
def model_name
|
17
|
+
model.name
|
18
|
+
end
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
@@ -1,12 +1,98 @@
|
|
1
1
|
module Warp
|
2
2
|
module ModelMatchers
|
3
|
-
class ValidationMatcher < Warp::Matcher
|
3
|
+
class ValidationMatcher < Warp::ModelMatchers::Matcher
|
4
|
+
VALIDATORS = [
|
5
|
+
ActiveModel::Validations::AcceptanceValidator,
|
6
|
+
ActiveModel::Validations::ConfirmationValidator,
|
7
|
+
ActiveModel::Validations::ExclusionValidator,
|
8
|
+
ActiveModel::Validations::FormatValidator,
|
9
|
+
ActiveModel::Validations::InclusionValidator,
|
10
|
+
ActiveModel::Validations::LengthValidator,
|
11
|
+
ActiveModel::Validations::NumericalityValidator,
|
12
|
+
ActiveModel::Validations::PresenceValidator
|
13
|
+
]
|
4
14
|
|
15
|
+
# AbsenceValidator added in Rails 4
|
16
|
+
if defined?(ActiveModel::Validations::AbsenceValidator)
|
17
|
+
VALIDATORS << ActiveModel::Validations::AbsenceValidator
|
18
|
+
end
|
5
19
|
|
20
|
+
if defined?(ActiveRecord)
|
21
|
+
VALIDATORS.concat [
|
22
|
+
ActiveRecord::Validations::AssociatedValidator,
|
23
|
+
ActiveRecord::Validations::UniquenessValidator
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
# In Rails 4 PresenceValidator is subclassed by AR
|
28
|
+
if defined?(ActiveRecord::Validations::PresenceValidator)
|
29
|
+
VALIDATORS.delete(ActiveModel::Validations::PresenceValidator)
|
30
|
+
VALIDATORS.push(ActiveRecord::Validations::PresenceValidator)
|
31
|
+
end
|
32
|
+
|
33
|
+
VALIDATORS.freeze
|
34
|
+
|
35
|
+
attr_reader :attr_name, :validator_class, :validator_options, :display_options
|
36
|
+
|
37
|
+
def initialize(attr_name, validator_class, validator_options, display_options)
|
38
|
+
@attr_name = attr_name
|
39
|
+
@validator_class = validator_class
|
40
|
+
@validator_options = validator_options
|
41
|
+
@display_options = display_options
|
42
|
+
end
|
43
|
+
|
44
|
+
def matches?(model_or_instance)
|
45
|
+
@model_or_instance = model_or_instance
|
46
|
+
|
47
|
+
validators.any? do |validator|
|
48
|
+
if values_match?(validator_class, validator.class)
|
49
|
+
validator_options.nil? || values_match?(validator_options, validator.options)
|
50
|
+
else
|
51
|
+
false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def failure_message
|
57
|
+
"expected #{model_name} to #{description}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def failure_message_when_negated
|
61
|
+
"expected #{model_name} to not #{description}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def description
|
65
|
+
str = "have validator #{validator_class.name} on :#{attr_name}"
|
66
|
+
str << " with options #{description_of(display_options)}" if display_options.present?
|
67
|
+
str
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def validators
|
73
|
+
model._validators[attr_name]
|
74
|
+
end
|
6
75
|
end
|
7
76
|
|
8
|
-
|
77
|
+
ValidationMatcher::VALIDATORS.each do |validator|
|
78
|
+
validator_name = validator.name.match(/::(?<name>\w+)Validator/)[:name].underscore.to_sym
|
79
|
+
method_name = (validator_name == :associated) ? "validate_associated" : "validate_#{validator_name}_of"
|
80
|
+
|
81
|
+
define_method method_name do |attr_name, *options|
|
82
|
+
display_options = options.first
|
83
|
+
options = display_options.try(:dup) || {}
|
84
|
+
|
85
|
+
case validator_name
|
86
|
+
when :uniqueness
|
87
|
+
options = {case_sensitive: true}.merge(options)
|
88
|
+
when :acceptance
|
89
|
+
options = {allow_nil: true, accept: "1"}.merge(options)
|
90
|
+
end
|
91
|
+
|
92
|
+
options = nil if options.empty?
|
9
93
|
|
94
|
+
ValidationMatcher.new(attr_name, validator, options, display_options)
|
95
|
+
end
|
10
96
|
end
|
11
97
|
end
|
12
98
|
end
|
data/lib/warp/model_matchers.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
unless defined?(ActiveModel)
|
2
|
+
raise RuntimeError, "ActiveModel is required to use Warp::ModelMatchers."
|
3
|
+
end
|
4
|
+
|
1
5
|
require "warp/model_matchers/matcher"
|
2
6
|
|
3
|
-
require "warp/model_matchers/association_matcher"
|
4
|
-
require "warp/model_matchers/attribute_matcher"
|
5
7
|
# require "warp/model_matchers/error_matcher"
|
6
|
-
|
8
|
+
require "warp/model_matchers/validation_matcher"
|
9
|
+
|
10
|
+
if defined?(ActiveRecord)
|
11
|
+
require "warp/model_matchers/association_matcher"
|
12
|
+
require "warp/model_matchers/attribute_matcher"
|
13
|
+
end
|
7
14
|
|
8
15
|
RSpec.configure do |config|
|
9
16
|
config.include Warp::ModelMatchers
|
data/lib/warp/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -14,6 +14,11 @@ module ModelHelpers
|
|
14
14
|
@columns ||= []
|
15
15
|
end
|
16
16
|
|
17
|
+
def self.attribute_method?(method)
|
18
|
+
method = method.to_s.sub("=", "")
|
19
|
+
columns.any? {|c| c.name == method }
|
20
|
+
end
|
21
|
+
|
17
22
|
def self.column(name, sql_type = nil, default = nil, null = true)
|
18
23
|
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
|
19
24
|
end
|
@@ -2,8 +2,6 @@ module WithContextsHelpers
|
|
2
2
|
class WithContextsBuilder
|
3
3
|
attr_accessor :contexts, :examples, :group
|
4
4
|
|
5
|
-
delegate :let, :before, :after, :subject, to: :group
|
6
|
-
|
7
5
|
def initialize(group)
|
8
6
|
@contexts = {}
|
9
7
|
@group = group
|
@@ -21,6 +19,18 @@ module WithContextsHelpers
|
|
21
19
|
self.examples = blk
|
22
20
|
end
|
23
21
|
|
22
|
+
def let(*args, &blk)
|
23
|
+
group.let(*args, &blk)
|
24
|
+
end
|
25
|
+
|
26
|
+
def before(*args, &blk)
|
27
|
+
group.before(*args, &blk)
|
28
|
+
end
|
29
|
+
|
30
|
+
def after(*args, &blk)
|
31
|
+
group.after(*args, &blk)
|
32
|
+
end
|
33
|
+
|
24
34
|
def execute
|
25
35
|
contexts.each do |name, blk|
|
26
36
|
context = group.context(name)
|
@@ -70,7 +70,7 @@ describe Warp::ModelMatchers::AssociationMatcher do
|
|
70
70
|
specify { expect(subject).to match(model_or_instance) }
|
71
71
|
|
72
72
|
describe_failure_message_when_negated do
|
73
|
-
specify { expect(subject).to eq "expected to not have
|
73
|
+
specify { expect(subject).to eq "expected TestModel to not have a #{matcher_macro} association with :#{key}" }
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -81,7 +81,7 @@ describe Warp::ModelMatchers::AssociationMatcher do
|
|
81
81
|
specify { expect(subject).to_not match(model_or_instance) }
|
82
82
|
|
83
83
|
describe_failure_message do
|
84
|
-
specify { expect(subject).to eq "expected to have
|
84
|
+
specify { expect(subject).to eq "expected TestModel to have a #{matcher_macro} association with :#{key}, but had a #{actual_macro} association with :#{key}" }
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
@@ -92,7 +92,7 @@ describe Warp::ModelMatchers::AssociationMatcher do
|
|
92
92
|
specify { expect(subject).to_not match(model_or_instance) }
|
93
93
|
|
94
94
|
describe_failure_message do
|
95
|
-
specify { expect(subject).to eq "expected to have
|
95
|
+
specify { expect(subject).to eq "expected TestModel to have a #{matcher_macro} association with :#{key}" }
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -25,7 +25,7 @@ describe Warp::ModelMatchers::AttributeMatcher do
|
|
25
25
|
specify { expect(subject).to match(model_or_instance) }
|
26
26
|
|
27
27
|
describe_failure_message_when_negated do
|
28
|
-
specify { expect(subject).to eq "expected to not have attribute :#{attr_name}" }
|
28
|
+
specify { expect(subject).to eq "expected TestModel to not have attribute :#{attr_name}" }
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -35,7 +35,7 @@ describe Warp::ModelMatchers::AttributeMatcher do
|
|
35
35
|
specify { expect(subject).to_not match(model_or_instance) }
|
36
36
|
|
37
37
|
describe_failure_message do
|
38
|
-
specify { expect(subject).to eq "expected to have attribute :#{attr_name}" }
|
38
|
+
specify { expect(subject).to eq "expected TestModel to have attribute :#{attr_name}" }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Warp::ModelMatchers::ValidationMatcher do
|
4
|
+
build_model do
|
5
|
+
column :foo
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:attr_name) { :foo }
|
9
|
+
|
10
|
+
let(:matcher) { send(matcher_method, attr_name) }
|
11
|
+
let(:matcher_with_options) { send(matcher_method, attr_name, matcher_options) }
|
12
|
+
|
13
|
+
let(:validator_name) { matcher.validator_class.name }
|
14
|
+
|
15
|
+
with_contexts do
|
16
|
+
context "with model" do
|
17
|
+
let(:model_or_instance) { model }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with model instance" do
|
21
|
+
let(:model_or_instance) { model.new }
|
22
|
+
end
|
23
|
+
|
24
|
+
behaviour do
|
25
|
+
with_contexts do
|
26
|
+
# AbsenceValidator added in Rails 4
|
27
|
+
if defined?(ActiveModel::Validations::AbsenceValidator)
|
28
|
+
context "#validate_absence_of" do
|
29
|
+
let(:matcher_method) { :validate_absence_of }
|
30
|
+
let(:matcher_options) { {message: "must be blank"} }
|
31
|
+
let(:validation_method) { :validates_absence_of }
|
32
|
+
let(:validation_base_options) { {} }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "#validate_acceptance_of" do
|
37
|
+
let(:matcher_method) { :validate_acceptance_of }
|
38
|
+
let(:matcher_options) { {if: :enabled?} }
|
39
|
+
let(:validation_method) { :validates_acceptance_of }
|
40
|
+
let(:validation_base_options) { {} }
|
41
|
+
end
|
42
|
+
|
43
|
+
context "#validate_confirmation_of" do
|
44
|
+
let(:matcher_method) { :validate_confirmation_of }
|
45
|
+
let(:matcher_options) { {unless: :tuesday?} }
|
46
|
+
let(:validation_method) { :validates_confirmation_of }
|
47
|
+
let(:validation_base_options) { {} }
|
48
|
+
end
|
49
|
+
|
50
|
+
context "#validate_exclusion_of" do
|
51
|
+
let(:matcher_method) { :validate_exclusion_of }
|
52
|
+
let(:matcher_options) { {in: 12..500} }
|
53
|
+
let(:validation_method) { :validates_exclusion_of }
|
54
|
+
let(:validation_base_options) { {in: [12, 500]} }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "#validate_format_of" do
|
58
|
+
let(:matcher_method) { :validate_format_of }
|
59
|
+
let(:matcher_options) { {with: /foo[bar]*/} }
|
60
|
+
let(:validation_method) { :validates_format_of }
|
61
|
+
let(:validation_base_options) { {with: /qu+x/} }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "#validate_inclusion_of" do
|
65
|
+
let(:matcher_method) { :validate_inclusion_of }
|
66
|
+
let(:matcher_options) { {in: ["foo", "bar", "baz", "qux"]} }
|
67
|
+
let(:validation_method) { :validates_inclusion_of }
|
68
|
+
let(:validation_base_options) { {in: 1..10} }
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#validate_length_of" do
|
72
|
+
let(:matcher_method) { :validate_length_of }
|
73
|
+
let(:matcher_options) { {maximum: 32} }
|
74
|
+
let(:validation_method) { :validates_length_of }
|
75
|
+
let(:validation_base_options) { {is: 32} }
|
76
|
+
end
|
77
|
+
|
78
|
+
context "#validate_numericality_of" do
|
79
|
+
let(:matcher_method) { :validate_numericality_of }
|
80
|
+
let(:matcher_options) { {even: true} }
|
81
|
+
let(:validation_method) { :validates_numericality_of }
|
82
|
+
let(:validation_base_options) { {} }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "#validate_presence_of" do
|
86
|
+
let(:matcher_method) { :validate_presence_of }
|
87
|
+
let(:matcher_options) { {unless: :not_required} }
|
88
|
+
let(:validation_method) { :validates_presence_of }
|
89
|
+
let(:validation_base_options) { {} }
|
90
|
+
end
|
91
|
+
|
92
|
+
context "#validate_association_of" do
|
93
|
+
let(:matcher_method) { :validate_associated }
|
94
|
+
let(:matcher_options) { {message: "it's neither here nor there"} }
|
95
|
+
let(:validation_method) { :validates_associated }
|
96
|
+
let(:validation_base_options) { {} }
|
97
|
+
end
|
98
|
+
|
99
|
+
context "#validate_uniqueness_of" do
|
100
|
+
let(:matcher_method) { :validate_uniqueness_of }
|
101
|
+
let(:matcher_options) { {scope: :post_id} }
|
102
|
+
let(:validation_method) { :validates_uniqueness_of }
|
103
|
+
let(:validation_base_options) { {} }
|
104
|
+
end
|
105
|
+
|
106
|
+
behaviour do
|
107
|
+
context "when matching without options" do
|
108
|
+
subject { matcher.tap {|m| m.matches?(model_or_instance) } }
|
109
|
+
|
110
|
+
context "with no matching validation" do
|
111
|
+
specify { expect(subject).to_not match(model_or_instance) }
|
112
|
+
|
113
|
+
describe_failure_message do
|
114
|
+
specify { expect(subject).to eq "expected TestModel to have validator #{validator_name} on :#{attr_name}" }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "with a matching validation" do
|
119
|
+
before do
|
120
|
+
model.send(validation_method, attr_name, validation_base_options)
|
121
|
+
end
|
122
|
+
|
123
|
+
specify { expect(subject).to match(model_or_instance) }
|
124
|
+
|
125
|
+
describe_failure_message_when_negated do
|
126
|
+
specify { expect(subject).to eq "expected TestModel to not have validator #{validator_name} on :#{attr_name}" }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when matching with options" do
|
132
|
+
subject { matcher_with_options.tap {|m| m.matches?(model_or_instance) } }
|
133
|
+
|
134
|
+
context "with no matching validation" do
|
135
|
+
specify { expect(subject).to_not match(model_or_instance) }
|
136
|
+
|
137
|
+
describe_failure_message do
|
138
|
+
specify { expect(subject).to eq "expected TestModel to have validator #{validator_name} on :#{attr_name} with options #{matcher_options.inspect}" }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "with a matching validation" do
|
143
|
+
context "with incorrect options" do
|
144
|
+
before do
|
145
|
+
model.send(validation_method, attr_name, validation_base_options)
|
146
|
+
end
|
147
|
+
|
148
|
+
specify { expect(subject).to_not match(model_or_instance) }
|
149
|
+
|
150
|
+
describe_failure_message do
|
151
|
+
specify { expect(subject).to eq "expected TestModel to have validator #{validator_name} on :#{attr_name} with options #{matcher_options.inspect}" }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "with correct options" do
|
156
|
+
before do
|
157
|
+
model.send(validation_method, attr_name, matcher_options)
|
158
|
+
end
|
159
|
+
|
160
|
+
specify { expect(subject).to match(model_or_instance) }
|
161
|
+
|
162
|
+
describe_failure_message_when_negated do
|
163
|
+
specify { expect(subject).to eq "expected TestModel to not have validator #{validator_name} on :#{attr_name} with options #{matcher_options.inspect}" }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/warp.gemspec
CHANGED
@@ -14,14 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.test_files = spec.files.grep(%r{^(spec)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
21
|
-
|
22
|
-
# spec.add_runtime_dependency "rspec", "~> 3.0.0"
|
23
|
-
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.5.1"
|
25
|
-
spec.add_development_dependency "rake"
|
26
|
-
spec.add_development_dependency "fuubar"
|
20
|
+
spec.add_runtime_dependency "rspec", ">= 2.14.0"
|
27
21
|
end
|
metadata
CHANGED
@@ -1,57 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: warp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Drake-Brockman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.5.1
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 1.5.1
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: fuubar
|
14
|
+
name: rspec
|
43
15
|
requirement: !ruby/object:Gem::Requirement
|
44
16
|
requirements:
|
45
17
|
- - ">="
|
46
18
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
type: :
|
19
|
+
version: 2.14.0
|
20
|
+
type: :runtime
|
49
21
|
prerelease: false
|
50
22
|
version_requirements: !ruby/object:Gem::Requirement
|
51
23
|
requirements:
|
52
24
|
- - ">="
|
53
25
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
26
|
+
version: 2.14.0
|
55
27
|
description: Rails matchers for your RSpec specs.
|
56
28
|
email:
|
57
29
|
- thom@sfedb.com
|
@@ -105,6 +77,7 @@ files:
|
|
105
77
|
- spec/warp/controller_matchers/set_flash_matcher_spec.rb
|
106
78
|
- spec/warp/model_helpers/association_matcher_spec.rb
|
107
79
|
- spec/warp/model_helpers/attribute_matcher_spec.rb
|
80
|
+
- spec/warp/model_helpers/validation_matcher_spec.rb
|
108
81
|
- warp.gemspec
|
109
82
|
homepage: ''
|
110
83
|
licenses:
|
@@ -141,3 +114,4 @@ test_files:
|
|
141
114
|
- spec/warp/controller_matchers/set_flash_matcher_spec.rb
|
142
115
|
- spec/warp/model_helpers/association_matcher_spec.rb
|
143
116
|
- spec/warp/model_helpers/attribute_matcher_spec.rb
|
117
|
+
- spec/warp/model_helpers/validation_matcher_spec.rb
|