rest_model 0.1.19 → 0.1.20

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.
@@ -0,0 +1,60 @@
1
+ $:.push 'examples'; require 'helper'
2
+
3
+ class Root < RestModel
4
+ id type: Integer
5
+ property :name
6
+ property :sudo, values: {true => "please"}
7
+ embeds_one :entry
8
+ end
9
+
10
+ class Entry < RestModel
11
+ property :name
12
+ property :some_date, type: Date
13
+ embeds_many :services
14
+ end
15
+
16
+ class Service < RestModel
17
+ property :code, type: Integer
18
+ embeds_many :products
19
+ end
20
+
21
+ class Product < RestModel
22
+ property :value, type: Float
23
+ property :created_at, type: DateTime
24
+ end
25
+
26
+
27
+ products = [
28
+ {
29
+ value: 100.00,
30
+ created_at: "non datetime (P0)"
31
+ },
32
+ {
33
+ value: "non float (P1)",
34
+ created_at: "2011-11-11T11:11:11"
35
+ }
36
+ ]
37
+
38
+ services = [
39
+ {
40
+ code: "non integer (S0)",
41
+ products: products
42
+ }
43
+ ]
44
+
45
+ entry = {
46
+ name: "Some name",
47
+ some_date: "some invalid date",
48
+ services: services
49
+ }
50
+
51
+ root = {
52
+ id: 1,
53
+ name: "Please",
54
+ sudo: true,
55
+ entry: entry
56
+ }
57
+
58
+ @root = Root.new(root)
59
+
60
+ inspect_rest_model(@root)
@@ -9,6 +9,10 @@ class RestModel
9
9
  @errors = errors
10
10
  end
11
11
 
12
+ def message
13
+ @errors
14
+ end
15
+
12
16
  def self.exception(errors = {})
13
17
  new(errors)
14
18
  end
@@ -18,8 +18,8 @@ class RestModel
18
18
  last = path.pop
19
19
  key_source = path.inject(source) {|buffer, key| buffer[key] = {}; buffer[key]}
20
20
  key_source[last] = raw? ? value
21
- : one? ? value.to_source(options)
22
- : value.map {|item| item.to_source(options)}
21
+ : one? ? embeds_one_source(value, options)
22
+ : embeds_many_source(value, options)
23
23
  else
24
24
  source.merge!(value.to_source(options))
25
25
  end
@@ -37,6 +37,27 @@ class RestModel
37
37
 
38
38
  input
39
39
  end
40
+
41
+ def embeds_one_source(value, options)
42
+ value.to_source(options)
43
+ end
44
+
45
+ def embeds_many_source(value, options)
46
+ errors = {}
47
+
48
+ source = value.each_with_index.map do |item, index|
49
+ begin
50
+ item.to_source(options)
51
+ rescue RestModel::SourceError => e
52
+ errors[self.name] ||= {}
53
+ errors[self.name][index] = e.message
54
+ end
55
+ end
56
+
57
+ fail RestModel::SourceError, errors unless errors.empty?
58
+
59
+ source
60
+ end
40
61
  end
41
62
  end
42
63
  end
@@ -2,6 +2,7 @@ class RestModel
2
2
  class Property
3
3
  module Builder
4
4
  def property(name, options = {})
5
+ options[:validate] = !options[:validate_if_present]
5
6
  key Property.new(name, options)
6
7
  end
7
8
 
@@ -5,8 +5,9 @@ class RestModel
5
5
  source_value = begin
6
6
  translation.translates_to_source? ? translation.translate_to_source(value, resource)
7
7
  : serializer.desserialize(value)
8
+
8
9
  rescue TranslationError, SerializationError => error
9
- raise error if options[:fail]
10
+ raise error if options[:fail] and validates?(value)
10
11
  end
11
12
 
12
13
  source = {}
@@ -22,6 +23,12 @@ class RestModel
22
23
 
23
24
  source
24
25
  end
26
+
27
+ private
28
+
29
+ def validates?(value)
30
+ (self.options[:validate_if_present] and !value.nil?) or self.options[:validate]
31
+ end
25
32
  end
26
33
  end
27
34
  end
@@ -3,10 +3,12 @@ class RestModel
3
3
  class String
4
4
  def self.serialize(value)
5
5
  value.nil? ? nil : value.to_s
6
+ rescue
7
+ raise SerializationError, "value '#{value}' is not a string"
6
8
  end
7
9
 
8
10
  def self.desserialize(value)
9
- value.nil? ? nil : value.to_s
11
+ serialize(value)
10
12
  end
11
13
  end
12
14
  end
@@ -16,8 +16,10 @@ class RestModel
16
16
 
17
17
  begin
18
18
  source.merge! key.to_source!(value, self, key_options)
19
- rescue TranslationError, SerializationError => error
20
- errors[key.name] = error.message
19
+ rescue TranslationError, SerializationError => e
20
+ errors[key.name] = e.message
21
+ rescue SourceError => e
22
+ errors.merge!(e.message)
21
23
  end
22
24
  end
23
25
 
@@ -1,3 +1,3 @@
1
1
  class RestModel
2
- VERSION = "0.1.19"
2
+ VERSION = "0.1.20"
3
3
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe "validations" do
4
+ describe_example "validations/simple" do
5
+ describe "#to_source!" do
6
+ it "raise a RestModel::SourceError" do
7
+ expected_message = {
8
+ some_date: "value 'some invalid date' is an invalid date",
9
+ services: {
10
+ 0 => {
11
+ code: "value 'non integer (S0)' is not an integer",
12
+ products: {
13
+ 0 => {
14
+ created_at: "value 'non datetime (P0)' is an invalid date time"
15
+ },
16
+ 1 => {
17
+ value: "value 'non float (P1)' is not a float"
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
23
+
24
+ proc {@root.to_source!}.should raise_error(RestModel::SourceError) {|e| e.message.should == expected_message}
25
+ end
26
+ end
27
+ end
28
+ end
@@ -33,7 +33,7 @@ describe RestModel::Property::Builder do
33
33
  end
34
34
 
35
35
  let(:field) {:id}
36
- let(:options) {{id: true}}
36
+ let(:options) {{id: true, validate: true}}
37
37
 
38
38
  it_behaves_like "a property"
39
39
  it_behaves_like "a key"
@@ -47,7 +47,7 @@ describe RestModel::Property::Builder do
47
47
  end
48
48
 
49
49
  let(:field) {:different_name}
50
- let(:options) {{id: true}}
50
+ let(:options) {{id: true, validate: true}}
51
51
 
52
52
  it_behaves_like "a property"
53
53
  it_behaves_like "a key"
@@ -61,7 +61,7 @@ describe RestModel::Property::Builder do
61
61
  end
62
62
 
63
63
  let(:field) {:id}
64
- let(:options) {{some_option: 'some option value', id: true}}
64
+ let(:options) {{some_option: 'some option value', id: true, validate: true}}
65
65
 
66
66
  it_behaves_like "a property"
67
67
  it_behaves_like "a key"
@@ -75,7 +75,7 @@ describe RestModel::Property::Builder do
75
75
  end
76
76
 
77
77
  let(:field) {:different_name}
78
- let(:options) {{some_option: 'some option value', id: true}}
78
+ let(:options) {{some_option: 'some option value', id: true, validate: true}}
79
79
 
80
80
  it_behaves_like "a property"
81
81
  it_behaves_like "a key"
@@ -89,7 +89,7 @@ describe RestModel::Property::Builder do
89
89
  end
90
90
 
91
91
  let(:field) {:id}
92
- let(:options) {{id: true}}
92
+ let(:options) {{id: true, validate: true}}
93
93
 
94
94
  it_behaves_like "a property"
95
95
  it_behaves_like "a key"
@@ -105,7 +105,7 @@ describe RestModel::Property::Builder do
105
105
  end
106
106
 
107
107
  let(:field) {:document_number}
108
- let(:options) {{some_option: 'this is an option'}}
108
+ let(:options) {{some_option: 'this is an option', validate: true}}
109
109
 
110
110
  it_behaves_like "a property"
111
111
  end
@@ -118,7 +118,7 @@ describe RestModel::Property::Builder do
118
118
  end
119
119
 
120
120
  let(:field) {:document_number}
121
- let(:options) {{id: true}}
121
+ let(:options) {{id: true, validate: true}}
122
122
 
123
123
  it_behaves_like "a property"
124
124
  it_behaves_like "a key"
@@ -136,7 +136,7 @@ describe RestModel::Property::Builder do
136
136
  [:id, :description].each do |item|
137
137
  context "for #{item}" do
138
138
  let(:field) {item}
139
- let(:options) {{}}
139
+ let(:options) {{validate: true}}
140
140
 
141
141
  it_behaves_like "a property"
142
142
  end
@@ -145,7 +145,7 @@ describe RestModel::Property::Builder do
145
145
  [:price, :quantity].each do |item|
146
146
  context "for #{item}" do
147
147
  let(:field) {item}
148
- let(:options) {{firstoption: 'this is the first option', secondoption: 'this is the second option'}}
148
+ let(:options) {{firstoption: 'this is the first option', secondoption: 'this is the second option', validate: true}}
149
149
 
150
150
  it_behaves_like "a property"
151
151
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.19
4
+ version: 0.1.20
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2011-12-02 00:00:00.000000000Z
14
+ date: 2011-12-06 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
- requirement: &70175820157140 !ruby/object:Gem::Requirement
18
+ requirement: &70239925984420 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '3.0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70175820157140
26
+ version_requirements: *70239925984420
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: i18n
29
- requirement: &70175820156640 !ruby/object:Gem::Requirement
29
+ requirement: &70239925983920 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: '0.5'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70175820156640
37
+ version_requirements: *70239925983920
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: rspec
40
- requirement: &70175820156180 !ruby/object:Gem::Requirement
40
+ requirement: &70239925983460 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ~>
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '2.6'
46
46
  type: :development
47
47
  prerelease: false
48
- version_requirements: *70175820156180
48
+ version_requirements: *70239925983460
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: guard
51
- requirement: &70175820155720 !ruby/object:Gem::Requirement
51
+ requirement: &70239925983000 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ~>
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '0.5'
57
57
  type: :development
58
58
  prerelease: false
59
- version_requirements: *70175820155720
59
+ version_requirements: *70239925983000
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: guard-rspec
62
- requirement: &70175820155260 !ruby/object:Gem::Requirement
62
+ requirement: &70239925982540 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ~>
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: '0.4'
68
68
  type: :development
69
69
  prerelease: false
70
- version_requirements: *70175820155260
70
+ version_requirements: *70239925982540
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: growl
73
- requirement: &70175820154800 !ruby/object:Gem::Requirement
73
+ requirement: &70239925982080 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ~>
@@ -78,7 +78,7 @@ dependencies:
78
78
  version: '1.0'
79
79
  type: :development
80
80
  prerelease: false
81
- version_requirements: *70175820154800
81
+ version_requirements: *70239925982080
82
82
  description: ''
83
83
  email:
84
84
  - victorcrodrigues@gmail.com
@@ -148,6 +148,7 @@ files:
148
148
  - examples/update_attributes/has_many.rb
149
149
  - examples/update_attributes/has_one.rb
150
150
  - examples/update_attributes/simple.rb
151
+ - examples/validations/simple.rb
151
152
  - lib/rest_model.rb
152
153
  - lib/rest_model/configuration.rb
153
154
  - lib/rest_model/errors.rb
@@ -193,6 +194,7 @@ files:
193
194
  - spec/integration/summarization_spec.rb
194
195
  - spec/integration/to_source_spec.rb
195
196
  - spec/integration/update_attributes_spec.rb
197
+ - spec/integration/validations_spec.rb
196
198
  - spec/spec_helper.rb
197
199
  - spec/support/examples.rb
198
200
  - spec/support/out.rb
@@ -255,6 +257,7 @@ test_files:
255
257
  - spec/integration/summarization_spec.rb
256
258
  - spec/integration/to_source_spec.rb
257
259
  - spec/integration/update_attributes_spec.rb
260
+ - spec/integration/validations_spec.rb
258
261
  - spec/spec_helper.rb
259
262
  - spec/support/examples.rb
260
263
  - spec/support/out.rb