class_composer 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a1bb350ed5d28637c5d2cf2574450eb66459c14c06a49e6f427eaece430df73f
4
- data.tar.gz: db684a27bbe7b948380538952c1a9f6a348c6c2c96c1e7774915b92709b0f372
3
+ metadata.gz: f723db5d8375b56bf7ac7a9e84b6cc0ddb0caa30300b75bf24cae0c6237ec8e0
4
+ data.tar.gz: '087156c95394f2c965a0cffe757bfbe881ff9e6af4bbfe086997163599fd11a2'
5
5
  SHA512:
6
- metadata.gz: 3a316374ba96891a3b1e202893bb79d125db16126636a981b7a19f5aa3caad8b34756f6b650bbc4632996e2de49e8ceb2399b40773213145570d7804fc77a4bd
7
- data.tar.gz: 0e04d577ad1984244d0a89be64c407f456d53641486ec06531d7cf390ce8439029dc8cdea7ee42acadb123d8ee1c5e7888e061a1524cee3b2b52c842fa1282d8
6
+ metadata.gz: 5402a22f9a561f8f7d1b40d764a3cdcec19030ff13218ffe125d13c8bc1a6d2158f501a6aa1d49612c071653fd1cd25f3a45bfe3c257c249087374194c9efed0
7
+ data.tar.gz: c3b42f9f53b843acbf404cc1a7188a8af981d45c15b0dcd28d2b11097fc4121c24829a0018f94a04e9f3630b2ba423004edb35343b5c74a3f5c7f7f2e959b23c
data/CHANGELOG.md CHANGED
@@ -1,26 +1,15 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
3
+ ### Versioning
4
4
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+ **Major:** x - Major Releases with new features that constitute a breaking change
7
6
 
8
- ## [Unreleased]
7
+ **Minor:** x.x - Minor changes or features added which are backwords compatible
9
8
 
10
- ## [0.0.1] - 2022-06-18
9
+ **Patch:** x.x.x - Patch Updates
11
10
 
12
- ### Added
13
- - New feature 1
14
- - New feature 2
11
+ # Release Notes
15
12
 
16
- ### Changed
17
- - Changed feature 1
18
- - Changed feature 2
19
-
20
- ### Removed
21
- - Removed feature 1
22
- - Removed feature 2
23
-
24
- ### Fixed
25
- - Bug fix 1
26
- - Bug fix 2
13
+ | Date | Version | Description |
14
+ |---|---|---|
15
+ | June 2022 | v1.0.0 | Initial launch of Composer
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- class_composer (0.0.1)
4
+ class_composer (0.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Matt Taylor"]
9
9
  spec.email = ["mattius.taylor@gmail.com"]
10
10
 
11
- spec.summary = "Describe the gem here"
12
- spec.description = "Describe the gem here"
11
+ spec.summary = "Easily compose a class via inline code or passed in YAML config. Add instance attributes with custom validations that will DRY up your code"
12
+ spec.description = "Compose configurations for any class."
13
13
  spec.homepage = "https://github.com/matt-taylor/class_composer"
14
14
  spec.license = "MIT"
15
15
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "class_composer/version"
4
+
5
+ # This is to add a falsey like default behavior
6
+ # When default value is not passed in let this be an allowed value
7
+ # This is intended to eventually be configurable
8
+
9
+ module ClassComposer
10
+ module DefaultObject
11
+ module_function
12
+
13
+ def value
14
+ nil
15
+ end
16
+ end
17
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "class_composer/version"
3
+ require "class_composer/default_object"
4
4
 
5
5
  module ClassComposer
6
6
  module Generator
@@ -13,22 +13,35 @@ module ClassComposer
13
13
  COMPOSER_ASSIGNED_ATTR_NAME = ->(name) { :"@__composer_#{name}_value_assigned__" }
14
14
  COMPOSER_ASSIGNED_ARRAY_METHODS = ->(name) { :"@__composer_#{name}_array_methods_set__" }
15
15
 
16
- def add_composer(name, allowed:, default: nil, accessor: true, validator: ->(_) { true }, **params)
17
- validate_proc = __composer_validator_proc__(validator: validator, allowed: allowed, name: name)
18
- __composer_validate_options__!(name: name, validate_proc: validate_proc, default: default)
16
+ def add_composer(name, allowed:, accessor: true, validator: ->(_) { true }, validation_error_klass: ::ClassComposer::ValidatorError, error_klass: ::ClassComposer::Error,**params)
17
+ default =
18
+ if params.has_key?(:default)
19
+ params[:default]
20
+ else
21
+ if allowed.is_a?(Array)
22
+ allowed << ClassComposer::DefaultObject
23
+ else
24
+ allowed = [allowed, ClassComposer::DefaultObject]
25
+ end
26
+ ClassComposer::DefaultObject
27
+ end
28
+
29
+ allowed.include?(ClassComposer::DefaultObject)
30
+ validate_proc = __composer_validator_proc__(validator: validator, allowed: allowed, name: name, error_klass: error_klass)
31
+ __composer_validate_options__!(name: name, validate_proc: validate_proc, default: default, validation_error_klass: validation_error_klass, error_klass: error_klass)
19
32
 
20
33
  array_proc = __composer_array_proc__(name: name, validator: validator, allowed: allowed, params: params)
21
- __composer_assignment__(name: name, params: params, validator: validate_proc, array_proc: array_proc)
34
+ __composer_assignment__(name: name, allowed: allowed, params: params, validator: validate_proc, array_proc: array_proc, validation_error_klass: validation_error_klass, error_klass: error_klass)
22
35
  __composer_retrieval__(name: name, default: default, array_proc: array_proc)
23
36
  end
24
37
 
25
- def __composer_validate_options__!(name:, validate_proc:, default:)
38
+ def __composer_validate_options__!(name:, validate_proc:, default:, params: {}, validation_error_klass:, error_klass:)
26
39
  unless validate_proc.(default)
27
- raise ClassComposer::ValidatorError, "Default value [#{default}] for #{self.class}.#{name} is not valid"
40
+ raise validation_error_klass, "Default value [#{default}] for #{self.class}.#{name} is not valid"
28
41
  end
29
42
 
30
- if self.class.instance_methods.include?(name.to_sym)
31
- raise ClassComposer::Error, "#{name} is already defined. Ensure composer names are all uniq and do not class with class instance methods"
43
+ if instance_methods.include?(name.to_sym)
44
+ raise error_klass, "[#{name}] is already defined. Ensure composer names are all uniq and do not class with class instance methods"
32
45
  end
33
46
  end
34
47
 
@@ -39,7 +52,7 @@ module ClassComposer
39
52
  end
40
53
 
41
54
  # create assignment method for the incoming name
42
- def __composer_assignment__(name:, params:, validator:, array_proc:)
55
+ def __composer_assignment__(name:, params:, allowed:, validator:, array_proc:, validation_error_klass:, error_klass:)
43
56
  define_method(:"#{name}=") do |value|
44
57
  is_valid = validator.(value)
45
58
 
@@ -47,11 +60,15 @@ module ClassComposer
47
60
  instance_variable_set(COMPOSER_ASSIGNED_ATTR_NAME.(name), true)
48
61
  instance_variable_set(:"@#{name}", value)
49
62
  else
50
- value.pop
51
- message = ["#{self.class}.#{name} failed validation."]
63
+ message = ["#{self.class}.#{name} failed validation. #{name} is expected to be #{allowed}."]
52
64
 
53
65
  message << (params[:invalid_message].is_a?(Proc) ? params[:invalid_message].(value) : params[:invalid_message].to_s)
54
- raise ClassComposer::ValidatorError, message.compact.join(" ")
66
+ if value.is_a?(Array)
67
+ # we assigned the array value...pop it from the array
68
+ # must be done after the message is created so that failing value can get passed appropriately
69
+ value.pop
70
+ end
71
+ raise validation_error_klass, message.compact.join(" ")
55
72
  end
56
73
 
57
74
  if value.is_a?(Array) && !value.instance_variable_get(COMPOSER_ASSIGNED_ARRAY_METHODS.(name))
@@ -79,14 +96,15 @@ module ClassComposer
79
96
  end
80
97
  default.instance_variable_set(COMPOSER_ASSIGNED_ARRAY_METHODS.(name), true)
81
98
  end
82
- default
99
+
100
+ default == ClassComposer::DefaultObject ? ClassComposer::DefaultObject.value : default
83
101
  end
84
102
  end
85
103
 
86
104
  # create validator method for incoming name
87
- def __composer_validator_proc__(validator:, allowed:, name:)
105
+ def __composer_validator_proc__(validator:, allowed:, name:, error_klass:)
88
106
  if validator && !validator.is_a?(Proc)
89
- raise ClassComposer::Error, "Expected validator to be a Proc. Received [#{validator.class}]"
107
+ raise error_klass, "Expected validator to be a Proc. Received [#{validator.class}]"
90
108
  end
91
109
 
92
110
  # Proc will validate the entire attribute -- Full assignment must occur before validate is called
@@ -98,9 +116,11 @@ module ClassComposer
98
116
  else
99
117
  allowed == value.class
100
118
  end
101
- allow && validator.(value)
119
+ # order is important -- Do not run validator if it is the default object
120
+ # Default object will likely raise an error if there is a custom validator
121
+ (allowed.include?(ClassComposer::DefaultObject) && value == ClassComposer::DefaultObject) || (allow && validator.(value))
102
122
  rescue StandardError => e
103
- raise ClassComposer::Error, "#{e} occured during validation for value [#{value}]. Check custom validator for #{name}"
123
+ raise error_klass, "#{e} occured during validation for value [#{value}]. Check custom validator for #{name}"
104
124
  end
105
125
  end
106
126
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClassComposer
4
- VERSION = "0.0.1"
4
+ VERSION = "1.0.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class_composer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Taylor
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-24 00:00:00.000000000 Z
11
+ date: 2022-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry-byebug
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.17.0
69
- description: Describe the gem here
69
+ description: Compose configurations for any class.
70
70
  email:
71
71
  - mattius.taylor@gmail.com
72
72
  executables: []
@@ -90,7 +90,7 @@ files:
90
90
  - class_composer.gemspec
91
91
  - docker-compose.yml
92
92
  - lib/class_composer.rb
93
- - lib/class_composer/array.rb
93
+ - lib/class_composer/default_object.rb
94
94
  - lib/class_composer/generator.rb
95
95
  - lib/class_composer/version.rb
96
96
  homepage: https://github.com/matt-taylor/class_composer
@@ -117,5 +117,6 @@ requirements: []
117
117
  rubygems_version: 3.3.11
118
118
  signing_key:
119
119
  specification_version: 4
120
- summary: Describe the gem here
120
+ summary: Easily compose a class via inline code or passed in YAML config. Add instance
121
+ attributes with custom validations that will DRY up your code
121
122
  test_files: []
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ClassComposer
4
- class Array
5
- def initialize(validator)
6
- @validator = validator
7
- super
8
- end
9
-
10
- def <<
11
- value = super
12
-
13
-
14
-
15
- value
16
- end
17
- end
18
- end