domain_model 0.1.4 → 0.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.
- data/Gemfile +0 -2
- data/domain_model.gemspec +2 -2
- data/lib/domain_model/version.rb +1 -1
- data/lib/domain_model.rb +38 -1
- data/spec/domain_model_spec.rb +82 -0
- metadata +25 -17
- checksums.yaml +0 -15
data/Gemfile
CHANGED
data/domain_model.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
22
21
|
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
24
24
|
end
|
data/lib/domain_model/version.rb
CHANGED
data/lib/domain_model.rb
CHANGED
@@ -23,6 +23,30 @@ module DomainModel
|
|
23
23
|
errors
|
24
24
|
end
|
25
25
|
|
26
|
+
def flat_errors
|
27
|
+
errors = self.errors
|
28
|
+
|
29
|
+
self.class.fields.each do |field|
|
30
|
+
next unless field.validate?
|
31
|
+
|
32
|
+
value = self.send(field.name)
|
33
|
+
|
34
|
+
if !field.collection? && value.is_a?(DomainModel)
|
35
|
+
value.flat_errors.each { |k, v| errors.add(:"#{field.name}.#{k}", v) }
|
36
|
+
end
|
37
|
+
|
38
|
+
if field.collection? && value.is_a?(Enumerable)
|
39
|
+
value.each_with_index do |element, index|
|
40
|
+
if element.is_a?(DomainModel)
|
41
|
+
element.flat_errors.each { |k, v| errors.add(:"#{field.name}[#{index}].#{k}", v) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
errors
|
48
|
+
end
|
49
|
+
|
26
50
|
def valid?
|
27
51
|
errors.empty?
|
28
52
|
end
|
@@ -161,23 +185,36 @@ module DomainModel
|
|
161
185
|
end
|
162
186
|
|
163
187
|
class ModelErrors
|
188
|
+
include Enumerable
|
189
|
+
|
164
190
|
def initialize
|
165
191
|
@hash = Hash.new
|
166
192
|
end
|
167
193
|
|
168
194
|
def add(field_name, error)
|
195
|
+
errors = Array(error)
|
196
|
+
|
197
|
+
return if errors.empty?
|
198
|
+
|
169
199
|
@hash[field_name] ||= []
|
170
200
|
@hash[field_name] += Array(error)
|
171
201
|
end
|
172
202
|
|
173
203
|
def [](field_name)
|
174
204
|
@hash[field_name] || []
|
175
|
-
|
176
205
|
end
|
177
206
|
|
178
207
|
def empty?
|
179
208
|
@hash.values.flatten.empty?
|
180
209
|
end
|
210
|
+
|
211
|
+
def each(&block)
|
212
|
+
@hash.each(&block)
|
213
|
+
end
|
214
|
+
|
215
|
+
def fields
|
216
|
+
@hash.keys
|
217
|
+
end
|
181
218
|
end
|
182
219
|
|
183
220
|
class FieldErrors
|
data/spec/domain_model_spec.rb
CHANGED
@@ -201,6 +201,21 @@ describe DomainModel do
|
|
201
201
|
expect(Client.new.errors).to be_empty
|
202
202
|
end
|
203
203
|
|
204
|
+
it "does not include fields with no errors" do
|
205
|
+
define { field :field }
|
206
|
+
client = Client.new(:field => :wrong)
|
207
|
+
|
208
|
+
expect(client.errors.fields).to eq([])
|
209
|
+
end
|
210
|
+
|
211
|
+
it "is enumerable" do
|
212
|
+
define { field :field, :required => true }
|
213
|
+
client = Client.new
|
214
|
+
|
215
|
+
expect(client.errors.is_a?(Enumerable)).to eq(true)
|
216
|
+
expect(client.errors.entries).to eq([[:field, ["cannot be nil"]]])
|
217
|
+
end
|
218
|
+
|
204
219
|
it "includes errors for incorrect types" do
|
205
220
|
define { field :field, :type => String }
|
206
221
|
client = Client.new(:field => :wrong)
|
@@ -351,6 +366,73 @@ describe DomainModel do
|
|
351
366
|
end
|
352
367
|
end
|
353
368
|
|
369
|
+
describe ".flat_errors" do
|
370
|
+
describe "associated DomainModels" do
|
371
|
+
subject do
|
372
|
+
name_class = Class.new do
|
373
|
+
include DomainModel
|
374
|
+
|
375
|
+
field :first, :required => true
|
376
|
+
field :last, :required => true
|
377
|
+
end
|
378
|
+
|
379
|
+
person_class = Class.new do
|
380
|
+
include DomainModel
|
381
|
+
|
382
|
+
field :name, :validate => true, :type => name_class
|
383
|
+
field :friends_names, :validate => true, :collection => true, :type => name_class
|
384
|
+
end
|
385
|
+
|
386
|
+
person_class.new({
|
387
|
+
:name => name_class.new,
|
388
|
+
:friends_names => [name_class.new]
|
389
|
+
})
|
390
|
+
end
|
391
|
+
|
392
|
+
it "includes associated models errors for scalar fields" do
|
393
|
+
expect(subject.flat_errors[:"name.first"]).to eq(["cannot be nil"])
|
394
|
+
end
|
395
|
+
|
396
|
+
it "includes associated models errors for collection fields" do
|
397
|
+
expect(subject.flat_errors[:"friends_names[0].first"]).to eq(["cannot be nil"])
|
398
|
+
end
|
399
|
+
|
400
|
+
it "does not raise exceptions if a scalar field not a DomainModel" do
|
401
|
+
subject.name = "WRONG"
|
402
|
+
expect { subject.flat_errors }.not_to raise_error
|
403
|
+
end
|
404
|
+
|
405
|
+
it "does not raise expections if a colleciton field is non-enumerable" do
|
406
|
+
subject.friends_names = 5
|
407
|
+
expect { subject.flat_errors }.not_to raise_error
|
408
|
+
end
|
409
|
+
|
410
|
+
|
411
|
+
it "does not raise expetions if an element of a Collection is not a DomainModel" do
|
412
|
+
subject.friends_names = ["WRONG"]
|
413
|
+
expect { subject.flat_errors }.not_to raise_error
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
it "does not attempt to retrieve errors from associated non-DomainModels" do
|
418
|
+
name_class = Class.new do
|
419
|
+
# Not a DomainModel
|
420
|
+
def valid?
|
421
|
+
false
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
person_class = Class.new do
|
426
|
+
include DomainModel
|
427
|
+
|
428
|
+
field :name, :validate => true, :type => name_class
|
429
|
+
end
|
430
|
+
|
431
|
+
person = person_class.new(:name => name_class.new)
|
432
|
+
expect(person.errors.fields).to eq([:name])
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
354
436
|
describe "#==" do
|
355
437
|
before { define { field :field } }
|
356
438
|
|
metadata
CHANGED
@@ -1,57 +1,64 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: domain_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Rafer Hazen
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2015-02-11 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: rake
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
21
|
+
version: '0'
|
20
22
|
type: :development
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
29
|
+
version: '0'
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
31
|
+
name: bundler
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- -
|
35
|
+
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
37
|
+
version: '1.3'
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
|
-
- -
|
43
|
+
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
45
|
+
version: '1.3'
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: rspec
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
53
|
+
version: '3.0'
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
61
|
+
version: '3.0'
|
55
62
|
description: Minimal framework for definition of (optionally) type-aware domain models
|
56
63
|
email:
|
57
64
|
- rafer@ralua.com
|
@@ -72,26 +79,27 @@ files:
|
|
72
79
|
homepage: ''
|
73
80
|
licenses:
|
74
81
|
- MIT
|
75
|
-
metadata: {}
|
76
82
|
post_install_message:
|
77
83
|
rdoc_options: []
|
78
84
|
require_paths:
|
79
85
|
- lib
|
80
86
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
81
88
|
requirements:
|
82
89
|
- - ! '>='
|
83
90
|
- !ruby/object:Gem::Version
|
84
91
|
version: '0'
|
85
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
86
94
|
requirements:
|
87
95
|
- - ! '>='
|
88
96
|
- !ruby/object:Gem::Version
|
89
97
|
version: '0'
|
90
98
|
requirements: []
|
91
99
|
rubyforge_project:
|
92
|
-
rubygems_version:
|
100
|
+
rubygems_version: 1.8.23.2
|
93
101
|
signing_key:
|
94
|
-
specification_version:
|
102
|
+
specification_version: 3
|
95
103
|
summary: Minimal framework for definition of (optionally) type-aware domain models
|
96
104
|
test_files:
|
97
105
|
- spec/domain_model_spec.rb
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
OGVkNWYxNzY4NDEyOThhMDM3NDY5MDM5YmQzNGRmNDFjYjBmYTcwMA==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MjQxZWFkZmZjZmY5ZmI3N2RkNWM2M2I3Y2YzODAyMGNhMGNlZjU3Ng==
|
7
|
-
SHA512:
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ODNlMDk1Y2M5NTlhOTZhODM1NDE2MDg4NmYzMTA4ODU1YTM2ZjVhODJmY2Fi
|
10
|
-
MTBlMGJjNjZmMDY4NzRjZWMxZmEzZDE2N2Y4ODgyZDc0MmU4N2RjNTlkZWZj
|
11
|
-
NTZlMTFhNjMyMmE1NTQ3ZjljZTE4MzAzZDRjMGI1NjQ4ZjkwMTM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTg1ZjJhODQwYWVhZDc2ZjUwYmRjNzY3MjM0ZTE5MzAyYTU1ZjY1NWI1ZTZh
|
14
|
-
MDRkMGI4YTEyZDczYWVmZDNmZWUxZjE1YzBkZTQ3NWZhZmY3ZmU4MDYzZjI3
|
15
|
-
ODE4YmI3MmJiMWM5ZDhiMDc3ZjJhMjQzZjJiZDY4MTM5MWQ1ZGM=
|