virtus 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 934dc95c7d8fd79268fcf7e2303257cd72378ef9
4
- data.tar.gz: dd9096d86a6df285b7b97f4cabab540afa72ed0b
3
+ metadata.gz: 1a85ace0a75695ebb65294da839a389e5349b660
4
+ data.tar.gz: 2c8d5150758b6bab5ce1bb8484cdaff11d1fe581
5
5
  SHA512:
6
- metadata.gz: 9095639c91403b8193bfe71a9067da701298a5190f65bdef2ac0ea0aaef130cf819529b2a672e071b48857ce614082402048a9125658b4a6f129d432968239f7
7
- data.tar.gz: ec1343ee430f0e6c6766c6e7a2457d116b7b4de00156f2ffe813989f1f62f96d712218756f750bfb45dc700552ba7999450ae243a3024ed1af3a5671e8a7b817
6
+ metadata.gz: e92ffbfc9ee7b17c58253130ad0e5bdf45857618d04d64d5c8e58b0d3d156deac13d2cc44d3b628f08ec76cdc9bc8634aca2570e987de2cd64e07ffe21fb8d04
7
+ data.tar.gz: 33db1e4a9040ce6d008062683a6eedcce3632b4854290a114795accad964233094d80f324d1b703487f6f14d6b1510e383dfce32bf7a341f9bf372d95fd37363
@@ -1,3 +1,9 @@
1
+ # v1.0.5 2015-03-18
2
+
3
+ * [feature] Support for :nullify_blank option when configuring a virtus module (lucasmazza)
4
+
5
+ [Compare v1.0.4..v1.0.5](https://github.com/solnic/virtus/compare/v1.0.4...v1.0.5)
6
+
1
7
  # v1.0.4 2015-01-03
2
8
 
3
9
  * [feature] Support for :required option when configuring a virtus module (solnic)
data/README.md CHANGED
@@ -10,7 +10,7 @@ Virtus
10
10
 
11
11
  # Ruby Object Mapper
12
12
 
13
- [![Gem Version](https://badge.fury.io/rb/rom.svg)][gem]
13
+ [![Gem Version](https://badge.fury.io/rb/virtus.svg)][gem]
14
14
  [![Build Status](https://travis-ci.org/solnic/virtus.svg?branch=master)][travis]
15
15
  [![Dependency Status](https://gemnasium.com/solnic/virtus.png)][gemnasium]
16
16
  [![Code Climate](https://codeclimate.com/github/solnic/virtus/badges/gpa.svg)][codeclimate]
@@ -60,12 +60,12 @@ class User
60
60
  attribute :birthday, DateTime
61
61
  end
62
62
 
63
- user = User.new(:name => 'Piotr', :age => 29)
64
- user.attributes # => { :name => "Piotr", :age => 29 }
63
+ user = User.new(:name => 'Piotr', :age => 31)
64
+ user.attributes # => { :name => "Piotr", :age => 31 }
65
65
 
66
66
  user.name # => "Piotr"
67
67
 
68
- user.age = '29' # => 29
68
+ user.age = '31' # => 31
69
69
  user.age.class # => Fixnum
70
70
 
71
71
  user.birthday = 'November 18th, 1983' # => #<DateTime: 1983-11-18T00:00:00+00:00 (4891313/2,0/1,2299161)>
@@ -508,6 +508,22 @@ end
508
508
  User.new :admin => "can't really say if true or false"
509
509
  ```
510
510
 
511
+ ## Nullify Blank Strings Mode
512
+
513
+ If you want to replace empty Strings with `nil` values (since they can't be
514
+ coerced into the expected type), you can use the `:nullify_blank` option.
515
+
516
+ ``` ruby
517
+ class User
518
+ include Virtus.model(:nullify_blank => true)
519
+
520
+ attribute :birthday, Date
521
+ end
522
+
523
+ User.new(:birthday => "").birthday # => nil
524
+ ```
525
+
526
+
511
527
  ## Building modules with custom configuration
512
528
 
513
529
  You can also build Virtus modules that contain their own configuration.
@@ -279,6 +279,7 @@ require 'virtus/attribute/accessor'
279
279
  require 'virtus/attribute/coercible'
280
280
  require 'virtus/attribute/strict'
281
281
  require 'virtus/attribute/lazy_default'
282
+ require 'virtus/attribute/nullify_blank'
282
283
 
283
284
  require 'virtus/attribute/boolean'
284
285
  require 'virtus/attribute/collection'
@@ -20,12 +20,13 @@ module Virtus
20
20
 
21
21
  include ::Equalizer.new(:type, :options)
22
22
 
23
- accept_options :primitive, :accessor, :default, :lazy, :strict, :required, :finalize
23
+ accept_options :primitive, :accessor, :default, :lazy, :strict, :required, :finalize, :nullify_blank
24
24
 
25
25
  strict false
26
26
  required true
27
27
  accessor :public
28
28
  finalize true
29
+ nullify_blank false
29
30
 
30
31
  # @see Virtus.coerce
31
32
  #
@@ -176,6 +177,23 @@ module Virtus
176
177
  kind_of?(Strict)
177
178
  end
178
179
 
180
+ # Return if the attribute is in the nullify blank coercion mode
181
+ #
182
+ # @example
183
+ #
184
+ # attr = Virtus::Attribute.build(String, :nullify_blank => true)
185
+ # attr.nullify_blank? # => true
186
+ #
187
+ # attr = Virtus::Attribute.build(String, :nullify_blank => false)
188
+ # attr.nullify_blank? # => false
189
+ #
190
+ # @return [Boolean]
191
+ #
192
+ # @api public
193
+ def nullify_blank?
194
+ kind_of?(NullifyBlank)
195
+ end
196
+
179
197
  # Return if the attribute is accepts nil values as valid coercion output
180
198
  #
181
199
  # @example
@@ -160,10 +160,11 @@ module Virtus
160
160
  def initialize_attribute
161
161
  @attribute = klass.new(type, options)
162
162
 
163
- @attribute.extend(Accessor) if options[:name]
164
- @attribute.extend(Coercible) if options[:coerce]
165
- @attribute.extend(Strict) if options[:strict]
166
- @attribute.extend(LazyDefault) if options[:lazy]
163
+ @attribute.extend(Accessor) if options[:name]
164
+ @attribute.extend(Coercible) if options[:coerce]
165
+ @attribute.extend(NullifyBlank) if options[:nullify_blank]
166
+ @attribute.extend(Strict) if options[:strict]
167
+ @attribute.extend(LazyDefault) if options[:lazy]
167
168
 
168
169
  @attribute.finalize if options[:finalize]
169
170
  end
@@ -0,0 +1,24 @@
1
+ module Virtus
2
+ class Attribute
3
+
4
+ # Attribute extension which nullifies blank attributes when coercion failed
5
+ #
6
+ module NullifyBlank
7
+
8
+ # @see [Attribute#coerce]
9
+ #
10
+ # @api public
11
+ def coerce(input)
12
+ output = super
13
+
14
+ if !value_coerced?(output) && input.to_s.empty?
15
+ nil
16
+ else
17
+ output
18
+ end
19
+ end
20
+
21
+ end # NullifyBlank
22
+
23
+ end # Attribute
24
+ end # Virtus
@@ -12,6 +12,9 @@ module Virtus
12
12
  # Access the strict setting for this instance
13
13
  attr_accessor :strict
14
14
 
15
+ # Access the nullify_blank setting for this instance
16
+ attr_accessor :nullify_blank
17
+
15
18
  # Access the required setting for this instance
16
19
  attr_accessor :required
17
20
 
@@ -30,6 +33,7 @@ module Virtus
30
33
  @finalize = options.fetch(:finalize, true)
31
34
  @coerce = options.fetch(:coerce, true)
32
35
  @strict = options.fetch(:strict, false)
36
+ @nullify_blank = options.fetch(:nullify_blank, false)
33
37
  @required = options.fetch(:required, true)
34
38
  @constructor = options.fetch(:constructor, true)
35
39
  @mass_assignment = options.fetch(:mass_assignment, true)
@@ -59,6 +63,7 @@ module Virtus
59
63
  { :coerce => coerce,
60
64
  :finalize => finalize,
61
65
  :strict => strict,
66
+ :nullify_blank => nullify_blank,
62
67
  :required => required,
63
68
  :configured_coercer => coercer }.freeze
64
69
  end
@@ -1,3 +1,3 @@
1
1
  module Virtus
2
- VERSION = '1.0.4'.freeze
2
+ VERSION = '1.0.5'.freeze
3
3
  end
@@ -19,6 +19,10 @@ describe 'I can create a Virtus module' do
19
19
  config.strict = true
20
20
  }
21
21
 
22
+ BlankModule = Virtus.model { |config|
23
+ config.nullify_blank = true
24
+ }
25
+
22
26
  class NoncoercedUser
23
27
  include NoncoercingModule
24
28
 
@@ -39,6 +43,13 @@ describe 'I can create a Virtus module' do
39
43
  attribute :stuff, Hash
40
44
  attribute :happy, Boolean, :strict => false
41
45
  end
46
+
47
+ class BlankModel
48
+ include BlankModule
49
+
50
+ attribute :stuff, Hash
51
+ attribute :happy, Boolean, :nullify_blank => false
52
+ end
42
53
  end
43
54
  end
44
55
 
@@ -65,4 +76,15 @@ describe 'I can create a Virtus module' do
65
76
 
66
77
  expect(model.happy).to eql('foo')
67
78
  end
79
+
80
+ specify 'including a custom module with nullify blank enabled' do
81
+ model = Examples::BlankModel.new
82
+
83
+ model.stuff = ''
84
+ expect(model.stuff).to be_nil
85
+
86
+ model.happy = 'foo'
87
+
88
+ expect(model.happy).to eql('foo')
89
+ end
68
90
  end
@@ -78,6 +78,14 @@ describe Virtus::Attribute, '.build' do
78
78
  it { is_expected.to be_strict }
79
79
  end
80
80
 
81
+ context 'when options specify nullify blank mode' do
82
+ let(:options) { { :nullify_blank => true } }
83
+
84
+ it_behaves_like 'a valid attribute instance'
85
+
86
+ it { is_expected.to be_nullify_blank }
87
+ end
88
+
81
89
  context 'when type is a string' do
82
90
  let(:type) { 'Integer' }
83
91
 
@@ -7,10 +7,11 @@ describe Virtus::Attribute, '#coerce' do
7
7
 
8
8
  let(:object) {
9
9
  described_class.build(String,
10
- :coercer => coercer, :strict => strict, :required => required)
10
+ :coercer => coercer, :strict => strict, :required => required, :nullify_blank => nullify_blank)
11
11
  }
12
12
 
13
13
  let(:required) { true }
14
+ let(:nullify_blank) { false }
14
15
  let(:input) { 1 }
15
16
  let(:output) { '1' }
16
17
 
@@ -78,4 +79,51 @@ describe Virtus::Attribute, '#coerce' do
78
79
  expect(coercer).to have_received.success?(String, input)
79
80
  end
80
81
  end
82
+
83
+ context 'when the input is an empty String' do
84
+ let(:input) { '' }
85
+ let(:output) { '' }
86
+
87
+ context 'when nullify_blank is turned on' do
88
+ let(:nullify_blank) { true }
89
+ let(:strict) { false }
90
+ let(:require) { false }
91
+
92
+ it 'returns nil' do
93
+ mock(coercer).call(input) { input }
94
+ mock(coercer).success?(String, input) { false }
95
+
96
+ expect(subject).to be_nil
97
+
98
+ expect(coercer).to have_received.call(input)
99
+ expect(coercer).to have_received.success?(String, input)
100
+ end
101
+
102
+ it 'returns the ouput if it was coerced' do
103
+ mock(coercer).call(input) { output }
104
+ mock(coercer).success?(String, output) { true }
105
+
106
+ expect(subject).to be(output)
107
+
108
+ expect(coercer).to have_received.call(input)
109
+ expect(coercer).to have_received.success?(String, output)
110
+ end
111
+ end
112
+
113
+ context 'when both nullify_blank and strict are turned on' do
114
+ let(:nullify_blank) { true }
115
+ let(:strict) { true }
116
+
117
+ it 'does not raises an coercion error' do
118
+ mock(coercer).call(input) { input }
119
+ mock(coercer).success?(String, input) { false }
120
+
121
+ expect { subject }.not_to raise_error
122
+ expect(subject).to be_nil
123
+
124
+ expect(coercer).to have_received.call(input)
125
+ expect(coercer).to have_received.success?(String, input)
126
+ end
127
+ end
128
+ end
81
129
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: virtus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-03 00:00:00.000000000 Z
11
+ date: 2015-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: descendants_tracker
@@ -132,6 +132,7 @@ files:
132
132
  - lib/virtus/attribute/embedded_value.rb
133
133
  - lib/virtus/attribute/hash.rb
134
134
  - lib/virtus/attribute/lazy_default.rb
135
+ - lib/virtus/attribute/nullify_blank.rb
135
136
  - lib/virtus/attribute/strict.rb
136
137
  - lib/virtus/attribute_set.rb
137
138
  - lib/virtus/builder.rb
@@ -237,9 +238,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
238
  version: '0'
238
239
  requirements: []
239
240
  rubyforge_project:
240
- rubygems_version: 2.2.2
241
+ rubygems_version: 2.4.5
241
242
  signing_key:
242
243
  specification_version: 4
243
244
  summary: Attributes on Steroids for Plain Old Ruby Objects
244
245
  test_files: []
245
- has_rdoc: