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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d53fe12431ff8f1dd4c42d7282d11a64637a0c3ab573e24a7d83443a8a9cac2
4
- data.tar.gz: 0376e66b2fef6bc976289dd1f4e4517830dd0a63c0e12519730efc9786865c9f
3
+ metadata.gz: ce164acfb44d923b971f227a236fef5388cbeef8295f8419a46f815ac8bdaa0f
4
+ data.tar.gz: a0adb222a5704fd56916621669c9cce3112e07a27e338ca2c5e8b51e4a91d42f
5
5
  SHA512:
6
- metadata.gz: b08e706f2f55865e6d4fab779896450dab524b946412ee8e8be8a673b205a8f3ded0a438db6dbce53d8ebc06c6a88a2dc6cba5a4da3bd5e22a599a205ea9cc0f
7
- data.tar.gz: bfa9491b16358fc59b221bd5ac847b861c52a6a5793dca4fc59c81a8ceef3e12c1d3148bd8679833e4c5a643e5738788a9647a1619f9aadc2171b9d497bd0f34
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: "2.7.5"
13
+ cc-report-collect-ruby: "3.3.5"
14
14
  matrix:
15
15
  parameters:
16
- ruby-version: ["2.7.5" , "3.0.0", "3.0.3"]
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
@@ -7,6 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  .DS_Store
10
+ spec/examples.txt
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
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 backwords compatible
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
- | Date | Version | Description |
14
- |---|---|---|
15
- | June 2022 | v1.0.0 | Initial launch of Composer
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.0.1
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 'faker'
9
- gem 'pry'
10
- gem 'rspec', '~> 3.0'
11
- gem 'rspec_junit_formatter'
12
- gem 'simplecov', require: false, group: :test
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.1.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.1.10)
12
- diff-lcs (1.5.0)
13
- docile (1.4.0)
14
- faker (2.21.0)
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.10.0)
15
+ i18n (1.14.6)
17
16
  concurrent-ruby (~> 1.0)
18
- method_source (1.0.0)
19
- pry (0.13.1)
17
+ method_source (1.1.0)
18
+ pry (0.15.0)
20
19
  coderay (~> 1.1)
21
20
  method_source (~> 1.0)
22
- pry-byebug (3.9.0)
23
- byebug (~> 11.0)
24
- pry (~> 0.13.0)
25
- rake (12.3.3)
26
- rspec (3.11.0)
27
- rspec-core (~> 3.11.0)
28
- rspec-expectations (~> 3.11.0)
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.11.0)
35
- rspec-mocks (3.11.1)
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.11.0)
38
- rspec-support (3.11.0)
39
- rspec_junit_formatter (0.5.1)
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.21.2)
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.12.3)
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
- pry-byebug
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
- ```ruby
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
- ### KWarg Options
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
- ### Advanced
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
- #### Usage with Array as Allowed
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
- ```ruby
121
- class CustomArrayClass
122
- include ClassComposer::Generator
49
+ ### Complex usage: Composer Blocking
123
50
 
124
- add_composer :array, allowed: Array, default: [], validator: ->(val) { val.sum < 40 }, invalid_message: ->(val) { "Array sum of [#{val.sum}] must be less than 40" }
125
- end
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
- instance = CustomArrayClass.new
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
- `rake rspec` to run the tests. You can also run `bin/console` for an interactive
162
- prompt that will allow you to experiment. Run `bundle exec class_composer` to use
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
@@ -5,6 +5,4 @@ set -vx
5
5
 
6
6
  bundle install
7
7
 
8
- lefthook install
9
-
10
8
  # Do any other automated setup that you need to do here
@@ -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(">= 2.7")
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
@@ -1,5 +1,3 @@
1
- version: '3'
2
-
3
1
  services:
4
2
  class-composer:
5
3
  command: tail -f /dev/null
@@ -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
+