virtus 0.5.5 → 1.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![
|
5
|
-
[![
|
6
|
-
[![
|
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
|
+
[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
|