virtus 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +19 -15
  3. data/Changelog.md +43 -2
  4. data/Gemfile +5 -5
  5. data/README.md +113 -78
  6. data/Rakefile +13 -3
  7. data/lib/virtus.rb +46 -6
  8. data/lib/virtus/attribute.rb +21 -3
  9. data/lib/virtus/attribute/accessor.rb +11 -0
  10. data/lib/virtus/attribute/builder.rb +8 -13
  11. data/lib/virtus/attribute/collection.rb +12 -3
  12. data/lib/virtus/attribute/default_value.rb +2 -0
  13. data/lib/virtus/attribute/hash.rb +3 -3
  14. data/lib/virtus/attribute/nullify_blank.rb +24 -0
  15. data/lib/virtus/attribute/strict.rb +1 -1
  16. data/lib/virtus/attribute_set.rb +2 -2
  17. data/lib/virtus/builder.rb +2 -6
  18. data/lib/virtus/class_inclusions.rb +0 -1
  19. data/lib/virtus/coercer.rb +1 -0
  20. data/lib/virtus/configuration.rb +17 -36
  21. data/lib/virtus/extensions.rb +13 -21
  22. data/lib/virtus/instance_methods.rb +3 -2
  23. data/lib/virtus/model.rb +1 -3
  24. data/lib/virtus/module_extensions.rb +8 -2
  25. data/lib/virtus/support/equalizer.rb +1 -1
  26. data/lib/virtus/support/options.rb +2 -1
  27. data/lib/virtus/support/type_lookup.rb +1 -1
  28. data/lib/virtus/version.rb +1 -1
  29. data/spec/integration/attributes_attribute_spec.rb +28 -0
  30. data/spec/integration/building_module_spec.rb +22 -0
  31. data/spec/integration/collection_member_coercion_spec.rb +34 -13
  32. data/spec/integration/custom_attributes_spec.rb +2 -2
  33. data/spec/integration/custom_collection_attributes_spec.rb +6 -6
  34. data/spec/integration/default_values_spec.rb +8 -8
  35. data/spec/integration/defining_attributes_spec.rb +25 -18
  36. data/spec/integration/embedded_value_spec.rb +5 -5
  37. data/spec/integration/extending_objects_spec.rb +5 -5
  38. data/spec/integration/hash_attributes_coercion_spec.rb +16 -12
  39. data/spec/integration/mass_assignment_with_accessors_spec.rb +5 -5
  40. data/spec/integration/overriding_virtus_spec.rb +4 -4
  41. data/spec/integration/required_attributes_spec.rb +1 -1
  42. data/spec/integration/struct_as_embedded_value_spec.rb +4 -4
  43. data/spec/integration/using_modules_spec.rb +8 -8
  44. data/spec/integration/value_object_with_custom_constructor_spec.rb +4 -4
  45. data/spec/integration/virtus/instance_level_attributes_spec.rb +1 -1
  46. data/spec/integration/virtus/value_object_spec.rb +14 -14
  47. data/spec/shared/freeze_method_behavior.rb +6 -3
  48. data/spec/shared/idempotent_method_behaviour.rb +1 -1
  49. data/spec/shared/options_class_method.rb +3 -3
  50. data/spec/spec_helper.rb +2 -18
  51. data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +3 -3
  52. data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +3 -3
  53. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +64 -24
  54. data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +2 -2
  55. data/spec/unit/virtus/attribute/coerce_spec.rb +58 -10
  56. data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +2 -2
  57. data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +15 -4
  58. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +25 -4
  59. data/spec/unit/virtus/attribute/collection/value_coerced_predicate_spec.rb +31 -0
  60. data/spec/unit/virtus/attribute/comparison_spec.rb +20 -0
  61. data/spec/unit/virtus/attribute/custom_collection_spec.rb +8 -2
  62. data/spec/unit/virtus/attribute/defined_spec.rb +20 -0
  63. data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +30 -15
  64. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +25 -11
  65. data/spec/unit/virtus/attribute/get_spec.rb +2 -2
  66. data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +21 -9
  67. data/spec/unit/virtus/attribute/hash/coerce_spec.rb +9 -9
  68. data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +2 -2
  69. data/spec/unit/virtus/attribute/rename_spec.rb +6 -3
  70. data/spec/unit/virtus/attribute/required_predicate_spec.rb +2 -2
  71. data/spec/unit/virtus/attribute/set_default_value_spec.rb +43 -10
  72. data/spec/unit/virtus/attribute/set_spec.rb +1 -1
  73. data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +2 -2
  74. data/spec/unit/virtus/attribute_set/append_spec.rb +6 -6
  75. data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +12 -11
  76. data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +13 -12
  77. data/spec/unit/virtus/attribute_set/each_spec.rb +21 -16
  78. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +2 -2
  79. data/spec/unit/virtus/attribute_set/element_set_spec.rb +17 -9
  80. data/spec/unit/virtus/attribute_set/merge_spec.rb +7 -5
  81. data/spec/unit/virtus/attribute_set/reset_spec.rb +22 -11
  82. data/spec/unit/virtus/attribute_spec.rb +8 -7
  83. data/spec/unit/virtus/attributes_reader_spec.rb +1 -1
  84. data/spec/unit/virtus/attributes_writer_spec.rb +1 -1
  85. data/spec/unit/virtus/element_reader_spec.rb +1 -1
  86. data/spec/unit/virtus/freeze_spec.rb +23 -3
  87. data/spec/unit/virtus/model_spec.rb +38 -7
  88. data/spec/unit/virtus/module_spec.rb +59 -2
  89. data/spec/unit/virtus/set_default_attributes_spec.rb +10 -3
  90. data/spec/unit/virtus/value_object_spec.rb +15 -5
  91. data/virtus.gemspec +7 -5
  92. metadata +46 -44
  93. data/.ruby-version +0 -1
  94. data/Gemfile.devtools +0 -54
  95. data/config/flay.yml +0 -3
  96. data/config/flog.yml +0 -2
  97. data/config/mutant.yml +0 -15
  98. data/config/reek.yml +0 -146
  99. data/config/yardstick.yml +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6888ad6cccbdd89e1d41781ceafcc78502aea7d6
4
- data.tar.gz: 6638f3068fdee7c541917a7171501a79be0077ea
2
+ SHA256:
3
+ metadata.gz: 51fade6650444cdaba10d9fee1ab99f7a5707ddacbdb9c08a734dc415c6a7af8
4
+ data.tar.gz: e8569ca6dc7f6b3bbbe6a00e1be51882dd3135b5e27ba218536f2409a3f495ec
5
5
  SHA512:
6
- metadata.gz: de43cc6cccde89c7009fcb77301e34aa062aea154cfbffc2655efd28d35e41bf0cb0eec547b522cc16861ea66805a7594fa532f2d147366dee5482ae69a9f73f
7
- data.tar.gz: 982101e49074af9ce296b4a647e9855e94dd327d7ab35196fb542201d83503b2c2e75e9d4e074e01e5e1565943f26f05b1784c8cca4501d5b638f6ff1992bbe7
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
- before_install: gem install bundler
3
- bundler_args: --without yard guard benchmarks
4
- script: "bundle exec rake spec"
3
+ bundler_args: --without tools
4
+ cache: bundler
5
5
  rvm:
6
- - 1.9.3
7
- - 2.0.0
8
- - jruby-19mode
9
- - rbx-19mode
10
- - ruby-head
11
- matrix:
12
- allow_failures:
13
- - rvm: ruby-head
14
- notifications:
15
- email:
16
- - piotr.solnica@gmail.com
17
- - dan.kubb@gmail.com
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
- # v1.0.0 2013-12-10
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..master](https://github.com/solnic/virtus/compare/v1.0.0...master)
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 'bogus', '~> 0.1'
6
- gem 'devtools', :git => 'https://github.com/rom-rb/devtools', branch: 'master'
5
+ gem 'dry-inflector'
6
+ gem 'rspec'
7
+ gem 'bogus'
8
+ gem 'simplecov', platform: :ruby
7
9
 
8
- eval_gemfile 'Gemfile.devtools'
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
- This is a partial extraction of the DataMapper [Property
17
- API](http://rubydoc.info/github/datamapper/dm-core/master/DataMapper/Property)
18
- with various modifications and improvements. The goal is to provide a common API
19
- for defining attributes on a model so all ORMs/ODMs could use it instead of
20
- reinventing the wheel all over again. It is also suitable for any other
21
- use case where you need to extend your ruby objects with attributes that require
22
- data-type coercions.
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 => 29)
54
- user.attributes # => { :name => "Piotr", :age => 29 }
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 = '29' # => 29
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
- coercer[value.class].to_string.upcase
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
- Coercions
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
- # ...or you can turn it off for a single attribute
474
+ ``` ruby
441
475
  class User
442
476
  include Virtus.model
443
477
 
444
- attribute :name, String, :coerce => false
445
- end
446
- ```
447
-
448
- You can configure coercers too:
478
+ attribute :name, String
449
479
 
450
- ```ruby
451
- Virtus.coercer do |config|
452
- config.string.boolean_map = { 'yup' => true, 'nope' => false }
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
- # Virtus.coercer instance is used by default for all attributes.
456
- # You *can* override it for a single attribute if you want:
489
+ user = User.new(name: "Frank")
490
+ user.name # => 'Frank'
457
491
 
458
- my_cool_coercer = Coercible::Coercer.new do |config|
459
- # some customization
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 = { 'yup' => true, 'nope' => false }
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
- # encoding: utf-8
1
+ require "rspec/core/rake_task"
2
2
 
3
- require 'devtools'
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ task default: [:spec]
4
5
 
5
- Devtools.init_rake_tasks
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, :primitive
14
+ attr_reader :output, :attribute
15
15
 
16
- def initialize(output, primitive)
17
- @output, @primitive = output, primitive
18
- super("Failed to coerce #{output.inspect} into #{primitive.inspect}")
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.call(&block)
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'