mongoid-rspec 2.1.0 → 4.1.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 +5 -5
- data/LICENSE +1 -1
- data/README.md +222 -102
- data/Rakefile +8 -5
- data/lib/matchers/accept_nested_attributes.rb +22 -23
- data/lib/matchers/allow_mass_assignment.rb +12 -12
- data/lib/matchers/associations.rb +85 -49
- data/lib/matchers/be_dynamic_document.rb +26 -0
- data/lib/matchers/be_mongoid_document.rb +26 -0
- data/lib/matchers/be_stored_in.rb +55 -0
- data/lib/matchers/have_field.rb +90 -0
- data/lib/matchers/have_timestamps.rb +61 -0
- data/lib/matchers/indexes/have_index_for.rb +16 -0
- data/lib/matchers/indexes/v3/have_index_for.rb +59 -0
- data/lib/matchers/indexes/v4/have_index_for.rb +54 -0
- data/lib/matchers/validations.rb +30 -11
- data/lib/matchers/validations/absence_of.rb +11 -0
- data/lib/matchers/validations/associated.rb +1 -1
- data/lib/matchers/validations/confirmation_of.rb +7 -1
- data/lib/matchers/validations/custom_validation_of.rb +1 -4
- data/lib/matchers/validations/exclusion_of.rb +5 -5
- data/lib/matchers/validations/format_of.rb +2 -2
- data/lib/matchers/validations/inclusion_of.rb +5 -5
- data/lib/matchers/validations/length_of.rb +13 -35
- data/lib/matchers/validations/numericality_of.rb +32 -16
- data/lib/matchers/validations/presence_of.rb +1 -1
- data/lib/matchers/validations/uniqueness_of.rb +7 -10
- data/lib/mongoid-rspec.rb +1 -33
- data/lib/mongoid/rspec.rb +46 -0
- data/lib/mongoid/rspec/version.rb +5 -0
- data/spec/models/article.rb +9 -6
- data/spec/models/comment.rb +1 -1
- data/spec/models/log.rb +3 -3
- data/spec/models/message.rb +17 -0
- data/spec/models/movie_article.rb +1 -2
- data/spec/models/person.rb +1 -1
- data/spec/models/profile.rb +2 -2
- data/spec/models/record.rb +1 -1
- data/spec/models/site.rb +5 -1
- data/spec/models/user.rb +12 -10
- data/spec/spec_helper.rb +12 -10
- data/spec/unit/accept_nested_attributes_spec.rb +1 -1
- data/spec/unit/associations_spec.rb +19 -7
- data/spec/unit/be_dynamic_document_spec.rb +21 -0
- data/spec/unit/be_mongoid_document_spec.rb +25 -0
- data/spec/unit/be_stored_in.rb +54 -0
- data/spec/unit/document_spec.rb +5 -14
- data/spec/unit/have_index_for_spec.rb +46 -0
- data/spec/unit/have_timestamps_spec.rb +71 -0
- data/spec/unit/validations_spec.rb +23 -14
- data/spec/validators/ssn_validator.rb +6 -6
- metadata +119 -43
- data/.document +0 -5
- data/.gitignore +0 -6
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/.travis.yml +0 -10
- data/Gemfile +0 -4
- data/lib/matchers/collections.rb +0 -9
- data/lib/matchers/document.rb +0 -173
- data/lib/matchers/indexes.rb +0 -69
- data/lib/matchers/validations/with_message.rb +0 -27
- data/lib/mongoid-rspec/version.rb +0 -5
- data/mongoid-rspec.gemspec +0 -25
- data/spec/unit/collections_spec.rb +0 -7
- data/spec/unit/indexes_spec.rb +0 -17
@@ -3,7 +3,7 @@ module Mongoid
|
|
3
3
|
module Matchers
|
4
4
|
class AllowMassAssignmentOfMatcher # :nodoc:
|
5
5
|
attr_reader :failure_message, :negative_failure_message
|
6
|
-
alias
|
6
|
+
alias failure_message_when_negated negative_failure_message
|
7
7
|
|
8
8
|
def initialize(attribute)
|
9
9
|
@attribute = attribute.to_s
|
@@ -12,7 +12,7 @@ module Mongoid
|
|
12
12
|
|
13
13
|
def as(role)
|
14
14
|
if active_model_less_than_3_1?
|
15
|
-
raise
|
15
|
+
raise 'You can specify role only in Rails 3.1 or greater'
|
16
16
|
end
|
17
17
|
@options[:role] = role
|
18
18
|
self
|
@@ -25,20 +25,20 @@ module Mongoid
|
|
25
25
|
@negative_failure_message = "#{@attribute} was made accessible"
|
26
26
|
else
|
27
27
|
if protected_attributes.empty?
|
28
|
-
@negative_failure_message =
|
28
|
+
@negative_failure_message = 'no attributes were protected'
|
29
29
|
else
|
30
|
-
@negative_failure_message = "#{class_name} is protecting "
|
31
|
-
|
32
|
-
|
30
|
+
@negative_failure_message = "#{class_name} is protecting " \
|
31
|
+
"#{protected_attributes.to_a.to_sentence}, " \
|
32
|
+
"but not #{@attribute}."
|
33
33
|
end
|
34
34
|
end
|
35
35
|
true
|
36
36
|
else
|
37
|
-
if whitelisting?
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
@failure_message = if whitelisting?
|
38
|
+
"Expected #{@attribute} to be accessible"
|
39
|
+
else
|
40
|
+
"Did not expect #{@attribute} to be protected"
|
41
|
+
end
|
42
42
|
false
|
43
43
|
end
|
44
44
|
end
|
@@ -62,7 +62,7 @@ module Mongoid
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def whitelisting?
|
65
|
-
authorizer.
|
65
|
+
authorizer.is_a?(::ActiveModel::MassAssignmentSecurity::WhiteList)
|
66
66
|
end
|
67
67
|
|
68
68
|
def attr_mass_assignable?
|
@@ -1,16 +1,29 @@
|
|
1
|
-
|
1
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
2
|
+
require 'mongoid/association'
|
3
|
+
else
|
4
|
+
require 'mongoid/relations'
|
5
|
+
end
|
2
6
|
|
3
7
|
module Mongoid
|
4
8
|
module Matchers
|
5
9
|
module Associations
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
11
|
+
HAS_MANY = Mongoid::Association::Referenced::HasMany
|
12
|
+
HAS_AND_BELONGS_TO_MANY = Mongoid::Association::Referenced::HasAndBelongsToMany
|
13
|
+
HAS_ONE = Mongoid::Association::Referenced::HasOne
|
14
|
+
BELONGS_TO = Mongoid::Association::Referenced::BelongsTo
|
15
|
+
EMBEDS_MANY = Mongoid::Association::Embedded::EmbedsMany
|
16
|
+
EMBEDS_ONE = Mongoid::Association::Embedded::EmbedsOne
|
17
|
+
EMBEDDED_IN = Mongoid::Association::Embedded::EmbeddedIn
|
18
|
+
else
|
19
|
+
HAS_MANY = Mongoid::Relations::Referenced::Many
|
20
|
+
HAS_AND_BELONGS_TO_MANY = Mongoid::Relations::Referenced::ManyToMany
|
21
|
+
HAS_ONE = Mongoid::Relations::Referenced::One
|
22
|
+
BELONGS_TO = Mongoid::Relations::Referenced::In
|
23
|
+
EMBEDS_MANY = Mongoid::Relations::Embedded::Many
|
24
|
+
EMBEDS_ONE = Mongoid::Relations::Embedded::One
|
25
|
+
EMBEDDED_IN = Mongoid::Relations::Embedded::In
|
26
|
+
end
|
14
27
|
|
15
28
|
class HaveAssociationMatcher
|
16
29
|
def initialize(name, association_type)
|
@@ -28,7 +41,6 @@ module Mongoid
|
|
28
41
|
end
|
29
42
|
|
30
43
|
def as_inverse_of(association_inverse_name)
|
31
|
-
raise "#{@association[:type].inspect} does not respond to :inverse_of" unless [HAS_MANY, HAS_AND_BELONGS_TO_MANY, BELONGS_TO, EMBEDDED_IN].include?(@association[:type])
|
32
44
|
@association[:inverse_of] = association_inverse_name.to_s
|
33
45
|
@expectation_message << " which is an inverse of #{@association[:inverse_of].inspect}"
|
34
46
|
self
|
@@ -39,7 +51,7 @@ module Mongoid
|
|
39
51
|
@association[:order] = association_field_name.to_s
|
40
52
|
@expectation_message << " ordered by #{@association[:order].inspect}"
|
41
53
|
|
42
|
-
if association_field_name.is_a?
|
54
|
+
if association_field_name.is_a? association_kind_of
|
43
55
|
@association[:order_operator] = association_field_name.operator
|
44
56
|
@expectation_message << " #{order_way(@association[:order_operator])}"
|
45
57
|
end
|
@@ -49,43 +61,43 @@ module Mongoid
|
|
49
61
|
|
50
62
|
def with_dependent(method_name)
|
51
63
|
@association[:dependent] = method_name
|
52
|
-
@expectation_message << " which specifies dependent as #{@association[:dependent]
|
64
|
+
@expectation_message << " which specifies dependent as #{@association[:dependent]}"
|
53
65
|
self
|
54
66
|
end
|
55
67
|
|
56
68
|
def with_autosave
|
57
69
|
@association[:autosave] = true
|
58
|
-
@expectation_message << " which specifies autosave as #{@association[:autosave]
|
70
|
+
@expectation_message << " which specifies autosave as #{@association[:autosave]}"
|
59
71
|
self
|
60
72
|
end
|
61
73
|
|
62
74
|
def with_index
|
63
75
|
@association[:index] = true
|
64
|
-
@expectation_message << " which specifies index as #{@association[:index]
|
76
|
+
@expectation_message << " which specifies index as #{@association[:index]}"
|
65
77
|
self
|
66
78
|
end
|
67
79
|
|
68
80
|
def with_autobuild
|
69
81
|
@association[:autobuild] = true
|
70
|
-
@expectation_message << " which specifies autobuild as #{@association[:autobuild]
|
82
|
+
@expectation_message << " which specifies autobuild as #{@association[:autobuild]}"
|
71
83
|
self
|
72
84
|
end
|
73
85
|
|
74
86
|
def with_polymorphism
|
75
87
|
@association[:polymorphic] = true
|
76
|
-
@expectation_message << " which specifies polymorphic as #{@association[:polymorphic]
|
88
|
+
@expectation_message << " which specifies polymorphic as #{@association[:polymorphic]}"
|
77
89
|
self
|
78
90
|
end
|
79
91
|
|
80
92
|
def with_cascading_callbacks
|
81
93
|
@association[:cascade_callbacks] = true
|
82
|
-
@expectation_message << " which specifies cascade_callbacks as #{@association[:cascade_callbacks]
|
94
|
+
@expectation_message << " which specifies cascade_callbacks as #{@association[:cascade_callbacks]}"
|
83
95
|
self
|
84
96
|
end
|
85
97
|
|
86
98
|
def cyclic
|
87
99
|
@association[:cyclic] = true
|
88
|
-
@expectation_message << " which specifies cyclic as #{@association[:cyclic]
|
100
|
+
@expectation_message << " which specifies cyclic as #{@association[:cyclic]}"
|
89
101
|
self
|
90
102
|
end
|
91
103
|
|
@@ -103,7 +115,13 @@ module Mongoid
|
|
103
115
|
|
104
116
|
def with_counter_cache
|
105
117
|
@association[:counter_cache] = true
|
106
|
-
@expectation_message << " which specifies counter_cache as #{@association[:counter_cache]
|
118
|
+
@expectation_message << " which specifies counter_cache as #{@association[:counter_cache]}"
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def with_optional
|
123
|
+
@association[:optional] = true
|
124
|
+
@expectation_message << " which specifies optional as #{@association[:optional]}"
|
107
125
|
self
|
108
126
|
end
|
109
127
|
|
@@ -118,7 +136,11 @@ module Mongoid
|
|
118
136
|
@positive_result_message = "association named #{@association[:name]}"
|
119
137
|
end
|
120
138
|
|
121
|
-
relation =
|
139
|
+
relation = if Mongoid::Compatibility::Version.mongoid7_or_newer?
|
140
|
+
metadata.class
|
141
|
+
else
|
142
|
+
metadata.relation
|
143
|
+
end
|
122
144
|
if relation != @association[:type]
|
123
145
|
@negative_result_message = "#{@actual.inspect} #{type_description(relation, false)} #{@association[:name]}"
|
124
146
|
return false
|
@@ -126,7 +148,7 @@ module Mongoid
|
|
126
148
|
@positive_result_message = "#{@actual.inspect} #{type_description(relation, false)} #{@association[:name]}"
|
127
149
|
end
|
128
150
|
|
129
|
-
if !@association[:class].nil?
|
151
|
+
if !@association[:class].nil? && (@association[:class] != metadata.klass)
|
130
152
|
@negative_result_message = "#{@positive_result_message} of type #{metadata.klass.inspect}"
|
131
153
|
return false
|
132
154
|
else
|
@@ -224,11 +246,11 @@ module Mongoid
|
|
224
246
|
end
|
225
247
|
|
226
248
|
if @association[:index]
|
227
|
-
if metadata.
|
249
|
+
if metadata.indexed?
|
250
|
+
@positive_result_message = "#{@positive_result_message} which set index"
|
251
|
+
else
|
228
252
|
@negative_result_message = "#{@positive_result_message} which did not set index"
|
229
253
|
return false
|
230
|
-
else
|
231
|
-
@positive_result_message = "#{@positive_result_message} which set index"
|
232
254
|
end
|
233
255
|
end
|
234
256
|
|
@@ -250,7 +272,16 @@ module Mongoid
|
|
250
272
|
end
|
251
273
|
end
|
252
274
|
|
253
|
-
|
275
|
+
if @association[:optional]
|
276
|
+
if metadata.options[:optional] != true
|
277
|
+
@negative_result_message = "#{@positive_result_message} which did not set optional"
|
278
|
+
return false
|
279
|
+
else
|
280
|
+
@positive_result_message = "#{@positive_result_message} which set optional"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
true
|
254
285
|
end
|
255
286
|
|
256
287
|
def failure_message_for_should
|
@@ -261,8 +292,8 @@ module Mongoid
|
|
261
292
|
"Expected #{@actual.inspect} to not #{@expectation_message}, got #{@positive_result_message}"
|
262
293
|
end
|
263
294
|
|
264
|
-
alias
|
265
|
-
alias
|
295
|
+
alias failure_message failure_message_for_should
|
296
|
+
alias failure_message_when_negated failure_message_for_should_not
|
266
297
|
|
267
298
|
def description
|
268
299
|
@expectation_message
|
@@ -271,29 +302,34 @@ module Mongoid
|
|
271
302
|
def type_description(type = nil, passive = true)
|
272
303
|
type ||= @association[:type]
|
273
304
|
case type.name
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
305
|
+
when EMBEDS_ONE.name
|
306
|
+
(passive ? 'embed' : 'embeds') << ' one'
|
307
|
+
when EMBEDS_MANY.name
|
308
|
+
(passive ? 'embed' : 'embeds') << ' many'
|
309
|
+
when EMBEDDED_IN.name
|
310
|
+
(passive ? 'be' : 'is') << ' embedded in'
|
311
|
+
when HAS_ONE.name
|
312
|
+
(passive ? 'reference' : 'references') << ' one'
|
313
|
+
when HAS_MANY.name
|
314
|
+
(passive ? 'reference' : 'references') << ' many'
|
315
|
+
when HAS_AND_BELONGS_TO_MANY.name
|
316
|
+
(passive ? 'reference' : 'references') << ' and referenced in many'
|
317
|
+
when BELONGS_TO.name
|
318
|
+
(passive ? 'be referenced in' : 'referenced in')
|
319
|
+
else
|
320
|
+
raise format("Unknown association type '%s'", type)
|
290
321
|
end
|
291
322
|
end
|
292
323
|
|
293
324
|
private
|
294
|
-
|
295
|
-
|
296
|
-
|
325
|
+
|
326
|
+
def order_way(operator)
|
327
|
+
[nil, 'ascending', 'descending'][operator]
|
328
|
+
end
|
329
|
+
|
330
|
+
def association_kind_of
|
331
|
+
Mongoid::Compatibility::Version.mongoid5_or_older? ? Origin::Key : Mongoid::Criteria::Queryable::Key
|
332
|
+
end
|
297
333
|
end
|
298
334
|
|
299
335
|
def embed_one(association_name)
|
@@ -311,12 +347,12 @@ module Mongoid
|
|
311
347
|
def have_one_related(association_name)
|
312
348
|
HaveAssociationMatcher.new(association_name, HAS_ONE)
|
313
349
|
end
|
314
|
-
alias
|
350
|
+
alias have_one have_one_related
|
315
351
|
|
316
352
|
def have_many_related(association_name)
|
317
353
|
HaveAssociationMatcher.new(association_name, HAS_MANY)
|
318
354
|
end
|
319
|
-
alias
|
355
|
+
alias have_many have_many_related
|
320
356
|
|
321
357
|
def have_and_belong_to_many(association_name)
|
322
358
|
HaveAssociationMatcher.new(association_name, HAS_AND_BELONGS_TO_MANY)
|
@@ -325,7 +361,7 @@ module Mongoid
|
|
325
361
|
def belong_to_related(association_name)
|
326
362
|
HaveAssociationMatcher.new(association_name, BELONGS_TO)
|
327
363
|
end
|
328
|
-
alias
|
364
|
+
alias belong_to belong_to_related
|
329
365
|
end
|
330
366
|
end
|
331
367
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
def be_dynamic_document
|
4
|
+
BeDynamicDocument.new
|
5
|
+
end
|
6
|
+
|
7
|
+
class BeDynamicDocument
|
8
|
+
def matches?(actual)
|
9
|
+
@model = actual.is_a?(Class) ? actual : actual.class
|
10
|
+
@model.included_modules.include?(Mongoid::Attributes::Dynamic)
|
11
|
+
end
|
12
|
+
|
13
|
+
def description
|
14
|
+
'include Mongoid::Attributes::Dynamic'
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expect #{@model.inspect} class to #{description}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_when_negated
|
22
|
+
"expect #{@model.inspect} class to not #{description}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
def be_mongoid_document
|
4
|
+
BeMongoidDocument.new
|
5
|
+
end
|
6
|
+
|
7
|
+
class BeMongoidDocument
|
8
|
+
def matches?(actual)
|
9
|
+
@model = actual.is_a?(Class) ? actual : actual.class
|
10
|
+
@model.included_modules.include?(Mongoid::Document)
|
11
|
+
end
|
12
|
+
|
13
|
+
def description
|
14
|
+
'include Mongoid::Document'
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expect #{@model.inspect} class to #{description}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message_when_negated
|
22
|
+
"expect #{@model.inspect} class to not #{description}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
def be_stored_in(options)
|
4
|
+
BeStoredIn.new(options)
|
5
|
+
end
|
6
|
+
|
7
|
+
class BeStoredIn
|
8
|
+
def initialize(expected)
|
9
|
+
@expected_options = expected.transform_values { |v| v.to_sym rescue v }.symbolize_keys
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(actual)
|
13
|
+
@model = actual.is_a?(Class) ? actual : actual.class
|
14
|
+
actual_options == @expected_options
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
"be stored in #{@expected_options.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message
|
22
|
+
"Expected #{@model.inspect} to #{description}, got #{actual_options.inspect}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def failure_message_when_negated
|
26
|
+
"Expected #{@model.inspect} not to #{description}, got #{actual_options.inspect}"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def actual_options
|
32
|
+
@actual_options ||= begin
|
33
|
+
hash = @model.storage_options.slice(*@expected_options.keys)
|
34
|
+
hash.each do |option, value|
|
35
|
+
hash[option] =
|
36
|
+
if value.is_a?(Proc)
|
37
|
+
evaluated_value = @model.persistence_context.send("#{option}_name")
|
38
|
+
begin
|
39
|
+
evaluated_value.to_sym
|
40
|
+
rescue StandardError
|
41
|
+
evaluated_value
|
42
|
+
end
|
43
|
+
else
|
44
|
+
begin
|
45
|
+
value.to_sym
|
46
|
+
rescue StandardError
|
47
|
+
value
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
class HaveField # :nodoc:
|
4
|
+
def initialize(*attrs)
|
5
|
+
@attributes = attrs.collect(&:to_s)
|
6
|
+
end
|
7
|
+
|
8
|
+
def localized
|
9
|
+
@localized = true
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def of_type(type)
|
14
|
+
@type = type
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_alias(field_alias)
|
19
|
+
@field_alias = field_alias
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_default_value_of(default)
|
24
|
+
@default = default
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def matches?(klass)
|
29
|
+
@klass = klass.is_a?(Class) ? klass : klass.class
|
30
|
+
@errors = []
|
31
|
+
@attributes.each do |attr|
|
32
|
+
if @klass.fields.include?(attr)
|
33
|
+
error = ''
|
34
|
+
if @type && (@klass.fields[attr].type != @type)
|
35
|
+
error << " of type #{@klass.fields[attr].type}"
|
36
|
+
end
|
37
|
+
|
38
|
+
unless @default.nil?
|
39
|
+
if @klass.fields[attr].default_val.nil?
|
40
|
+
error << ' with default not set'
|
41
|
+
elsif @klass.fields[attr].default_val != @default
|
42
|
+
error << " with default value of #{@klass.fields[attr].default_val}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if @field_alias && (@klass.fields[attr].options[:as] != @field_alias)
|
47
|
+
error << " with alias #{@klass.fields[attr].options[:as]}"
|
48
|
+
end
|
49
|
+
|
50
|
+
@errors.push("field #{attr.inspect}" << error) unless error.blank?
|
51
|
+
|
52
|
+
if @localized
|
53
|
+
unless @klass.fields[attr].localized?
|
54
|
+
@errors.push "is not localized #{attr.inspect}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
else
|
59
|
+
@errors.push "no field named #{attr.inspect}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
@errors.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
def failure_message_for_should
|
66
|
+
"Expected #{@klass.inspect} to #{description}, got #{@errors.to_sentence}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def failure_message_for_should_not
|
70
|
+
"Expected #{@klass.inspect} to not #{description}, got #{@klass.inspect} to #{description}"
|
71
|
+
end
|
72
|
+
|
73
|
+
alias failure_message failure_message_for_should
|
74
|
+
alias failure_message_when_negated failure_message_for_should_not
|
75
|
+
|
76
|
+
def description
|
77
|
+
desc = "have #{@attributes.size > 1 ? 'fields' : 'field'} named #{@attributes.collect(&:inspect).to_sentence}"
|
78
|
+
desc << " of type #{@type.inspect}" if @type
|
79
|
+
desc << " with alias #{@field_alias}" if @field_alias
|
80
|
+
desc << " with default value of #{@default.inspect}" unless @default.nil?
|
81
|
+
desc
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def have_field(*args)
|
86
|
+
HaveField.new(*args)
|
87
|
+
end
|
88
|
+
alias have_fields have_field
|
89
|
+
end
|
90
|
+
end
|