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.
Files changed (268) hide show
  1. data/.rspec +1 -1
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +6 -8
  5. data/Gemfile +8 -2
  6. data/Gemfile.devtools +24 -30
  7. data/Guardfile +17 -6
  8. data/README.md +215 -77
  9. data/TODO.md +6 -0
  10. data/config/flay.yml +2 -2
  11. data/config/flog.yml +1 -1
  12. data/config/mutant.yml +12 -1
  13. data/config/reek.yml +57 -66
  14. data/lib/virtus.rb +126 -42
  15. data/lib/virtus/attribute.rb +52 -240
  16. data/lib/virtus/attribute/accessor.rb +91 -0
  17. data/lib/virtus/attribute/boolean.rb +11 -8
  18. data/lib/virtus/attribute/builder.rb +120 -0
  19. data/lib/virtus/attribute/coercer.rb +51 -0
  20. data/lib/virtus/attribute/coercible.rb +14 -0
  21. data/lib/virtus/attribute/collection.rb +44 -90
  22. data/lib/virtus/attribute/default_value/from_callable.rb +1 -1
  23. data/lib/virtus/attribute/default_value/from_clonable.rb +1 -6
  24. data/lib/virtus/attribute/default_value/from_symbol.rb +3 -3
  25. data/lib/virtus/attribute/embedded_value.rb +37 -28
  26. data/lib/virtus/attribute/hash.rb +69 -71
  27. data/lib/virtus/attribute/lazy_default.rb +18 -0
  28. data/lib/virtus/attribute/strict.rb +16 -0
  29. data/lib/virtus/attribute_set.rb +81 -9
  30. data/lib/virtus/class_inclusions.rb +24 -17
  31. data/lib/virtus/class_methods.rb +13 -31
  32. data/lib/virtus/configuration.rb +77 -0
  33. data/lib/virtus/const_missing_extensions.rb +16 -0
  34. data/lib/virtus/extensions.rb +86 -61
  35. data/lib/virtus/instance_methods.rb +107 -128
  36. data/lib/virtus/model.rb +68 -0
  37. data/lib/virtus/module_builder.rb +184 -0
  38. data/lib/virtus/module_extensions.rb +27 -15
  39. data/lib/virtus/support/equalizer.rb +2 -3
  40. data/lib/virtus/support/type_lookup.rb +1 -1
  41. data/lib/virtus/value_object.rb +24 -31
  42. data/lib/virtus/version.rb +1 -1
  43. data/spec/integration/building_module_spec.rb +68 -0
  44. data/spec/integration/custom_attributes_spec.rb +8 -15
  45. data/spec/integration/custom_collection_attributes_spec.rb +101 -0
  46. data/spec/integration/default_values_spec.rb +9 -2
  47. data/spec/integration/defining_attributes_spec.rb +2 -2
  48. data/spec/integration/using_modules_spec.rb +5 -3
  49. data/spec/shared/freeze_method_behavior.rb +2 -2
  50. data/spec/shared/options_class_method.rb +1 -1
  51. data/spec/spec_helper.rb +25 -5
  52. data/spec/unit/virtus/attribute/boolean/value_coerced_predicate_spec.rb +25 -0
  53. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +115 -22
  54. data/spec/unit/virtus/attribute/class_methods/coerce_spec.rb +32 -0
  55. data/spec/unit/virtus/attribute/coerce_spec.rb +38 -21
  56. data/spec/unit/virtus/attribute/coercible_predicate_spec.rb +20 -0
  57. data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +84 -0
  58. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +37 -24
  59. data/spec/unit/virtus/attribute/custom_collection_spec.rb +23 -0
  60. data/spec/unit/virtus/attribute/embedded_value/class_methods/build_spec.rb +37 -0
  61. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +46 -10
  62. data/spec/unit/virtus/attribute/get_spec.rb +15 -63
  63. data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +80 -0
  64. data/spec/unit/virtus/attribute/hash/coerce_spec.rb +75 -13
  65. data/spec/unit/virtus/attribute/lazy_predicate_spec.rb +20 -0
  66. data/spec/unit/virtus/attribute/set_default_value_spec.rb +74 -0
  67. data/spec/unit/virtus/attribute/set_spec.rb +16 -36
  68. data/spec/unit/virtus/attribute/value_coerced_predicate_spec.rb +19 -0
  69. data/spec/unit/virtus/attribute_set/append_spec.rb +3 -5
  70. data/spec/unit/virtus/attribute_set/define_reader_method_spec.rb +1 -1
  71. data/spec/unit/virtus/attribute_set/define_writer_method_spec.rb +1 -1
  72. data/spec/unit/virtus/attribute_set/each_spec.rb +3 -3
  73. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +1 -1
  74. data/spec/unit/virtus/attribute_set/element_set_spec.rb +4 -4
  75. data/spec/unit/virtus/attribute_set/merge_spec.rb +10 -16
  76. data/spec/unit/virtus/attribute_set/reset_spec.rb +6 -10
  77. data/spec/unit/virtus/attribute_spec.rb +222 -0
  78. data/spec/unit/virtus/attributes_reader_spec.rb +41 -0
  79. data/spec/unit/virtus/attributes_writer_spec.rb +51 -0
  80. data/spec/unit/virtus/class_methods/new_spec.rb +39 -0
  81. data/spec/unit/virtus/config_spec.rb +13 -0
  82. data/spec/unit/virtus/element_reader_spec.rb +21 -0
  83. data/spec/unit/virtus/element_writer_spec.rb +19 -0
  84. data/spec/unit/virtus/freeze_spec.rb +21 -0
  85. data/spec/unit/virtus/model_spec.rb +134 -0
  86. data/spec/unit/virtus/module_spec.rb +76 -0
  87. data/spec/unit/virtus/set_default_attributes_spec.rb +25 -0
  88. data/spec/unit/virtus/value_object_spec.rb +105 -0
  89. data/virtus.gemspec +4 -2
  90. metadata +82 -191
  91. data/.rvmrc +0 -1
  92. data/TODO +0 -1
  93. data/config/roodi.yml +0 -17
  94. data/lib/virtus/attribute/array.rb +0 -24
  95. data/lib/virtus/attribute/class.rb +0 -21
  96. data/lib/virtus/attribute/date.rb +0 -34
  97. data/lib/virtus/attribute/date_time.rb +0 -36
  98. data/lib/virtus/attribute/decimal.rb +0 -21
  99. data/lib/virtus/attribute/embedded_value/from_open_struct.rb +0 -19
  100. data/lib/virtus/attribute/embedded_value/from_struct.rb +0 -19
  101. data/lib/virtus/attribute/float.rb +0 -30
  102. data/lib/virtus/attribute/integer.rb +0 -27
  103. data/lib/virtus/attribute/numeric.rb +0 -11
  104. data/lib/virtus/attribute/object.rb +0 -11
  105. data/lib/virtus/attribute/set.rb +0 -24
  106. data/lib/virtus/attribute/string.rb +0 -24
  107. data/lib/virtus/attribute/symbol.rb +0 -21
  108. data/lib/virtus/attribute/time.rb +0 -36
  109. data/lib/virtus/coercion.rb +0 -32
  110. data/lib/virtus/coercion/array.rb +0 -23
  111. data/lib/virtus/coercion/date.rb +0 -26
  112. data/lib/virtus/coercion/date_time.rb +0 -26
  113. data/lib/virtus/coercion/decimal.rb +0 -40
  114. data/lib/virtus/coercion/false_class.rb +0 -24
  115. data/lib/virtus/coercion/float.rb +0 -39
  116. data/lib/virtus/coercion/hash.rb +0 -71
  117. data/lib/virtus/coercion/integer.rb +0 -83
  118. data/lib/virtus/coercion/numeric.rb +0 -66
  119. data/lib/virtus/coercion/object.rb +0 -125
  120. data/lib/virtus/coercion/string.rb +0 -218
  121. data/lib/virtus/coercion/symbol.rb +0 -24
  122. data/lib/virtus/coercion/time.rb +0 -40
  123. data/lib/virtus/coercion/time_coercions.rb +0 -86
  124. data/lib/virtus/coercion/true_class.rb +0 -24
  125. data/spec/unit/virtus/attribute/array/coerce_spec.rb +0 -13
  126. data/spec/unit/virtus/attribute/boolean/coerce_spec.rb +0 -85
  127. data/spec/unit/virtus/attribute/boolean/define_reader_method_spec.rb +0 -15
  128. data/spec/unit/virtus/attribute/boolean/value_coerced_spec.rb +0 -97
  129. data/spec/unit/virtus/attribute/boolean_spec.rb +0 -19
  130. data/spec/unit/virtus/attribute/class/coerce_spec.rb +0 -13
  131. data/spec/unit/virtus/attribute/class_methods/accessor_spec.rb +0 -12
  132. data/spec/unit/virtus/attribute/class_methods/coercion_method_spec.rb +0 -9
  133. data/spec/unit/virtus/attribute/class_methods/default_spec.rb +0 -9
  134. data/spec/unit/virtus/attribute/class_methods/determine_type_spec.rb +0 -117
  135. data/spec/unit/virtus/attribute/class_methods/merge_options_spec.rb +0 -11
  136. data/spec/unit/virtus/attribute/class_methods/primitive_spec.rb +0 -9
  137. data/spec/unit/virtus/attribute/class_methods/reader_spec.rb +0 -9
  138. data/spec/unit/virtus/attribute/class_methods/writer_spec.rb +0 -9
  139. data/spec/unit/virtus/attribute/coercion_method_spec.rb +0 -12
  140. data/spec/unit/virtus/attribute/collection/class_methods/merge_options_spec.rb +0 -40
  141. data/spec/unit/virtus/attribute/collection/coerce_and_append_member_spec.rb +0 -16
  142. data/spec/unit/virtus/attribute/collection/member_coercion/coerce_and_append_member_spec.rb +0 -18
  143. data/spec/unit/virtus/attribute/collection/member_type_spec.rb +0 -17
  144. data/spec/unit/virtus/attribute/collection/new_collection_spec.rb +0 -9
  145. data/spec/unit/virtus/attribute/date/coerce_spec.rb +0 -47
  146. data/spec/unit/virtus/attribute/date/value_coerced_spec.rb +0 -46
  147. data/spec/unit/virtus/attribute/date_time/coerce_spec.rb +0 -80
  148. data/spec/unit/virtus/attribute/decimal/coerce_spec.rb +0 -123
  149. data/spec/unit/virtus/attribute/default_spec.rb +0 -28
  150. data/spec/unit/virtus/attribute/default_value/call_spec.rb +0 -21
  151. data/spec/unit/virtus/attribute/default_value/class_methods/build_spec.rb +0 -23
  152. data/spec/unit/virtus/attribute/default_value/class_methods/new_spec.rb +0 -21
  153. data/spec/unit/virtus/attribute/default_value/from_callable/call_spec.rb +0 -19
  154. data/spec/unit/virtus/attribute/default_value/from_callable/class_methods/handle_spec.rb +0 -17
  155. data/spec/unit/virtus/attribute/default_value/from_clonable/call_spec.rb +0 -20
  156. data/spec/unit/virtus/attribute/default_value/from_clonable/class_methods/handle_spec.rb +0 -19
  157. data/spec/unit/virtus/attribute/default_value/from_symbol/call_spec.rb +0 -17
  158. data/spec/unit/virtus/attribute/default_value/from_symbol/class_methods/handle_spec.rb +0 -17
  159. data/spec/unit/virtus/attribute/default_value/value_spec.rb +0 -10
  160. data/spec/unit/virtus/attribute/define_accessor_methods_spec.rb +0 -26
  161. data/spec/unit/virtus/attribute/define_reader_method_spec.rb +0 -24
  162. data/spec/unit/virtus/attribute/define_writer_method_spec.rb +0 -24
  163. data/spec/unit/virtus/attribute/embedded_value/class_methods/determine_type_spec.rb +0 -23
  164. data/spec/unit/virtus/attribute/embedded_value/class_methods/merge_options_spec.rb +0 -17
  165. data/spec/unit/virtus/attribute/embedded_value/from_open_struct/coerce_spec.rb +0 -34
  166. data/spec/unit/virtus/attribute/embedded_value/from_struct/coerce_spec.rb +0 -34
  167. data/spec/unit/virtus/attribute/float/coerce_spec.rb +0 -123
  168. data/spec/unit/virtus/attribute/hash/class_methods/merge_options_spec.rb +0 -33
  169. data/spec/unit/virtus/attribute/hash/key_type_spec.rb +0 -10
  170. data/spec/unit/virtus/attribute/hash/value_type_spec.rb +0 -10
  171. data/spec/unit/virtus/attribute/inspect_spec.rb +0 -27
  172. data/spec/unit/virtus/attribute/integer/coerce_spec.rb +0 -117
  173. data/spec/unit/virtus/attribute/name_spec.rb +0 -12
  174. data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +0 -15
  175. data/spec/unit/virtus/attribute/numeric/class_methods/max_spec.rb +0 -9
  176. data/spec/unit/virtus/attribute/numeric/class_methods/min_spec.rb +0 -9
  177. data/spec/unit/virtus/attribute/options_spec.rb +0 -14
  178. data/spec/unit/virtus/attribute/public_reader_spec.rb +0 -24
  179. data/spec/unit/virtus/attribute/public_writer_spec.rb +0 -24
  180. data/spec/unit/virtus/attribute/set/coerce_spec.rb +0 -13
  181. data/spec/unit/virtus/attribute/string/coerce_spec.rb +0 -11
  182. data/spec/unit/virtus/attribute/symbol/coerce_spec.rb +0 -13
  183. data/spec/unit/virtus/attribute/time/coerce_spec.rb +0 -67
  184. data/spec/unit/virtus/attribute/value_coerced_spec.rb +0 -19
  185. data/spec/unit/virtus/class_methods/attribute_set_spec.rb +0 -9
  186. data/spec/unit/virtus/class_methods/attribute_spec.rb +0 -30
  187. data/spec/unit/virtus/class_methods/attributes_spec.rb +0 -22
  188. data/spec/unit/virtus/class_methods/const_missing_spec.rb +0 -27
  189. data/spec/unit/virtus/class_methods/inherited_spec.rb +0 -21
  190. data/spec/unit/virtus/coercion/array/class_methods/to_set_spec.rb +0 -12
  191. data/spec/unit/virtus/coercion/class_methods/element_reference_spec.rb +0 -17
  192. data/spec/unit/virtus/coercion/class_methods/primitive_spec.rb +0 -13
  193. data/spec/unit/virtus/coercion/date/class_methods/to_date_spec.rb +0 -10
  194. data/spec/unit/virtus/coercion/date/class_methods/to_datetime_spec.rb +0 -30
  195. data/spec/unit/virtus/coercion/date/class_methods/to_string_spec.rb +0 -12
  196. data/spec/unit/virtus/coercion/date/class_methods/to_time_spec.rb +0 -12
  197. data/spec/unit/virtus/coercion/date_time/class_methods/to_date_spec.rb +0 -30
  198. data/spec/unit/virtus/coercion/date_time/class_methods/to_datetime_spec.rb +0 -10
  199. data/spec/unit/virtus/coercion/date_time/class_methods/to_string_spec.rb +0 -12
  200. data/spec/unit/virtus/coercion/date_time/class_methods/to_time_spec.rb +0 -30
  201. data/spec/unit/virtus/coercion/decimal/class_methods/to_decimal_spec.rb +0 -9
  202. data/spec/unit/virtus/coercion/decimal/class_methods/to_float_spec.rb +0 -12
  203. data/spec/unit/virtus/coercion/decimal/class_methods/to_integer_spec.rb +0 -12
  204. data/spec/unit/virtus/coercion/decimal/class_methods/to_string_spec.rb +0 -12
  205. data/spec/unit/virtus/coercion/false_class/class_methods/to_string_spec.rb +0 -12
  206. data/spec/unit/virtus/coercion/float/class_methods/to_decimal_spec.rb +0 -12
  207. data/spec/unit/virtus/coercion/float/class_methods/to_float_spec.rb +0 -9
  208. data/spec/unit/virtus/coercion/float/class_methods/to_integer_spec.rb +0 -12
  209. data/spec/unit/virtus/coercion/float/class_methods/to_string_spec.rb +0 -12
  210. data/spec/unit/virtus/coercion/hash/class_methods/to_date_spec.rb +0 -38
  211. data/spec/unit/virtus/coercion/hash/class_methods/to_datetime_spec.rb +0 -38
  212. data/spec/unit/virtus/coercion/hash/class_methods/to_time_spec.rb +0 -38
  213. data/spec/unit/virtus/coercion/integer/class_methods/to_boolean_spec.rb +0 -25
  214. data/spec/unit/virtus/coercion/integer/class_methods/to_decimal_spec.rb +0 -12
  215. data/spec/unit/virtus/coercion/integer/class_methods/to_float_spec.rb +0 -12
  216. data/spec/unit/virtus/coercion/integer/class_methods/to_integer_spec.rb +0 -9
  217. data/spec/unit/virtus/coercion/integer/class_methods/to_string_spec.rb +0 -12
  218. data/spec/unit/virtus/coercion/numeric/class_methods/to_decimal_spec.rb +0 -10
  219. data/spec/unit/virtus/coercion/numeric/class_methods/to_float_spec.rb +0 -10
  220. data/spec/unit/virtus/coercion/numeric/class_methods/to_integer_spec.rb +0 -10
  221. data/spec/unit/virtus/coercion/numeric/class_methods/to_string_spec.rb +0 -12
  222. data/spec/unit/virtus/coercion/object/class_methods/method_missing_spec.rb +0 -33
  223. data/spec/unit/virtus/coercion/object/class_methods/to_array_spec.rb +0 -51
  224. data/spec/unit/virtus/coercion/object/class_methods/to_hash_spec.rb +0 -22
  225. data/spec/unit/virtus/coercion/object/class_methods/to_integer_spec.rb +0 -22
  226. data/spec/unit/virtus/coercion/object/class_methods/to_string_spec.rb +0 -22
  227. data/spec/unit/virtus/coercion/string/class_methods/to_boolean_spec.rb +0 -29
  228. data/spec/unit/virtus/coercion/string/class_methods/to_constant_spec.rb +0 -49
  229. data/spec/unit/virtus/coercion/string/class_methods/to_date_spec.rb +0 -23
  230. data/spec/unit/virtus/coercion/string/class_methods/to_datetime_spec.rb +0 -50
  231. data/spec/unit/virtus/coercion/string/class_methods/to_decimal_spec.rb +0 -47
  232. data/spec/unit/virtus/coercion/string/class_methods/to_float_spec.rb +0 -57
  233. data/spec/unit/virtus/coercion/string/class_methods/to_integer_spec.rb +0 -68
  234. data/spec/unit/virtus/coercion/string/class_methods/to_symbol_spec.rb +0 -9
  235. data/spec/unit/virtus/coercion/string/class_methods/to_time_spec.rb +0 -50
  236. data/spec/unit/virtus/coercion/symbol/class_methods/to_string_spec.rb +0 -12
  237. data/spec/unit/virtus/coercion/time/class_methods/to_integer_spec.rb +0 -10
  238. data/spec/unit/virtus/coercion/time/class_methods/to_time_spec.rb +0 -10
  239. data/spec/unit/virtus/coercion/time_coercions/to_date_spec.rb +0 -33
  240. data/spec/unit/virtus/coercion/time_coercions/to_datetime_spec.rb +0 -33
  241. data/spec/unit/virtus/coercion/time_coercions/to_string_spec.rb +0 -18
  242. data/spec/unit/virtus/coercion/time_coercions/to_time_spec.rb +0 -33
  243. data/spec/unit/virtus/coercion/true_class/class_methods/to_string_spec.rb +0 -12
  244. data/spec/unit/virtus/equalizer/append_spec.rb +0 -82
  245. data/spec/unit/virtus/equalizer/class_method/new_spec.rb +0 -111
  246. data/spec/unit/virtus/equalizer/methods/eql_spec.rb +0 -47
  247. data/spec/unit/virtus/equalizer/methods/equal_value_spec.rb +0 -57
  248. data/spec/unit/virtus/extensions/allowed_writer_methods_spec.rb +0 -25
  249. data/spec/unit/virtus/extensions/attribute_spec.rb +0 -26
  250. data/spec/unit/virtus/instance_methods/attributes_spec.rb +0 -140
  251. data/spec/unit/virtus/instance_methods/element_reference_spec.rb +0 -24
  252. data/spec/unit/virtus/instance_methods/element_set_spec.rb +0 -28
  253. data/spec/unit/virtus/instance_methods/freeze_spec.rb +0 -64
  254. data/spec/unit/virtus/instance_methods/initialize_spec.rb +0 -48
  255. data/spec/unit/virtus/instance_methods/to_hash_spec.rb +0 -23
  256. data/spec/unit/virtus/module_extensions/attribute_spec.rb +0 -31
  257. data/spec/unit/virtus/options/accept_options_spec.rb +0 -37
  258. data/spec/unit/virtus/options/accepted_options_spec.rb +0 -21
  259. data/spec/unit/virtus/options/options_spec.rb +0 -34
  260. data/spec/unit/virtus/type_lookup/class_methods/extended_spec.rb +0 -9
  261. data/spec/unit/virtus/type_lookup/determine_type_spec.rb +0 -81
  262. data/spec/unit/virtus/type_lookup/primitive_spec.rb +0 -9
  263. data/spec/unit/virtus/value_object/class_methods/allowed_writer_methods_spec.rb +0 -15
  264. data/spec/unit/virtus/value_object/class_methods/attribute_spec.rb +0 -50
  265. data/spec/unit/virtus/value_object/class_methods/equalizer_spec.rb +0 -24
  266. data/spec/unit/virtus/value_object/initialize_spec.rb +0 -19
  267. data/spec/unit/virtus/value_object/instance_methods/clone_spec.rb +0 -21
  268. data/spec/unit/virtus/value_object/instance_methods/with_spec.rb +0 -31
data/TODO.md ADDED
@@ -0,0 +1,6 @@
1
+ 1.0.0.rc ROADMAP:
2
+
3
+ - Refactor to use soon-to-be-extracted axiom-types
4
+ - Add ability to pass in custom reader/writer *objects*
5
+ - Refactor to use extracted equalizer gem
6
+ - Tune Adamantium usage to memoize common methods in Attribute
@@ -1,3 +1,3 @@
1
1
  ---
2
- threshold: 18
3
- total_score: 340
2
+ threshold: 13
3
+ total_score: 321
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 18.2
2
+ threshold: 21.4
@@ -1,3 +1,14 @@
1
1
  ---
2
2
  name: virtus
3
- namespace: Virtus
3
+ namespace:
4
+ - 'Virtus::Attribute'
5
+ - 'Virtus::AttributeSet'
6
+ - 'Virtus::ClassInclusions'
7
+ - 'Virtus::ClassMethods'
8
+ - 'Virtus::Configuration'
9
+ - 'Virtus::ConstMissingExtensions'
10
+ - 'Virtus::Extensions'
11
+ - 'Virtus::InstanceMethods'
12
+ - 'Virtus::ModuleBuilder'
13
+ - 'Virtus::ModuleExtensions'
14
+ - 'Virtus::ValueObject'
@@ -1,105 +1,96 @@
1
1
  ---
2
- UncommunicativeParameterName:
3
- accept: []
2
+ Attribute:
3
+ enabled: true
4
4
  exclude: []
5
+ BooleanParameter:
5
6
  enabled: true
6
- reject:
7
- - !ruby/regexp /^.$/
8
- - !ruby/regexp /[0-9]$/
9
- - !ruby/regexp /[A-Z]/
10
- LargeClass:
11
- max_methods: 14
12
7
  exclude: []
8
+ ClassVariable:
13
9
  enabled: true
14
- max_instance_variables: 8
15
- UncommunicativeMethodName:
16
- accept: []
17
10
  exclude: []
11
+ ControlParameter:
18
12
  enabled: true
19
- reject:
20
- - !ruby/regexp /^[a-z]$/
21
- - !ruby/regexp /[0-9]$/
22
- - !ruby/regexp /[A-Z]/
23
- LongParameterList:
24
- max_params: 3
25
13
  exclude: []
14
+ DataClump:
26
15
  enabled: true
27
- overrides: {}
16
+ exclude: []
17
+ max_copies: 2
18
+ min_clump_size: 2
19
+ DuplicateMethodCall:
20
+ enabled: false
28
21
  FeatureEnvy:
29
- exclude: [
30
- Virtus::Attribute::Boolean#value_coerced?,
31
- Virtus::ClassMethods#build_attribute,
32
- Virtus::Coercion::TimeCoercions#to_string,
33
- Virtus::Coercion::TimeCoercions#coerce_with_method,
34
- Virtus::TypeLookup#determine_type_from_primitive,
35
- Virtus::ValueObject::ClassMethods#attribute
36
- ]
37
22
  enabled: true
38
- ClassVariable:
39
23
  exclude: []
24
+ IrresponsibleModule:
40
25
  enabled: true
41
- BooleanParameter:
42
26
  exclude: []
27
+ LongParameterList:
43
28
  enabled: true
44
- IrresponsibleModule:
45
29
  exclude: []
30
+ max_params: 2
31
+ LongYieldList:
46
32
  enabled: true
47
- UncommunicativeModuleName:
48
- accept: []
49
33
  exclude: []
50
- enabled: true
51
- reject:
52
- - !ruby/regexp /^.$/
53
- - !ruby/regexp /[0-9]$/
34
+ max_params: 2
54
35
  NestedIterators:
36
+ enabled: true
37
+ max_allowed_nesting: 1
55
38
  ignore_iterators: []
56
39
  exclude: []
40
+ NilCheck:
57
41
  enabled: true
58
- max_allowed_nesting: 2
59
- LongMethod:
60
- max_statements: 6
61
42
  exclude: []
43
+ RepeatedConditional:
62
44
  enabled: true
63
- Duplication:
64
- allow_calls: []
65
- exclude: [
66
- Virtus::Attribute::DefaultValue#evaluate
67
- ]
45
+ exclude: []
46
+ max_ifs: 1
47
+ TooManyInstanceVariables:
68
48
  enabled: true
69
- max_calls: 1
70
- UtilityFunction:
71
- max_helper_calls: 1
72
- exclude: [
73
- Virtus::Attribute::Boolean#value_coerced?,
74
- Virtus::ClassMethods#build_attribute
75
- ]
49
+ exclude: []
50
+ max_instance_variables: 3
51
+ TooManyMethods:
76
52
  enabled: true
77
- Attribute:
78
53
  exclude: []
79
- enabled: false
80
- UncommunicativeVariableName:
81
- accept: []
54
+ max_methods: 10
55
+ TooManyStatements:
56
+ enabled: true
82
57
  exclude: []
58
+ max_statements: 4
59
+ UncommunicativeMethodName:
83
60
  enabled: true
61
+ exclude: []
84
62
  reject:
85
- - !ruby/regexp /^.$/
63
+ - !ruby/regexp /^[a-z]$/
86
64
  - !ruby/regexp /[0-9]$/
87
65
  - !ruby/regexp /[A-Z]/
88
- SimulatedPolymorphism:
66
+ accept: []
67
+ UncommunicativeModuleName:
68
+ enabled: true
89
69
  exclude: []
70
+ reject:
71
+ - !ruby/regexp /^.$/
72
+ - !ruby/regexp /[0-9]$/
73
+ accept: []
74
+ UncommunicativeParameterName:
90
75
  enabled: true
91
- max_ifs: 1
92
- DataClump:
93
76
  exclude: []
77
+ reject:
78
+ - !ruby/regexp /^.$/
79
+ - !ruby/regexp /[0-9]$/
80
+ - !ruby/regexp /[A-Z]/
81
+ accept: []
82
+ UncommunicativeVariableName:
94
83
  enabled: true
95
- max_copies: 2
96
- min_clump_size: 2
97
- ControlCouple:
98
- exclude: [
99
- 'Virtus::InstanceMethods#initialize'
100
- ]
84
+ exclude: []
85
+ reject:
86
+ - !ruby/regexp /^.$/
87
+ - !ruby/regexp /[0-9]$/
88
+ - !ruby/regexp /[A-Z]/
89
+ accept: []
90
+ UnusedParameters:
101
91
  enabled: true
102
- LongYieldList:
103
- max_params: 1
104
92
  exclude: []
93
+ UtilityFunction:
105
94
  enabled: true
95
+ exclude: []
96
+ max_helper_calls: 0
@@ -1,10 +1,4 @@
1
- require 'set'
2
- require 'date'
3
- require 'time'
4
- require 'bigdecimal'
5
- require 'bigdecimal/util'
6
1
  require 'ostruct'
7
- require 'backports'
8
2
 
9
3
  # Base module which adds Attribute API to your classes
10
4
  module Virtus
@@ -18,7 +12,7 @@ module Virtus
18
12
 
19
13
  # Extends base class or a module with virtus methods
20
14
  #
21
- # @param [Class] descendant
15
+ # @param [Object] object
22
16
  #
23
17
  # @return [undefined]
24
18
  #
@@ -26,8 +20,10 @@ module Virtus
26
20
  def self.included(object)
27
21
  super
28
22
  if Class === object
23
+ Virtus.warn("including Virtus module is deprecated. Use 'include Virtus.model' instead #{caller.first}")
29
24
  object.send(:include, ClassInclusions)
30
25
  else
26
+ Virtus.warn("including Virtus module is deprecated. Use 'include Virtus.module' instead #{caller.first}")
31
27
  object.extend(ModuleExtensions)
32
28
  end
33
29
  end
@@ -41,22 +37,135 @@ module Virtus
41
37
  #
42
38
  # @api private
43
39
  def self.extended(object)
40
+ Virtus.warn("extending with Virtus module is deprecated. Use 'extend(Virtus.model)' instead #{caller.first}")
44
41
  object.extend(Extensions)
45
42
  end
46
43
  private_class_method :extended
47
44
 
45
+ # Sets the global coercer configuration
46
+ #
47
+ # @example
48
+ # Virtus.coercer do |config|
49
+ # config.string.boolean_map = { true => '1', false => '0' }
50
+ # end
51
+ #
52
+ # @return [Coercible::Coercer]
53
+ #
54
+ # @api public
55
+ def self.coercer(&block)
56
+ configuration.coercer(&block)
57
+ end
58
+
59
+ # Sets the global coercion configuration value
60
+ #
61
+ # @param [Boolean] value
62
+ #
63
+ # @return [Virtus]
64
+ #
65
+ # @api public
66
+ def self.coerce=(value)
67
+ configuration.coerce = value
68
+ self
69
+ end
70
+
71
+ # Returns the global coercion setting
72
+ #
73
+ # @return [Boolean]
74
+ #
75
+ # @api public
76
+ def self.coerce
77
+ configuration.coerce
78
+ end
79
+
80
+ # Provides access to the global Virtus configuration
81
+ #
82
+ # @example
83
+ # Virtus.config do |config|
84
+ # config.coerce = false
85
+ # end
86
+ #
87
+ # @return [Configuration]
88
+ #
89
+ # @api public
90
+ def self.config(&block)
91
+ configuration.call(&block)
92
+ end
93
+
94
+ # Provides access to the Virtus module builder
95
+ # see Virtus::ModuleBuilder
96
+ #
97
+ # @example
98
+ # MyVirtusModule = Virtus.module { |mod|
99
+ # mod.coerce = true
100
+ # mod.string.boolean_map = { 'yup' => true, 'nope' => false }
101
+ # }
102
+ #
103
+ # class Book
104
+ # include MyVirtusModule
105
+ #
106
+ # attribute :published, Boolean
107
+ # end
108
+ #
109
+ # # This could be made more succinct as well
110
+ # class OtherBook
111
+ # include Virtus.module { |m| m.coerce = false }
112
+ # end
113
+ #
114
+ # @return [Module]
115
+ #
116
+ # @api public
117
+ def self.model(options = {}, &block)
118
+ ModelExtensionBuilder.call(options, &block)
119
+ end
120
+
121
+ # Builds a module for...modules
122
+ #
123
+ # @api public
124
+ def self.module(options = {}, &block)
125
+ ModuleExtensionBuilder.call(options, &block)
126
+ end
127
+
128
+ # Builds a module for value object models
129
+ #
130
+ # @api public
131
+ def self.value_object(options = {}, &block)
132
+ ValueObjectExtensionBuilder.call(options, &block)
133
+ end
134
+
135
+ # Global configuration instance
136
+ #
137
+ # @ return [Configuration]
138
+ #
139
+ # @api private
140
+ def self.configuration
141
+ @configuration ||= Configuration.new
142
+ end
143
+
144
+ # @api private
145
+ def self.warn(msg)
146
+ Kernel.warn(msg)
147
+ end
148
+
48
149
  end # module Virtus
49
150
 
50
151
  require 'descendants_tracker'
152
+ require 'equalizer'
153
+ require 'axiom-types'
154
+ require 'coercible'
51
155
 
52
- require 'virtus/support/type_lookup'
53
- require 'virtus/support/options'
54
156
  require 'virtus/support/equalizer'
157
+ require 'virtus/support/options'
158
+ require 'virtus/support/type_lookup'
55
159
 
160
+ require 'virtus/model'
56
161
  require 'virtus/extensions'
162
+ require 'virtus/const_missing_extensions'
57
163
  require 'virtus/class_inclusions'
58
164
  require 'virtus/module_extensions'
59
165
 
166
+ require 'virtus/configuration'
167
+ require 'virtus/module_builder'
168
+
60
169
  require 'virtus/class_methods'
61
170
  require 'virtus/instance_methods'
62
171
 
@@ -64,45 +173,20 @@ require 'virtus/value_object'
64
173
 
65
174
  require 'virtus/attribute_set'
66
175
 
67
- require 'virtus/coercion'
68
- require 'virtus/coercion/object'
69
- require 'virtus/coercion/numeric'
70
- require 'virtus/coercion/integer'
71
- require 'virtus/coercion/float'
72
- require 'virtus/coercion/decimal'
73
- require 'virtus/coercion/false_class'
74
- require 'virtus/coercion/true_class'
75
- require 'virtus/coercion/hash'
76
- require 'virtus/coercion/array'
77
- require 'virtus/coercion/time_coercions'
78
- require 'virtus/coercion/date'
79
- require 'virtus/coercion/date_time'
80
- require 'virtus/coercion/time'
81
- require 'virtus/coercion/string'
82
- require 'virtus/coercion/symbol'
83
-
84
176
  require 'virtus/attribute/default_value'
85
177
  require 'virtus/attribute/default_value/from_clonable'
86
178
  require 'virtus/attribute/default_value/from_callable'
87
179
  require 'virtus/attribute/default_value/from_symbol'
88
180
 
89
181
  require 'virtus/attribute'
90
- require 'virtus/attribute/object'
91
- require 'virtus/attribute/class'
92
- require 'virtus/attribute/collection'
93
- require 'virtus/attribute/array'
94
- require 'virtus/attribute/set'
182
+ require 'virtus/attribute/builder'
183
+ require 'virtus/attribute/coercer'
184
+ require 'virtus/attribute/accessor'
185
+ require 'virtus/attribute/coercible'
186
+ require 'virtus/attribute/strict'
187
+ require 'virtus/attribute/lazy_default'
188
+
95
189
  require 'virtus/attribute/boolean'
96
- require 'virtus/attribute/date'
97
- require 'virtus/attribute/date_time'
98
- require 'virtus/attribute/numeric'
99
- require 'virtus/attribute/decimal'
100
- require 'virtus/attribute/float'
190
+ require 'virtus/attribute/collection'
101
191
  require 'virtus/attribute/hash'
102
- require 'virtus/attribute/integer'
103
- require 'virtus/attribute/symbol'
104
- require 'virtus/attribute/string'
105
- require 'virtus/attribute/time'
106
192
  require 'virtus/attribute/embedded_value'
107
- require 'virtus/attribute/embedded_value/from_struct'
108
- require 'virtus/attribute/embedded_value/from_open_struct'
@@ -1,49 +1,28 @@
1
1
  module Virtus
2
2
 
3
- # Abstract class implementing base API for attribute types
4
- #
5
- # @abstract
6
3
  class Attribute
7
- extend DescendantsTracker
8
- extend TypeLookup
9
- extend Options
10
- include Equalizer.new(inspect) << :name << :options
4
+ extend DescendantsTracker, Options, TypeLookup
11
5
 
12
- accept_options :primitive, :accessor, :reader,
13
- :writer, :coercion_method, :default
6
+ include ::Equalizer.new(:type, :options)
14
7
 
8
+ accept_options :primitive, :accessor, :default, :lazy, :strict
9
+
10
+ strict false
15
11
  accessor :public
16
12
 
17
- # Returns name of the attribute
18
- #
19
- # @example
20
- # User.attributes[:age].name # => :age
13
+ # @see Virtus.coerce
21
14
  #
22
- # @return [Symbol]
15
+ # @deprecated
23
16
  #
24
17
  # @api public
25
- attr_reader :name
26
-
27
- # Returns options hash for the attribute
28
- #
29
- # @return [Hash]
30
- #
31
- # @api private
32
- attr_reader :options
18
+ def self.coerce(value = Undefined)
19
+ Virtus.warn "#{self}.coerce is deprecated and will be removed in 1.0.0. Use Virtus.coerce instead: ##{caller.first}"
20
+ return Virtus.coerce if value.equal?(Undefined)
21
+ Virtus.coerce = value
22
+ self
23
+ end
33
24
 
34
- # Returns method name that should be used for coerceing
35
- #
36
- # @return [Symbol]
37
- #
38
- # @api private
39
- attr_reader :coercion_method
40
-
41
- # Returns default value
42
- #
43
- # @return [Object]
44
- #
45
- # @api private
46
- attr_reader :default
25
+ attr_reader :type, :primitive, :options, :default_value, :coercer
47
26
 
48
27
  # Builds an attribute instance
49
28
  #
@@ -59,54 +38,25 @@ module Virtus
59
38
  # @return [Attribute]
60
39
  #
61
40
  # @api private
62
- def self.build(name, type = Object, options = {})
63
- attribute_class = determine_type(type) or
64
- raise ArgumentError, "#{type.inspect} does not map to an attribute type"
65
- attribute_options = attribute_class.merge_options(type, options)
66
- attribute_class.new(name, attribute_options)
41
+ def self.build(type, options = {})
42
+ Builder.call(type, options)
67
43
  end
68
44
 
69
- # Determine attribute type based on class or name
70
- #
71
- # Returns Attribute::EmbeddedValue if a virtus class is passed
72
- #
73
- # @example
74
- # address_class = Class.new { include Virtus }
75
- # Virtus::Attribute.determine_type(address_class) # => Virtus::Attribute::EmbeddedValue
76
- #
77
- # @see Virtus::Support::TypeLookup.determine_type
78
- #
79
- # @return [Class]
80
- #
81
- # @api public
82
- def self.determine_type(class_or_name)
83
- case class_or_name
84
- when ::Class
85
- Attribute::EmbeddedValue.determine_type(class_or_name) || super
86
- when ::String
87
- super
88
- when ::Enumerable
89
- super(class_or_name.class)
90
- else
91
- super
92
- end
45
+ # @api private
46
+ def self.new(*args)
47
+ attribute = super
48
+ yield(attribute)
49
+ attribute.finalize
93
50
  end
94
51
 
95
- # A hook for Attributes to update options based on the type from the caller
96
- #
97
- # @param [Object] type
98
- # The raw type, typically given by the caller of ClassMethods#attribute
99
- # @param [Hash] options
100
- # Attribute configuration options
101
- #
102
- # @return [Hash]
103
- # New Hash instance, potentially updated with information from the args
104
- #
105
52
  # @api private
106
- #
107
- # @todo add type arg to Attribute#initialize signature and handle there?
108
- def self.merge_options(type, options)
109
- options
53
+ def self.build_type(options)
54
+ Axiom::Types.infer(options[:primitive])
55
+ end
56
+
57
+ # @api private
58
+ def self.merge_options!(*)
59
+ # noop
110
60
  end
111
61
 
112
62
  # Initializes an attribute instance
@@ -120,192 +70,54 @@ module Virtus
120
70
  # @return [undefined]
121
71
  #
122
72
  # @api private
123
- def initialize(name, options = {})
124
- @name = name.to_sym
125
- @options = self.class.options.merge(options).freeze
126
- @instance_variable_name = "@#{@name}".to_sym
127
- @primitive = @options.fetch(:primitive)
128
- @coercion_method = @options.fetch(:coercion_method)
129
- @default = DefaultValue.build(@options[:default])
130
- initialize_visibility
131
- end
132
-
133
- # Returns a concise string representation of the attribute instance
134
- #
135
- # @example
136
- # attribute = Virtus::Attribute::String.new(:name)
137
- # attribute.inspect # => #<Virtus::Attribute::String @name=:name>
138
- #
139
- # @return [String]
140
- #
141
- # @api public
142
- def inspect
143
- "#<#{self.class.inspect} @name=#{name.inspect}>"
73
+ def initialize(type, options)
74
+ @type = type
75
+ @primitive = type.primitive
76
+ @options = options
77
+ @default_value = options.fetch(:default_value)
78
+ @coercer = options.fetch(:coercer)
144
79
  end
145
80
 
146
- # Returns value of an attribute for the given instance
147
- #
148
- # Sets the default value if an ivar is not set and default
149
- # value is configured
150
- #
151
- # @example
152
- # attribute.get(instance) # => value
153
- #
154
- # @return [Object]
155
- # value of an attribute
156
- #
157
81
  # @api public
158
- def get(instance)
159
- if instance.instance_variable_defined?(@instance_variable_name)
160
- get!(instance)
161
- else
162
- value = default.call(instance, self)
163
- set!(instance, value)
164
- value
165
- end
82
+ def coerce(value)
83
+ coercer.call(value)
166
84
  end
167
85
 
168
- # Returns the instance variable of the attribute
169
- #
170
- # @example
171
- # attribute.get!(instance) # => value
172
- #
173
- # @return [Object]
174
- # value of an attribute
175
- #
176
86
  # @api public
177
- def get!(instance)
178
- instance.instance_variable_get(@instance_variable_name)
87
+ def value_coerced?(value)
88
+ coercer.success?(primitive, value)
179
89
  end
180
90
 
181
- # Sets the value on the instance
182
- #
183
- # @example
184
- # attribute.set(instance, value) # => value
91
+ # Return if the attribute is coercible
185
92
  #
186
- # @return [self]
93
+ # @return [Boolean]
187
94
  #
188
95
  # @api public
189
- def set(instance, value)
190
- set!(instance, coerce(value))
96
+ def coercible?
97
+ kind_of?(Coercible)
191
98
  end
192
99
 
193
- # Sets instance variable of the attribute
194
- #
195
- # @example
196
- # attribute.set!(instance, value) # => value
197
- #
198
- # @return [self]
199
- #
200
100
  # @api public
201
- def set!(instance, value)
202
- instance.instance_variable_set(@instance_variable_name, value)
203
- self
101
+ def lazy?
102
+ kind_of?(LazyDefault)
204
103
  end
205
104
 
206
- # Converts the given value to the primitive type
207
- #
208
- # @example
209
- # attribute.coerce(value) # => primitive_value
210
- #
211
- # @param [Object] value
212
- # the value
213
- #
214
- # @return [Object]
215
- # nil, original value or value converted to the primitive type
216
- #
217
105
  # @api public
218
- def coerce(value)
219
- Coercion[value.class].public_send(coercion_method, value)
106
+ def strict?
107
+ kind_of?(Strict)
220
108
  end
221
109
 
222
- # Is the given value coerced into the target type for this attribute?
223
- #
224
- # @example
225
- # string_attribute = Virtus::Attribute::String.new(:str)
226
- # string_attribute.value_coerced?('foo') # => true
227
- # string_attribute.value_coerced?(:foo) # => false
228
- # integer_attribute = Virtus::Attribute::Integer.new(:integer)
229
- # integer_attribute.value_coerced?(5) # => true
230
- # integer_attribute.value_coerced?('5') # => false
231
- # date_attribute = Virtus::Attribute::Date.new(:date)
232
- # date_attribute.value_coerced?('2011-12-31') # => false
233
- # date_attribute.value_coerced?(Date.today) # => true
234
- #
235
- # @return [Boolean]
236
- #
237
110
  # @api private
238
- def value_coerced?(value)
239
- @primitive === value
111
+ def define_accessor_methods(attribute_set)
112
+ attribute_set.define_reader_method(self, name, options[:reader])
113
+ attribute_set.define_writer_method(self, "#{name}=", options[:writer])
240
114
  end
241
115
 
242
- # Define reader and writer methods for an Attribute
243
- #
244
- # @param [Attribute] attribute
245
- #
246
- # @return [self]
247
- #
248
- # @api private
249
- def define_accessor_methods(mod)
250
- define_reader_method(mod)
251
- define_writer_method(mod)
252
- self
253
- end
254
-
255
- # Creates an attribute reader method
256
- #
257
- # @param [Module] mod
258
- #
259
- # @return [self]
260
- #
261
116
  # @api private
262
- def define_reader_method(mod)
263
- mod.define_reader_method(self, name, @reader_visibility)
264
- self
265
- end
266
-
267
- # Creates an attribute writer method
268
- #
269
- # @param [Module] mod
270
- #
271
- # @return [self]
272
- #
273
- # @api private
274
- def define_writer_method(mod)
275
- mod.define_writer_method(self, "#{name}=".to_sym, @writer_visibility)
276
- self
277
- end
278
-
279
- # Returns a Boolean indicating whether the reader method is public
280
- #
281
- # @return [Boolean]
282
- #
283
- # @api private
284
- def public_reader?
285
- @reader_visibility == :public
286
- end
287
-
288
- # Returns a Boolean indicating whether the writer method is public
289
- #
290
- # @return [Boolean]
291
- #
292
- # @api private
293
- def public_writer?
294
- @writer_visibility == :public
295
- end
296
-
297
- private
298
-
299
- # Initialize visibility of reader/write methods based on the options hash
300
- #
301
- # @return [undefined]
302
- #
303
- # @api private
304
- def initialize_visibility
305
- default_accessor = @options.fetch(:accessor)
306
- @reader_visibility = @options.fetch(:reader, default_accessor)
307
- @writer_visibility = @options.fetch(:writer, default_accessor)
117
+ def finalize
118
+ freeze
308
119
  end
309
120
 
310
121
  end # class Attribute
122
+
311
123
  end # module Virtus