domain_model 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,2 @@
1
1
  source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in model.gemspec
4
2
  gemspec
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 "rspec", "~> 2.14"
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
24
  end
@@ -1,3 +1,3 @@
1
1
  module DomainModel
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
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
@@ -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.1.4
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: 2014-09-19 00:00:00.000000000 Z
12
+ date: 2015-02-11 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: bundler
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: '1.3'
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: '1.3'
29
+ version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
- name: rake
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: '0'
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: '0'
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: '2.14'
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: '2.14'
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: 2.3.0
100
+ rubygems_version: 1.8.23.2
93
101
  signing_key:
94
- specification_version: 4
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=