virtus 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +19 -15
- data/Changelog.md +43 -2
- data/Gemfile +5 -5
- data/README.md +113 -78
- data/Rakefile +13 -3
- data/lib/virtus.rb +46 -6
- data/lib/virtus/attribute.rb +21 -3
- data/lib/virtus/attribute/accessor.rb +11 -0
- data/lib/virtus/attribute/builder.rb +8 -13
- data/lib/virtus/attribute/collection.rb +12 -3
- data/lib/virtus/attribute/default_value.rb +2 -0
- data/lib/virtus/attribute/hash.rb +3 -3
- data/lib/virtus/attribute/nullify_blank.rb +24 -0
- data/lib/virtus/attribute/strict.rb +1 -1
- data/lib/virtus/attribute_set.rb +2 -2
- data/lib/virtus/builder.rb +2 -6
- data/lib/virtus/class_inclusions.rb +0 -1
- data/lib/virtus/coercer.rb +1 -0
- data/lib/virtus/configuration.rb +17 -36
- data/lib/virtus/extensions.rb +13 -21
- data/lib/virtus/instance_methods.rb +3 -2
- data/lib/virtus/model.rb +1 -3
- data/lib/virtus/module_extensions.rb +8 -2
- data/lib/virtus/support/equalizer.rb +1 -1
- data/lib/virtus/support/options.rb +2 -1
- data/lib/virtus/support/type_lookup.rb +1 -1
- data/lib/virtus/version.rb +1 -1
- data/spec/integration/attributes_attribute_spec.rb +28 -0
- data/spec/integration/building_module_spec.rb +22 -0
- data/spec/integration/collection_member_coercion_spec.rb +34 -13
- data/spec/integration/custom_attributes_spec.rb +2 -2
- data/spec/integration/custom_collection_attributes_spec.rb +6 -6
- data/spec/integration/default_values_spec.rb +8 -8
- data/spec/integration/defining_attributes_spec.rb +25 -18
- data/spec/integration/embedded_value_spec.rb +5 -5
- data/spec/integration/extending_objects_spec.rb +5 -5
- data/spec/integration/hash_attributes_coercion_spec.rb +16 -12
- data/spec/integration/mass_assignment_with_accessors_spec.rb +5 -5
- data/spec/integration/overriding_virtus_spec.rb +4 -4
- data/spec/integration/required_attributes_spec.rb +1 -1
- data/spec/integration/struct_as_embedded_value_spec.rb +4 -4
- data/spec/integration/using_modules_spec.rb +8 -8
- data/spec/integration/value_object_with_custom_constructor_spec.rb +4 -4
- data/spec/integration/virtus/instance_level_attributes_spec.rb +1 -1
- data/spec/integration/virtus/value_object_spec.rb +14 -14
- data/spec/shared/freeze_method_behavior.rb +6 -3
- data/spec/shared/idempotent_method_behaviour.rb +1 -1
- data/spec/shared/options_class_method.rb +3 -3
- data/spec/spec_helper.rb +2 -18
- data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +3 -3
- data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +3 -3
- data/spec/unit/virtus/attribute/class_methods/build_spec.rb +64 -24
- data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +2 -2
- data/spec/unit/virtus/attribute/coerce_spec.rb +58 -10
- data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +2 -2
- data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +15 -4
- data/spec/unit/virtus/attribute/collection/coerce_spec.rb +25 -4
- data/spec/unit/virtus/attribute/collection/value_coerced_predicate_spec.rb +31 -0
- data/spec/unit/virtus/attribute/comparison_spec.rb +20 -0
- data/spec/unit/virtus/attribute/custom_collection_spec.rb +8 -2
- data/spec/unit/virtus/attribute/defined_spec.rb +20 -0
- data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +30 -15
- data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +25 -11
- data/spec/unit/virtus/attribute/get_spec.rb +2 -2
- data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +21 -9
- data/spec/unit/virtus/attribute/hash/coerce_spec.rb +9 -9
- data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +2 -2
- data/spec/unit/virtus/attribute/rename_spec.rb +6 -3
- data/spec/unit/virtus/attribute/required_predicate_spec.rb +2 -2
- data/spec/unit/virtus/attribute/set_default_value_spec.rb +43 -10
- data/spec/unit/virtus/attribute/set_spec.rb +1 -1
- data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +2 -2
- data/spec/unit/virtus/attribute_set/append_spec.rb +6 -6
- data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +12 -11
- data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +13 -12
- data/spec/unit/virtus/attribute_set/each_spec.rb +21 -16
- data/spec/unit/virtus/attribute_set/element_reference_spec.rb +2 -2
- data/spec/unit/virtus/attribute_set/element_set_spec.rb +17 -9
- data/spec/unit/virtus/attribute_set/merge_spec.rb +7 -5
- data/spec/unit/virtus/attribute_set/reset_spec.rb +22 -11
- data/spec/unit/virtus/attribute_spec.rb +8 -7
- data/spec/unit/virtus/attributes_reader_spec.rb +1 -1
- data/spec/unit/virtus/attributes_writer_spec.rb +1 -1
- data/spec/unit/virtus/element_reader_spec.rb +1 -1
- data/spec/unit/virtus/freeze_spec.rb +23 -3
- data/spec/unit/virtus/model_spec.rb +38 -7
- data/spec/unit/virtus/module_spec.rb +59 -2
- data/spec/unit/virtus/set_default_attributes_spec.rb +10 -3
- data/spec/unit/virtus/value_object_spec.rb +15 -5
- data/virtus.gemspec +7 -5
- metadata +46 -44
- data/.ruby-version +0 -1
- data/Gemfile.devtools +0 -54
- data/config/flay.yml +0 -3
- data/config/flog.yml +0 -2
- data/config/mutant.yml +0 -15
- data/config/reek.yml +0 -146
- data/config/yardstick.yml +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 51fade6650444cdaba10d9fee1ab99f7a5707ddacbdb9c08a734dc415c6a7af8
|
4
|
+
data.tar.gz: e8569ca6dc7f6b3bbbe6a00e1be51882dd3135b5e27ba218536f2409a3f495ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 289ce0a7a1d1841d832df7644fe1aa4d0202dd906161fb3b3704d0823ea1adb113976e0320505d8ea9ed2e8d00beb97ba235def16c4760ec9f384ceff3a3cdaf
|
7
|
+
data.tar.gz: 7a0b0d652a88006bd1b5cd1e24157eb96700e788e6e2f6dc5e4d442f838a2fb59274f918aaab1ac93f042d0268bbd5bcee484e2e80cf2b3eeaacfb34f7448a00
|
data/.travis.yml
CHANGED
@@ -1,17 +1,21 @@
|
|
1
|
+
sudo: false
|
1
2
|
language: ruby
|
2
|
-
|
3
|
-
|
4
|
-
script: "bundle exec rake spec"
|
3
|
+
bundler_args: --without tools
|
4
|
+
cache: bundler
|
5
5
|
rvm:
|
6
|
-
-
|
7
|
-
- 2.
|
8
|
-
-
|
9
|
-
-
|
10
|
-
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
6
|
+
- 2.0
|
7
|
+
- 2.1
|
8
|
+
- 2.2
|
9
|
+
- 2.3
|
10
|
+
- 2.4
|
11
|
+
- 2.5
|
12
|
+
- 2.6
|
13
|
+
- 2.7
|
14
|
+
- 3.0
|
15
|
+
- jruby
|
16
|
+
before_script:
|
17
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
18
|
+
- chmod +x ./cc-test-reporter
|
19
|
+
- ./cc-test-reporter before-build
|
20
|
+
after_script:
|
21
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Changelog.md
CHANGED
@@ -1,9 +1,50 @@
|
|
1
|
-
#
|
1
|
+
# v2.0.0 2021-06-07
|
2
|
+
|
3
|
+
* [added] New method `Virtus::Atrribute::Collection#value_coerced?` (dslh)
|
4
|
+
* [changed] inflecto was replaced with dry-inflector (solnic)
|
5
|
+
* [changed] equalizer was replaced with the internal virtus/equalizer (solnic)
|
6
|
+
* [changed] `Virtus::Attribute#==` was revised (see ef57af319334a1d4f3e0860acbde7c6d6f0eb8ef) (novikserg)
|
7
|
+
* [fixed] Mass assignment bug fix (see #325) (novikserg)
|
8
|
+
|
9
|
+
[Compare v1.0.5..v2.0.0](https://github.com/solnic/virtus/compare/v1.0.5...v2.0.0)
|
10
|
+
|
11
|
+
# v1.0.5 2015-03-18
|
12
|
+
|
13
|
+
* [feature] Support for :nullify_blank option when configuring a virtus module (lucasmazza)
|
14
|
+
|
15
|
+
[Compare v1.0.4..v1.0.5](https://github.com/solnic/virtus/compare/v1.0.4...v1.0.5)
|
16
|
+
|
17
|
+
# v1.0.4 2015-01-03
|
18
|
+
|
19
|
+
* [feature] Support for :required option when configuring a virtus module (solnic)
|
20
|
+
|
21
|
+
[Compare v1.0.3..v1.0.4](https://github.com/solnic/virtus/compare/v1.0.3...v1.0.4)
|
22
|
+
|
23
|
+
# v1.0.3 2014-07-24
|
24
|
+
|
25
|
+
* [improvement] Expose attribute name in the exception when in strict mode (ntl)
|
26
|
+
* [improvement] Set #to_h as an alias to #to_hash (fnando)
|
27
|
+
* [fixed] Fix handling of nil in collection coercion (edgibbs)
|
28
|
+
* [fixed] Fix issues with using multiple virtus modules (trptcolin)
|
29
|
+
* [fixed] Fix handling of Range type (hampei)
|
30
|
+
* [fixed] Fix strict mode for collection and hash types (solnic)
|
31
|
+
|
32
|
+
[Compare v1.0.2..v1.0.3](https://github.com/solnic/virtus/compare/v1.0.2...v1.0.3)
|
33
|
+
|
34
|
+
# v1.0.2 2013-12-03
|
35
|
+
|
36
|
+
* [improvement] Don’t override already-defined default values when freezing (amarshall)
|
37
|
+
* [improvement] Improved performance of `AttributeSet#each` (Antti)
|
38
|
+
* updated axiom-types dependency to ~> 0.1 (solnic)
|
39
|
+
|
40
|
+
[Compare v1.0.1..v1.0.2](https://github.com/solnic/virtus/compare/v1.0.1...v1.0.2)
|
41
|
+
|
42
|
+
# v1.0.1 2013-12-10
|
2
43
|
|
3
44
|
* [feature] re-introduce `ValueObject#with`, which was removed in the past (senny)
|
4
45
|
* [fixed] strict mode for Boolean type (solnic)
|
5
46
|
|
6
|
-
[Compare v1.0.0..
|
47
|
+
[Compare v1.0.0..v1.0.1](https://github.com/solnic/virtus/compare/v1.0.0...v1.0.1)
|
7
48
|
|
8
49
|
# v1.0.0 2013-10-16
|
9
50
|
|
data/Gemfile
CHANGED
@@ -2,9 +2,9 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem '
|
6
|
-
gem '
|
5
|
+
gem 'dry-inflector'
|
6
|
+
gem 'rspec'
|
7
|
+
gem 'bogus'
|
8
|
+
gem 'simplecov', platform: :ruby
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
gem 'mutant', git: 'https://github.com/solnic/mutant.git', branch: 'auto-expand-scope'
|
10
|
+
gem "codeclimate-test-reporter", group: :test, require: false
|
data/README.md
CHANGED
@@ -1,25 +1,38 @@
|
|
1
|
-
Virtus
|
2
|
-
======
|
3
|
-
|
4
|
-
[![Gem Version](https://badge.fury.io/rb/virtus.png)][gem]
|
5
|
-
[![Build Status](https://secure.travis-ci.org/solnic/virtus.png?branch=master)][travis]
|
6
|
-
[![Dependency Status](https://gemnasium.com/solnic/virtus.png)][gemnasium]
|
7
|
-
[![Code Climate](https://codeclimate.com/github/solnic/virtus.png)][codeclimate]
|
8
|
-
[![Coverage Status](https://coveralls.io/repos/solnic/virtus/badge.png?branch=master)][coveralls]
|
9
|
-
|
10
1
|
[gem]: https://rubygems.org/gems/virtus
|
11
2
|
[travis]: https://travis-ci.org/solnic/virtus
|
12
|
-
[gemnasium]: https://gemnasium.com/solnic/virtus
|
13
3
|
[codeclimate]: https://codeclimate.com/github/solnic/virtus
|
14
4
|
[coveralls]: https://coveralls.io/r/solnic/virtus
|
5
|
+
[inchpages]: http://inch-ci.org/github/solnic/virtus/
|
15
6
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
for
|
20
|
-
|
21
|
-
|
22
|
-
|
7
|
+
DISCONTINUED
|
8
|
+
------------
|
9
|
+
|
10
|
+
> Working on virtus taught me a lot about handling data in Ruby, which involves coercions, type safety and validation (amongst other things). Even though the project has been successful, and serving well for many people, I decided to build something better. As a result, [dry-types](https://github.com/dry-rb/dry-types), [dry-struct](https://github.com/dry-rb/dry-struct) and [dry-schema](https://github.com/dry-rb/dry-schema) were born. These projects should be considered as virtus' successors, with better separation of concerns and better features. If you're interested in a modern take on same problems that virtus tried to solve, please check out these projects!
|
11
|
+
>
|
12
|
+
> @solnic
|
13
|
+
|
14
|
+
Virtus
|
15
|
+
======
|
16
|
+
|
17
|
+
[![Gem Version](https://badge.fury.io/rb/virtus.svg)][gem]
|
18
|
+
[![Build Status](https://travis-ci.org/solnic/virtus.svg?branch=master)][travis]
|
19
|
+
[![Code Climate](https://codeclimate.com/github/solnic/virtus/badges/gpa.svg)][codeclimate]
|
20
|
+
[![Test Coverage](https://codeclimate.com/github/solnic/virtus/badges/coverage.svg)][codeclimate]
|
21
|
+
[![Inline docs](http://inch-ci.org/github/solnic/virtus.svg?branch=master)][inchpages]
|
22
|
+
|
23
|
+
Virtus allows you to define attributes on classes, modules or class instances with
|
24
|
+
optional information about types, reader/writer method visibility and coercion
|
25
|
+
behavior. It supports a lot of coercions and advanced mapping of embedded objects
|
26
|
+
and collections.
|
27
|
+
|
28
|
+
You can use it in many different contexts like:
|
29
|
+
|
30
|
+
* Input parameter sanitization and coercion in web applications
|
31
|
+
* Mapping JSON to domain objects
|
32
|
+
* Encapsulating data-access in Value Objects
|
33
|
+
* Domain model prototyping
|
34
|
+
|
35
|
+
And probably more.
|
23
36
|
|
24
37
|
Installation
|
25
38
|
------------
|
@@ -50,12 +63,12 @@ class User
|
|
50
63
|
attribute :birthday, DateTime
|
51
64
|
end
|
52
65
|
|
53
|
-
user = User.new(:name => 'Piotr', :age =>
|
54
|
-
user.attributes # => { :name => "Piotr", :age =>
|
66
|
+
user = User.new(:name => 'Piotr', :age => 31)
|
67
|
+
user.attributes # => { :name => "Piotr", :age => 31, :birthday => nil }
|
55
68
|
|
56
69
|
user.name # => "Piotr"
|
57
70
|
|
58
|
-
user.age = '
|
71
|
+
user.age = '31' # => 31
|
59
72
|
user.age.class # => Fixnum
|
60
73
|
|
61
74
|
user.birthday = 'November 18th, 1983' # => #<DateTime: 1983-11-18T00:00:00+00:00 (4891313/2,0/1,2299161)>
|
@@ -179,6 +192,19 @@ page.reset_attribute(:views) # => 0
|
|
179
192
|
page.views # => 0
|
180
193
|
```
|
181
194
|
|
195
|
+
### Default values on dynamically extended instances
|
196
|
+
|
197
|
+
This requires you to set `:lazy` option because default values are set in the
|
198
|
+
constructor if it's set to false (which is the default setting):
|
199
|
+
|
200
|
+
``` ruby
|
201
|
+
User = Class.new
|
202
|
+
user = User.new
|
203
|
+
user.extend(Virtus.model)
|
204
|
+
user.attribute :name, String, default: 'jane', lazy: true
|
205
|
+
user.name # => "jane"
|
206
|
+
```
|
207
|
+
|
182
208
|
### Embedded Value
|
183
209
|
|
184
210
|
``` ruby
|
@@ -271,6 +297,22 @@ package = Package.new(:dimensions => { 'width' => "2.2", :height => 2, "length"
|
|
271
297
|
package.dimensions # => { :width => 2.2, :height => 2.0, :length => 4.5 }
|
272
298
|
```
|
273
299
|
|
300
|
+
### IMPORTANT note about Boolean type
|
301
|
+
|
302
|
+
Be aware that some libraries may do a terrible thing and define a global Boolean
|
303
|
+
constant which breaks virtus' constant type lookup, if you see issues with the
|
304
|
+
boolean type you can workaround it like that:
|
305
|
+
|
306
|
+
``` ruby
|
307
|
+
class User
|
308
|
+
include Virtus.model
|
309
|
+
|
310
|
+
attribute :admin, Axiom::Types::Boolean
|
311
|
+
end
|
312
|
+
```
|
313
|
+
|
314
|
+
This will be improved in Virtus 2.0.
|
315
|
+
|
274
316
|
### IMPORTANT note about member coercions
|
275
317
|
|
276
318
|
Virtus performs coercions only when a value is being assigned. If you mutate the value later on using its own
|
@@ -381,7 +423,7 @@ end
|
|
381
423
|
class User
|
382
424
|
include Virtus.model
|
383
425
|
|
384
|
-
attribute :info, Json
|
426
|
+
attribute :info, Json, default: {}
|
385
427
|
end
|
386
428
|
|
387
429
|
user = User.new
|
@@ -391,7 +433,7 @@ user.info.class # => Hash
|
|
391
433
|
# With a custom attribute encapsulating coercion-specific configuration
|
392
434
|
class NoisyString < Virtus::Attribute
|
393
435
|
def coerce(value)
|
394
|
-
|
436
|
+
value.to_s.upcase
|
395
437
|
end
|
396
438
|
end
|
397
439
|
|
@@ -427,48 +469,31 @@ user.set_unique_id('1234-1234')
|
|
427
469
|
user.unique_id # => '1234-1234'
|
428
470
|
```
|
429
471
|
|
430
|
-
|
431
|
-
---------
|
432
|
-
|
433
|
-
Virtus uses [Coercible](https://github.com/solnic/coercible) for coercions. This
|
434
|
-
feature is turned on by default. You can turn it off for all attributes like that:
|
435
|
-
|
436
|
-
```ruby
|
437
|
-
# Turn coercions off globally
|
438
|
-
Virtus.coerce(false)
|
472
|
+
### Overriding setters
|
439
473
|
|
440
|
-
|
474
|
+
``` ruby
|
441
475
|
class User
|
442
476
|
include Virtus.model
|
443
477
|
|
444
|
-
attribute :name, String
|
445
|
-
end
|
446
|
-
```
|
447
|
-
|
448
|
-
You can configure coercers too:
|
478
|
+
attribute :name, String
|
449
479
|
|
450
|
-
|
451
|
-
|
452
|
-
|
480
|
+
def name=(new_name)
|
481
|
+
custom_name = nil
|
482
|
+
if new_name == "Godzilla"
|
483
|
+
custom_name = "Can't tell"
|
484
|
+
end
|
485
|
+
super custom_name || new_name
|
486
|
+
end
|
453
487
|
end
|
454
488
|
|
455
|
-
|
456
|
-
#
|
489
|
+
user = User.new(name: "Frank")
|
490
|
+
user.name # => 'Frank'
|
457
491
|
|
458
|
-
|
459
|
-
|
460
|
-
end
|
492
|
+
user = User.new(name: "Godzilla")
|
493
|
+
user.name # => 'Can't tell'
|
461
494
|
|
462
|
-
class User
|
463
|
-
include Virtus.model
|
464
|
-
|
465
|
-
attribute :name, String, :coercer => my_cool_coercer
|
466
|
-
end
|
467
495
|
```
|
468
496
|
|
469
|
-
Please check out [Coercible README](https://github.com/solnic/coercible/blob/master/README.md)
|
470
|
-
for more information.
|
471
|
-
|
472
497
|
## Strict Coercion Mode
|
473
498
|
|
474
499
|
By default Virtus returns the input value even when it couldn't coerce it to the expected type.
|
@@ -486,6 +511,22 @@ end
|
|
486
511
|
User.new :admin => "can't really say if true or false"
|
487
512
|
```
|
488
513
|
|
514
|
+
## Nullify Blank Strings Mode
|
515
|
+
|
516
|
+
If you want to replace empty Strings with `nil` values (since they can't be
|
517
|
+
coerced into the expected type), you can use the `:nullify_blank` option.
|
518
|
+
|
519
|
+
``` ruby
|
520
|
+
class User
|
521
|
+
include Virtus.model(:nullify_blank => true)
|
522
|
+
|
523
|
+
attribute :birthday, Date
|
524
|
+
end
|
525
|
+
|
526
|
+
User.new(:birthday => "").birthday # => nil
|
527
|
+
```
|
528
|
+
|
529
|
+
|
489
530
|
## Building modules with custom configuration
|
490
531
|
|
491
532
|
You can also build Virtus modules that contain their own configuration.
|
@@ -493,7 +534,7 @@ You can also build Virtus modules that contain their own configuration.
|
|
493
534
|
```ruby
|
494
535
|
YupNopeBooleans = Virtus.model { |mod|
|
495
536
|
mod.coerce = true
|
496
|
-
mod.string.boolean_map = { '
|
537
|
+
mod.coercer.config.string.boolean_map = { 'nope' => false, 'yup' => true }
|
497
538
|
}
|
498
539
|
|
499
540
|
class User
|
@@ -541,6 +582,24 @@ Blog.attribute_set[:posts].member_type.primitive # => Post
|
|
541
582
|
Post.attribute_set[:blog].type.primitive # => Blog
|
542
583
|
```
|
543
584
|
|
585
|
+
## Plugins / Extensions
|
586
|
+
|
587
|
+
List of plugins/extensions that add features to Virtus:
|
588
|
+
|
589
|
+
* [virtus-localized](https://github.com/XescuGC/virtus-localized): Localize the attributes
|
590
|
+
* [virtus-relations](https://github.com/smanolloff/virtus-relations): Add relations to Virtus objects
|
591
|
+
|
592
|
+
Ruby version support
|
593
|
+
--------------------
|
594
|
+
|
595
|
+
Virtus is known to work correctly with the following rubies:
|
596
|
+
|
597
|
+
* 1.9.3
|
598
|
+
* 2.0.0
|
599
|
+
* 2.1.2
|
600
|
+
* jruby
|
601
|
+
* (probably) rbx
|
602
|
+
|
544
603
|
Credits
|
545
604
|
-------
|
546
605
|
|
@@ -562,27 +621,3 @@ Contributing
|
|
562
621
|
* Commit, do not mess with Rakefile or version
|
563
622
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
564
623
|
* Send me a pull request. Bonus points for topic branches.
|
565
|
-
|
566
|
-
License
|
567
|
-
-------
|
568
|
-
|
569
|
-
Copyright (c) 2011-2013 Piotr Solnica
|
570
|
-
|
571
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
572
|
-
a copy of this software and associated documentation files (the
|
573
|
-
"Software"), to deal in the Software without restriction, including
|
574
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
575
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
576
|
-
permit persons to whom the Software is furnished to do so, subject to
|
577
|
-
the following conditions:
|
578
|
-
|
579
|
-
The above copyright notice and this permission notice shall be
|
580
|
-
included in all copies or substantial portions of the Software.
|
581
|
-
|
582
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
583
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
584
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
585
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
586
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
587
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
588
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,5 +1,15 @@
|
|
1
|
-
|
1
|
+
require "rspec/core/rake_task"
|
2
2
|
|
3
|
-
|
3
|
+
RSpec::Core::RakeTask.new(:spec)
|
4
|
+
task default: [:spec]
|
4
5
|
|
5
|
-
|
6
|
+
begin
|
7
|
+
require "rubocop/rake_task"
|
8
|
+
|
9
|
+
Rake::Task[:default].enhance [:rubocop]
|
10
|
+
|
11
|
+
RuboCop::RakeTask.new do |task|
|
12
|
+
task.options << "--display-cop-names"
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
end
|
data/lib/virtus.rb
CHANGED
@@ -11,11 +11,31 @@ module Virtus
|
|
11
11
|
Undefined = Object.new.freeze
|
12
12
|
|
13
13
|
class CoercionError < StandardError
|
14
|
-
attr_reader :output, :
|
14
|
+
attr_reader :output, :attribute
|
15
15
|
|
16
|
-
def initialize(output,
|
17
|
-
@output, @
|
18
|
-
super(
|
16
|
+
def initialize(output, attribute)
|
17
|
+
@output, @attribute = output, attribute
|
18
|
+
super(build_message)
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_message
|
22
|
+
if attribute_name?
|
23
|
+
"Failed to coerce attribute `#{attribute_name}' from #{output.inspect} into #{target_type}"
|
24
|
+
else
|
25
|
+
"Failed to coerce #{output.inspect} into #{target_type}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def attribute_name
|
30
|
+
attribute.options[:name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def attribute_name?
|
34
|
+
attribute_name ? true : false
|
35
|
+
end
|
36
|
+
|
37
|
+
def target_type
|
38
|
+
attribute.primitive.inspect
|
19
39
|
end
|
20
40
|
end
|
21
41
|
|
@@ -101,7 +121,8 @@ module Virtus
|
|
101
121
|
#
|
102
122
|
# @api public
|
103
123
|
def self.config(&block)
|
104
|
-
configuration
|
124
|
+
yield configuration if block_given?
|
125
|
+
configuration
|
105
126
|
end
|
106
127
|
|
107
128
|
# Provides access to the Virtus module builder
|
@@ -186,6 +207,25 @@ module Virtus
|
|
186
207
|
@configuration ||= Configuration.new
|
187
208
|
end
|
188
209
|
|
210
|
+
# @api private
|
211
|
+
def self.constantize(type)
|
212
|
+
inflector.constantize(type)
|
213
|
+
end
|
214
|
+
|
215
|
+
# @api private
|
216
|
+
def self.inflector
|
217
|
+
@inflector ||=
|
218
|
+
begin
|
219
|
+
require 'dry/inflector'
|
220
|
+
Dry::Inflector.new
|
221
|
+
rescue LoadError
|
222
|
+
raise(
|
223
|
+
NotImplementedError,
|
224
|
+
'Virtus needs dry-inflector gem to constantize namespaced constant names'
|
225
|
+
)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
189
229
|
# Finalize pending attributes
|
190
230
|
#
|
191
231
|
# @example
|
@@ -220,7 +260,6 @@ module Virtus
|
|
220
260
|
end # module Virtus
|
221
261
|
|
222
262
|
require 'descendants_tracker'
|
223
|
-
require 'equalizer'
|
224
263
|
require 'axiom-types'
|
225
264
|
require 'coercible'
|
226
265
|
|
@@ -258,6 +297,7 @@ require 'virtus/attribute/accessor'
|
|
258
297
|
require 'virtus/attribute/coercible'
|
259
298
|
require 'virtus/attribute/strict'
|
260
299
|
require 'virtus/attribute/lazy_default'
|
300
|
+
require 'virtus/attribute/nullify_blank'
|
261
301
|
|
262
302
|
require 'virtus/attribute/boolean'
|
263
303
|
require 'virtus/attribute/collection'
|