warp 1.1.0 → 1.2.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.
- 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
|