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/lib/virtus/model.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
module Model
|
4
|
+
|
5
|
+
# @api private
|
6
|
+
def self.included(descendant)
|
7
|
+
super
|
8
|
+
descendant.send(:include, ClassInclusions) if Class === descendant
|
9
|
+
end
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
def self.extended(descendant)
|
13
|
+
super
|
14
|
+
descendant.extend(Extensions)
|
15
|
+
end
|
16
|
+
|
17
|
+
module Core
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
def self.included(descendant)
|
21
|
+
super
|
22
|
+
descendant.extend(ClassMethods)
|
23
|
+
descendant.send(:include, ClassInclusions::Methods)
|
24
|
+
descendant.send(:include, InstanceMethods)
|
25
|
+
end
|
26
|
+
private_class_method :included
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def self.extended(descendant)
|
30
|
+
super
|
31
|
+
descendant.extend(Extensions::Methods)
|
32
|
+
descendant.extend(InstanceMethods)
|
33
|
+
end
|
34
|
+
private_class_method :included
|
35
|
+
|
36
|
+
end # Core
|
37
|
+
|
38
|
+
module Constructor
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
def self.included(descendant)
|
42
|
+
super
|
43
|
+
descendant.send(:include, InstanceMethods::Constructor)
|
44
|
+
end
|
45
|
+
private_class_method :included
|
46
|
+
|
47
|
+
end # Constructor
|
48
|
+
|
49
|
+
module MassAssignment
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def self.included(descendant)
|
53
|
+
super
|
54
|
+
descendant.send(:include, InstanceMethods::MassAssignment)
|
55
|
+
end
|
56
|
+
private_class_method :included
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def self.extended(descendant)
|
60
|
+
super
|
61
|
+
descendant.extend(InstanceMethods::MassAssignment)
|
62
|
+
end
|
63
|
+
private_class_method :included
|
64
|
+
|
65
|
+
end # MassAssignment
|
66
|
+
|
67
|
+
end # Model
|
68
|
+
end # Virtus
|
@@ -0,0 +1,184 @@
|
|
1
|
+
module Virtus
|
2
|
+
|
3
|
+
# Class to build a Virtus module with it's own configuration
|
4
|
+
#
|
5
|
+
# This allows for individual Virtus modules to be included in
|
6
|
+
# classes and not impacted by the global Virtus configuration,
|
7
|
+
# which is implemented using Virtus::Configuration.
|
8
|
+
#
|
9
|
+
# @private
|
10
|
+
class ExtensionBuilder
|
11
|
+
|
12
|
+
# Return module
|
13
|
+
#
|
14
|
+
# @return [Module]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :module
|
18
|
+
|
19
|
+
# Return configuration
|
20
|
+
#
|
21
|
+
# @return [Configuration]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :configuration
|
25
|
+
|
26
|
+
# Builds a new Virtus module
|
27
|
+
#
|
28
|
+
# The block is passed to Virtus::Configuration
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# ModuleBuilder.call do |config|
|
32
|
+
# # config settings
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# @return [Module]
|
36
|
+
#
|
37
|
+
# @api public
|
38
|
+
def self.call(options = {}, &block)
|
39
|
+
config = Configuration.build(&block)
|
40
|
+
options.each { |key, value| config.public_send("#{key}=", value) }
|
41
|
+
builder = new(config)
|
42
|
+
builder.add_included_hook
|
43
|
+
builder.add_extended_hook
|
44
|
+
builder.module
|
45
|
+
end
|
46
|
+
|
47
|
+
# Initializes a new ModuleBuilder
|
48
|
+
#
|
49
|
+
# @param [Configuration] configuration
|
50
|
+
#
|
51
|
+
# @param [Module] mod
|
52
|
+
#
|
53
|
+
# @return [undefined]
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
def initialize(configuration, mod = Module.new)
|
57
|
+
@configuration = configuration
|
58
|
+
@module = mod
|
59
|
+
end
|
60
|
+
|
61
|
+
# Adds the .included hook to the anonymous module which then defines the
|
62
|
+
# .attribute method to override the default.
|
63
|
+
#
|
64
|
+
# @return [Module]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
def add_included_hook
|
68
|
+
attribute_proc = attribute_method(configuration)
|
69
|
+
constructor = configuration.constructor
|
70
|
+
mass_assignment = configuration.mass_assignment
|
71
|
+
extensions = core_extensions
|
72
|
+
inclusions = core_inclusions
|
73
|
+
|
74
|
+
self.module.define_singleton_method :included do |object|
|
75
|
+
super(object)
|
76
|
+
extensions.each { |mod| object.extend(mod) }
|
77
|
+
inclusions.each { |mod| object.send(:include, mod) }
|
78
|
+
object.send(:include, Model::Constructor) if constructor
|
79
|
+
object.send(:include, Model::MassAssignment) if mass_assignment
|
80
|
+
object.send(:define_singleton_method, :attribute, attribute_proc)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
def add_extended_hook
|
86
|
+
attribute_proc = attribute_method(configuration)
|
87
|
+
mass_assignment = configuration.mass_assignment
|
88
|
+
extensions = core_inclusions + core_extensions
|
89
|
+
|
90
|
+
self.module.define_singleton_method :extended do |object|
|
91
|
+
super(object)
|
92
|
+
extensions.each { |mod| object.extend(mod) }
|
93
|
+
object.extend(Model::MassAssignment) if mass_assignment
|
94
|
+
object.send :define_singleton_method, :attribute, attribute_proc
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Wrapper for the attribute method that is used in .add_included_hook
|
99
|
+
# The coercer is passed in the unused key :configured_coercer to allow the
|
100
|
+
# property encapsulation by Virtus::Attribute::Coercer, where the
|
101
|
+
# coercion method is known.
|
102
|
+
#
|
103
|
+
# @return [Proc(lambda)]
|
104
|
+
#
|
105
|
+
# @api private
|
106
|
+
def attribute_method(configuration)
|
107
|
+
module_options = self.module_options
|
108
|
+
|
109
|
+
lambda do |name, type, options = {}|
|
110
|
+
super(name, type, module_options.merge(options))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# @api private
|
115
|
+
def module_options
|
116
|
+
{ :coerce => configuration.coerce,
|
117
|
+
:strict => configuration.strict,
|
118
|
+
:configured_coercer => configuration.coercer }
|
119
|
+
end
|
120
|
+
|
121
|
+
# @api private
|
122
|
+
def core_inclusions
|
123
|
+
[Model::Core]
|
124
|
+
end
|
125
|
+
|
126
|
+
# @api private
|
127
|
+
def core_extensions
|
128
|
+
[]
|
129
|
+
end
|
130
|
+
|
131
|
+
end # class ExtensionBuilder
|
132
|
+
|
133
|
+
# @private
|
134
|
+
class ModelExtensionBuilder < ExtensionBuilder
|
135
|
+
end # ModelExtensionBuilder
|
136
|
+
|
137
|
+
# @private
|
138
|
+
class ModuleExtensionBuilder < ExtensionBuilder
|
139
|
+
|
140
|
+
# @api private
|
141
|
+
def add_included_hook
|
142
|
+
attribute_proc = attribute_method(configuration)
|
143
|
+
inclusions = core_inclusions
|
144
|
+
|
145
|
+
inclusions << Model::Constructor if configuration.constructor
|
146
|
+
inclusions << Model::MassAssignment if configuration.mass_assignment
|
147
|
+
|
148
|
+
self.module.define_singleton_method :included do |object|
|
149
|
+
super(object)
|
150
|
+
object.extend(ModuleExtensions)
|
151
|
+
object.instance_variable_set('@inclusions', inclusions)
|
152
|
+
object.send(:define_singleton_method, :attribute, attribute_proc)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end # ModuleExtensionBuilder
|
157
|
+
|
158
|
+
# @private
|
159
|
+
class ValueObjectExtensionBuilder < ExtensionBuilder
|
160
|
+
|
161
|
+
# @api private
|
162
|
+
def initialize(configuration, mod = Module.new)
|
163
|
+
super
|
164
|
+
@configuration.constructor = true
|
165
|
+
end
|
166
|
+
|
167
|
+
# @api private
|
168
|
+
def module_options
|
169
|
+
super.update(:writer => :private)
|
170
|
+
end
|
171
|
+
|
172
|
+
# @api private
|
173
|
+
def core_inclusions
|
174
|
+
super << ValueObject::AllowedWriterMethods << ValueObject::InstanceMethods
|
175
|
+
end
|
176
|
+
|
177
|
+
# @api private
|
178
|
+
def core_extensions
|
179
|
+
super << ValueObject::AllowedWriterMethods
|
180
|
+
end
|
181
|
+
|
182
|
+
end # ValueObjectBuilder
|
183
|
+
|
184
|
+
end # module Virtus
|
@@ -2,7 +2,21 @@ module Virtus
|
|
2
2
|
|
3
3
|
# Virtus module that can define attributes for later inclusion
|
4
4
|
#
|
5
|
+
# @private
|
5
6
|
module ModuleExtensions
|
7
|
+
include ConstMissingExtensions
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
def self.extended(mod)
|
11
|
+
super
|
12
|
+
setup(mod)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
def self.setup(mod, inclusions = [Model], attribute_definitions = [])
|
17
|
+
mod.instance_variable_set('@inclusions', inclusions)
|
18
|
+
mod.instance_variable_set('@attribute_definitions', attribute_definitions)
|
19
|
+
end
|
6
20
|
|
7
21
|
# Define an attribute in the module
|
8
22
|
#
|
@@ -11,12 +25,12 @@ module Virtus
|
|
11
25
|
# @return [self]
|
12
26
|
#
|
13
27
|
# @api private
|
14
|
-
def attribute(
|
15
|
-
attribute_definitions <<
|
28
|
+
def attribute(name, type, options = {})
|
29
|
+
@attribute_definitions << [name, type, options]
|
16
30
|
self
|
17
31
|
end
|
18
32
|
|
19
|
-
|
33
|
+
private
|
20
34
|
|
21
35
|
# Extend an object with Virtus methods and define attributes
|
22
36
|
#
|
@@ -27,8 +41,9 @@ module Virtus
|
|
27
41
|
# @api private
|
28
42
|
def extended(object)
|
29
43
|
super
|
30
|
-
object.extend(
|
44
|
+
@inclusions.each { |mod| object.extend(mod) }
|
31
45
|
define_attributes(object)
|
46
|
+
object.set_default_attributes
|
32
47
|
end
|
33
48
|
|
34
49
|
# Extend a class with Virtus methods and define attributes
|
@@ -40,17 +55,14 @@ module Virtus
|
|
40
55
|
# @api private
|
41
56
|
def included(object)
|
42
57
|
super
|
43
|
-
object.module_eval { include Virtus }
|
44
|
-
define_attributes(object)
|
45
|
-
end
|
46
58
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
59
|
+
if Class === object
|
60
|
+
@inclusions.each { |mod| object.send(:include, mod) }
|
61
|
+
define_attributes(object)
|
62
|
+
else
|
63
|
+
object.extend(ModuleExtensions)
|
64
|
+
ModuleExtensions.setup(object, @inclusions, @attribute_definitions)
|
65
|
+
end
|
54
66
|
end
|
55
67
|
|
56
68
|
# Define attributes on a class or instance
|
@@ -61,7 +73,7 @@ module Virtus
|
|
61
73
|
#
|
62
74
|
# @api private
|
63
75
|
def define_attributes(object)
|
64
|
-
attribute_definitions.each do |attribute_args|
|
76
|
+
@attribute_definitions.each do |attribute_args|
|
65
77
|
object.attribute(*attribute_args)
|
66
78
|
end
|
67
79
|
end
|
@@ -105,7 +105,7 @@ module Virtus
|
|
105
105
|
#
|
106
106
|
# @api public
|
107
107
|
def eql?(other)
|
108
|
-
instance_of?(other.class)
|
108
|
+
instance_of?(other.class) && cmp?(__method__, other)
|
109
109
|
end
|
110
110
|
|
111
111
|
# Compare the object with other object for equivalency
|
@@ -120,8 +120,7 @@ module Virtus
|
|
120
120
|
#
|
121
121
|
# @api public
|
122
122
|
def ==(other)
|
123
|
-
|
124
|
-
cmp?(__method__, other)
|
123
|
+
other.kind_of?(self.class) && cmp?(__method__, other)
|
125
124
|
end
|
126
125
|
|
127
126
|
end # module Methods
|
@@ -81,7 +81,7 @@ module Virtus
|
|
81
81
|
# @api private
|
82
82
|
def determine_type_from_primitive(primitive)
|
83
83
|
type = nil
|
84
|
-
descendants.reverse_each do |descendant|
|
84
|
+
descendants.select(&:primitive).reverse_each do |descendant|
|
85
85
|
descendant_primitive = descendant.primitive
|
86
86
|
next unless primitive <= descendant_primitive
|
87
87
|
type = descendant if type.nil? or type.primitive > descendant_primitive
|
data/lib/virtus/value_object.rb
CHANGED
@@ -31,10 +31,13 @@ module Virtus
|
|
31
31
|
#
|
32
32
|
# @api private
|
33
33
|
def self.included(base)
|
34
|
+
Virtus.warn "Virtus::ValueObject is deprecated and will be removed in 1.0.0 #{caller.first}"
|
35
|
+
|
34
36
|
base.instance_eval do
|
35
37
|
include ::Virtus
|
36
38
|
include InstanceMethods
|
37
39
|
extend ClassMethods
|
40
|
+
extend AllowedWriterMethods
|
38
41
|
private :attributes=
|
39
42
|
end
|
40
43
|
end
|
@@ -43,19 +46,6 @@ module Virtus
|
|
43
46
|
|
44
47
|
module InstanceMethods
|
45
48
|
|
46
|
-
# the #get_attributes method accept a Proc object that will filter
|
47
|
-
# out an attribute when the block returns false. the ValueObject
|
48
|
-
# needs all the attributes, so we allow every attribute.
|
49
|
-
FILTER_NONE = proc { true }
|
50
|
-
|
51
|
-
def initialize(attributes = {})
|
52
|
-
set_attributes(attributes)
|
53
|
-
end
|
54
|
-
|
55
|
-
def with(attribute_updates)
|
56
|
-
self.class.new(get_attributes(&FILTER_NONE).merge(attribute_updates))
|
57
|
-
end
|
58
|
-
|
59
49
|
# ValueObjects are immutable and can't be cloned
|
60
50
|
#
|
61
51
|
# They always represent the same value
|
@@ -74,6 +64,22 @@ module Virtus
|
|
74
64
|
|
75
65
|
end
|
76
66
|
|
67
|
+
module AllowedWriterMethods
|
68
|
+
# The list of writer methods that can be mass-assigned to in #attributes=
|
69
|
+
#
|
70
|
+
# @return [Set]
|
71
|
+
#
|
72
|
+
# @api private
|
73
|
+
def allowed_writer_methods
|
74
|
+
@allowed_writer_methods ||=
|
75
|
+
begin
|
76
|
+
allowed_writer_methods = super
|
77
|
+
allowed_writer_methods += attribute_set.map{|attr| "#{attr.name}="}
|
78
|
+
allowed_writer_methods.to_set.freeze
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
77
83
|
module ClassMethods
|
78
84
|
|
79
85
|
# Define an attribute on the receiver
|
@@ -94,10 +100,9 @@ module Virtus
|
|
94
100
|
# @return [self]
|
95
101
|
#
|
96
102
|
# @api public
|
97
|
-
def attribute(name,
|
103
|
+
def attribute(name, type, options = {})
|
98
104
|
equalizer << name
|
99
|
-
|
100
|
-
super name, *args << options.merge(:writer => :private)
|
105
|
+
super name, type, options.merge(:writer => :private)
|
101
106
|
end
|
102
107
|
|
103
108
|
# Define and include a module that provides Value Object semantics
|
@@ -116,26 +121,14 @@ module Virtus
|
|
116
121
|
def equalizer
|
117
122
|
@equalizer ||=
|
118
123
|
begin
|
119
|
-
equalizer = Equalizer.new(name || inspect)
|
124
|
+
equalizer = Virtus::Equalizer.new(name || inspect)
|
120
125
|
include equalizer
|
121
126
|
equalizer
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
125
|
-
# The list of writer methods that can be mass-assigned to in #attributes=
|
126
|
-
#
|
127
|
-
# @return [Set]
|
128
|
-
#
|
129
|
-
# @api private
|
130
|
-
def allowed_writer_methods
|
131
|
-
@allowed_writer_methods ||=
|
132
|
-
begin
|
133
|
-
allowed_writer_methods = super
|
134
|
-
allowed_writer_methods += attribute_set.map{|attr| "#{attr.name}="}
|
135
|
-
allowed_writer_methods.to_set.freeze
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
130
|
end # module ClassMethods
|
131
|
+
|
140
132
|
end # module ValueObject
|
133
|
+
|
141
134
|
end # module Virtus
|