reorm 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +219 -0
- data/Rakefile +2 -0
- data/config/database.yml +11 -0
- data/lib/reorm/configuration.rb +12 -0
- data/lib/reorm/cursor.rb +162 -0
- data/lib/reorm/exceptions.rb +13 -0
- data/lib/reorm/field_path.rb +53 -0
- data/lib/reorm/model.rb +132 -0
- data/lib/reorm/modules/database_modules.rb +67 -0
- data/lib/reorm/modules/event_modules.rb +82 -0
- data/lib/reorm/modules/validation_modules.rb +29 -0
- data/lib/reorm/modules.rb +7 -0
- data/lib/reorm/property_errors.rb +53 -0
- data/lib/reorm/validators/exclusion_validator.rb +18 -0
- data/lib/reorm/validators/inclusion_validator.rb +18 -0
- data/lib/reorm/validators/maximum_length_validator.rb +19 -0
- data/lib/reorm/validators/minimum_length_validator.rb +19 -0
- data/lib/reorm/validators/presence_validator.rb +17 -0
- data/lib/reorm/validators/validator.rb +13 -0
- data/lib/reorm/validators.rb +10 -0
- data/lib/reorm/version.rb +6 -0
- data/lib/reorm.rb +47 -0
- data/reorm.gemspec +30 -0
- data/spec/catwalk/modules/timestamped_spec.rb +17 -0
- data/spec/reorm/cursor_spec.rb +214 -0
- data/spec/reorm/field_path_spec.rb +65 -0
- data/spec/reorm/model_spec.rb +268 -0
- data/spec/reorm/modules/event_source_spec.rb +49 -0
- data/spec/reorm/modules/table_backed_spec.rb +46 -0
- data/spec/reorm/modules/timestamped_spec.rb +28 -0
- data/spec/reorm/modules/validation_modules_spec.rb +157 -0
- data/spec/reorm/property_errors_spec.rb +120 -0
- data/spec/reorm/validators/exclusion_validator_spec.rb +34 -0
- data/spec/reorm/validators/inclusion_validator_spec.rb +36 -0
- data/spec/reorm/validators/maximum_length_validator_spec.rb +37 -0
- data/spec/reorm/validators/minimum_length_validator_spec.rb +39 -0
- data/spec/reorm/validators/presence_validator_spec.rb +44 -0
- data/spec/reorm/validators/validator_spec.rb +23 -0
- data/spec/spec_helper.rb +118 -0
- metadata +216 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Reorm::FieldPath do
|
4
|
+
describe "#name()" do
|
5
|
+
subject {
|
6
|
+
Reorm::FieldPath.new(:first, :second, :third)
|
7
|
+
}
|
8
|
+
|
9
|
+
it "returns the last element of the field path as the name" do
|
10
|
+
expect(subject.name).to eq(:third)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#value()" do
|
15
|
+
it "fetches the value from the input" do
|
16
|
+
field = Reorm::FieldPath.new(:first)
|
17
|
+
expect(field.value({first: 1})).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "traverses a hierarchy if one has been specified" do
|
21
|
+
field = Reorm::FieldPath.new(:first, :second, :third)
|
22
|
+
expect(field.value({first: {second: {third: 3}}})).to eq(3)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns nil of the field does not exist" do
|
26
|
+
field = Reorm::FieldPath.new(:first, :second, :third)
|
27
|
+
expect(field.value({first: 1})).to be_nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#value!()" do
|
32
|
+
it "raises an exception if the value does not exist" do
|
33
|
+
field = Reorm::FieldPath.new(:first, :second, :third)
|
34
|
+
expect {
|
35
|
+
field.value!({first: 1})
|
36
|
+
}.to raise_exception(Reorm::Error, "Unable to locate the #{field.name} (full path: #{field}) field for an instance of the Hash class.")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#exists?()" do
|
41
|
+
subject {
|
42
|
+
Reorm::FieldPath.new(:first, :second, :third)
|
43
|
+
}
|
44
|
+
|
45
|
+
it "returns true if the field exists within the specified document" do
|
46
|
+
expect(subject.exists?({first: {second: {third: 3}}})).to eq(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns false if the field does not exist within the specified document" do
|
50
|
+
expect(subject.exists?({first: 1})).to eq(false)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#to_s" do
|
55
|
+
it "returns the correct value for a simple field path" do
|
56
|
+
field = Reorm::FieldPath.new(:first)
|
57
|
+
expect(field.to_s).to eq("first")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns the correct value for a more complicated field path" do
|
61
|
+
field = Reorm::FieldPath.new(:first, :second, :third)
|
62
|
+
expect(field.to_s).to eq("first -> second -> third")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class ValidationTestModel < Reorm::Model
|
4
|
+
before_validate :called
|
5
|
+
after_validate :called
|
6
|
+
|
7
|
+
def initialize(setting=nil)
|
8
|
+
super(blah: setting)
|
9
|
+
@calls = 0
|
10
|
+
end
|
11
|
+
attr_reader :calls
|
12
|
+
|
13
|
+
def called
|
14
|
+
@calls += 1
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate
|
18
|
+
super
|
19
|
+
errors.add(:blah, "has not been set") if [nil, ""].include?(blah)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class SaveTestModel < Reorm::Model
|
24
|
+
after_create :on_after_create
|
25
|
+
after_save :on_after_save
|
26
|
+
after_update :on_after_update
|
27
|
+
before_create :on_before_create
|
28
|
+
before_save :on_before_save
|
29
|
+
before_update :on_before_update
|
30
|
+
|
31
|
+
def initialize(properties={})
|
32
|
+
super(properties)
|
33
|
+
@events = []
|
34
|
+
end
|
35
|
+
attr_reader :events
|
36
|
+
|
37
|
+
def reset_events
|
38
|
+
@events = []
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_after_create
|
42
|
+
@events << :after_create
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_after_save
|
46
|
+
@events << :after_save
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_after_update
|
50
|
+
@events << :after_update
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_before_create
|
54
|
+
@events << :before_create
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_before_save
|
58
|
+
@events << :before_save
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_before_update
|
62
|
+
@events << :before_update
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe Reorm::Model do
|
67
|
+
describe "#valid?()" do
|
68
|
+
subject {
|
69
|
+
ValidationTestModel.new
|
70
|
+
}
|
71
|
+
|
72
|
+
it "returns true if the an object does not fail validation" do
|
73
|
+
subject.blah = 1
|
74
|
+
expect(subject.valid?).to eq(true)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns false if an object fails validation" do
|
78
|
+
expect(subject.valid?).to eq(false)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#validate" do
|
83
|
+
subject {
|
84
|
+
ValidationTestModel.new
|
85
|
+
}
|
86
|
+
|
87
|
+
it "resets the list of errors for an object" do
|
88
|
+
expect(subject.valid?).to eq(false)
|
89
|
+
expect(subject.errors.clear?).to eq(false)
|
90
|
+
subject.blah = 123
|
91
|
+
subject.validate
|
92
|
+
expect(subject.errors.clear?).to eq(true)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "fires a before and after validation events when called" do
|
96
|
+
subject.validate
|
97
|
+
expect(subject.calls).to eq(2)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#save()" do
|
102
|
+
describe "for a previously unsaved object" do
|
103
|
+
subject {
|
104
|
+
SaveTestModel.new(one: 1, two: 2, three: 3)
|
105
|
+
}
|
106
|
+
|
107
|
+
it "creates a record when called on a valid object" do
|
108
|
+
subject.save
|
109
|
+
expect(subject.id).not_to be_nil
|
110
|
+
record = nil
|
111
|
+
Reorm.connection do |connection|
|
112
|
+
record = r.table(subject.table_name).get(subject.id).run(connection)
|
113
|
+
end
|
114
|
+
expect(record).not_to be_nil
|
115
|
+
expect(record["id"]).to eq(subject.id)
|
116
|
+
expect(record["one"]).to eq(subject.one)
|
117
|
+
expect(record["two"]).to eq(subject.two)
|
118
|
+
expect(record["three"]).to eq(subject.three)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "fires the before create, before save, after save and after create events" do
|
122
|
+
subject.save
|
123
|
+
expect(subject.events).to eq([:before_create, :before_save, :after_save, :after_create])
|
124
|
+
end
|
125
|
+
|
126
|
+
it "raises an exception if the object is invalid and validation is required" do
|
127
|
+
expect {
|
128
|
+
ValidationTestModel.new(nil).save
|
129
|
+
}.to raise_exception(Reorm::Error, "Validation error encountered saving an instance of the ValidationTestModel class.")
|
130
|
+
end
|
131
|
+
|
132
|
+
it "does not raises an exception if the object is invalid but validation is off" do
|
133
|
+
expect {
|
134
|
+
ValidationTestModel.new(nil).save(false)
|
135
|
+
}.not_to raise_exception
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "for a previously saved object" do
|
140
|
+
subject {
|
141
|
+
SaveTestModel.new(one: 1, two: 2, three: 3)
|
142
|
+
}
|
143
|
+
|
144
|
+
before do
|
145
|
+
subject.save
|
146
|
+
subject.reset_events
|
147
|
+
end
|
148
|
+
|
149
|
+
it "updates the objects record when called on a valid object" do
|
150
|
+
subject.two = "TWO"
|
151
|
+
subject.save
|
152
|
+
record = nil
|
153
|
+
Reorm.connection do |connection|
|
154
|
+
record = r.table(subject.table_name).get(subject.id).run(connection)
|
155
|
+
end
|
156
|
+
expect(record).not_to be_nil
|
157
|
+
expect(record["id"]).to eq(subject.id)
|
158
|
+
expect(record["one"]).to eq(subject.one)
|
159
|
+
expect(record["two"]).to eq(subject.two)
|
160
|
+
expect(record["three"]).to eq(subject.three)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "fires the before update, before save, after save and after update events" do
|
164
|
+
subject.save
|
165
|
+
expect(subject.events).to eq([:before_update, :before_save, :after_save, :after_update])
|
166
|
+
end
|
167
|
+
|
168
|
+
it "raises an exception if the object is invalid and validation is required" do
|
169
|
+
model = ValidationTestModel.new(1)
|
170
|
+
model.save
|
171
|
+
model.blah = nil
|
172
|
+
expect {
|
173
|
+
model.save
|
174
|
+
}.to raise_exception(Reorm::Error, "Validation error encountered saving an instance of the ValidationTestModel class.")
|
175
|
+
end
|
176
|
+
|
177
|
+
it "does not raises an exception if the object is invalid but validation is off" do
|
178
|
+
model = ValidationTestModel.new(1)
|
179
|
+
model.save
|
180
|
+
model.blah = nil
|
181
|
+
expect {
|
182
|
+
model.save(false)
|
183
|
+
}.not_to raise_exception
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "#[]()" do
|
189
|
+
subject {
|
190
|
+
SaveTestModel.new(one: 1, two: "Two")
|
191
|
+
}
|
192
|
+
|
193
|
+
it "returns the value of the named property if it exists" do
|
194
|
+
expect(subject[:one]).to eq(1)
|
195
|
+
expect(subject[:two]).to eq("Two")
|
196
|
+
end
|
197
|
+
|
198
|
+
it "returns nil if the named property does not exist" do
|
199
|
+
expect(subject[:blah]).to be_nil
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "#[]=()" do
|
204
|
+
subject {
|
205
|
+
SaveTestModel.new(one: 1, two: "Two")
|
206
|
+
}
|
207
|
+
|
208
|
+
it "assigns the property value if it does not exist" do
|
209
|
+
subject[:three] = 3
|
210
|
+
expect(subject.three).to eq(3)
|
211
|
+
end
|
212
|
+
|
213
|
+
it "updates the property value if it does exist" do
|
214
|
+
subject[:one] = "One"
|
215
|
+
expect(subject[:one]).to eq("One")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "#create()" do
|
220
|
+
let(:standin) {
|
221
|
+
SaveTestModel.new
|
222
|
+
}
|
223
|
+
|
224
|
+
it "creates and saves an instance of the specified class" do
|
225
|
+
expect(standin).to receive(:save)
|
226
|
+
expect(SaveTestModel).to receive(:new).and_return(standin)
|
227
|
+
expect(SaveTestModel.create).to eq(standin)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "#all()" do
|
232
|
+
before do
|
233
|
+
SaveTestModel.create(one: 1, two: 2)
|
234
|
+
SaveTestModel.create(one: 3, two: 4)
|
235
|
+
SaveTestModel.create(one: 5, two: 6)
|
236
|
+
end
|
237
|
+
|
238
|
+
subject {
|
239
|
+
SaveTestModel
|
240
|
+
}
|
241
|
+
|
242
|
+
it "returns a cursor for the model records" do
|
243
|
+
cursor = subject.all
|
244
|
+
expect(cursor).not_to be_nil
|
245
|
+
expect(cursor.class).to eq(Reorm::Cursor)
|
246
|
+
expect(cursor.inject([]) {|list, entry| list << entry.one}.sort).to eq([1,3,5])
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe "#filter()" do
|
251
|
+
before do
|
252
|
+
SaveTestModel.create(one: 1, two: 2)
|
253
|
+
SaveTestModel.create(one: 3, two: 4)
|
254
|
+
SaveTestModel.create(one: 5, two: 6)
|
255
|
+
end
|
256
|
+
|
257
|
+
subject {
|
258
|
+
SaveTestModel
|
259
|
+
}
|
260
|
+
|
261
|
+
it "returns a cursor for the model records" do
|
262
|
+
cursor = subject.filter(two: 4)
|
263
|
+
expect(cursor).not_to be_nil
|
264
|
+
expect(cursor.class).to eq(Reorm::Cursor)
|
265
|
+
expect(cursor.inject([]) {|list, entry| list << entry.one}.sort).to eq([3])
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class EventSourceTest
|
4
|
+
include Reorm::EventHandler
|
5
|
+
include Reorm::EventSource
|
6
|
+
extend Reorm::EventHandler
|
7
|
+
extend Reorm::EventSource
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@count = 0
|
11
|
+
end
|
12
|
+
attr_reader :count
|
13
|
+
|
14
|
+
def reset
|
15
|
+
@count = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def event_handler
|
19
|
+
@count += 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe EventSourceTest do
|
24
|
+
subject {
|
25
|
+
EventSourceTest.new
|
26
|
+
}
|
27
|
+
|
28
|
+
before do
|
29
|
+
subject.reset
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#fire_events()" do
|
33
|
+
describe "called at the instance level" do
|
34
|
+
it "calls methods assigned to events when those events are fired" do
|
35
|
+
subject.before_create :event_handler
|
36
|
+
subject.fire_events(events: [:before_create])
|
37
|
+
expect(subject.count).to eq(1)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "called at the class level" do
|
42
|
+
it "calls methods assigned to events when those events are fired" do
|
43
|
+
EventSourceTest.before_create :event_handler
|
44
|
+
EventSourceTest.fire_events({target: subject, events: [:before_create]})
|
45
|
+
expect(subject.count).to eq(1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class TableBackedClass
|
4
|
+
include Reorm::TableBacked
|
5
|
+
end
|
6
|
+
|
7
|
+
describe TableBackedClass do
|
8
|
+
describe "class level methods" do
|
9
|
+
class TableBackedClass1
|
10
|
+
include Reorm::TableBacked
|
11
|
+
table_name "my_table_1"
|
12
|
+
primary_key :other
|
13
|
+
end
|
14
|
+
|
15
|
+
subject {
|
16
|
+
TableBackedClass1
|
17
|
+
}
|
18
|
+
|
19
|
+
it "allows the table name to be set and retrieved at the class level" do
|
20
|
+
expect(subject.table_name).to eq("my_table_1")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "allows the primary key to be set and retrieved at the class leve" do
|
24
|
+
expect(subject.primary_key).to eq(:other)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "instance level methods" do
|
29
|
+
class TableBackedClass2
|
30
|
+
include Reorm::TableBacked
|
31
|
+
end
|
32
|
+
|
33
|
+
subject {
|
34
|
+
TableBackedClass2.new
|
35
|
+
}
|
36
|
+
|
37
|
+
it "allows the table name to be retrieved at the instance level" do
|
38
|
+
expect(subject.table_name).to eq("table_backed_class2s")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "allows the primary key to be set and retrieved at the instance level" do
|
42
|
+
instance = TableBackedClass.new
|
43
|
+
expect(subject.primary_key).to eq(:id)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class TimestampedTestClass < Reorm::Model
|
4
|
+
include Reorm::Timestamped
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Reorm::Timestamped do
|
8
|
+
subject {
|
9
|
+
TimestampedTestClass
|
10
|
+
}
|
11
|
+
|
12
|
+
it "set the timestamp fields when a record is created" do
|
13
|
+
record = subject.create(label: "First")
|
14
|
+
expect(record.created_at).not_to be_nil
|
15
|
+
expect(record.updated_at).to be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "set the update_at field when a record is updated" do
|
19
|
+
record = subject.create(label: "Second")
|
20
|
+
created = record.created_at.to_i
|
21
|
+
sleep(0.2)
|
22
|
+
|
23
|
+
record.label = "Updated"
|
24
|
+
record.save
|
25
|
+
expect(record.created_at.to_i).to eq(created)
|
26
|
+
expect(record.updated_at).not_to be_nil
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class ValidationsTestClass < Reorm::Model
|
4
|
+
include Reorm::Validations
|
5
|
+
|
6
|
+
def initialize(properties={})
|
7
|
+
super(properties)
|
8
|
+
@errors = Reorm::PropertyErrors.new
|
9
|
+
end
|
10
|
+
attr_reader :errors
|
11
|
+
|
12
|
+
def include?(property)
|
13
|
+
to_h.include?(property)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Reorm::Validations do
|
18
|
+
subject {
|
19
|
+
ValidationsTestClass.new
|
20
|
+
}
|
21
|
+
let(:path) {
|
22
|
+
"one -> two -> three".to_sym
|
23
|
+
}
|
24
|
+
|
25
|
+
describe "#validate_presence_of()" do
|
26
|
+
it "does not set an error if the field value is set" do
|
27
|
+
subject.one = {two: {three: 3}}
|
28
|
+
subject.validate_presence_of([:one, :two, :three])
|
29
|
+
expect(subject.errors.clear?).to eq(true)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sets an error if the object does not possess the field value" do
|
33
|
+
subject.validate_presence_of([:one, :two, :three])
|
34
|
+
expect(subject.errors.clear?).to eq(false)
|
35
|
+
expect(subject.errors).to include(path)
|
36
|
+
expect(subject.errors.messages(path)).to include("cannot be blank.")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "sets an error if the object does possess the field value but its a blank string" do
|
40
|
+
subject.one = {two: {three: ""}}
|
41
|
+
subject.validate_presence_of([:one, :two, :three])
|
42
|
+
expect(subject.errors.clear?).to eq(false)
|
43
|
+
expect(subject.errors).to include(path)
|
44
|
+
expect(subject.errors.messages(path)).to include("cannot be blank.")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "sets an error if the object does possess the field value but its nil" do
|
48
|
+
subject.one = {two: {three: nil}}
|
49
|
+
subject.validate_presence_of([:one, :two, :three])
|
50
|
+
expect(subject.errors.clear?).to eq(false)
|
51
|
+
expect(subject.errors).to include(path)
|
52
|
+
expect(subject.errors.messages(path)).to include("cannot be blank.")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#validate_length_of()" do
|
57
|
+
describe "with a minimum setting" do
|
58
|
+
it "does not set an error if the object as a field value that exceeds the minimum length" do
|
59
|
+
subject.one = {two: {three: "12345"}}
|
60
|
+
subject.validate_length_of([:one, :two, :three], minimum: 3)
|
61
|
+
expect(subject.errors.clear?).to eq(true)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "does not set an error if the object as a field value that equals the minimum length" do
|
65
|
+
subject.one = {two: {three: "123"}}
|
66
|
+
subject.validate_length_of([:one, :two, :three], minimum: 3)
|
67
|
+
expect(subject.errors.clear?).to eq(true)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "does not set an error if the object does not possess the field value" do
|
71
|
+
subject.validate_length_of([:one, :two, :three], minimum: 3)
|
72
|
+
expect(subject.errors.clear?).to eq(false)
|
73
|
+
expect(subject.errors).to include(path)
|
74
|
+
expect(subject.errors.messages(path)).to include("is too short (minimum length is 3 characters).")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "does set an error if the object has a field value that is less than the minimum length" do
|
78
|
+
subject.one = {two: {three: "12"}}
|
79
|
+
subject.validate_length_of([:one, :two, :three], minimum: 3)
|
80
|
+
expect(subject.errors.clear?).to eq(false)
|
81
|
+
expect(subject.errors).to include(path)
|
82
|
+
expect(subject.errors.messages(path)).to include("is too short (minimum length is 3 characters).")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "with a maximum setting" do
|
87
|
+
it "does not set an error if the object as a field value that is less than the maximum length" do
|
88
|
+
subject.one = {two: {three: "12"}}
|
89
|
+
subject.validate_length_of([:one, :two, :three], maximum: 3)
|
90
|
+
expect(subject.errors.clear?).to eq(true)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "does not set an error if the object as a field value that equals the maximum length" do
|
94
|
+
subject.one = {two: {three: "123"}}
|
95
|
+
subject.validate_length_of([:one, :two, :three], maximum: 3)
|
96
|
+
expect(subject.errors.clear?).to eq(true)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "does not set an error if the object does not possess the field value" do
|
100
|
+
subject.validate_length_of([:one, :two, :three], maximum: 3)
|
101
|
+
expect(subject.errors.clear?).to eq(true)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "does set an error if the object has a field value that is greater than the maximum length" do
|
105
|
+
subject.one = {two: {three: "1234"}}
|
106
|
+
subject.validate_length_of([:one, :two, :three], maximum: 3)
|
107
|
+
expect(subject.errors.clear?).to eq(false)
|
108
|
+
expect(subject.errors).to include(path)
|
109
|
+
expect(subject.errors.messages(path)).to include("is too long (maximum length is 3 characters).")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#validate_inclusion_of()" do
|
115
|
+
it "does not set an error if the object field value is one of the permitted set" do
|
116
|
+
subject.one = {two: {three: 3}}
|
117
|
+
subject.validate_inclusion_of([:one, :two, :three], 1, 2, 3, 4, 5)
|
118
|
+
expect(subject.errors.clear?).to eq(true)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "does set an error if the object does not possess the field value" do
|
122
|
+
subject.validate_inclusion_of([:one, :two, :three], 1, 2, 3, 4, 5)
|
123
|
+
expect(subject.errors.clear?).to eq(false)
|
124
|
+
expect(subject.errors).to include(path)
|
125
|
+
expect(subject.errors.messages(path)).to include("is not set to one of its permitted values.")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "does set an error if the object field value is not one of the permitted set" do
|
129
|
+
subject.one = {two: {three: 17}}
|
130
|
+
subject.validate_inclusion_of([:one, :two, :three], 1, 2, 3, 4, 5)
|
131
|
+
expect(subject.errors.clear?).to eq(false)
|
132
|
+
expect(subject.errors).to include(path)
|
133
|
+
expect(subject.errors.messages(path)).to include("is not set to one of its permitted values.")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#validate_exclusion_of()" do
|
138
|
+
it "does not set an error if the object field value is not one of the excluded set" do
|
139
|
+
subject.one = {two: {three: 10}}
|
140
|
+
subject.validate_exclusion_of([:one, :two, :three], 1, 2, 3, 4, 5)
|
141
|
+
expect(subject.errors.clear?).to eq(true)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "does not set an error if the object does not possess the field value" do
|
145
|
+
subject.validate_exclusion_of([:one, :two, :three], 1, 2, 3, 4, 5)
|
146
|
+
expect(subject.errors.clear?).to eq(true)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "it does set an error if the object field value is one of the excluded set" do
|
150
|
+
subject.one = {two: {three: 4}}
|
151
|
+
subject.validate_exclusion_of([:one, :two, :three], 1, 2, 3, 4, 5)
|
152
|
+
expect(subject.errors.clear?).to eq(false)
|
153
|
+
expect(subject.errors).to include(path)
|
154
|
+
expect(subject.errors.messages(path)).to include("is set to an unpermitted value.")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|