smart_initializer 0.1.0.alpha2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +36 -5
  4. data/CHANGELOG.md +15 -0
  5. data/Gemfile.lock +63 -43
  6. data/README.md +263 -11
  7. data/Rakefile +1 -1
  8. data/bin/rspec +54 -0
  9. data/gemfiles/with_external_deps.gemfile +7 -0
  10. data/gemfiles/with_external_deps.gemfile.lock +102 -0
  11. data/gemfiles/without_external_deps.gemfile +5 -0
  12. data/gemfiles/without_external_deps.gemfile.lock +100 -0
  13. data/lib/smart_core/initializer.rb +44 -28
  14. data/lib/smart_core/initializer/attribute.rb +12 -5
  15. data/lib/smart_core/initializer/attribute/factory.rb +47 -27
  16. data/lib/smart_core/initializer/attribute/parameters.rb +12 -4
  17. data/lib/smart_core/initializer/configuration.rb +33 -0
  18. data/lib/smart_core/initializer/constructor.rb +60 -23
  19. data/lib/smart_core/initializer/{attribute → constructor}/definer.rb +64 -12
  20. data/lib/smart_core/initializer/dsl.rb +47 -10
  21. data/lib/smart_core/initializer/dsl/inheritance.rb +1 -0
  22. data/lib/smart_core/initializer/errors.rb +44 -0
  23. data/lib/smart_core/initializer/extensions.rb +9 -0
  24. data/lib/smart_core/initializer/extensions/abstract.rb +8 -0
  25. data/lib/smart_core/initializer/extensions/ext_init.rb +31 -0
  26. data/lib/smart_core/initializer/extensions/list.rb +74 -0
  27. data/lib/smart_core/initializer/functionality.rb +36 -0
  28. data/lib/smart_core/initializer/instance_attribute_accessing.rb +51 -0
  29. data/lib/smart_core/initializer/plugins.rb +17 -0
  30. data/lib/smart_core/initializer/plugins/abstract.rb +55 -0
  31. data/lib/smart_core/initializer/plugins/access_mixin.rb +47 -0
  32. data/lib/smart_core/initializer/plugins/registry.rb +166 -0
  33. data/lib/smart_core/initializer/plugins/registry_interface.rb +77 -0
  34. data/lib/smart_core/initializer/plugins/thy_types.rb +30 -0
  35. data/lib/smart_core/initializer/plugins/thy_types/errors.rb +11 -0
  36. data/lib/smart_core/initializer/plugins/thy_types/thy_types.rb +23 -0
  37. data/lib/smart_core/initializer/plugins/thy_types/thy_types/abstract_factory.rb +78 -0
  38. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation.rb +12 -0
  39. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/base.rb +9 -0
  40. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/cast.rb +21 -0
  41. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/valid.rb +16 -0
  42. data/lib/smart_core/initializer/plugins/thy_types/thy_types/operation/validate.rb +19 -0
  43. data/lib/smart_core/initializer/settings.rb +49 -0
  44. data/lib/smart_core/initializer/settings/duplicator.rb +20 -0
  45. data/lib/smart_core/initializer/settings/type_system.rb +69 -0
  46. data/lib/smart_core/initializer/type_system.rb +16 -0
  47. data/lib/smart_core/initializer/type_system/interop.rb +103 -0
  48. data/lib/smart_core/initializer/type_system/interop/abstract_factory.rb +70 -0
  49. data/lib/smart_core/initializer/type_system/interop/aliasing.rb +72 -0
  50. data/lib/smart_core/initializer/type_system/interop/aliasing/alias_list.rb +141 -0
  51. data/lib/smart_core/initializer/type_system/interop/operation.rb +30 -0
  52. data/lib/smart_core/initializer/type_system/registry.rb +174 -0
  53. data/lib/smart_core/initializer/type_system/registry_interface.rb +102 -0
  54. data/lib/smart_core/initializer/type_system/smart_types.rb +48 -0
  55. data/lib/smart_core/initializer/type_system/smart_types/abstract_factory.rb +72 -0
  56. data/lib/smart_core/initializer/type_system/smart_types/operation.rb +13 -0
  57. data/lib/smart_core/initializer/type_system/smart_types/operation/base.rb +8 -0
  58. data/lib/smart_core/initializer/type_system/smart_types/operation/cast.rb +16 -0
  59. data/lib/smart_core/initializer/type_system/smart_types/operation/valid.rb +16 -0
  60. data/lib/smart_core/initializer/type_system/smart_types/operation/validate.rb +16 -0
  61. data/lib/smart_core/initializer/version.rb +2 -1
  62. data/smart_initializer.gemspec +13 -9
  63. metadata +73 -17
  64. data/lib/smart_core/initializer/type_aliasing.rb +0 -50
  65. data/lib/smart_core/initializer/type_aliasing/alias_list.rb +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f835709c40984d70109e260c33764194c3f63422f37dafa4ba32b8b3b29b745d
4
- data.tar.gz: de748657c5ac079a378e916c24eb7781ecc40790b429c97d9af1bffc74129200
3
+ metadata.gz: 5134f8c4bce2fc85b936310f04e67bf2d065205a29a34a53435eca06efba17f6
4
+ data.tar.gz: b4de1f15734ca61d124c944aeaca4f87fb6e5c1d5e4f8d92a3c7b63516ce708e
5
5
  SHA512:
6
- metadata.gz: 79232e232cf4f5148fd3f98e87093a6b06fbfbaf8773e497dff082dde601101dbc4fe7ca9ed10de55d4559a6d2d03eb30659299ac7d1018f296884fb7ab0f3ed
7
- data.tar.gz: 9e8ac0af865c59a16535a70ae9006cd0de3cc9b680354401f81d9de8baba6524f2fd008cba0404600cd0b160cf21500dd3e5da63c02034e43ab2337e1c7d47c7
6
+ metadata.gz: 86e1523cec71037f80aa99a6e36a5ffe06ca0da34d90f97e836dafdcd096cadceaebcb147499a636d1ce0f6868b0781e22ba21e0d589fb127cdfe41ff4882940
7
+ data.tar.gz: 4b9e5b9f6e3742cfa38fb969a7b3d0d2a5e85d49cd94a7f498d6302cdb1ac3910642772f5c9246a51fb4bf1ab4231af3c8a2a8328c4b343471a4e2563b3e9cd6
@@ -5,7 +5,7 @@ inherit_gem:
5
5
  - lib/rubocop.rspec.yml
6
6
 
7
7
  AllCops:
8
- TargetRubyVersion: 2.4.9
8
+ TargetRubyVersion: 2.7.1
9
9
  Include:
10
10
  - lib/**/*.rb
11
11
  - spec/**/*.rb
@@ -2,19 +2,50 @@
2
2
  language: ruby
3
3
  cache: bundler
4
4
  os: linux
5
- before_install: gem install bundler -v 2.1.2
5
+ dist: xenial
6
+ before_install: gem install bundler
6
7
  script:
7
8
  - bundle exec rake rubocop
8
9
  - bundle exec rake rspec
9
10
  jobs:
10
11
  fast_finish: true
11
12
  include:
12
- - rvm: 2.4.9
13
- - rvm: 2.5.7
14
- - rvm: 2.6.5
15
- - rvm: 2.7.0
13
+ - rvm: 2.4.10
14
+ gemfile: gemfiles/with_external_deps.gemfile
15
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
16
+ - rvm: 2.5.8
17
+ gemfile: gemfiles/with_external_deps.gemfile
18
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
19
+ - rvm: 2.6.6
20
+ gemfile: gemfiles/with_external_deps.gemfile
21
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
22
+ - rvm: 2.7.1
23
+ gemfile: gemfiles/with_external_deps.gemfile
24
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
16
25
  - rvm: ruby-head
26
+ gemfile: gemfiles/with_external_deps.gemfile
27
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
17
28
  - rvm: jruby-head
29
+ gemfile: gemfiles/with_external_deps.gemfile
30
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
31
+ - rvm: truffleruby
32
+ gemfile: gemfiles/with_external_deps.gemfile
33
+ env: TEST_PLUGINS=true FULL_TEST_COVERAGE_CHECK=true
34
+ - rvm: 2.4.10
35
+ gemfile: gemfiles/without_external_deps.gemfile
36
+ - rvm: 2.5.8
37
+ gemfile: gemfiles/without_external_deps.gemfile
38
+ - rvm: 2.6.6
39
+ gemfile: gemfiles/without_external_deps.gemfile
40
+ - rvm: 2.7.1
41
+ gemfile: gemfiles/without_external_deps.gemfile
42
+ - rvm: ruby-head
43
+ gemfile: gemfiles/without_external_deps.gemfile
44
+ - rvm: jruby-head
45
+ gemfile: gemfiles/without_external_deps.gemfile
46
+ - rvm: truffleruby
47
+ gemfile: gemfiles/without_external_deps.gemfile
18
48
  allow_failures:
19
49
  - rvm: ruby-head
20
50
  - rvm: jruby-head
51
+ - rvm: truffleruby
@@ -1,2 +1,17 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
+
4
+ ## [0.3.0] - 2020-07-11
5
+ ### Added
6
+ - `extend_initialization_flow` alias method for `SmartCore::Initializer.ext_init`;
7
+ - Access methods to the instance attribute lists (`#__params`, `#__options__`, `#__attributes__`);
8
+
9
+ ### Changed
10
+ - Updated development dependencies;
11
+
12
+ ## [0.2.0] - 2020-05-16
13
+ ### Changed
14
+ - **Constructor**: disallow unknown option attributes;
15
+
16
+ ## [0.1.0] - 2020-05-10
17
+ - Release :)
@@ -1,80 +1,100 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smart_initializer (0.1.0.alpha1)
5
- smart_engine (~> 0.5)
6
- smart_types (~> 0.1.0.alpha6)
4
+ smart_initializer (0.2.0)
5
+ qonfig (~> 0.24)
6
+ smart_engine (~> 0.7)
7
+ smart_types (~> 0.1.0)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
- armitage-rubocop (0.79.0)
12
- rubocop (= 0.79.0)
13
- rubocop-performance (= 1.5.2)
14
- rubocop-rails (= 2.4.1)
15
- rubocop-rake (= 0.5.0)
16
- rubocop-rspec (= 1.37.1)
17
- ast (2.4.0)
18
- diff-lcs (1.3)
12
+ activesupport (6.0.3.2)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 0.7, < 2)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ zeitwerk (~> 2.2, >= 2.2.2)
18
+ armitage-rubocop (0.87.1.2)
19
+ rubocop (= 0.87.1)
20
+ rubocop-performance (= 1.7.0)
21
+ rubocop-rails (= 2.6.0)
22
+ rubocop-rake (= 0.5.1)
23
+ rubocop-rspec (= 1.42.0)
24
+ ast (2.4.1)
25
+ concurrent-ruby (1.1.6)
26
+ diff-lcs (1.4.4)
19
27
  docile (1.3.2)
20
- jaro_winkler (1.5.4)
21
- json (2.3.0)
22
- parallel (1.19.1)
23
- parser (2.7.0.2)
24
- ast (~> 2.4.0)
25
- rack (2.1.1)
28
+ i18n (1.8.3)
29
+ concurrent-ruby (~> 1.0)
30
+ minitest (5.14.1)
31
+ parallel (1.19.2)
32
+ parser (2.7.1.4)
33
+ ast (~> 2.4.1)
34
+ qonfig (0.24.1)
35
+ rack (2.2.3)
26
36
  rainbow (3.0.0)
27
37
  rake (13.0.1)
38
+ regexp_parser (1.7.1)
39
+ rexml (3.2.4)
28
40
  rspec (3.9.0)
29
41
  rspec-core (~> 3.9.0)
30
42
  rspec-expectations (~> 3.9.0)
31
43
  rspec-mocks (~> 3.9.0)
32
- rspec-core (3.9.1)
33
- rspec-support (~> 3.9.1)
34
- rspec-expectations (3.9.0)
44
+ rspec-core (3.9.2)
45
+ rspec-support (~> 3.9.3)
46
+ rspec-expectations (3.9.2)
35
47
  diff-lcs (>= 1.2.0, < 2.0)
36
48
  rspec-support (~> 3.9.0)
37
49
  rspec-mocks (3.9.1)
38
50
  diff-lcs (>= 1.2.0, < 2.0)
39
51
  rspec-support (~> 3.9.0)
40
- rspec-support (3.9.2)
41
- rubocop (0.79.0)
42
- jaro_winkler (~> 1.5.1)
52
+ rspec-support (3.9.3)
53
+ rubocop (0.87.1)
43
54
  parallel (~> 1.10)
44
- parser (>= 2.7.0.1)
55
+ parser (>= 2.7.1.1)
45
56
  rainbow (>= 2.2.2, < 4.0)
57
+ regexp_parser (>= 1.7)
58
+ rexml
59
+ rubocop-ast (>= 0.1.0, < 1.0)
46
60
  ruby-progressbar (~> 1.7)
47
- unicode-display_width (>= 1.4.0, < 1.7)
48
- rubocop-performance (1.5.2)
49
- rubocop (>= 0.71.0)
50
- rubocop-rails (2.4.1)
61
+ unicode-display_width (>= 1.4.0, < 2.0)
62
+ rubocop-ast (0.1.0)
63
+ parser (>= 2.7.0.1)
64
+ rubocop-performance (1.7.0)
65
+ rubocop (>= 0.82.0)
66
+ rubocop-rails (2.6.0)
67
+ activesupport (>= 4.2.0)
51
68
  rack (>= 1.1)
52
- rubocop (>= 0.72.0)
53
- rubocop-rake (0.5.0)
69
+ rubocop (>= 0.82.0)
70
+ rubocop-rake (0.5.1)
54
71
  rubocop
55
- rubocop-rspec (1.37.1)
56
- rubocop (>= 0.68.1)
72
+ rubocop-rspec (1.42.0)
73
+ rubocop (>= 0.87.0)
57
74
  ruby-progressbar (1.10.1)
58
- simplecov (0.17.1)
75
+ simplecov (0.18.5)
59
76
  docile (~> 1.1)
60
- json (>= 1.8, < 3)
61
- simplecov-html (~> 0.10.0)
62
- simplecov-html (0.10.2)
63
- smart_engine (0.5.0)
64
- smart_types (0.1.0.alpha6)
65
- smart_engine (~> 0.5)
66
- unicode-display_width (1.6.1)
77
+ simplecov-html (~> 0.11)
78
+ simplecov-html (0.12.2)
79
+ smart_engine (0.7.0)
80
+ smart_types (0.1.0)
81
+ smart_engine (~> 0.6)
82
+ thread_safe (0.3.6)
83
+ tzinfo (1.2.7)
84
+ thread_safe (~> 0.1)
85
+ unicode-display_width (1.7.0)
86
+ zeitwerk (2.3.1)
67
87
 
68
88
  PLATFORMS
69
89
  ruby
70
90
 
71
91
  DEPENDENCIES
72
- armitage-rubocop (~> 0.78)
92
+ armitage-rubocop (~> 0.87)
73
93
  bundler (~> 2.1)
74
94
  rake (~> 13.0)
75
95
  rspec (~> 3.9)
76
- simplecov (~> 0.17)
96
+ simplecov (~> 0.18)
77
97
  smart_initializer!
78
98
 
79
99
  BUNDLED WITH
80
- 2.1.2
100
+ 2.1.4
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # SmartCore::Initializer &middot; [![Gem Version](https://badge.fury.io/rb/smart_initializer.svg)](https://badge.fury.io/rb/smart_initializer) [![Build Status](https://travis-ci.org/smart-rb/smart_initializer.svg?branch=master)](https://travis-ci.org/smart-rb/smart_initializer)
2
2
 
3
- A simple and convenient way to declare complex constructors (**in active development**).
3
+ A simple and convenient way to declare complex constructors with a support for various commonly used type systems.
4
+ (**in active development**).
4
5
 
5
6
  ## Installation
6
7
 
@@ -11,20 +12,105 @@ gem 'smart_initializer'
11
12
  ```shell
12
13
  bundle install
13
14
  # --- or ---
14
- gem install smart_types
15
+ gem install smart_initializer
15
16
  ```
16
17
 
17
18
  ```ruby
18
- require 'smart_core/types'
19
+ require 'smart_core/initializer'
19
20
  ```
20
21
 
21
22
  ---
22
23
 
23
- ## Synopsis (DEMO)
24
+ ## Table of contents
25
+
26
+ - [Synopsis](#synopsis)
27
+ - [Access to the instance attributes](#access-to-the-instance-attributes)
28
+ - [Configuration](#configuration)
29
+ - [Type aliasing](#type-aliasing)
30
+ - [Initialization extension](#initialization-extension)
31
+ - [Plugins](#plugins)
32
+ - [thy-types](#plugin-thy-types)
33
+ - [How to run tests](#how-to-run-tests)
34
+
35
+ ---
36
+
37
+ ## Synopsis
38
+
39
+ **Initialization flow**:
40
+
41
+ 1. Parameter + Option definitioning;
42
+ 2. Original #initialize invokation;
43
+ 3. Initialization extensions invokation;
44
+
45
+ **Constructor definition**:
46
+
47
+ - `param` - defines name-like attribute:
48
+ - `cast` - type-cast received value if value has invalid type;
49
+ - `privacy` - reader incapsulation level;
50
+ - `finalize` - value post-processing (receives method name or proc);
51
+ - `type_system` - differently chosen type system for the current attribute;
52
+ - (limitation) param has no `:default` option;
53
+ - `option` - defined kwarg-like attribute:
54
+ - `cast` - type-cast received value if value has invalid type;
55
+ - `privacy` - reader incapsulation level;
56
+ - `finalize` - value post-processing (receives method name or proc);
57
+ - `default` - defalut value (if an attribute is not provided);
58
+ - `type_system` - differently chosen type system for the current attribute;
59
+ - last `Hash` argument will be treated as `kwarg`s;
60
+
61
+ #### initializer integration
62
+
63
+ ```ruby
64
+ # with pre-configured type system (:smart_types, see Configuration doc)
65
+
66
+ class MyStructure
67
+ include SmartCore::Initializer
68
+ end
69
+ ```
70
+
71
+ ```ruby
72
+ # with manually chosen type system
73
+
74
+ class MyStructure
75
+ include SmartCore::Initializer(type_system: :smart_types)
76
+ end
77
+
78
+ class AnotherStructure
79
+ include SmartCore::Initializer(type_system: :thy_types)
80
+ end
81
+ ```
82
+
83
+ #### `param` signautre:
84
+
85
+ ```ruby
86
+ param <attribute_name>,
87
+ <type=SmartCore::Types::Value::Any>, # Any by default
88
+ cast: false, # false by default
89
+ privacy: :public, # :public by default
90
+ finalize: proc { |value| value }, # no finalization by default
91
+ type_system: :smart_types # used by default
92
+ ```
93
+
94
+ #### `option` signature:
95
+
96
+ ```ruby
97
+ option <attribute_name>,
98
+ <type=SmartCore::Types::Value::Any>, # Any by default
99
+ cast: false, # false by default
100
+ privacy: :public, # :public by default
101
+ finalize: proc { |value| value }, # no finalization by default
102
+ default: 123, # no default value by default
103
+ type_system: :smart_types # used by default
104
+ ```
105
+
106
+ Example:
107
+
24
108
 
25
109
  ```ruby
26
110
  class User
27
111
  include SmartCore::Initializer
112
+ # --- or ---
113
+ include SmartCore::Initializer(type_system: :smart_types)
28
114
 
29
115
  param :user_id, SmartCore::Types::Value::Integer, cast: false, privacy: :public
30
116
  option :role, default: :user, finalize: -> { |value| Role.find(name: value) }
@@ -36,22 +122,188 @@ end
36
122
  User.new(1, 'John', 'test123', role: :admin, metadata: {}, enabled: false)
37
123
  ```
38
124
 
39
- **Limitations**:
125
+ ---
126
+
127
+ ## Access to the instance attributes
128
+
129
+ - `#__params__` - returns a list of initialized params;
130
+ - `#__options__` - returns a list of initialized options;
131
+ - `#__attributes__` - returns a list of merged params and options;
132
+
133
+ ```ruby
134
+ class User
135
+ include SmartCore::Initializer
136
+
137
+ param :first_name, 'string'
138
+ param :second_name, 'string'
139
+ option :age, 'numeric'
140
+ option :is_admin, 'boolean', default: true
141
+ end
142
+
143
+ user = User.new('Rustam', 'Ibragimov', age: 28)
144
+
145
+ user.__params__ # => { first_name: 'Rustam', second_name: 'Ibragimov' }
146
+ user.__options__ # => { age: 28, is_admin: true }
147
+ user.__attributes__ # => { first_name: 'Rustam', second_name: 'Ibragimov', age: 28, is_admin: true }
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Configuration
153
+
154
+ - based on `Qonfig` gem;
155
+ - you can read config values via `[]` or `.config.settings` or `.config[key]`;
156
+ - setitngs:
157
+ - `default_type_system` - default type system (`smart_types` by default);
158
+
159
+ ```ruby
160
+ # configure:
161
+ SmartCore::Initializer::Configuration.configure do |config|
162
+ config.default_type_system = :smart_types # default setting value
163
+ end
164
+ ```
165
+
166
+ ```ruby
167
+ # read:
168
+ SmartCore::Initializer::Configuration[:default_type_system]
169
+ SmartCore::Initializer::Configuration.config[:default_type_system]
170
+ SmartCore::Initializer::Configuration.config.settings.default_type_system
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Type aliasing
176
+
177
+ - Usage:
178
+
179
+ ```ruby
180
+ # for smart_types:
181
+ SmartCore::Initializer::TypeSystem::SmartTypes.type_alias('hsh', SmartCore::Types::Value::Hash)
182
+
183
+ # for thy:
184
+ SmartCore::Initializer::TypeSystem::ThyTypes.type_alias('int', Thy::Tyhes::Integer)
185
+
186
+ class User
187
+ include SmartCore::Initializer
188
+
189
+ param :data, 'hsh' # use your new defined type alias
190
+ option :metadata, :hsh # use your new defined type alias
40
191
 
41
- - `param` has no :default option (at all);
42
- - last hash argument will be treated as `kwarg`s;
192
+ param :age, 'int', type_system: :thy_types
193
+ end
194
+ ```
43
195
 
44
- **Type aliasing**:
196
+ - Predefined aliases:
45
197
 
46
198
  ```ruby
47
- SmartCore::Initializer.type_alias(:hash, SmartCore::Types::Value::Hash)
199
+ # for smart_types:
200
+ SmartCore::Initializer::TypeSystem::SmartTypes.type_aliases
201
+
202
+ # for thy_types:
203
+ SmartCore::Initializer::TypeSystem::ThyTypes.type_aliases
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Initialization extension
48
209
 
210
+ - `ext_init(&block)`:
211
+ - you can define as many extensions as you want;
212
+ - extensions are invoked in the order they are defined;
213
+ - alias method: `extend_initialization_flow`;
214
+
215
+ ```ruby
49
216
  class User
50
217
  include SmartCore::Initializer
51
218
 
52
- param :data, :hash
53
- option :metadata, :hash
219
+ option :name, :name
220
+ option :age, :integer
221
+
222
+ ext_init { |instance| instance.define_singleton_method(:extra) { :ext1 } }
223
+ ext_init { |instance| instance.define_singleton_method(:extra2) { :ext2 } }
54
224
  end
225
+
226
+ user = User.new(name: 'keka', age: 123)
227
+ user.name # => 'keka'
228
+ user.age # => 123
229
+ user.extra # => :ext1
230
+ user.extra2 # => :ext2
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Plugins
236
+
237
+ - [thy-types](#plugin-thy-types)
238
+
239
+ ---
240
+
241
+ ## Plugin: thy-types
242
+
243
+ Support for `Thy::Types` type system ([gem](https://github.com/akxcv/thy))
244
+
245
+ - install `thy` types (`gem install thy`):
246
+
247
+ ```ruby
248
+ gem 'thy'
249
+ ```
250
+
251
+ ```shell
252
+ bundle install
253
+ ```
254
+
255
+ - enable `thy_types` plugin:
256
+
257
+ ```ruby
258
+ require 'thy'
259
+ SmartCore::Initializer::Configuration.plugin(:thy_types)
260
+ ```
261
+
262
+ - usage:
263
+
264
+ ```ruby
265
+ class User
266
+ include SmartCore::Initializer(type_system: :thy_types)
267
+
268
+ param :nickname, 'string'
269
+ param :email, 'value.text', type_system: :smart_types # mixing with smart_types
270
+ option :admin, Thy::Types::Boolean, default: false
271
+ option :age, (Thy::Type.new { |value| value > 18 }) # custom thy type is supported too
272
+ end
273
+
274
+ # valid case:
275
+ User.new('daiver', 'iamdaiver@gmail.com', { admin: true, age: 19 })
276
+ # => new user object
277
+
278
+ # invalid case (invalid age)
279
+ User.new('daiver', 'iamdaiver@gmail.com', { age: 17 })
280
+ # SmartCore::Initializer::ThyTypeValidationError
281
+
282
+ # invaldi case (invalid nickname)
283
+ User.new(123, 'test', { admin: true, age: 22 })
284
+ # => SmartCore::Initializer::ThyTypeValidationError
285
+ ```
286
+
287
+ ---
288
+
289
+ ## How to run tests
290
+
291
+ - with plugin tests:
292
+
293
+ ```shell
294
+ bin/rspec -w
295
+ ```
296
+
297
+ - without plugin tests:
298
+
299
+ ```shell
300
+ bin/rspec -n
301
+ ```
302
+
303
+ - help message:
304
+
305
+ ```shell
306
+ bin/rspec -h
55
307
  ```
56
308
 
57
309
  ---