mongoid-rspec 4.0.1 → 4.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 +5 -5
- data/README.md +55 -7
- data/Rakefile +1 -4
- data/lib/matchers/associations.rb +35 -1
- data/lib/matchers/indexes/v3/have_index_for.rb +1 -1
- data/lib/matchers/validations.rb +27 -1
- data/lib/mongoid/rspec/version.rb +1 -1
- data/lib/mongoid/rspec.rb +1 -1
- metadata +73 -69
- data/spec/models/article.rb +0 -32
- data/spec/models/comment.rb +0 -6
- data/spec/models/log.rb +0 -9
- data/spec/models/message.rb +0 -11
- data/spec/models/movie_article.rb +0 -7
- data/spec/models/permalink.rb +0 -5
- data/spec/models/person.rb +0 -10
- data/spec/models/profile.rb +0 -16
- data/spec/models/record.rb +0 -5
- data/spec/models/site.rb +0 -13
- data/spec/models/user.rb +0 -37
- data/spec/spec_helper.rb +0 -36
- data/spec/unit/accept_nested_attributes_spec.rb +0 -12
- data/spec/unit/associations_spec.rb +0 -48
- data/spec/unit/be_dynamic_document_spec.rb +0 -21
- data/spec/unit/be_mongoid_document_spec.rb +0 -25
- data/spec/unit/be_stored_in.rb +0 -54
- data/spec/unit/document_spec.rb +0 -17
- data/spec/unit/have_index_for_spec.rb +0 -46
- data/spec/unit/have_timestamps_spec.rb +0 -71
- data/spec/unit/validations_spec.rb +0 -61
- data/spec/validators/ssn_validator.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 711f91347b02d3d6982a72b6946bb781ea07dba16f858109da01166c7a768ecf
|
4
|
+
data.tar.gz: 58e81131678e670e5a7b63385122fa316afadb18d49749c3544a4e5e1898d3fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7aab1843f0f0b8778916039f3ef8b0f89e815bbc9cfafe0d7244a903df8c524ec6e990914478d6cd403b5b9e81e885b007850fe58cbf78841d989a472e98cdb2
|
7
|
+
data.tar.gz: 3e068496db19d24acfd05ff8ac630ecd41ccab1606e6597ddf0d0bf5969296dd7e1f2f5cf3a7a847801b44c84363e784908024a392317b7d1a95825f2c66bf9f
|
data/README.md
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
# [mongoid-rspec](https://github.com/mongoid/mongoid-rspec "A collection of RSpec-compatible matchers that help to test Mongoid documents.")
|
2
2
|
|
3
|
-
[](https://travis-ci.org/mongoid/mongoid-rspec)
|
4
3
|
[](https://badge.fury.io/rb/mongoid-rspec)
|
4
|
+
[](https://github.com/mongoid/mongoid-rspec/actions)
|
5
|
+
[](https://github.com/mongoid/mongoid-rspec/actions)
|
5
6
|
|
6
7
|
The mongoid-rspec library provides a collection of RSpec-compatible matchers that help to test Mongoid documents.
|
7
8
|
|
9
|
+
[Tested](https://github.com/mongoid/mongoid-locker/actions) against:
|
10
|
+
- MRI: `2.6.x`, `2.7.x`, `3.0.x`, `3.1.x`, `3.2.x`
|
11
|
+
- Mongoid: `4`, `5`, `6`, `7`, `8`, `9`
|
12
|
+
|
13
|
+
See [.github/workflows/rspec.yml](.github/workflows/rspec.yml) for the latest test matrix.
|
14
|
+
|
8
15
|
## Installation
|
9
16
|
|
10
17
|
Drop this line into your Gemfile:
|
@@ -18,7 +25,7 @@ end
|
|
18
25
|
|
19
26
|
## Compatibility
|
20
27
|
|
21
|
-
This gem is compatible with Mongoid 3, 4, 5, 6
|
28
|
+
This gem is compatible with Mongoid 3, 4, 5, 6, 7, 8, 9.
|
22
29
|
|
23
30
|
## Configuration
|
24
31
|
|
@@ -181,7 +188,7 @@ end
|
|
181
188
|
|
182
189
|
```ruby
|
183
190
|
class Article
|
184
|
-
index({ title: 1 }, { unique: true, background: true
|
191
|
+
index({ title: 1 }, { unique: true, background: true })
|
185
192
|
index({ title: 1, created_at: -1 })
|
186
193
|
index({ category: 1 })
|
187
194
|
end
|
@@ -190,7 +197,7 @@ RSpec.describe Article, type: :model do
|
|
190
197
|
it do
|
191
198
|
is_expected
|
192
199
|
.to have_index_for(title: 1)
|
193
|
-
.with_options(unique: true, background: true
|
200
|
+
.with_options(unique: true, background: true)
|
194
201
|
end
|
195
202
|
it { is_expected.to have_index_for(title: 1, created_at: -1) }
|
196
203
|
it { is_expected.to have_index_for(category: 1) }
|
@@ -201,9 +208,9 @@ end
|
|
201
208
|
|
202
209
|
```ruby
|
203
210
|
RSpec.describe Article do
|
204
|
-
it { is_expected.to have_field(:published).of_type(Boolean).with_default_value_of(false) }
|
205
|
-
it { is_expected.to have_field(:allow_comments).of_type(Boolean).with_default_value_of(true) }
|
206
|
-
it { is_expected.not_to have_field(:allow_comments).of_type(Boolean).with_default_value_of(false) }
|
211
|
+
it { is_expected.to have_field(:published).of_type(Mongoid::Boolean).with_default_value_of(false) }
|
212
|
+
it { is_expected.to have_field(:allow_comments).of_type(Mongoid::Boolean).with_default_value_of(true) }
|
213
|
+
it { is_expected.not_to have_field(:allow_comments).of_type(Mongoid::Boolean).with_default_value_of(false) }
|
207
214
|
it { is_expected.not_to have_field(:number_of_comments).of_type(Integer).with_default_value_of(1) }
|
208
215
|
end
|
209
216
|
|
@@ -249,6 +256,27 @@ RSpec.describe Article do
|
|
249
256
|
it { is_expected.to embed_many(:comments) }
|
250
257
|
end
|
251
258
|
|
259
|
+
# when the touch option is provided, then we can also verify that it is set
|
260
|
+
|
261
|
+
# by default, with_touch matches true when no parameters are provided
|
262
|
+
describe Article do
|
263
|
+
it { is_expected.to belong_to(:author).of_type(User).as_inverse_of(:articles).with_index.with_touch }
|
264
|
+
end
|
265
|
+
|
266
|
+
# parameters are supported for explicit matching
|
267
|
+
describe Comment do
|
268
|
+
it { is_expected.to be_embedded_in(:article).as_inverse_of(:comments).with_polymorphism.with_touch(true) }
|
269
|
+
end
|
270
|
+
|
271
|
+
describe Permalink do
|
272
|
+
it { is_expected.to be_embedded_in(:linkable).as_inverse_of(:link).with_touch(false) }
|
273
|
+
end
|
274
|
+
|
275
|
+
# touch can also take a symbol representing a field on the parent to touch
|
276
|
+
describe Record do
|
277
|
+
it { is_expected.to belong_to(:user).as_inverse_of(:record).with_touch(:record_updated_at) }
|
278
|
+
end
|
279
|
+
|
252
280
|
RSpec.describe Comment do
|
253
281
|
it { is_expected.to be_embedded_in(:article).as_inverse_of(:comments) }
|
254
282
|
it { is_expected.to belong_to(:user).as_inverse_of(:comments) }
|
@@ -261,6 +289,10 @@ end
|
|
261
289
|
RSpec.describe Site do
|
262
290
|
it { is_expected.to have_many(:users).as_inverse_of(:site).ordered_by(:email.asc).with_counter_cache }
|
263
291
|
end
|
292
|
+
|
293
|
+
RSpec.describe Message do
|
294
|
+
it { is_expected.to belong_to(:user).with_optional }
|
295
|
+
end
|
264
296
|
```
|
265
297
|
|
266
298
|
### Validation Matchers
|
@@ -311,6 +343,22 @@ RSpec.describe Person do
|
|
311
343
|
# should redefine the kind method to return :custom, i.e. "def self.kind() :custom end"
|
312
344
|
it { is_expected.to custom_validate(:ssn).with_validator(SsnValidator) }
|
313
345
|
end
|
346
|
+
|
347
|
+
# If you're using validators with if/unless conditionals, spec subject must be object instance
|
348
|
+
# This is supported on Mongoid 4 and newer
|
349
|
+
Rspec.describe User do
|
350
|
+
context 'when user has `admin` role' do
|
351
|
+
subject { User.new(role: 'admin') }
|
352
|
+
|
353
|
+
it { is_expected.to validate_length_of(:password).greater_than(20) }
|
354
|
+
end
|
355
|
+
|
356
|
+
context 'when user does not have `admin` role' do
|
357
|
+
subject { User.new(role: 'member') }
|
358
|
+
|
359
|
+
it { is_expected.not_to validate_length_of(:password) }
|
360
|
+
end
|
361
|
+
end
|
314
362
|
```
|
315
363
|
|
316
364
|
### Mass Assignment Matcher
|
data/Rakefile
CHANGED
@@ -51,7 +51,7 @@ module Mongoid
|
|
51
51
|
@association[:order] = association_field_name.to_s
|
52
52
|
@expectation_message << " ordered by #{@association[:order].inspect}"
|
53
53
|
|
54
|
-
if association_field_name.is_a?
|
54
|
+
if association_field_name.is_a? association_kind_of
|
55
55
|
@association[:order_operator] = association_field_name.operator
|
56
56
|
@expectation_message << " #{order_way(@association[:order_operator])}"
|
57
57
|
end
|
@@ -119,6 +119,18 @@ module Mongoid
|
|
119
119
|
self
|
120
120
|
end
|
121
121
|
|
122
|
+
def with_touch(touch = true)
|
123
|
+
@association[:touch] = touch
|
124
|
+
@expectation_message << " which specifies touch as #{@association[:touch]}"
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
def with_optional
|
129
|
+
@association[:optional] = true
|
130
|
+
@expectation_message << " which specifies optional as #{@association[:optional]}"
|
131
|
+
self
|
132
|
+
end
|
133
|
+
|
122
134
|
def matches?(actual)
|
123
135
|
@actual = actual.is_a?(Class) ? actual : actual.class
|
124
136
|
metadata = @actual.relations[@association[:name]]
|
@@ -266,6 +278,24 @@ module Mongoid
|
|
266
278
|
end
|
267
279
|
end
|
268
280
|
|
281
|
+
unless @association[:touch].nil?
|
282
|
+
if metadata.options[:touch] != @association[:touch]
|
283
|
+
@negative_result_message = "#{@positive_result_message} which sets touch as #{metadata.options[:touch].inspect}"
|
284
|
+
return false
|
285
|
+
else
|
286
|
+
@positive_result_message = "#{@positive_result_message} which sets touch as #{metadata.options[:touch].inspect}"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
if @association[:optional]
|
291
|
+
if metadata.options[:optional] != true
|
292
|
+
@negative_result_message = "#{@positive_result_message} which did not set optional"
|
293
|
+
return false
|
294
|
+
else
|
295
|
+
@positive_result_message = "#{@positive_result_message} which set optional"
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
269
299
|
true
|
270
300
|
end
|
271
301
|
|
@@ -311,6 +341,10 @@ module Mongoid
|
|
311
341
|
def order_way(operator)
|
312
342
|
[nil, 'ascending', 'descending'][operator]
|
313
343
|
end
|
344
|
+
|
345
|
+
def association_kind_of
|
346
|
+
Mongoid::Compatibility::Version.mongoid5_or_older? ? Origin::Key : Mongoid::Criteria::Queryable::Key
|
347
|
+
end
|
314
348
|
end
|
315
349
|
|
316
350
|
def embed_one(association_name)
|
data/lib/matchers/validations.rb
CHANGED
@@ -12,7 +12,8 @@ module Mongoid
|
|
12
12
|
@klass = actual.is_a?(Class) ? actual : actual.class
|
13
13
|
|
14
14
|
@validator = @klass.validators_on(@field).detect do |v|
|
15
|
-
(v.kind.to_s == @type) && (!v.options[:on] || on_options_matches?(v))
|
15
|
+
(v.kind.to_s == @type) && (!v.options[:on] || on_options_matches?(v)) &&
|
16
|
+
if_condition_matches?(actual, v) && unless_condition_matches?(actual, v)
|
16
17
|
end
|
17
18
|
|
18
19
|
if @validator
|
@@ -59,6 +60,31 @@ module Mongoid
|
|
59
60
|
|
60
61
|
private
|
61
62
|
|
63
|
+
def if_condition_matches?(actual, validator)
|
64
|
+
return true unless validator.options[:if]
|
65
|
+
|
66
|
+
check_condition actual, validator.options[:if]
|
67
|
+
end
|
68
|
+
|
69
|
+
def unless_condition_matches?(actual, validator)
|
70
|
+
return true unless validator.options[:unless]
|
71
|
+
|
72
|
+
!check_condition actual, validator.options[:unless]
|
73
|
+
end
|
74
|
+
|
75
|
+
def check_condition(actual, filter)
|
76
|
+
raise ArgumentError, 'Spec subject must be object instance when testing validators with if/unless condition.' if actual.is_a?(Class)
|
77
|
+
|
78
|
+
case filter
|
79
|
+
when Symbol
|
80
|
+
actual.send filter
|
81
|
+
when ::Proc
|
82
|
+
actual.instance_exec(&filter)
|
83
|
+
else
|
84
|
+
raise ArgumentError, "Unexpected filter: #{filter.inspect}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
62
88
|
def check_on
|
63
89
|
validator_on_methods = [@validator.options[:on]].flatten
|
64
90
|
|
data/lib/mongoid/rspec.rb
CHANGED
@@ -6,7 +6,7 @@ require 'rspec/core'
|
|
6
6
|
require 'rspec/expectations'
|
7
7
|
require 'rspec/mocks'
|
8
8
|
require 'active_support/core_ext/hash/keys'
|
9
|
-
require 'active_support/core_ext/hash/transform_values' if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
9
|
+
require 'active_support/core_ext/hash/transform_values' if Mongoid::Compatibility::Version.mongoid4_or_newer? && ActiveSupport.version < Gem::Version.new('6')
|
10
10
|
require 'active_support/core_ext/object/blank'
|
11
11
|
require 'active_support/core_ext/string/inflections'
|
12
12
|
|
metadata
CHANGED
@@ -1,70 +1,118 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Sagge
|
8
8
|
- Rodrigo Pinto
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-06-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: appraisal
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: mongoid-danger
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.2'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.2'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: pry
|
16
44
|
requirement: !ruby/object:Gem::Requirement
|
17
45
|
requirements:
|
18
46
|
- - ">="
|
19
47
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
21
|
-
type: :
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
22
50
|
prerelease: false
|
23
51
|
version_requirements: !ruby/object:Gem::Requirement
|
24
52
|
requirements:
|
25
53
|
- - ">="
|
26
54
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
55
|
+
version: '0'
|
28
56
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
57
|
+
name: rails
|
30
58
|
requirement: !ruby/object:Gem::Requirement
|
31
59
|
requirements:
|
32
60
|
- - ">="
|
33
61
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
35
|
-
type: :
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
36
64
|
prerelease: false
|
37
65
|
version_requirements: !ruby/object:Gem::Requirement
|
38
66
|
requirements:
|
39
67
|
- - ">="
|
40
68
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
69
|
+
version: '0'
|
42
70
|
- !ruby/object:Gem::Dependency
|
43
71
|
name: rspec
|
44
72
|
requirement: !ruby/object:Gem::Requirement
|
45
73
|
requirements:
|
46
|
-
- - "
|
74
|
+
- - ">="
|
47
75
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
49
|
-
type: :
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
50
78
|
prerelease: false
|
51
79
|
version_requirements: !ruby/object:Gem::Requirement
|
52
80
|
requirements:
|
53
|
-
- - "
|
81
|
+
- - ">="
|
54
82
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
83
|
+
version: '0'
|
56
84
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
85
|
+
name: rubocop
|
58
86
|
requirement: !ruby/object:Gem::Requirement
|
59
87
|
requirements:
|
60
88
|
- - "~>"
|
61
89
|
- !ruby/object:Gem::Version
|
62
|
-
version:
|
90
|
+
version: 1.36.0
|
63
91
|
type: :development
|
64
92
|
prerelease: false
|
65
93
|
version_requirements: !ruby/object:Gem::Requirement
|
66
94
|
requirements:
|
67
95
|
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 1.36.0
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: mongoid
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '3.0'
|
105
|
+
- - "<"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '10.0'
|
108
|
+
type: :runtime
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '3.0'
|
115
|
+
- - "<"
|
68
116
|
- !ruby/object:Gem::Version
|
69
117
|
version: '10.0'
|
70
118
|
- !ruby/object:Gem::Dependency
|
@@ -118,33 +166,12 @@ files:
|
|
118
166
|
- lib/mongoid-rspec.rb
|
119
167
|
- lib/mongoid/rspec.rb
|
120
168
|
- lib/mongoid/rspec/version.rb
|
121
|
-
- spec/models/article.rb
|
122
|
-
- spec/models/comment.rb
|
123
|
-
- spec/models/log.rb
|
124
|
-
- spec/models/message.rb
|
125
|
-
- spec/models/movie_article.rb
|
126
|
-
- spec/models/permalink.rb
|
127
|
-
- spec/models/person.rb
|
128
|
-
- spec/models/profile.rb
|
129
|
-
- spec/models/record.rb
|
130
|
-
- spec/models/site.rb
|
131
|
-
- spec/models/user.rb
|
132
|
-
- spec/spec_helper.rb
|
133
|
-
- spec/unit/accept_nested_attributes_spec.rb
|
134
|
-
- spec/unit/associations_spec.rb
|
135
|
-
- spec/unit/be_dynamic_document_spec.rb
|
136
|
-
- spec/unit/be_mongoid_document_spec.rb
|
137
|
-
- spec/unit/be_stored_in.rb
|
138
|
-
- spec/unit/document_spec.rb
|
139
|
-
- spec/unit/have_index_for_spec.rb
|
140
|
-
- spec/unit/have_timestamps_spec.rb
|
141
|
-
- spec/unit/validations_spec.rb
|
142
|
-
- spec/validators/ssn_validator.rb
|
143
169
|
homepage: http://github.com/mongoid-rspec/mongoid-rspec
|
144
170
|
licenses:
|
145
171
|
- MIT
|
146
|
-
metadata:
|
147
|
-
|
172
|
+
metadata:
|
173
|
+
rubygems_mfa_required: 'true'
|
174
|
+
post_install_message:
|
148
175
|
rdoc_options: []
|
149
176
|
require_paths:
|
150
177
|
- lib
|
@@ -152,38 +179,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
179
|
requirements:
|
153
180
|
- - ">="
|
154
181
|
- !ruby/object:Gem::Version
|
155
|
-
version: '2.
|
182
|
+
version: '2.6'
|
156
183
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
184
|
requirements:
|
158
185
|
- - ">="
|
159
186
|
- !ruby/object:Gem::Version
|
160
187
|
version: 1.3.6
|
161
188
|
requirements: []
|
162
|
-
|
163
|
-
|
164
|
-
signing_key:
|
189
|
+
rubygems_version: 3.5.10
|
190
|
+
signing_key:
|
165
191
|
specification_version: 4
|
166
192
|
summary: RSpec matchers for Mongoid
|
167
|
-
test_files:
|
168
|
-
- spec/models/article.rb
|
169
|
-
- spec/models/comment.rb
|
170
|
-
- spec/models/log.rb
|
171
|
-
- spec/models/message.rb
|
172
|
-
- spec/models/movie_article.rb
|
173
|
-
- spec/models/permalink.rb
|
174
|
-
- spec/models/person.rb
|
175
|
-
- spec/models/profile.rb
|
176
|
-
- spec/models/record.rb
|
177
|
-
- spec/models/site.rb
|
178
|
-
- spec/models/user.rb
|
179
|
-
- spec/spec_helper.rb
|
180
|
-
- spec/unit/accept_nested_attributes_spec.rb
|
181
|
-
- spec/unit/associations_spec.rb
|
182
|
-
- spec/unit/be_dynamic_document_spec.rb
|
183
|
-
- spec/unit/be_mongoid_document_spec.rb
|
184
|
-
- spec/unit/be_stored_in.rb
|
185
|
-
- spec/unit/document_spec.rb
|
186
|
-
- spec/unit/have_index_for_spec.rb
|
187
|
-
- spec/unit/have_timestamps_spec.rb
|
188
|
-
- spec/unit/validations_spec.rb
|
189
|
-
- spec/validators/ssn_validator.rb
|
193
|
+
test_files: []
|
data/spec/models/article.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
class Article
|
2
|
-
include Mongoid::Document
|
3
|
-
include Mongoid::Timestamps
|
4
|
-
|
5
|
-
field :title, localize: true
|
6
|
-
field :content
|
7
|
-
field :published, type: Boolean, default: false
|
8
|
-
field :allow_comments, type: Boolean, default: true
|
9
|
-
field :number_of_comments, type: Integer
|
10
|
-
field :status, type: Symbol
|
11
|
-
field :deletion_date, type: DateTime, default: nil
|
12
|
-
|
13
|
-
embeds_many :comments, cascade_callbacks: true, inverse_of: :article
|
14
|
-
embeds_one :permalink, inverse_of: :linkable
|
15
|
-
belongs_to :author, class_name: 'User', inverse_of: :articles, index: true
|
16
|
-
|
17
|
-
validates :title, presence: true
|
18
|
-
|
19
|
-
validates_inclusion_of :status, in: [:pending], on: :create
|
20
|
-
validates_inclusion_of :status, in: %i[approved rejected], on: :update
|
21
|
-
|
22
|
-
validates_length_of :title, within: 8..16
|
23
|
-
validates_length_of :content, minimum: 200
|
24
|
-
|
25
|
-
validates_absence_of :deletion_date if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
26
|
-
|
27
|
-
index({ title: 1 }, unique: true, background: true, drop_dups: true)
|
28
|
-
index(published: 1)
|
29
|
-
index('permalink._id' => 1)
|
30
|
-
|
31
|
-
accepts_nested_attributes_for :permalink
|
32
|
-
end
|
data/spec/models/comment.rb
DELETED
data/spec/models/log.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
class Log
|
2
|
-
include Mongoid::Document
|
3
|
-
include Mongoid::Timestamps
|
4
|
-
include Mongoid::Attributes::Dynamic if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
5
|
-
|
6
|
-
store_in collection: 'logs'
|
7
|
-
|
8
|
-
index({ created_at: 1 }, bucket_size: 100, expire_after_seconds: 3600)
|
9
|
-
end
|
data/spec/models/message.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
class Message
|
2
|
-
include Mongoid::Document
|
3
|
-
|
4
|
-
field :identifier
|
5
|
-
field :from
|
6
|
-
field :to
|
7
|
-
|
8
|
-
validates :identifier, uniqueness: { message: 'uniqueness' }
|
9
|
-
validates :from, presence: { message: 'required' }
|
10
|
-
validates :to, format: { with: /[a-z]+/, message: 'format' }
|
11
|
-
end
|
@@ -1,7 +0,0 @@
|
|
1
|
-
class MovieArticle < Article
|
2
|
-
field :rating, type: Float
|
3
|
-
field :classification, type: Integer
|
4
|
-
|
5
|
-
validates :rating, numericality: { greater_than: 0, less_than_or_equal_to: 5 }
|
6
|
-
validates :classification, numericality: { even: true, only_integer: true, allow_nil: false }
|
7
|
-
end
|
data/spec/models/permalink.rb
DELETED
data/spec/models/person.rb
DELETED
data/spec/models/profile.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
class Profile
|
2
|
-
include Mongoid::Document
|
3
|
-
|
4
|
-
field :first_name
|
5
|
-
field :last_name
|
6
|
-
field :age
|
7
|
-
field :hobbies, type: Array, default: []
|
8
|
-
|
9
|
-
embedded_in :user, inverse_of: :profile
|
10
|
-
|
11
|
-
validates :age, numericality: { greater_than: 0 }
|
12
|
-
validates :terms_of_service, acceptance: true
|
13
|
-
validates :hobbies, length: { minimum: 1, message: 'requires at least one hobby' }
|
14
|
-
|
15
|
-
index(first_name: 1, last_name: 1)
|
16
|
-
end
|
data/spec/models/record.rb
DELETED
data/spec/models/site.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
class Site
|
2
|
-
include Mongoid::Document
|
3
|
-
|
4
|
-
field :name
|
5
|
-
|
6
|
-
if Mongoid::Compatibility::Version.mongoid6_or_older?
|
7
|
-
has_many :users, inverse_of: :site, order: :email.desc, counter_cache: true
|
8
|
-
else
|
9
|
-
has_many :users, inverse_of: :site, order: :email.desc
|
10
|
-
end
|
11
|
-
|
12
|
-
validates :name, presence: true, uniqueness: true
|
13
|
-
end
|
data/spec/models/user.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
class User
|
2
|
-
include Mongoid::Document
|
3
|
-
include Mongoid::Timestamps::Created
|
4
|
-
|
5
|
-
field :login
|
6
|
-
field :email
|
7
|
-
field :role
|
8
|
-
field :age, type: Integer
|
9
|
-
field :password, type: String
|
10
|
-
field :provider_uid
|
11
|
-
field :locale
|
12
|
-
|
13
|
-
belongs_to :site, inverse_of: :users
|
14
|
-
has_many :articles, foreign_key: :author_id, order: :title
|
15
|
-
has_many :comments, dependent: :destroy, autosave: true
|
16
|
-
has_and_belongs_to_many :children, class_name: 'User'
|
17
|
-
has_one :record, autobuild: true, inverse_of: :user
|
18
|
-
|
19
|
-
embeds_one :profile, inverse_of: :user
|
20
|
-
|
21
|
-
validates :login, presence: true, uniqueness: { scope: :site }, format: { with: /\A[\w\-]+\z/ }, exclusion: { in: %w[super index edit] }
|
22
|
-
validates :email, uniqueness: { case_sensitive: false, scope: :site, message: 'is already taken' }, confirmation: true
|
23
|
-
validates :role, presence: true, inclusion: { in: %w[admin moderator member] }
|
24
|
-
validates :profile, presence: true, associated: true
|
25
|
-
validates :age, presence: true, numericality: true, inclusion: { in: 23..42 }, on: %i[create update]
|
26
|
-
validates :password, presence: true, on: %i[create update]
|
27
|
-
validates :password, exclusion: { in: ->(_user) { ['password'] } }
|
28
|
-
validates :password, confirmation: { message: 'Password confirmation must match given password' }
|
29
|
-
validates :provider_uid, presence: true
|
30
|
-
validates :locale, inclusion: { in: ->(_user) { %i[en ru] } }
|
31
|
-
|
32
|
-
accepts_nested_attributes_for :articles, :comments
|
33
|
-
|
34
|
-
def admin?
|
35
|
-
false
|
36
|
-
end
|
37
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
3
|
-
MODELS = File.join(File.dirname(__FILE__), 'models')
|
4
|
-
$LOAD_PATH.unshift(MODELS)
|
5
|
-
VALIDATORS = File.join(File.dirname(__FILE__), 'validators')
|
6
|
-
$LOAD_PATH.unshift(VALIDATORS)
|
7
|
-
|
8
|
-
require 'rubygems'
|
9
|
-
require 'bundler'
|
10
|
-
Bundler.setup
|
11
|
-
|
12
|
-
require 'mongoid'
|
13
|
-
require 'rspec'
|
14
|
-
require 'rspec/core'
|
15
|
-
require 'rspec/expectations'
|
16
|
-
require 'mongoid/compatibility'
|
17
|
-
|
18
|
-
Mongoid::Config.connect_to('mongoid-rspec-test') if Mongoid::Compatibility::Version.mongoid3_or_newer?
|
19
|
-
Mongo::Logger.logger.level = ::Logger::INFO if Mongoid::Compatibility::Version.mongoid5_or_newer?
|
20
|
-
|
21
|
-
Dir[File.join(MODELS, '*.rb')].sort.each { |file| require File.basename(file) }
|
22
|
-
|
23
|
-
require 'mongoid-rspec'
|
24
|
-
|
25
|
-
RSpec.configure do |config|
|
26
|
-
config.include RSpec::Matchers
|
27
|
-
config.include Mongoid::Matchers
|
28
|
-
config.mock_with :rspec
|
29
|
-
config.after :all do
|
30
|
-
Mongoid::Config.purge!
|
31
|
-
end
|
32
|
-
config.after :suite do
|
33
|
-
print "\n# Mongoid v#{Mongoid::VERSION}"
|
34
|
-
end
|
35
|
-
config.disable_monkey_patching!
|
36
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe 'AcceptsNestedAttributes' do
|
4
|
-
describe User do
|
5
|
-
it { is_expected.to accept_nested_attributes_for(:articles) }
|
6
|
-
it { is_expected.to accept_nested_attributes_for(:comments) }
|
7
|
-
end
|
8
|
-
|
9
|
-
describe Article do
|
10
|
-
it { is_expected.to accept_nested_attributes_for(:permalink) }
|
11
|
-
end
|
12
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe 'Associations' do
|
4
|
-
describe User do
|
5
|
-
if Mongoid::Compatibility::Version.mongoid6_or_newer?
|
6
|
-
it { is_expected.to have_many(:articles).with_foreign_key(:author_id).ordered_by(:title) }
|
7
|
-
end
|
8
|
-
|
9
|
-
it { is_expected.to have_one(:record).as_inverse_of(:user).with_autobuild }
|
10
|
-
|
11
|
-
it { is_expected.to have_many(:comments).with_dependent(:destroy).with_autosave }
|
12
|
-
|
13
|
-
it { is_expected.to embed_one(:profile).as_inverse_of(:user) }
|
14
|
-
|
15
|
-
it { is_expected.to have_and_belong_to_many(:children).of_type(User) }
|
16
|
-
end
|
17
|
-
|
18
|
-
describe Profile do
|
19
|
-
it { is_expected.to be_embedded_in(:user).as_inverse_of(:profile) }
|
20
|
-
end
|
21
|
-
|
22
|
-
describe Article do
|
23
|
-
it { is_expected.to belong_to(:author).of_type(User).as_inverse_of(:articles).with_index }
|
24
|
-
it { is_expected.to embed_many(:comments).as_inverse_of(:article).with_cascading_callbacks }
|
25
|
-
it { is_expected.to embed_one(:permalink).as_inverse_of(:linkable) }
|
26
|
-
end
|
27
|
-
|
28
|
-
describe Comment do
|
29
|
-
it { is_expected.to be_embedded_in(:article).as_inverse_of(:comments).with_polymorphism }
|
30
|
-
it { is_expected.to belong_to(:user).as_inverse_of(:comments) }
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Record do
|
34
|
-
it { is_expected.to belong_to(:user).as_inverse_of(:record) }
|
35
|
-
end
|
36
|
-
|
37
|
-
describe Permalink do
|
38
|
-
it { is_expected.to be_embedded_in(:linkable).as_inverse_of(:link) }
|
39
|
-
end
|
40
|
-
|
41
|
-
describe Site do
|
42
|
-
if Mongoid::Compatibility::Version.mongoid6?
|
43
|
-
it { is_expected.to have_many(:users).as_inverse_of(:site).ordered_by(:email.desc).with_counter_cache }
|
44
|
-
elsif Mongoid::Compatibility::Version.mongoid7_or_newer?
|
45
|
-
it { is_expected.to have_many(:users).as_inverse_of(:site).ordered_by(:email.desc) }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Mongoid::Matchers::BeDynamicDocument do
|
4
|
-
context 'when model does\'t include Mongoid::Document' do
|
5
|
-
subject do
|
6
|
-
Class.new
|
7
|
-
end
|
8
|
-
|
9
|
-
it { is_expected.not_to be_mongoid_document }
|
10
|
-
end
|
11
|
-
|
12
|
-
context 'when model doesn\'t include Mongoid::Document' do
|
13
|
-
subject do
|
14
|
-
Class.new do
|
15
|
-
include Mongoid::Document
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
it { is_expected.to be_mongoid_document }
|
20
|
-
end
|
21
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
3
|
-
RSpec.describe Mongoid::Matchers::BeMongoidDocument do
|
4
|
-
context 'when model does\'t include Mongoid::Attributes::Dynamic' do
|
5
|
-
subject do
|
6
|
-
Class.new do
|
7
|
-
include Mongoid::Document
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
it { is_expected.not_to be_dynamic_document }
|
12
|
-
end
|
13
|
-
|
14
|
-
context 'when model doesn\'t include Mongoid::Attributes::Dynamic' do
|
15
|
-
subject do
|
16
|
-
Class.new do
|
17
|
-
include Mongoid::Document
|
18
|
-
include Mongoid::Attributes::Dynamic
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
it { is_expected.to be_dynamic_document }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/spec/unit/be_stored_in.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Mongoid::Matchers::BeStoredIn do
|
4
|
-
subject do
|
5
|
-
Class.new do
|
6
|
-
include Mongoid::Document
|
7
|
-
store_in collection: 'citizens', database: 'other', client: 'secondary'
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'detects storage options' do
|
12
|
-
is_expected.to be_stored_in(collection: 'citizens', database: 'other', client: 'secondary')
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'detects even part of storage options' do
|
16
|
-
is_expected.to be_stored_in(database: 'other')
|
17
|
-
is_expected.to be_stored_in(client: 'secondary')
|
18
|
-
is_expected.to be_stored_in(collection: 'citizens')
|
19
|
-
is_expected.to be_stored_in(collection: 'citizens', database: 'other')
|
20
|
-
is_expected.to be_stored_in(database: 'other', client: 'secondary')
|
21
|
-
is_expected.to be_stored_in(collection: 'citizens', client: 'secondary')
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'detects differences' do
|
25
|
-
is_expected.not_to be_stored_in(collection: 'aliens')
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'when models has storage options defined via blocks, procs or lambdas' do
|
29
|
-
subject do
|
30
|
-
Class.new do
|
31
|
-
include Mongoid::Document
|
32
|
-
store_in database: -> { Thread.current[:database] }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
before do
|
37
|
-
Thread.current[:database] = 'db1981'
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'detects storage options' do
|
41
|
-
is_expected.to be_stored_in(database: 'db1981')
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'reflects changes in storage options' do
|
45
|
-
is_expected.to be_stored_in(database: 'db1981')
|
46
|
-
Thread.current[:database] = 'db2200'
|
47
|
-
is_expected.to be_stored_in(database: 'db2200')
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'detects differences' do
|
51
|
-
is_expected.not_to be_stored_in(database: 'other')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
data/spec/unit/document_spec.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe 'Document' do
|
4
|
-
describe User do
|
5
|
-
it { is_expected.to have_fields(:email, :login) }
|
6
|
-
end
|
7
|
-
|
8
|
-
describe Article do
|
9
|
-
klass_boolean = Mongoid::Compatibility::Version.mongoid4_or_newer? ? Mongoid::Boolean : Boolean
|
10
|
-
it { is_expected.to have_field(:published).of_type(klass_boolean).with_default_value_of(false) }
|
11
|
-
it { is_expected.to have_field(:allow_comments).of_type(klass_boolean).with_default_value_of(true) }
|
12
|
-
it { is_expected.to belong_to(:author) }
|
13
|
-
it { is_expected.to have_field(:title).localized }
|
14
|
-
it { is_expected.not_to have_field(:allow_comments).of_type(klass_boolean).with_default_value_of(false) }
|
15
|
-
it { is_expected.not_to have_field(:number_of_comments).of_type(Integer).with_default_value_of(1) }
|
16
|
-
end
|
17
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Mongoid::Matchers::HaveIndexFor do
|
4
|
-
subject do
|
5
|
-
Class.new do
|
6
|
-
include Mongoid::Document
|
7
|
-
|
8
|
-
field :fizz, as: :buzz, type: String
|
9
|
-
|
10
|
-
index(foo: 1)
|
11
|
-
index({ bar: 1 }, unique: true, background: true, drop_dups: true)
|
12
|
-
index(foo: 1, bar: -1)
|
13
|
-
index('baz._id' => 1)
|
14
|
-
index(buzz: 1)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'detects an index for singular field key' do
|
19
|
-
is_expected.to have_index_for(foo: 1)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'detects an index for multipple fields key' do
|
23
|
-
is_expected.to have_index_for(foo: 1, bar: -1)
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'detects an index with options' do
|
27
|
-
is_expected
|
28
|
-
.to have_index_for(bar: 1)
|
29
|
-
.with_options(unique: true, background: true, drop_dups: true)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'detects an index with only part of options' do
|
33
|
-
is_expected
|
34
|
-
.to have_index_for(bar: 1)
|
35
|
-
.with_options(unique: true)
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'detects an index for string key' do
|
39
|
-
is_expected.to have_index_for('baz._id' => 1)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'detect an index for aliased fields' do
|
43
|
-
is_expected.to have_index_for(fizz: 1)
|
44
|
-
is_expected.to have_index_for(buzz: 1) if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
45
|
-
end
|
46
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Mongoid::Matchers::HaveTimestamps do
|
4
|
-
context 'when model includes Mongoid::Timestamps' do
|
5
|
-
subject do
|
6
|
-
Class.new do
|
7
|
-
include Mongoid::Document
|
8
|
-
include Mongoid::Timestamps
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
it { is_expected.to have_timestamps }
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'when model includes Mongoid::Timestamps::Short' do
|
16
|
-
subject do
|
17
|
-
Class.new do
|
18
|
-
include Mongoid::Document
|
19
|
-
include Mongoid::Timestamps::Short
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
it { is_expected.to have_timestamps.shortened }
|
24
|
-
end
|
25
|
-
|
26
|
-
context 'when model includes Mongoid::Timestamps::Updated' do
|
27
|
-
subject do
|
28
|
-
Class.new do
|
29
|
-
include Mongoid::Document
|
30
|
-
include Mongoid::Timestamps::Updated
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
it { is_expected.to have_timestamps.for(:updating) }
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'when model includes Mongoid::Timestamps::Updated::Short' do
|
38
|
-
subject do
|
39
|
-
Class.new do
|
40
|
-
include Mongoid::Document
|
41
|
-
include Mongoid::Timestamps::Updated::Short
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it { is_expected.to have_timestamps.for(:updating).shortened }
|
46
|
-
it { is_expected.to have_timestamps.shortened.for(:updating) }
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'when model includes Mongoid::Timestamps::Created' do
|
50
|
-
subject do
|
51
|
-
Class.new do
|
52
|
-
include Mongoid::Document
|
53
|
-
include Mongoid::Timestamps::Created
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
it { is_expected.to have_timestamps.for(:creating) }
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'when model includes Mongoid::Timestamps::Created::Short' do
|
61
|
-
subject do
|
62
|
-
Class.new do
|
63
|
-
include Mongoid::Document
|
64
|
-
include Mongoid::Timestamps::Created::Short
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
it { is_expected.to have_timestamps.for(:creating).shortened }
|
69
|
-
it { is_expected.to have_timestamps.shortened.for(:creating) }
|
70
|
-
end
|
71
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe 'Validations' do
|
4
|
-
describe Site do
|
5
|
-
it { is_expected.to validate_presence_of(:name) }
|
6
|
-
it { is_expected.to validate_uniqueness_of(:name) }
|
7
|
-
end
|
8
|
-
|
9
|
-
describe User do
|
10
|
-
it { is_expected.to validate_presence_of(:login) }
|
11
|
-
it { is_expected.to validate_uniqueness_of(:login).scoped_to(:site) }
|
12
|
-
it { is_expected.to validate_uniqueness_of(:email).case_insensitive.with_message('is already taken') }
|
13
|
-
it { is_expected.to validate_format_of(:login).to_allow('valid_login').not_to_allow('invalid login') }
|
14
|
-
it { is_expected.to validate_associated(:profile) }
|
15
|
-
it { is_expected.to validate_exclusion_of(:login).to_not_allow('super', 'index', 'edit') }
|
16
|
-
it { is_expected.to validate_exclusion_of(:password).to_not_allow('password') }
|
17
|
-
it { is_expected.to validate_inclusion_of(:role).to_allow('admin', 'member') }
|
18
|
-
it { is_expected.to validate_inclusion_of(:role).to_allow(%w[admin member]) }
|
19
|
-
it { is_expected.to validate_confirmation_of(:email) }
|
20
|
-
it { is_expected.to validate_presence_of(:age).on(:create, :update) }
|
21
|
-
it { is_expected.to validate_numericality_of(:age).on(:create, :update) }
|
22
|
-
it { is_expected.to validate_inclusion_of(:age).to_allow(23..42).on(%i[create update]) }
|
23
|
-
it { is_expected.to validate_presence_of(:password).on(:create) }
|
24
|
-
it { is_expected.to validate_confirmation_of(:password).with_message('Password confirmation must match given password') }
|
25
|
-
it { is_expected.to validate_presence_of(:provider_uid).on(:create) }
|
26
|
-
it { is_expected.to validate_inclusion_of(:locale).to_allow(%i[en ru]) }
|
27
|
-
end
|
28
|
-
|
29
|
-
describe Profile do
|
30
|
-
it { is_expected.to validate_numericality_of(:age).greater_than(0) }
|
31
|
-
it { is_expected.not_to validate_numericality_of(:age).greater_than(0).only_integer(true) }
|
32
|
-
it { is_expected.to validate_acceptance_of(:terms_of_service) }
|
33
|
-
it { is_expected.to validate_length_of(:hobbies).with_minimum(1).with_message('requires at least one hobby') }
|
34
|
-
end
|
35
|
-
|
36
|
-
describe Article do
|
37
|
-
it { is_expected.to validate_length_of(:title).within(8..16) }
|
38
|
-
it { is_expected.not_to validate_length_of(:content).greater_than(200).less_than(16) }
|
39
|
-
it { is_expected.to validate_length_of(:content).greater_than(200) }
|
40
|
-
it { is_expected.to validate_inclusion_of(:status).to_allow([:pending]).on(:create) }
|
41
|
-
it { is_expected.to validate_inclusion_of(:status).to_allow(%i[approved rejected]).on(:update) }
|
42
|
-
it { is_expected.to validate_absence_of(:deletion_date) } if Mongoid::Compatibility::Version.mongoid4_or_newer?
|
43
|
-
end
|
44
|
-
|
45
|
-
describe MovieArticle do
|
46
|
-
it { is_expected.to validate_numericality_of(:rating).greater_than(0) }
|
47
|
-
it { is_expected.to validate_numericality_of(:rating).to_allow(greater_than: 0).less_than_or_equal_to(5) }
|
48
|
-
it { is_expected.to validate_numericality_of(:classification).to_allow(even: true, only_integer: true, nil: false) }
|
49
|
-
end
|
50
|
-
|
51
|
-
describe Person do
|
52
|
-
it { is_expected.to custom_validate(:ssn).with_validator(SsnValidator) }
|
53
|
-
it { is_expected.not_to custom_validate(:name) }
|
54
|
-
end
|
55
|
-
|
56
|
-
describe Message do
|
57
|
-
it { is_expected.to validate_uniqueness_of(:identifier).with_message('uniqueness') }
|
58
|
-
it { is_expected.to validate_presence_of(:from).with_message('required') }
|
59
|
-
it { is_expected.to validate_format_of(:to).with_message('format') }
|
60
|
-
end
|
61
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
class SsnValidator < ActiveModel::EachValidator
|
2
|
-
def validate_each(record, attribute, value)
|
3
|
-
unless valid_ssn?(record, attribute, value)
|
4
|
-
record.errors[attribute] << "#{value} is not a valid Social Security Number"
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.kind
|
9
|
-
:custom
|
10
|
-
end
|
11
|
-
|
12
|
-
def valid_ssn?(_record, _attribute, _value)
|
13
|
-
# irrelevant here how validation is done
|
14
|
-
true
|
15
|
-
end
|
16
|
-
end
|