virtus 0.5.5 → 1.0.0.beta3
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.
- data/.rspec +1 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -8
- data/Gemfile +8 -2
- data/Gemfile.devtools +24 -30
- data/Guardfile +17 -6
- data/README.md +215 -77
- data/TODO.md +6 -0
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/mutant.yml +12 -1
- data/config/reek.yml +57 -66
- data/lib/virtus.rb +126 -42
- data/lib/virtus/attribute.rb +52 -240
- data/lib/virtus/attribute/accessor.rb +91 -0
- data/lib/virtus/attribute/boolean.rb +11 -8
- data/lib/virtus/attribute/builder.rb +120 -0
- data/lib/virtus/attribute/coercer.rb +51 -0
- data/lib/virtus/attribute/coercible.rb +14 -0
- data/lib/virtus/attribute/collection.rb +44 -90
- data/lib/virtus/attribute/default_value/from_callable.rb +1 -1
- data/lib/virtus/attribute/default_value/from_clonable.rb +1 -6
- data/lib/virtus/attribute/default_value/from_symbol.rb +3 -3
- data/lib/virtus/attribute/embedded_value.rb +37 -28
- data/lib/virtus/attribute/hash.rb +69 -71
- data/lib/virtus/attribute/lazy_default.rb +18 -0
- data/lib/virtus/attribute/strict.rb +16 -0
- data/lib/virtus/attribute_set.rb +81 -9
- data/lib/virtus/class_inclusions.rb +24 -17
- data/lib/virtus/class_methods.rb +13 -31
- data/lib/virtus/configuration.rb +77 -0
- data/lib/virtus/const_missing_extensions.rb +16 -0
- data/lib/virtus/extensions.rb +86 -61
- data/lib/virtus/instance_methods.rb +107 -128
- data/lib/virtus/model.rb +68 -0
- data/lib/virtus/module_builder.rb +184 -0
- data/lib/virtus/module_extensions.rb +27 -15
- data/lib/virtus/support/equalizer.rb +2 -3
- data/lib/virtus/support/type_lookup.rb +1 -1
- data/lib/virtus/value_object.rb +24 -31
- data/lib/virtus/version.rb +1 -1
- data/spec/integration/building_module_spec.rb +68 -0
- data/spec/integration/custom_attributes_spec.rb +8 -15
- data/spec/integration/custom_collection_attributes_spec.rb +101 -0
- data/spec/integration/default_values_spec.rb +9 -2
- data/spec/integration/defining_attributes_spec.rb +2 -2
- data/spec/integration/using_modules_spec.rb +5 -3
- data/spec/shared/freeze_method_behavior.rb +2 -2
- data/spec/shared/options_class_method.rb +1 -1
- data/spec/spec_helper.rb +25 -5
- data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +25 -0
- data/spec/unit/virtus/attribute/class_methods/build_spec.rb +115 -22
- data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +32 -0
- data/spec/unit/virtus/attribute/coerce_spec.rb +38 -21
- data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +20 -0
- data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +84 -0
- data/spec/unit/virtus/attribute/collection/coerce_spec.rb +37 -24
- data/spec/unit/virtus/attribute/custom_collection_spec.rb +23 -0
- data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +37 -0
- data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +46 -10
- data/spec/unit/virtus/attribute/get_spec.rb +15 -63
- data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +80 -0
- data/spec/unit/virtus/attribute/hash/coerce_spec.rb +75 -13
- data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +20 -0
- data/spec/unit/virtus/attribute/set_default_value_spec.rb +74 -0
- data/spec/unit/virtus/attribute/set_spec.rb +16 -36
- data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +19 -0
- data/spec/unit/virtus/attribute_set/append_spec.rb +3 -5
- data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +1 -1
- data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +1 -1
- data/spec/unit/virtus/attribute_set/each_spec.rb +3 -3
- data/spec/unit/virtus/attribute_set/element_reference_spec.rb +1 -1
- data/spec/unit/virtus/attribute_set/element_set_spec.rb +4 -4
- data/spec/unit/virtus/attribute_set/merge_spec.rb +10 -16
- data/spec/unit/virtus/attribute_set/reset_spec.rb +6 -10
- data/spec/unit/virtus/attribute_spec.rb +222 -0
- data/spec/unit/virtus/attributes_reader_spec.rb +41 -0
- data/spec/unit/virtus/attributes_writer_spec.rb +51 -0
- data/spec/unit/virtus/class_methods/new_spec.rb +39 -0
- data/spec/unit/virtus/config_spec.rb +13 -0
- data/spec/unit/virtus/element_reader_spec.rb +21 -0
- data/spec/unit/virtus/element_writer_spec.rb +19 -0
- data/spec/unit/virtus/freeze_spec.rb +21 -0
- data/spec/unit/virtus/model_spec.rb +134 -0
- data/spec/unit/virtus/module_spec.rb +76 -0
- data/spec/unit/virtus/set_default_attributes_spec.rb +25 -0
- data/spec/unit/virtus/value_object_spec.rb +105 -0
- data/virtus.gemspec +4 -2
- metadata +82 -191
- data/.rvmrc +0 -1
- data/TODO +0 -1
- data/config/roodi.yml +0 -17
- data/lib/virtus/attribute/array.rb +0 -24
- data/lib/virtus/attribute/class.rb +0 -21
- data/lib/virtus/attribute/date.rb +0 -34
- data/lib/virtus/attribute/date_time.rb +0 -36
- data/lib/virtus/attribute/decimal.rb +0 -21
- data/lib/virtus/attribute/embedded_value/from_open_struct.rb +0 -19
- data/lib/virtus/attribute/embedded_value/from_struct.rb +0 -19
- data/lib/virtus/attribute/float.rb +0 -30
- data/lib/virtus/attribute/integer.rb +0 -27
- data/lib/virtus/attribute/numeric.rb +0 -11
- data/lib/virtus/attribute/object.rb +0 -11
- data/lib/virtus/attribute/set.rb +0 -24
- data/lib/virtus/attribute/string.rb +0 -24
- data/lib/virtus/attribute/symbol.rb +0 -21
- data/lib/virtus/attribute/time.rb +0 -36
- data/lib/virtus/coercion.rb +0 -32
- data/lib/virtus/coercion/array.rb +0 -23
- data/lib/virtus/coercion/date.rb +0 -26
- data/lib/virtus/coercion/date_time.rb +0 -26
- data/lib/virtus/coercion/decimal.rb +0 -40
- data/lib/virtus/coercion/false_class.rb +0 -24
- data/lib/virtus/coercion/float.rb +0 -39
- data/lib/virtus/coercion/hash.rb +0 -71
- data/lib/virtus/coercion/integer.rb +0 -83
- data/lib/virtus/coercion/numeric.rb +0 -66
- data/lib/virtus/coercion/object.rb +0 -125
- data/lib/virtus/coercion/string.rb +0 -218
- data/lib/virtus/coercion/symbol.rb +0 -24
- data/lib/virtus/coercion/time.rb +0 -40
- data/lib/virtus/coercion/time_coercions.rb +0 -86
- data/lib/virtus/coercion/true_class.rb +0 -24
- data/spec/unit/virtus/attribute/array/coerce_spec.rb +0 -13
- data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +0 -85
- data/spec/unit/virtus/attribute/boolean/define_reader_method_spec.rb +0 -15
- data/spec/unit/virtus/attribute/boolean/value_coerced_spec.rb +0 -97
- data/spec/unit/virtus/attribute/boolean_spec.rb +0 -19
- data/spec/unit/virtus/attribute/class/coerce_spec.rb +0 -13
- data/spec/unit/virtus/attribute/class_methods/accessor_spec.rb +0 -12
- data/spec/unit/virtus/attribute/class_methods/coercion_method_spec.rb +0 -9
- data/spec/unit/virtus/attribute/class_methods/default_spec.rb +0 -9
- data/spec/unit/virtus/attribute/class_methods/determine_type_spec.rb +0 -117
- data/spec/unit/virtus/attribute/class_methods/merge_options_spec.rb +0 -11
- data/spec/unit/virtus/attribute/class_methods/primitive_spec.rb +0 -9
- data/spec/unit/virtus/attribute/class_methods/reader_spec.rb +0 -9
- data/spec/unit/virtus/attribute/class_methods/writer_spec.rb +0 -9
- data/spec/unit/virtus/attribute/coercion_method_spec.rb +0 -12
- data/spec/unit/virtus/attribute/collection/class_methods/merge_options_spec.rb +0 -40
- data/spec/unit/virtus/attribute/collection/coerce_and_append_member_spec.rb +0 -16
- data/spec/unit/virtus/attribute/collection/member_coercion/coerce_and_append_member_spec.rb +0 -18
- data/spec/unit/virtus/attribute/collection/member_type_spec.rb +0 -17
- data/spec/unit/virtus/attribute/collection/new_collection_spec.rb +0 -9
- data/spec/unit/virtus/attribute/date/coerce_spec.rb +0 -47
- data/spec/unit/virtus/attribute/date/value_coerced_spec.rb +0 -46
- data/spec/unit/virtus/attribute/date_time/coerce_spec.rb +0 -80
- data/spec/unit/virtus/attribute/decimal/coerce_spec.rb +0 -123
- data/spec/unit/virtus/attribute/default_spec.rb +0 -28
- data/spec/unit/virtus/attribute/default_value/call_spec.rb +0 -21
- data/spec/unit/virtus/attribute/default_value/class_methods/build_spec.rb +0 -23
- data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +0 -21
- data/spec/unit/virtus/attribute/default_value/from_callable/call_spec.rb +0 -19
- data/spec/unit/virtus/attribute/default_value/from_callable/class_methods/handle_spec.rb +0 -17
- data/spec/unit/virtus/attribute/default_value/from_clonable/call_spec.rb +0 -20
- data/spec/unit/virtus/attribute/default_value/from_clonable/class_methods/handle_spec.rb +0 -19
- data/spec/unit/virtus/attribute/default_value/from_symbol/call_spec.rb +0 -17
- data/spec/unit/virtus/attribute/default_value/from_symbol/class_methods/handle_spec.rb +0 -17
- data/spec/unit/virtus/attribute/default_value/value_spec.rb +0 -10
- data/spec/unit/virtus/attribute/define_accessor_methods_spec.rb +0 -26
- data/spec/unit/virtus/attribute/define_reader_method_spec.rb +0 -24
- data/spec/unit/virtus/attribute/define_writer_method_spec.rb +0 -24
- data/spec/unit/virtus/attribute/embedded_value/class_methods/determine_type_spec.rb +0 -23
- data/spec/unit/virtus/attribute/embedded_value/class_methods/merge_options_spec.rb +0 -17
- data/spec/unit/virtus/attribute/embedded_value/from_open_struct/coerce_spec.rb +0 -34
- data/spec/unit/virtus/attribute/embedded_value/from_struct/coerce_spec.rb +0 -34
- data/spec/unit/virtus/attribute/float/coerce_spec.rb +0 -123
- data/spec/unit/virtus/attribute/hash/class_methods/merge_options_spec.rb +0 -33
- data/spec/unit/virtus/attribute/hash/key_type_spec.rb +0 -10
- data/spec/unit/virtus/attribute/hash/value_type_spec.rb +0 -10
- data/spec/unit/virtus/attribute/inspect_spec.rb +0 -27
- data/spec/unit/virtus/attribute/integer/coerce_spec.rb +0 -117
- data/spec/unit/virtus/attribute/name_spec.rb +0 -12
- data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +0 -15
- data/spec/unit/virtus/attribute/numeric/class_methods/max_spec.rb +0 -9
- data/spec/unit/virtus/attribute/numeric/class_methods/min_spec.rb +0 -9
- data/spec/unit/virtus/attribute/options_spec.rb +0 -14
- data/spec/unit/virtus/attribute/public_reader_spec.rb +0 -24
- data/spec/unit/virtus/attribute/public_writer_spec.rb +0 -24
- data/spec/unit/virtus/attribute/set/coerce_spec.rb +0 -13
- data/spec/unit/virtus/attribute/string/coerce_spec.rb +0 -11
- data/spec/unit/virtus/attribute/symbol/coerce_spec.rb +0 -13
- data/spec/unit/virtus/attribute/time/coerce_spec.rb +0 -67
- data/spec/unit/virtus/attribute/value_coerced_spec.rb +0 -19
- data/spec/unit/virtus/class_methods/attribute_set_spec.rb +0 -9
- data/spec/unit/virtus/class_methods/attribute_spec.rb +0 -30
- data/spec/unit/virtus/class_methods/attributes_spec.rb +0 -22
- data/spec/unit/virtus/class_methods/const_missing_spec.rb +0 -27
- data/spec/unit/virtus/class_methods/inherited_spec.rb +0 -21
- data/spec/unit/virtus/coercion/array/class_methods/to_set_spec.rb +0 -12
- data/spec/unit/virtus/coercion/class_methods/element_reference_spec.rb +0 -17
- data/spec/unit/virtus/coercion/class_methods/primitive_spec.rb +0 -13
- data/spec/unit/virtus/coercion/date/class_methods/to_date_spec.rb +0 -10
- data/spec/unit/virtus/coercion/date/class_methods/to_datetime_spec.rb +0 -30
- data/spec/unit/virtus/coercion/date/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/date/class_methods/to_time_spec.rb +0 -12
- data/spec/unit/virtus/coercion/date_time/class_methods/to_date_spec.rb +0 -30
- data/spec/unit/virtus/coercion/date_time/class_methods/to_datetime_spec.rb +0 -10
- data/spec/unit/virtus/coercion/date_time/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/date_time/class_methods/to_time_spec.rb +0 -30
- data/spec/unit/virtus/coercion/decimal/class_methods/to_decimal_spec.rb +0 -9
- data/spec/unit/virtus/coercion/decimal/class_methods/to_float_spec.rb +0 -12
- data/spec/unit/virtus/coercion/decimal/class_methods/to_integer_spec.rb +0 -12
- data/spec/unit/virtus/coercion/decimal/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/false_class/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/float/class_methods/to_decimal_spec.rb +0 -12
- data/spec/unit/virtus/coercion/float/class_methods/to_float_spec.rb +0 -9
- data/spec/unit/virtus/coercion/float/class_methods/to_integer_spec.rb +0 -12
- data/spec/unit/virtus/coercion/float/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/hash/class_methods/to_date_spec.rb +0 -38
- data/spec/unit/virtus/coercion/hash/class_methods/to_datetime_spec.rb +0 -38
- data/spec/unit/virtus/coercion/hash/class_methods/to_time_spec.rb +0 -38
- data/spec/unit/virtus/coercion/integer/class_methods/to_boolean_spec.rb +0 -25
- data/spec/unit/virtus/coercion/integer/class_methods/to_decimal_spec.rb +0 -12
- data/spec/unit/virtus/coercion/integer/class_methods/to_float_spec.rb +0 -12
- data/spec/unit/virtus/coercion/integer/class_methods/to_integer_spec.rb +0 -9
- data/spec/unit/virtus/coercion/integer/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/numeric/class_methods/to_decimal_spec.rb +0 -10
- data/spec/unit/virtus/coercion/numeric/class_methods/to_float_spec.rb +0 -10
- data/spec/unit/virtus/coercion/numeric/class_methods/to_integer_spec.rb +0 -10
- data/spec/unit/virtus/coercion/numeric/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/object/class_methods/method_missing_spec.rb +0 -33
- data/spec/unit/virtus/coercion/object/class_methods/to_array_spec.rb +0 -51
- data/spec/unit/virtus/coercion/object/class_methods/to_hash_spec.rb +0 -22
- data/spec/unit/virtus/coercion/object/class_methods/to_integer_spec.rb +0 -22
- data/spec/unit/virtus/coercion/object/class_methods/to_string_spec.rb +0 -22
- data/spec/unit/virtus/coercion/string/class_methods/to_boolean_spec.rb +0 -29
- data/spec/unit/virtus/coercion/string/class_methods/to_constant_spec.rb +0 -49
- data/spec/unit/virtus/coercion/string/class_methods/to_date_spec.rb +0 -23
- data/spec/unit/virtus/coercion/string/class_methods/to_datetime_spec.rb +0 -50
- data/spec/unit/virtus/coercion/string/class_methods/to_decimal_spec.rb +0 -47
- data/spec/unit/virtus/coercion/string/class_methods/to_float_spec.rb +0 -57
- data/spec/unit/virtus/coercion/string/class_methods/to_integer_spec.rb +0 -68
- data/spec/unit/virtus/coercion/string/class_methods/to_symbol_spec.rb +0 -9
- data/spec/unit/virtus/coercion/string/class_methods/to_time_spec.rb +0 -50
- data/spec/unit/virtus/coercion/symbol/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/coercion/time/class_methods/to_integer_spec.rb +0 -10
- data/spec/unit/virtus/coercion/time/class_methods/to_time_spec.rb +0 -10
- data/spec/unit/virtus/coercion/time_coercions/to_date_spec.rb +0 -33
- data/spec/unit/virtus/coercion/time_coercions/to_datetime_spec.rb +0 -33
- data/spec/unit/virtus/coercion/time_coercions/to_string_spec.rb +0 -18
- data/spec/unit/virtus/coercion/time_coercions/to_time_spec.rb +0 -33
- data/spec/unit/virtus/coercion/true_class/class_methods/to_string_spec.rb +0 -12
- data/spec/unit/virtus/equalizer/append_spec.rb +0 -82
- data/spec/unit/virtus/equalizer/class_method/new_spec.rb +0 -111
- data/spec/unit/virtus/equalizer/methods/eql_spec.rb +0 -47
- data/spec/unit/virtus/equalizer/methods/equal_value_spec.rb +0 -57
- data/spec/unit/virtus/extensions/allowed_writer_methods_spec.rb +0 -25
- data/spec/unit/virtus/extensions/attribute_spec.rb +0 -26
- data/spec/unit/virtus/instance_methods/attributes_spec.rb +0 -140
- data/spec/unit/virtus/instance_methods/element_reference_spec.rb +0 -24
- data/spec/unit/virtus/instance_methods/element_set_spec.rb +0 -28
- data/spec/unit/virtus/instance_methods/freeze_spec.rb +0 -64
- data/spec/unit/virtus/instance_methods/initialize_spec.rb +0 -48
- data/spec/unit/virtus/instance_methods/to_hash_spec.rb +0 -23
- data/spec/unit/virtus/module_extensions/attribute_spec.rb +0 -31
- data/spec/unit/virtus/options/accept_options_spec.rb +0 -37
- data/spec/unit/virtus/options/accepted_options_spec.rb +0 -21
- data/spec/unit/virtus/options/options_spec.rb +0 -34
- data/spec/unit/virtus/type_lookup/class_methods/extended_spec.rb +0 -9
- data/spec/unit/virtus/type_lookup/determine_type_spec.rb +0 -81
- data/spec/unit/virtus/type_lookup/primitive_spec.rb +0 -9
- data/spec/unit/virtus/value_object/class_methods/allowed_writer_methods_spec.rb +0 -15
- data/spec/unit/virtus/value_object/class_methods/attribute_spec.rb +0 -50
- data/spec/unit/virtus/value_object/class_methods/equalizer_spec.rb +0 -24
- data/spec/unit/virtus/value_object/initialize_spec.rb +0 -19
- data/spec/unit/virtus/value_object/instance_methods/clone_spec.rb +0 -21
- data/spec/unit/virtus/value_object/instance_methods/with_spec.rb +0 -31
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--
|
2
|
+
--order random
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
virtus
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3
|
data/.travis.yml
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
2
|
+
before_install: gem install bundler
|
3
|
+
bundler_args: --without yard guard benchmarks
|
3
4
|
script: "bundle exec rake spec"
|
4
5
|
rvm:
|
5
|
-
- 1.8.7
|
6
|
-
- 1.9.2
|
7
6
|
- 1.9.3
|
8
|
-
-
|
7
|
+
- 2.0.0
|
9
8
|
- jruby-19mode
|
10
|
-
- rbx-18mode
|
11
9
|
- rbx-19mode
|
12
|
-
-
|
13
|
-
- jruby-head
|
10
|
+
- ruby-head
|
14
11
|
matrix:
|
15
12
|
allow_failures:
|
16
|
-
- rvm:
|
13
|
+
- rvm: ruby-head
|
14
|
+
- rvm: rbx-19mode
|
17
15
|
notifications:
|
18
16
|
email:
|
19
17
|
- piotr.solnica@gmail.com
|
data/Gemfile
CHANGED
@@ -2,6 +2,12 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem '
|
5
|
+
gem 'bogus', '~> 0.1'
|
6
6
|
|
7
|
-
|
7
|
+
gem 'axiom-types', :git => 'https://github.com/dkubb/axiom-types'
|
8
|
+
|
9
|
+
gem 'devtools', :git => 'https://github.com/rom-rb/devtools', branch: 'master'
|
10
|
+
|
11
|
+
eval_gemfile 'Gemfile.devtools'
|
12
|
+
|
13
|
+
gem 'mutant', git: 'https://github.com/solnic/mutant.git', branch: 'auto-expand-scope'
|
data/Gemfile.devtools
CHANGED
@@ -1,52 +1,46 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
group :development do
|
4
|
-
gem 'rake', '~> 10.0
|
5
|
-
gem 'rspec', '~> 2.
|
6
|
-
gem 'yard', '~> 0.8.
|
4
|
+
gem 'rake', '~> 10.1.0'
|
5
|
+
gem 'rspec', '~> 2.14.1'
|
6
|
+
gem 'yard', '~> 0.8.7'
|
7
7
|
end
|
8
8
|
|
9
9
|
group :yard do
|
10
|
-
gem 'kramdown', '~> 1.0
|
10
|
+
gem 'kramdown', '~> 1.2.0'
|
11
11
|
end
|
12
12
|
|
13
13
|
group :guard do
|
14
|
-
gem 'guard', '~> 1.8.
|
14
|
+
gem 'guard', '~> 1.8.1'
|
15
15
|
gem 'guard-bundler', '~> 1.0.0'
|
16
|
-
gem 'guard-rspec', '~>
|
16
|
+
gem 'guard-rspec', '~> 3.0.2'
|
17
|
+
gem 'guard-rubocop', '~> 0.2.0'
|
18
|
+
gem 'guard-mutant', '~> 0.0.1'
|
17
19
|
|
18
20
|
# file system change event handling
|
19
|
-
gem 'listen', '~> 1.0
|
20
|
-
gem 'rb-fchange', '~> 0.0.6', :
|
21
|
-
gem 'rb-fsevent', '~> 0.9.3', :
|
22
|
-
gem 'rb-inotify', '~> 0.9.0', :
|
21
|
+
gem 'listen', '~> 1.3.0'
|
22
|
+
gem 'rb-fchange', '~> 0.0.6', require: false
|
23
|
+
gem 'rb-fsevent', '~> 0.9.3', require: false
|
24
|
+
gem 'rb-inotify', '~> 0.9.0', require: false
|
23
25
|
|
24
26
|
# notification handling
|
25
|
-
gem 'libnotify', '~> 0.8.0', :
|
26
|
-
gem 'rb-notifu', '~> 0.0.4', :
|
27
|
-
gem 'terminal-notifier-guard', '~> 1.5.3', :
|
27
|
+
gem 'libnotify', '~> 0.8.0', require: false
|
28
|
+
gem 'rb-notifu', '~> 0.0.4', require: false
|
29
|
+
gem 'terminal-notifier-guard', '~> 1.5.3', require: false
|
28
30
|
end
|
29
31
|
|
30
32
|
group :metrics do
|
31
|
-
gem '
|
32
|
-
gem '
|
33
|
-
gem '
|
34
|
-
gem '
|
35
|
-
gem '
|
36
|
-
gem 'simplecov',
|
37
|
-
gem 'yardstick',
|
38
|
-
|
39
|
-
platforms :ruby_19 do
|
33
|
+
gem 'coveralls', '~> 0.6.7'
|
34
|
+
gem 'flay', '~> 2.4.0'
|
35
|
+
gem 'flog', '~> 4.1.1'
|
36
|
+
gem 'reek', '~> 1.3.2'
|
37
|
+
gem 'rubocop', '~> 0.13.0'
|
38
|
+
gem 'simplecov', '~> 0.7.1'
|
39
|
+
gem 'yardstick', '~> 0.9.7', git: 'https://github.com/dkubb/yardstick.git'
|
40
|
+
|
41
|
+
platforms :ruby_19, :ruby_20 do
|
40
42
|
gem 'yard-spellcheck', '~> 0.1.5'
|
41
43
|
end
|
42
|
-
|
43
|
-
platforms :mri_19, :rbx do
|
44
|
-
gem 'mutant', '~> 0.2.20'
|
45
|
-
end
|
46
|
-
|
47
|
-
platforms :rbx do
|
48
|
-
gem 'pelusa', '~> 0.2.2'
|
49
|
-
end
|
50
44
|
end
|
51
45
|
|
52
46
|
group :benchmarks do
|
data/Guardfile
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
-
|
2
|
-
#
|
1
|
+
guard :rspec, spec_paths: 'spec/unit' do
|
2
|
+
#run all specs if configuration is modified
|
3
|
+
watch('Guardfile') { 'spec' }
|
4
|
+
watch('Gemfile.lock') { 'spec' }
|
5
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
3
6
|
|
4
|
-
|
5
|
-
watch(%r{
|
6
|
-
|
7
|
-
|
7
|
+
# run all specs if supporting files files are modified
|
8
|
+
watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec' }
|
9
|
+
|
10
|
+
# run unit specs if associated lib code is modified
|
11
|
+
watch(%r{\Alib/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}"] }
|
12
|
+
watch(%r{\Alib/(.+)/support/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}/#{m[2]}"] }
|
13
|
+
watch("lib/#{File.basename(File.expand_path('../', __FILE__))}.rb") { 'spec' }
|
14
|
+
|
15
|
+
# run a spec if it is modified
|
16
|
+
watch(%r{\Aspec/(?:unit|integration)/.+_spec\.rb\z})
|
17
|
+
|
18
|
+
notification :tmux, :display_message => true
|
8
19
|
end
|
data/README.md
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
Virtus
|
2
2
|
======
|
3
3
|
|
4
|
-
[][gem]
|
5
|
+
[][travis]
|
6
|
+
[][gemnasium]
|
7
|
+
[][codeclimate]
|
8
|
+
[][coveralls]
|
9
|
+
|
10
|
+
[gem]: https://rubygems.org/gems/virtus
|
11
|
+
[travis]: https://travis-ci.org/solnic/virtus
|
12
|
+
[gemnasium]: https://gemnasium.com/solnic/virtus
|
13
|
+
[codeclimate]: https://codeclimate.com/github/solnic/virtus
|
14
|
+
[coveralls]: https://coveralls.io/r/solnic/virtus
|
7
15
|
|
8
16
|
This is a partial extraction of the DataMapper [Property
|
9
17
|
API](http://rubydoc.info/github/datamapper/dm-core/master/DataMapper/Property)
|
@@ -35,19 +43,19 @@ You can create classes extended with virtus and define attributes:
|
|
35
43
|
|
36
44
|
``` ruby
|
37
45
|
class User
|
38
|
-
include Virtus
|
46
|
+
include Virtus.model
|
39
47
|
|
40
48
|
attribute :name, String
|
41
49
|
attribute :age, Integer
|
42
50
|
attribute :birthday, DateTime
|
43
51
|
end
|
44
52
|
|
45
|
-
user = User.new(:name => 'Piotr', :age =>
|
46
|
-
user.attributes # => { :name => "Piotr", :age =>
|
53
|
+
user = User.new(:name => 'Piotr', :age => 29)
|
54
|
+
user.attributes # => { :name => "Piotr", :age => 29 }
|
47
55
|
|
48
56
|
user.name # => "Piotr"
|
49
57
|
|
50
|
-
user.age = '
|
58
|
+
user.age = '29' # => 29
|
51
59
|
user.age.class # => Fixnum
|
52
60
|
|
53
61
|
user.birthday = 'November 18th, 1983' # => #<DateTime: 1983-11-18T00:00:00+00:00 (4891313/2,0/1,2299161)>
|
@@ -58,6 +66,51 @@ user.name # => "Jane"
|
|
58
66
|
user.age # => 21
|
59
67
|
```
|
60
68
|
|
69
|
+
### Cherry-picking extensions
|
70
|
+
|
71
|
+
``` ruby
|
72
|
+
# include just the attribute DSL
|
73
|
+
class User
|
74
|
+
include Virtus::Model::Core
|
75
|
+
|
76
|
+
attribute :name, String
|
77
|
+
end
|
78
|
+
|
79
|
+
user = User.new
|
80
|
+
user.name = 'Piotr'
|
81
|
+
|
82
|
+
# include attribute DSL + constructor
|
83
|
+
class User
|
84
|
+
include Virtus::Model::Core
|
85
|
+
include Virtus::Model::Constructor
|
86
|
+
|
87
|
+
attribute :name, String
|
88
|
+
end
|
89
|
+
|
90
|
+
User.new(:name => 'Piotr')
|
91
|
+
|
92
|
+
# include attribute DSL + constructor + mass-assignment
|
93
|
+
class User
|
94
|
+
include Virtus::Model::Core
|
95
|
+
include Virtus::Model::Constructor
|
96
|
+
include Virtus::Model::MassAssignment
|
97
|
+
|
98
|
+
attribute :name, String
|
99
|
+
end
|
100
|
+
|
101
|
+
user = User.new(:name => 'Piotr')
|
102
|
+
user.attributes = { :name => 'John' }
|
103
|
+
user.attributes
|
104
|
+
# => {:name => 'John'}
|
105
|
+
|
106
|
+
# starting from virtus 1.0.0 preffered way to do this is to use module builder
|
107
|
+
MyModel = Virtus.model(:constructor => false, :mass_assignment => false)
|
108
|
+
|
109
|
+
class User
|
110
|
+
include MyModel
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
61
114
|
### Using Virtus with Modules
|
62
115
|
|
63
116
|
You can create modules extended with virtus and define attributes for later
|
@@ -65,13 +118,13 @@ inclusion in your classes:
|
|
65
118
|
|
66
119
|
```ruby
|
67
120
|
module Name
|
68
|
-
include Virtus
|
121
|
+
include Virtus.module
|
69
122
|
|
70
123
|
attribute :name, String
|
71
124
|
end
|
72
125
|
|
73
126
|
module Age
|
74
|
-
include Virtus
|
127
|
+
include Virtus.module(:coerce => false)
|
75
128
|
|
76
129
|
attribute :age, Integer
|
77
130
|
end
|
@@ -80,7 +133,7 @@ class User
|
|
80
133
|
include Name, Age
|
81
134
|
end
|
82
135
|
|
83
|
-
user = User.new(:name => 'John', :age =>
|
136
|
+
user = User.new(:name => 'John', :age => 30)
|
84
137
|
```
|
85
138
|
|
86
139
|
### Dynamically Extending Instances
|
@@ -93,7 +146,7 @@ class User
|
|
93
146
|
end
|
94
147
|
|
95
148
|
user = User.new
|
96
|
-
user.extend(Virtus)
|
149
|
+
user.extend(Virtus.model)
|
97
150
|
user.attribute :name, String
|
98
151
|
user.name = 'John'
|
99
152
|
user.name # => 'John'
|
@@ -103,7 +156,7 @@ user.name # => 'John'
|
|
103
156
|
|
104
157
|
``` ruby
|
105
158
|
class Page
|
106
|
-
include Virtus
|
159
|
+
include Virtus.model
|
107
160
|
|
108
161
|
attribute :title, String
|
109
162
|
|
@@ -129,19 +182,24 @@ page.slug # => 'virtus-readme'
|
|
129
182
|
page.views # => 0
|
130
183
|
page.published # => false
|
131
184
|
page.editor_title # => "UNPUBLISHED: Virtus README"
|
185
|
+
|
186
|
+
page.views = 10
|
187
|
+
page.views # => 10
|
188
|
+
page.reset_attribute(:views) # => 0
|
189
|
+
page.views # => 0
|
132
190
|
```
|
133
191
|
|
134
192
|
### Embedded Value
|
135
193
|
|
136
194
|
``` ruby
|
137
195
|
class City
|
138
|
-
include Virtus
|
196
|
+
include Virtus.model
|
139
197
|
|
140
198
|
attribute :name, String
|
141
199
|
end
|
142
200
|
|
143
201
|
class Address
|
144
|
-
include Virtus
|
202
|
+
include Virtus.model
|
145
203
|
|
146
204
|
attribute :street, String
|
147
205
|
attribute :zipcode, String
|
@@ -149,7 +207,7 @@ class Address
|
|
149
207
|
end
|
150
208
|
|
151
209
|
class User
|
152
|
-
include Virtus
|
210
|
+
include Virtus.model
|
153
211
|
|
154
212
|
attribute :name, String
|
155
213
|
attribute :address, Address
|
@@ -167,7 +225,7 @@ user.address.city.name # => "NYC"
|
|
167
225
|
``` ruby
|
168
226
|
# Support "primitive" classes
|
169
227
|
class Book
|
170
|
-
include Virtus
|
228
|
+
include Virtus.model
|
171
229
|
|
172
230
|
attribute :page_numbers, Array[Integer]
|
173
231
|
end
|
@@ -177,7 +235,7 @@ book.page_numbers # => [1, 2, 3]
|
|
177
235
|
|
178
236
|
# Support EmbeddedValues, too!
|
179
237
|
class Address
|
180
|
-
include Virtus
|
238
|
+
include Virtus.model
|
181
239
|
|
182
240
|
attribute :address, String
|
183
241
|
attribute :locality, String
|
@@ -186,13 +244,13 @@ class Address
|
|
186
244
|
end
|
187
245
|
|
188
246
|
class PhoneNumber
|
189
|
-
include Virtus
|
247
|
+
include Virtus.model
|
190
248
|
|
191
249
|
attribute :number, String
|
192
250
|
end
|
193
251
|
|
194
252
|
class User
|
195
|
-
include Virtus
|
253
|
+
include Virtus.model
|
196
254
|
|
197
255
|
attribute :phone_numbers, Array[PhoneNumber]
|
198
256
|
attribute :addresses, Set[Address]
|
@@ -214,7 +272,7 @@ user.addresses # => #<Set: {#<Address:0x007fdb2d3be448 @address="1234 Any St.",
|
|
214
272
|
|
215
273
|
``` ruby
|
216
274
|
class Package
|
217
|
-
include Virtus
|
275
|
+
include Virtus.model
|
218
276
|
|
219
277
|
attribute :dimensions, Hash[Symbol => Float]
|
220
278
|
end
|
@@ -232,13 +290,13 @@ Here's an example:
|
|
232
290
|
|
233
291
|
``` ruby
|
234
292
|
class Book
|
235
|
-
include Virtus
|
293
|
+
include Virtus.model
|
236
294
|
|
237
295
|
attribute :title, String
|
238
296
|
end
|
239
297
|
|
240
298
|
class Library
|
241
|
-
include Virtus
|
299
|
+
include Virtus.model
|
242
300
|
|
243
301
|
attribute :books, Array[Book]
|
244
302
|
end
|
@@ -257,7 +315,7 @@ mutation methods that perform coercions. For example:
|
|
257
315
|
|
258
316
|
``` ruby
|
259
317
|
class Book
|
260
|
-
include Virtus
|
318
|
+
include Virtus.model
|
261
319
|
|
262
320
|
attribute :title, String
|
263
321
|
end
|
@@ -273,7 +331,7 @@ class BookCollection < Array
|
|
273
331
|
end
|
274
332
|
|
275
333
|
class Library
|
276
|
-
include Virtus
|
334
|
+
include Virtus.model
|
277
335
|
|
278
336
|
attribute :books, BookCollection[Book]
|
279
337
|
end
|
@@ -286,17 +344,21 @@ library.books << { :title => 'Another Introduction to Virtus' }
|
|
286
344
|
|
287
345
|
``` ruby
|
288
346
|
class GeoLocation
|
289
|
-
include Virtus
|
347
|
+
include Virtus.value_object
|
290
348
|
|
291
|
-
|
292
|
-
|
349
|
+
values do
|
350
|
+
attribute :latitude, Float
|
351
|
+
attribute :longitude, Float
|
352
|
+
end
|
293
353
|
end
|
294
354
|
|
295
355
|
class Venue
|
296
|
-
include Virtus
|
356
|
+
include Virtus.value_object
|
297
357
|
|
298
|
-
|
299
|
-
|
358
|
+
values do
|
359
|
+
attribute :name, String
|
360
|
+
attribute :location, GeoLocation
|
361
|
+
end
|
300
362
|
end
|
301
363
|
|
302
364
|
venue = Venue.new(
|
@@ -315,75 +377,151 @@ venue_other = Venue.new(
|
|
315
377
|
venue.location === venue_other.location # => true
|
316
378
|
```
|
317
379
|
|
318
|
-
###
|
380
|
+
### Custom Coercions
|
381
|
+
|
382
|
+
``` ruby
|
383
|
+
require 'json'
|
384
|
+
|
385
|
+
class Json < Virtus::Attribute
|
386
|
+
def coerce(value)
|
387
|
+
value.is_a?(::Hash) ? value : JSON.parse(value)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
class User
|
392
|
+
include Virtus.model
|
393
|
+
|
394
|
+
attribute :info, Json
|
395
|
+
end
|
396
|
+
|
397
|
+
user = User.new
|
398
|
+
user.info = '{"email":"john@domain.com"}' # => {"email"=>"john@domain.com"}
|
399
|
+
user.info.class # => Hash
|
400
|
+
|
401
|
+
# With a custom attribute encapsulating coercion-specific configuration
|
402
|
+
class NoisyString < Virtus::Attribute
|
403
|
+
def coerce(value)
|
404
|
+
coercer[value.class].to_string.upcase
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
class User
|
409
|
+
include Virtus.model
|
410
|
+
|
411
|
+
attribute :scream, NoisyString
|
412
|
+
end
|
319
413
|
|
320
|
-
|
321
|
-
|
322
|
-
|
414
|
+
user = User.new(:scream => 'hello world!')
|
415
|
+
user.scream # => "HELLO WORLD!"
|
416
|
+
```
|
417
|
+
|
418
|
+
### Private Attributes
|
323
419
|
|
324
420
|
``` ruby
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
# Defining the Coercion method
|
334
|
-
module Virtus
|
335
|
-
class Coercion
|
336
|
-
class String < Virtus::Coercion::Object
|
337
|
-
def self.to_md5(value)
|
338
|
-
Digest::MD5.hexdigest value
|
339
|
-
end
|
340
|
-
end
|
421
|
+
class User
|
422
|
+
include Virtus.model
|
423
|
+
|
424
|
+
attribute :unique_id, String, :writer => :private
|
425
|
+
|
426
|
+
def set_unique_id(id)
|
427
|
+
self.unique_id = id
|
341
428
|
end
|
342
429
|
end
|
343
430
|
|
344
|
-
|
431
|
+
user = User.new(:unique_id => '1234-1234')
|
432
|
+
user.unique_id # => nil
|
433
|
+
|
434
|
+
user.unique_id = '1234-1234' # => NoMethodError: private method `unique_id='
|
435
|
+
|
436
|
+
user.set_unique_id('1234-1234')
|
437
|
+
user.unique_id # => '1234-1234'
|
438
|
+
```
|
439
|
+
|
440
|
+
Coercions
|
441
|
+
---------
|
442
|
+
|
443
|
+
Virtus uses [Coercible](https://github.com/solnic/coercible) for coercions. This
|
444
|
+
feature is turned on by default. You can turn it off for all attributes like that:
|
445
|
+
|
446
|
+
```ruby
|
447
|
+
# Turn coercions off globally
|
448
|
+
Virtus.coerce(false)
|
449
|
+
|
450
|
+
# ...or you can turn it off for a single attribute
|
345
451
|
class User
|
346
|
-
include Virtus
|
452
|
+
include Virtus.model
|
347
453
|
|
348
|
-
attribute :name, String
|
349
|
-
|
454
|
+
attribute :name, String, :coerce => false
|
455
|
+
end
|
456
|
+
```
|
457
|
+
|
458
|
+
You can configure coercers too:
|
459
|
+
|
460
|
+
```ruby
|
461
|
+
Virtus.coercer do |config|
|
462
|
+
config.string.boolean_map = { 'yup' => true, 'nope' => false }
|
350
463
|
end
|
351
464
|
|
352
|
-
|
353
|
-
|
354
|
-
|
465
|
+
# Virtus.coercer instance is used by default for all attributes.
|
466
|
+
# You *can* override it for a single attribute if you want:
|
467
|
+
|
468
|
+
my_cool_coercer = Coercible::Coercer.new do |config|
|
469
|
+
# some customization
|
470
|
+
end
|
471
|
+
|
472
|
+
class User
|
473
|
+
include Virtus.model
|
474
|
+
|
475
|
+
attribute :name, String, :coercer => my_cool_coercer
|
476
|
+
end
|
355
477
|
```
|
356
478
|
|
357
|
-
|
479
|
+
## Strict Coercion Mode
|
480
|
+
|
481
|
+
By default virtus returns input value even when it couldn't coerce it to expected type.
|
482
|
+
If you want to catch such cases in a noisy way you can use the strict mode in which
|
483
|
+
virtus raises an exception when it failed to coerce an input value.
|
358
484
|
|
359
485
|
``` ruby
|
360
|
-
|
486
|
+
class User
|
487
|
+
include Virtus.model(:strict => true)
|
361
488
|
|
362
|
-
|
489
|
+
attribute :admin, Boolean
|
490
|
+
end
|
363
491
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
primitive Hash
|
492
|
+
# this will raise an error
|
493
|
+
User.new :admin => "can't really say if true or false"
|
494
|
+
```
|
368
495
|
|
369
|
-
|
370
|
-
::JSON.parse value
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
496
|
+
## Building modules with custom configuration
|
374
497
|
|
375
|
-
|
376
|
-
include Virtus
|
498
|
+
You can also build Virtus modules that contain their own configuration.
|
377
499
|
|
378
|
-
|
379
|
-
|
500
|
+
```ruby
|
501
|
+
YupNopeBooleans = Virtus.model { |mod|
|
502
|
+
mod.coerce = true
|
503
|
+
mod.string.boolean_map = { 'yup' => true, 'nope' => false }
|
504
|
+
}
|
505
|
+
|
506
|
+
class User
|
507
|
+
include YupNopeBooleans
|
508
|
+
|
509
|
+
attribute :name, String
|
510
|
+
attribute :admin, Boolean
|
380
511
|
end
|
381
512
|
|
382
|
-
|
383
|
-
|
384
|
-
|
513
|
+
# Or just include the module straight away ...
|
514
|
+
class User
|
515
|
+
include Virtus.model(:coerce => false)
|
516
|
+
|
517
|
+
attribute :name, String
|
518
|
+
attribute :admin, Boolean
|
519
|
+
end
|
385
520
|
```
|
386
521
|
|
522
|
+
Please check out [Coercible README](https://github.com/solnic/coercible/blob/master/README.md)
|
523
|
+
for more information.
|
524
|
+
|
387
525
|
Credits
|
388
526
|
-------
|
389
527
|
|
@@ -409,7 +547,7 @@ Contributing
|
|
409
547
|
License
|
410
548
|
-------
|
411
549
|
|
412
|
-
Copyright (c) 2011-
|
550
|
+
Copyright (c) 2011-2013 Piotr Solnica
|
413
551
|
|
414
552
|
Permission is hereby granted, free of charge, to any person obtaining
|
415
553
|
a copy of this software and associated documentation files (the
|