class_composer 1.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +2 -2
- data/.gitignore +1 -0
- data/CHANGELOG.md +23 -4
- data/Dockerfile +1 -1
- data/Gemfile +5 -5
- data/Gemfile.lock +24 -30
- data/README.md +14 -126
- data/bin/setup +0 -2
- data/class_composer.gemspec +1 -8
- data/docker-compose.yml +0 -2
- data/docs/array_usage.md +25 -0
- data/docs/basic_composer.md +133 -0
- data/docs/basic_composer_example.md +35 -0
- data/docs/composer_blocking.md +84 -0
- data/docs/freezing.md +58 -0
- data/docs/generating_initializer.md +74 -0
- data/lib/class_composer/generate_config.rb +143 -0
- data/lib/class_composer/generator/class_methods.rb +233 -0
- data/lib/class_composer/generator/instance_methods.rb +73 -0
- data/lib/class_composer/generator.rb +9 -118
- data/lib/class_composer/version.rb +1 -1
- data/lib/class_composer.rb +0 -1
- metadata +15 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce164acfb44d923b971f227a236fef5388cbeef8295f8419a46f815ac8bdaa0f
|
4
|
+
data.tar.gz: a0adb222a5704fd56916621669c9cce3112e07a27e338ca2c5e8b51e4a91d42f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fee77c510173e27b695924ff5f5ddb050e00bfb3d26e4b8f5a124576fa72554f462ca06e0ecd31abbb150b6aca339cb22fef11d46724829e0bb0f11f937d4ac8
|
7
|
+
data.tar.gz: 5ce561d2dcc6b3e0e87efc4e55eec8ab243aff03ae758c069ce816674378a39c6f3e8e0c36e925c013e3d255b56d714647dd6ca4a831f3cd82dc0c3306ad6abd
|
data/.circleci/config.yml
CHANGED
@@ -10,10 +10,10 @@ workflows:
|
|
10
10
|
- cst/enforce-gem-version-bump
|
11
11
|
- cst/rspec-ruby:
|
12
12
|
rspec-system-args: "SIMPLE_COV_RUN=true"
|
13
|
-
cc-report-collect-ruby: "
|
13
|
+
cc-report-collect-ruby: "3.3.5"
|
14
14
|
matrix:
|
15
15
|
parameters:
|
16
|
-
ruby-version: ["
|
16
|
+
ruby-version: ["3.1.5" , "3.2.4", "3.3.5"]
|
17
17
|
alias: required-matrix-tests
|
18
18
|
name: test-ruby<< matrix.ruby-version >>
|
19
19
|
- cst/publish-gem:
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,12 +4,31 @@
|
|
4
4
|
|
5
5
|
**Major:** x - Major Releases with new features that constitute a breaking change
|
6
6
|
|
7
|
-
**Minor:** x.x - Minor changes or features added which are
|
7
|
+
**Minor:** x.x - Minor changes or features added which are backwards compatible
|
8
8
|
|
9
9
|
**Patch:** x.x.x - Patch Updates
|
10
10
|
|
11
11
|
# Release Notes
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
## v2.1.0 (Dec 2024)
|
14
|
+
- Default Dynamic Configuration -- Allow config options to be defaulted to other config variables. Ability to provide a Symbol of an existing `composer` or a Proc to custom define from anything in the application
|
15
|
+
- Update how default_shown works when generating the config
|
16
|
+
- Extract `class_methods` and `instance_methods` to their own files
|
17
|
+
|
18
|
+
## v2.0.0 (Nov 2024)
|
19
|
+
- Minimum Ruby Version bumped to v3.1
|
20
|
+
- Initializer File Generator
|
21
|
+
- Add(`desc:`) key to your configs and ClassComposer can create a Initializer for you with all options
|
22
|
+
- Automatically will track new options added
|
23
|
+
- Options added:
|
24
|
+
- `desc:` -- Describe what the configuration is doing. Recommended but optional
|
25
|
+
- `default_shown:` With Config Initializer file Generation, you can add a custom value to display as the default (For example: Use this options with ENV variables or sensitive arguments)
|
26
|
+
- `&block`: Provide a block to the composer class method. This block gets executed on assignment after validation.
|
27
|
+
- Methods Added:
|
28
|
+
- `add_composer_blocking`(Class): Recommended composer method to use when default is another ClassComposer included class (See Readme for more details)
|
29
|
+
- `class_composer_assign_defaults!` (Instance): Class Composer values are lazily loaded. This option allows you to load configured options by calling a method (See Readme for more details)
|
30
|
+
- `class_composer_freeze_objects!`(Instance): Call this instance method if you want to make the instance immutable to changes. Helpful to ensure all changes are made before the application code runs (See Readme for more details)
|
31
|
+
- `composer_generate_config`(Instance): Create the Configuration text for an initializer file. (See Readme for more details)
|
32
|
+
|
33
|
+
## v1.0.0 June 2022
|
34
|
+
- Initial Launch!
|
data/Dockerfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM ruby:3.
|
1
|
+
FROM ruby:3.3.6
|
2
2
|
RUN cd /tmp && curl -L --output ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.12.0/ghr_v0.12.0_linux_amd64.tar.gz && \
|
3
3
|
tar -xzvf ghr.tar.gz && chmod +x ghr_v0.12.0_linux_amd64/ghr && mv ghr_v0.12.0_linux_amd64/ghr /usr/local/bin/ghr && rm -rf /tmp/*
|
4
4
|
|
data/Gemfile
CHANGED
@@ -5,8 +5,8 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in GEMNAME.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
8
|
+
gem "faker"
|
9
|
+
gem "pry"
|
10
|
+
gem "rspec"
|
11
|
+
gem "rspec_junit_formatter"
|
12
|
+
gem "simplecov"
|
data/Gemfile.lock
CHANGED
@@ -1,60 +1,54 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
class_composer (0.
|
4
|
+
class_composer (2.0.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
byebug (11.1.3)
|
10
9
|
coderay (1.1.3)
|
11
|
-
concurrent-ruby (1.
|
12
|
-
diff-lcs (1.5.
|
13
|
-
docile (1.4.
|
14
|
-
faker (
|
10
|
+
concurrent-ruby (1.3.4)
|
11
|
+
diff-lcs (1.5.1)
|
12
|
+
docile (1.4.1)
|
13
|
+
faker (3.5.1)
|
15
14
|
i18n (>= 1.8.11, < 2)
|
16
|
-
i18n (1.
|
15
|
+
i18n (1.14.6)
|
17
16
|
concurrent-ruby (~> 1.0)
|
18
|
-
method_source (1.
|
19
|
-
pry (0.
|
17
|
+
method_source (1.1.0)
|
18
|
+
pry (0.15.0)
|
20
19
|
coderay (~> 1.1)
|
21
20
|
method_source (~> 1.0)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
rspec (3.
|
27
|
-
rspec-
|
28
|
-
|
29
|
-
rspec-mocks (~> 3.11.0)
|
30
|
-
rspec-core (3.11.0)
|
31
|
-
rspec-support (~> 3.11.0)
|
32
|
-
rspec-expectations (3.11.0)
|
21
|
+
rspec (3.13.0)
|
22
|
+
rspec-core (~> 3.13.0)
|
23
|
+
rspec-expectations (~> 3.13.0)
|
24
|
+
rspec-mocks (~> 3.13.0)
|
25
|
+
rspec-core (3.13.2)
|
26
|
+
rspec-support (~> 3.13.0)
|
27
|
+
rspec-expectations (3.13.3)
|
33
28
|
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
-
rspec-support (~> 3.
|
35
|
-
rspec-mocks (3.
|
29
|
+
rspec-support (~> 3.13.0)
|
30
|
+
rspec-mocks (3.13.2)
|
36
31
|
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
-
rspec-support (~> 3.
|
38
|
-
rspec-support (3.
|
39
|
-
rspec_junit_formatter (0.
|
32
|
+
rspec-support (~> 3.13.0)
|
33
|
+
rspec-support (3.13.1)
|
34
|
+
rspec_junit_formatter (0.6.0)
|
40
35
|
rspec-core (>= 2, < 4, != 2.12.0)
|
41
|
-
simplecov (0.
|
36
|
+
simplecov (0.22.0)
|
42
37
|
docile (~> 1.1)
|
43
38
|
simplecov-html (~> 0.11)
|
44
39
|
simplecov_json_formatter (~> 0.1)
|
45
|
-
simplecov-html (0.
|
40
|
+
simplecov-html (0.13.1)
|
46
41
|
simplecov_json_formatter (0.1.4)
|
47
42
|
|
48
43
|
PLATFORMS
|
44
|
+
aarch64-linux
|
49
45
|
x86_64-linux
|
50
46
|
|
51
47
|
DEPENDENCIES
|
52
48
|
class_composer!
|
53
49
|
faker
|
54
50
|
pry
|
55
|
-
|
56
|
-
rake (~> 12.0)
|
57
|
-
rspec (~> 3.0)
|
51
|
+
rspec
|
58
52
|
rspec_junit_formatter
|
59
53
|
simplecov
|
60
54
|
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
### Basic
|
25
|
+
### Basic Add Composer
|
26
26
|
|
27
27
|
`add_composer` is the driving method behind the composer gem. It will
|
28
28
|
- Add a setter Method
|
@@ -32,144 +32,32 @@ Or install it yourself as:
|
|
32
32
|
|
33
33
|
In short, Composer will behave similarly to `attr_accessor`
|
34
34
|
|
35
|
+
Check out [Basic Composer](docs/basic_composer.md) for usage details
|
35
36
|
|
36
|
-
|
37
|
-
require 'class_composer'
|
38
|
-
|
39
|
-
class MyConfigurableClass
|
40
|
-
include ClassComposer::Generator
|
41
|
-
|
42
|
-
ALLOWED_FIBONACCI = [0, 2, 8, 13, 34]
|
43
|
-
|
44
|
-
add_composer :status, allowed: Integer, default: 35
|
45
|
-
add_composer :number, allowed: Integer, default: 0, validator: -> (val) { val < 50 }
|
46
|
-
# when no default is provided, nil will be returned
|
47
|
-
add_composer :fibbonacci, allowed: Array, validator: ->(val) { val.all? {|i| i.is_a?(Integer) } && val.all? { |i| ALLOWED_FIBONACCI.include?(i) } }, invalid_message: ->(val) { "We only allow #{ALLOWED_FIBONACCI} numbers. Received #{val}" }
|
48
|
-
# Allowed can be passed an array of allowed class types
|
49
|
-
add_composer :type, allowed: [Proc, Integer], default: 35
|
50
|
-
end
|
51
|
-
|
52
|
-
instance = MyConfigurableClass.new
|
53
|
-
instance.type
|
54
|
-
=> 35
|
55
|
-
instance.number = 75
|
56
|
-
ClassComposer::ValidatorError: MyConfigurableClass.number failed validation. number is expected to be Integer.
|
57
|
-
from /gem/lib/class_composer/generator.rb:71:in `block in __composer_assignment__`
|
58
|
-
instance.number = 15
|
59
|
-
=> 15
|
60
|
-
instance.number
|
61
|
-
=> 15
|
62
|
-
instance.fibbonacci
|
63
|
-
=> nil
|
64
|
-
instance.fibbonacci = [1,2,3]
|
65
|
-
ClassComposer::ValidatorError: MyConfigurableClass.fibbonacci failed validation. fibbonacci is expected to be [Array]. We only allow [0, 2, 8, 13, 34] numbers. Received [1, 2, 3]
|
66
|
-
from /gem/lib/class_composer/generator.rb:71:in `block in __composer_assignment__`
|
67
|
-
instance.fibbonacci = [0,13,34]
|
68
|
-
=> [0, 13, 34]
|
69
|
-
instance.fibbonacci
|
70
|
-
=> [0, 13, 34]
|
71
|
-
```
|
37
|
+
### Usage with Arrays
|
72
38
|
|
73
|
-
|
39
|
+
Composer allows interactions with arrays in a native way. When the allowed type is `Array`, ClassComposer will add a custom method `<<` to overwrite the native Array method. This ensures that ClassComposer Validations run when adding to the Array.
|
74
40
|
|
75
|
-
|
76
|
-
allowed
|
77
|
-
- Required: True
|
78
|
-
- What: Expected value of the name of the composed method
|
79
|
-
- Type: Array of Class types or Single Class type
|
80
|
-
|
81
|
-
validator
|
82
|
-
- Required: False
|
83
|
-
- What: Custom way to validate the value of the composed method
|
84
|
-
- Type: Proc
|
85
|
-
- Default: ->(_) { true }
|
86
|
-
- By default validation happens on the `allowed` KWARG first and then the passed in validator function. Proc should expect that the type passed in is one of `allowed`
|
87
|
-
|
88
|
-
validation_error_klass
|
89
|
-
- Required: false
|
90
|
-
- What: Class to raise when a validation error occurs from `allowed` KWarg or from the passed in `validator` proc
|
91
|
-
- Type: Class
|
92
|
-
- Default: ClassComposer::ValidatorError
|
93
|
-
|
94
|
-
validation_error_klass
|
95
|
-
- Required: false
|
96
|
-
- What: Class to raise when a errors occur outside of validation. This can be for composer method errors or proc errors during validation
|
97
|
-
- Type: Class
|
98
|
-
- Default: ClassComposer::Error
|
99
|
-
|
100
|
-
default
|
101
|
-
- Required: false
|
102
|
-
- What: This is the default value to set for the composed method
|
103
|
-
- Type: Should match the `allowed` KWarg
|
104
|
-
- Default: nil
|
105
|
-
- Note: When no default value is provided, the return value from the getter will be `nil`. However, this does not mean that NilClass will be an acceptable value during the setter method
|
106
|
-
|
107
|
-
invalid_message
|
108
|
-
- Required: False
|
109
|
-
- What: Message to add to the base invalid setter method
|
110
|
-
- Type: Proc or String
|
111
|
-
- Proc: ->(val) { } # where val is the failed value of the setter method
|
41
|
+
For more information, check out [Array Usage](docs/array_usage.md)
|
112
42
|
|
113
|
-
|
43
|
+
### Freezing Objects
|
114
44
|
|
115
|
-
|
45
|
+
Sometimes you want freeze an instance of a Configuration. Freezing it will make it immutable from changes Users may try to make.
|
116
46
|
|
117
|
-
|
118
|
-
Arrays are treated special with the composed methods. `ClassComposer` will inject a custom method `<<` so that it can be treated as a regular array with the added benefit of validation still occuring.
|
47
|
+
For more information, check out [Freezing Class Composer Instances](docs/freezing.md)
|
119
48
|
|
120
|
-
|
121
|
-
class CustomArrayClass
|
122
|
-
include ClassComposer::Generator
|
49
|
+
### Complex usage: Composer Blocking
|
123
50
|
|
124
|
-
|
125
|
-
|
51
|
+
Composer blocking builds on top of the [Basic Composer](docs/basic_composer.md) to help with nested Configurations that include `ClassCompser::Generator`.
|
52
|
+
Nested configuration's allow complex configurations for entire projects to work seamlessly together.
|
126
53
|
|
127
|
-
|
128
|
-
instance.array << 1
|
129
|
-
instance.array << 2
|
130
|
-
instance.array
|
131
|
-
=> [1, 2]
|
132
|
-
instance.array << 50
|
133
|
-
ClassComposer::ValidatorError: CustomArrayClass.array failed validation. array is expected to be Array. Array sum of [53] must be less than 40
|
134
|
-
|
135
|
-
```
|
136
|
-
|
137
|
-
#### Usage with complex configuration
|
138
|
-
|
139
|
-
```ruby
|
140
|
-
class ComplexDependencies
|
141
|
-
include ClassComposer::Generator
|
142
|
-
|
143
|
-
add_composer :use_scope, allowed: [TrueClass, FalseClass], default: false
|
144
|
-
add_composer :scope, allowed: Proc
|
145
|
-
|
146
|
-
def scope
|
147
|
-
# skip unless use_scope is explicitly set
|
148
|
-
return -> {} unless @use_scope
|
149
|
-
|
150
|
-
# use passed in scope if present
|
151
|
-
# Otherwise default to blank default
|
152
|
-
@scope || -> {}
|
153
|
-
end
|
154
|
-
end
|
155
|
-
```
|
156
|
-
Adding custom methods allows for higher level of complexity. The methods can be used and accessed just as an `attr_accessor` would.
|
54
|
+
For Examples and use cases, check out [Composer Blocking](docs/composer_blocking.md)
|
157
55
|
|
158
56
|
## Development
|
159
57
|
|
160
58
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
161
|
-
`
|
162
|
-
prompt that will allow you to experiment.
|
163
|
-
the gem in this directory, ignoring other installed copies of this gem.
|
164
|
-
|
165
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
166
|
-
|
167
|
-
To release a new version:
|
168
|
-
|
169
|
-
1. Update the version number in [lib/class_composer/version.rb]
|
170
|
-
2. Update [CHANGELOG.md]
|
171
|
-
3. Merge to the main branch. This will trigger an automatic build in CircleCI
|
172
|
-
and push the new gem to the repo.
|
59
|
+
`bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive
|
60
|
+
prompt that will allow you to experiment.
|
173
61
|
|
174
62
|
## Contributing
|
175
63
|
|
data/bin/setup
CHANGED
data/class_composer.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/matt-taylor/class_composer"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
16
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.1")
|
17
17
|
|
18
18
|
spec.metadata = {
|
19
19
|
"homepage_uri" => spec.homepage,
|
@@ -25,12 +25,5 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
26
|
%x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
27
|
end
|
28
|
-
spec.bindir = "exe"
|
29
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
28
|
spec.require_paths = ["lib"]
|
31
|
-
|
32
|
-
spec.add_development_dependency "pry-byebug"
|
33
|
-
spec.add_development_dependency "rake", "~> 12.0"
|
34
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
35
|
-
spec.add_development_dependency "simplecov", "~> 0.17.0"
|
36
29
|
end
|
data/docker-compose.yml
CHANGED
data/docs/array_usage.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Usage with Array
|
2
|
+
|
3
|
+
For more details on basic setup, visit [Basic Composer Page](basic_composer.md)
|
4
|
+
|
5
|
+
---
|
6
|
+
|
7
|
+
Arrays are treated special with the composed methods. `ClassComposer` will inject a custom method `<<` so that it can be treated as a regular array with the added benefit of validation still occurring.
|
8
|
+
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
class CustomArrayClass
|
12
|
+
include ClassComposer::Generator
|
13
|
+
|
14
|
+
add_composer :array, allowed: Array, default: [], validator: ->(val) { val.sum < 40 }, invalid_message: ->(val) { "Array sum of [#{val.sum}] must be less than 40" }
|
15
|
+
end
|
16
|
+
|
17
|
+
instance = CustomArrayClass.new
|
18
|
+
instance.array << 1
|
19
|
+
instance.array << 2
|
20
|
+
instance.array
|
21
|
+
=> [1, 2]
|
22
|
+
instance.array << 50
|
23
|
+
ClassComposer::ValidatorError: CustomArrayClass.array failed validation. array is expected to be Array. Array sum of [53] must be less than 40
|
24
|
+
|
25
|
+
```
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# Add Composer
|
2
|
+
|
3
|
+
`ClassComposer` by default is a DRY way to compose configurations for a class. It provides re-usable validations to ensure variables are set correctly. It is lazily loaded by default and has some wicked options available
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
require "class_composer"
|
7
|
+
class MyCoolClass
|
8
|
+
include ClassComposer::Generator
|
9
|
+
|
10
|
+
add_composer :status, allowed: Symbol, default: :in_progress
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
|
15
|
+
## Available Options:
|
16
|
+
|
17
|
+
### Allowed
|
18
|
+
- Required: Yes
|
19
|
+
- Description: This defines allowed types for this composed item. If `===` fails, it will return a runtime error
|
20
|
+
- Type: Type of allowed assignments. Or an Array of allowed assignments --
|
21
|
+
|
22
|
+
Examples:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
add_composer :status, allowed: Symbol, default: :in_progress
|
26
|
+
|
27
|
+
add_composer :status, allowed: [Symbol, String], default: :in_progress
|
28
|
+
```
|
29
|
+
|
30
|
+
### Default
|
31
|
+
- Required: False
|
32
|
+
- Description: This option allows you to set a sane default for configuration while still allowing others to overwrite the value
|
33
|
+
- Type: It _should_ be one of the `allowed` types to ensure it passes validation
|
34
|
+
|
35
|
+
Examples
|
36
|
+
```ruby
|
37
|
+
add_composer :status, allowed: Symbol, default: :different_default
|
38
|
+
|
39
|
+
add_composer :status, allowed: Symbol, default: "This type does not match Symbol. This default value will raise error"
|
40
|
+
```
|
41
|
+
|
42
|
+
### Dynamic Default
|
43
|
+
- Required: False
|
44
|
+
- Description: This option allows you to set a dynamic default composed of other `add_composer` values. The `dynamic_default` is lazy loaded.
|
45
|
+
- Type: Expected value to be a Symbol mapping to another `add_composer` method or a Proc that takes an instance as an argument.
|
46
|
+
- Note: When using `dynamic_default`, validations will lazily get run on retrieval. This means that you could have a runtime error if the dynamic value is not of the correct `allowed` type.
|
47
|
+
|
48
|
+
Examples
|
49
|
+
```ruby
|
50
|
+
add_composer :app_name, allowed: Symbol, default: "My Cool App Name"
|
51
|
+
|
52
|
+
add_composer :app_name_comms, allowed: String, dynamic_default: :app_name
|
53
|
+
|
54
|
+
add_composer :app_name_website, allowed: String, dynamic_default: ->(instance) { "#{instance.app_name} + #{instance.app_name_comms}" }
|
55
|
+
```
|
56
|
+
|
57
|
+
### Description
|
58
|
+
- Required: False (Recommend)
|
59
|
+
- Description: This option provides a human readable description of what the current configuration option does. This value is useful when [Generating an Initializer](generating_initializer.md)
|
60
|
+
- Type: String
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
add_composer :status, allowed: Symbol, default: :in_progress, desc: "This config value is the current status for the entity."
|
64
|
+
```
|
65
|
+
|
66
|
+
|
67
|
+
### Default Shown
|
68
|
+
- Required: False (Recommend)
|
69
|
+
- Description: This option is helpful when the `default` value is a class or retrieved from an ENV variable. It will overload the `default` value when [Generating an Initializer](generating_initializer.md)
|
70
|
+
- Type: String
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
add_composer :status, allowed: Symbol, default: :in_progress, desc: "This config value is the current status for the entity.", default_shown: "completed"
|
74
|
+
```
|
75
|
+
|
76
|
+
### Provide a Block
|
77
|
+
- Required: False
|
78
|
+
- Description: The optional block will get executed after all validations have completed successful. This is a valuable option when you need to do a secondary action after the value is assigned/changed.
|
79
|
+
- Type: Proc that accepts (`key`, `value`)
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
BLOCK = Proc.new do |key, value|
|
83
|
+
User.send_mail("Your Status has changed to #{key}")
|
84
|
+
end
|
85
|
+
|
86
|
+
add_composer :status, allowed: Symbol, default: :in_progress, desc: "This config value is the current status for the entity.", default_shown: "completed", &BLOCK
|
87
|
+
```
|
88
|
+
|
89
|
+
### Validator
|
90
|
+
- Required: False
|
91
|
+
- Description: This option provides additional validation to do on the item during assignment.
|
92
|
+
- Type: Proc that returns a truthy or falsey value. Truthy response will pass validation. Falsey response will fail validation and raise a runtime error
|
93
|
+
- Default: `->(_) { true }`
|
94
|
+
|
95
|
+
Examples:
|
96
|
+
```ruby
|
97
|
+
add_composer :status, allowed: Symbol, default: :in_progress, validator: ->(value) { [:backlog,:in_progress, :complete].include?(value) }
|
98
|
+
```
|
99
|
+
|
100
|
+
### Invalid Message
|
101
|
+
- Required: False (Recommended with `validator`)
|
102
|
+
- Description: When provided, you can add a custom validation message to the runtime error. Recommended when `validator` is provided
|
103
|
+
- Type: Proc that returns a string to add to validation message
|
104
|
+
|
105
|
+
Examples:
|
106
|
+
```ruby
|
107
|
+
ALLOWED = [:backlog,:in_progress, :complete]
|
108
|
+
add_composer :status, allowed: Symbol, default: :in_progress, validator: ->(value) { ALLOWED.include?(value) }, invalid_message: ->(value) { "Value must be one of #{ALLOWED}" }
|
109
|
+
```
|
110
|
+
|
111
|
+
### Validation Error Class
|
112
|
+
- Required False
|
113
|
+
- Description: The default error to raise when validation fails.
|
114
|
+
- Default: `ClassComposer::ValidatorError`
|
115
|
+
- Type: Class that has `StandardError` Ancestor
|
116
|
+
|
117
|
+
### Error Class
|
118
|
+
- Required: False
|
119
|
+
- Description: The default error class to raise when errors outside of ClassComposer occur. EG during custom validation
|
120
|
+
- Default: `ClassComposer::Error`
|
121
|
+
- Type: Class that has `StandardError` ancestor
|
122
|
+
|
123
|
+
Examples:
|
124
|
+
```ruby
|
125
|
+
ALLOWED = [:backlog,:in_progress, :complete]
|
126
|
+
add_composer :status, allowed: Symbol, default: :in_progress, validator: ->(value) { UNDEFINED_VARIABLE.include?(value) } validation_error_klass: Exception
|
127
|
+
# Will raise with `Exception`
|
128
|
+
```
|
129
|
+
|
130
|
+
---
|
131
|
+
|
132
|
+
To see some complete Examples, visit [Basic Composer Example](basic_composer_example,md)
|
133
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
```ruby
|
2
|
+
require 'class_composer'
|
3
|
+
|
4
|
+
class MyConfigurableClass
|
5
|
+
include ClassComposer::Generator
|
6
|
+
|
7
|
+
ALLOWED_FIBONACCI = [0, 2, 8, 13, 34]
|
8
|
+
|
9
|
+
add_composer :status, allowed: Integer, default: 35
|
10
|
+
add_composer :number, allowed: Integer, default: 0, validator: -> (val) { val < 50 }
|
11
|
+
# when no default is provided, nil will be returned
|
12
|
+
add_composer :fibbonacci, allowed: Array, validator: ->(val) { val.all? {|i| i.is_a?(Integer) } && val.all? { |i| ALLOWED_FIBONACCI.include?(i) } }, invalid_message: ->(val) { "We only allow #{ALLOWED_FIBONACCI} numbers. Received #{val}" }
|
13
|
+
# Allowed can be passed an array of allowed class types
|
14
|
+
add_composer :type, allowed: [Proc, Integer], default: 35
|
15
|
+
end
|
16
|
+
|
17
|
+
instance = MyConfigurableClass.new
|
18
|
+
instance.type
|
19
|
+
=> 35
|
20
|
+
instance.number = 75
|
21
|
+
ClassComposer::ValidatorError: MyConfigurableClass.number failed validation. number is expected to be Integer.
|
22
|
+
from /gem/lib/class_composer/generator.rb:71:in `block in __composer_assignment__`
|
23
|
+
instance.number = 15
|
24
|
+
=> 15
|
25
|
+
instance.number
|
26
|
+
=> 15
|
27
|
+
instance.fibbonacci
|
28
|
+
=> nil
|
29
|
+
instance.fibbonacci = [1,2,3]
|
30
|
+
ClassComposer::ValidatorError: MyConfigurableClass.fibbonacci failed validation. fibbonacci is expected to be [Array]. We only allow [0, 2, 8, 13, 34] numbers. Received [1, 2, 3]
|
31
|
+
from /gem/lib/class_composer/generator.rb:71:in `block in __composer_assignment__`
|
32
|
+
instance.fibbonacci = [0,13,34]
|
33
|
+
=> [0, 13, 34]
|
34
|
+
instance.fibbonacci
|
35
|
+
=> [0, 13, 34]
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# Composer Blocking
|
2
|
+
|
3
|
+
Composer Blocking enhances nested configuration's that utilize `ClassComposer::Generator`. It is a method that provides additional validations and usability.
|
4
|
+
|
5
|
+
Basic Example:
|
6
|
+
```ruby
|
7
|
+
require "class_composer"
|
8
|
+
|
9
|
+
class LoginStrategy
|
10
|
+
include ClassComposer::Generator
|
11
|
+
|
12
|
+
add_composer :password_regex, allowed: Regexp, default: /\A\w{6,20}\z/, desc: "Password must include valid characters between 6 and 20 in length"
|
13
|
+
|
14
|
+
add_composer :username_length, allowed: Integer, default: 10
|
15
|
+
|
16
|
+
add_composer :type, allowed: String, default: "plain_text"
|
17
|
+
end
|
18
|
+
|
19
|
+
class LockableStrategy
|
20
|
+
include ClassComposer::Generator
|
21
|
+
|
22
|
+
add_composer :enable, default: false, allowed: [TrueClass, FalseClass], desc: "By default Lockable Strategy is disabled."
|
23
|
+
add_composer :password_attempts, default: 10, allowed: Integer, desc: "Max password attempts before the account is locked"
|
24
|
+
end
|
25
|
+
|
26
|
+
class AppConfiguration
|
27
|
+
include ClassComposer::Generator
|
28
|
+
|
29
|
+
add_composer_blocking :login, composer_class: LoginStrategy, desc: "Login Strategy for my Application"
|
30
|
+
|
31
|
+
add_composer_blocking :lockable, composer_class: LockableStrategy, enable_attr: :enable, desc: "Lock Strategy for my Application. By default this is disabled"
|
32
|
+
end
|
33
|
+
|
34
|
+
instance = AppConfiguration.new
|
35
|
+
instance.with_login! do |login|
|
36
|
+
login.type = "oauth"
|
37
|
+
login.username_length = 20
|
38
|
+
end
|
39
|
+
instance.login.type
|
40
|
+
=> "oauth"
|
41
|
+
instance.login.type = "plain_text"
|
42
|
+
=> "plain_text"
|
43
|
+
|
44
|
+
instance.lockable?
|
45
|
+
=> false
|
46
|
+
# Calling the block automatically enables the config when passed the `enable_attr`
|
47
|
+
instance.with_lockable! do |lock|
|
48
|
+
lock.password_attempts = 5
|
49
|
+
end
|
50
|
+
instance.lockable?
|
51
|
+
=> true
|
52
|
+
```
|
53
|
+
|
54
|
+
## What does it produce?
|
55
|
+
### Configuration Blocking Method
|
56
|
+
Provides easy invocation for setting a nested composer configuration. By providing a block, you can easily and cleanly set your options for a specific composer item.
|
57
|
+
|
58
|
+
### Check for composer Enable
|
59
|
+
When the `enable_attr` method is provided, you can easily check if the composer instance is enabled by invoking `item_name?`. This convenience method can be used throughout the application to easily check which code paths to go down
|
60
|
+
|
61
|
+
## Allowed Options
|
62
|
+
|
63
|
+
### Composer Class
|
64
|
+
- Required: True
|
65
|
+
- Description: This is the Class object that includes `ClassComposer::Generator`. If the inclusion is missing, the method will raise an runtime error.
|
66
|
+
- Type: Class that includes `ClassComposer::Generator`
|
67
|
+
|
68
|
+
### Description
|
69
|
+
- Required: False (Recommend)
|
70
|
+
- Description: This option provides a human readable description of what the current configuration option does. This value is useful when [Generating an Initializer](generating_initializer.md)
|
71
|
+
- Type: String
|
72
|
+
|
73
|
+
### Block Prepend
|
74
|
+
- Required: False
|
75
|
+
- Description: By default, Composer Blocking prepends blocks with `with_`. This options allows you to set a custom prepended name
|
76
|
+
- Default: `with`
|
77
|
+
- Type: String or Symbol
|
78
|
+
|
79
|
+
### Enable Attr
|
80
|
+
- Required: False
|
81
|
+
- Description: When passed the `enable_attr:`, Class composer will enable the composer instance when called with a block and provide a convenience method `item_name?` to check for if the item is enabled.
|
82
|
+
- Type: String or Symbol
|
83
|
+
|
84
|
+
|