virtus 1.0.1 → 2.0.0

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.
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'