dsl_compose 1.1.0 → 1.3.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.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/dsl_compose/composer.rb +6 -6
  4. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/equal_to_validation.rb +1 -1
  5. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/format_validation.rb +1 -1
  6. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/greater_than_or_equal_to_validation.rb +1 -1
  7. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/greater_than_validation.rb +1 -1
  8. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/in_validation.rb +1 -1
  9. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/interpreter.rb +2 -2
  10. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/length_validation.rb +1 -1
  11. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/less_than_or_equal_to_validation.rb +1 -1
  12. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/less_than_validation.rb +1 -1
  13. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument/not_in_validation.rb +1 -1
  14. data/lib/dsl_compose/dsl/{dsl_method → arguments}/argument.rb +1 -1
  15. data/lib/dsl_compose/dsl/arguments.rb +113 -0
  16. data/lib/dsl_compose/dsl/dsl_method/interpreter.rb +4 -4
  17. data/lib/dsl_compose/dsl/dsl_method.rb +3 -73
  18. data/lib/dsl_compose/dsl/interpreter.rb +20 -0
  19. data/lib/dsl_compose/dsl.rb +4 -0
  20. data/lib/dsl_compose/interpreter/execution/arguments.rb +145 -0
  21. data/lib/dsl_compose/interpreter/execution/method_calls/method_call.rb +2 -104
  22. data/lib/dsl_compose/interpreter/execution.rb +5 -1
  23. data/lib/dsl_compose/interpreter.rb +36 -11
  24. data/lib/dsl_compose/version.rb +1 -1
  25. data/lib/dsl_compose.rb +15 -12
  26. metadata +15 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6093d554121170f4ea168c0a5d0e6480befc3ae02f24396b2006534ac7252b2
4
- data.tar.gz: 759d6dcf22ff3f049f29f0e4e5fffac72fd535cd1b4b0927934b94cba379ece0
3
+ metadata.gz: f8b82032e4bea7187d0dd4a00528472ce1a5b29d4aea64b94d6090b8d013b47b
4
+ data.tar.gz: 628dda5efddcfdc2b9de8df09245c5af67c233de24dee7654d7266b193b6ef95
5
5
  SHA512:
6
- metadata.gz: 2406e9b5a49d8764a4dc66b00489f58686cb2135980345cac72dbf451c5b97693cfae625153980dd2c124bf84a80b96c8aa59c924c275b36ae825a366194b194
7
- data.tar.gz: 83bf9a8302f434adb63906e1abf07ffb3d56a3bcc9336465b0647710e42ff3b076be3d255df19aad6ff7a6f4a35fcbcec37aee4a3bf1f9d5b05ff767d07a377e
6
+ metadata.gz: 670c5b83e8d8e3dd986933499d96d92604da968088b31dba613421712beb5ded7c7defec91714a1c23df1a4ba82d55a15a815864376d2ad3970a426232bb42cc
7
+ data.tar.gz: 48f76cf798a28b60efe4cf1c69d2f21c3594e86de5bbcf674d4a16f68114e76cde998a68c8dfbfbe8860362165bd9af7c37f6be3842e6efbdf9db8568ce72246
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0](https://github.com/craigulliott/dsl_compose/compare/v1.2.0...v1.3.0) (2023-06-22)
4
+
5
+
6
+ ### Features
7
+
8
+ * adding an executions_by_class method to make processing the configuration more convenient ([#8](https://github.com/craigulliott/dsl_compose/issues/8)) ([313507c](https://github.com/craigulliott/dsl_compose/commit/313507ca572f59c03162a91d58e62500a9464f25))
9
+ * fixing release please job ([#10](https://github.com/craigulliott/dsl_compose/issues/10)) ([880fa5b](https://github.com/craigulliott/dsl_compose/commit/880fa5b2aceed67aa9ff1e7cf53629af23e31b10))
10
+
11
+ ## [1.2.0](https://github.com/craigulliott/dsl_compose/compare/v1.1.0...v1.2.0) (2023-06-22)
12
+
13
+
14
+ ### Features
15
+
16
+ * adding arguments to initial DSL activation method ([bda7cd4](https://github.com/craigulliott/dsl_compose/commit/bda7cd4ef55bcd4bfd2be530b6a28645dee87885))
17
+
3
18
  ## [1.1.0](https://github.com/craigulliott/dsl_compose/compare/v1.0.0...v1.1.0) (2023-06-20)
4
19
 
5
20
 
@@ -10,13 +10,13 @@ module DSLCompose
10
10
 
11
11
  class MethodAlreadyExistsWithThisDSLNameError < StandardError
12
12
  def message
13
- "The define_dsl singleton method already exists for this class."
13
+ "The `define_dsl` singleton method already exists for this class."
14
14
  end
15
15
  end
16
16
 
17
17
  class GetDSLExecutionResultsMethodAlreadyExistsError < StandardError
18
18
  def message
19
- "The dsl_interpreter singleton method already exists for this class."
19
+ "The `dsls` singleton method already exists for this class."
20
20
  end
21
21
  end
22
22
 
@@ -30,11 +30,11 @@ module DSLCompose
30
30
  interpreter = DSLCompose::Interpreter.new
31
31
 
32
32
  # return a specific DSL which is defined for this class
33
- if klass.respond_to? :dsl_interpreter
33
+ if klass.respond_to? :dsls
34
34
  raise GetDSLExecutionResultsMethodAlreadyExistsError
35
35
  end
36
36
 
37
- klass.define_singleton_method :dsl_interpreter do
37
+ klass.define_singleton_method :dsls do
38
38
  interpreter
39
39
  end
40
40
 
@@ -56,10 +56,10 @@ module DSLCompose
56
56
  end
57
57
 
58
58
  # add a singleton method with the name of this new DSL onto our class, this is how our new DSL will be accessed
59
- define_singleton_method name do |&block|
59
+ define_singleton_method name do |*args, &block|
60
60
  # when it is called, we process this new dynamic DSL with the interpreter
61
61
  # `self` here is the class in which the dsl is being used, not the class in which the DSL was defined
62
- interpreter.execute_dsl self, dsl, &block
62
+ interpreter.execute_dsl self, dsl, *args, &block
63
63
  end
64
64
 
65
65
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class EqualToValidation
8
8
  class ValidationFailedError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class FormatValidation
8
8
  class ValidationFailedError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class GreaterThanOrEqualToValidation
8
8
  class InvalidValueError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class GreaterThanValidation
8
8
  class InvalidValueError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class InValidation
8
8
  class InvalidValueError < StandardError
@@ -2,13 +2,13 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  # This class is reponsible for parsing and executing argument definitions
8
8
  # within our internal DSL. These argument definitions determine what arguments
9
9
  # will be available on the methods within our new dynamic DSL.
10
10
  #
11
- # This class is instantaited by the DSLCompose::DSL::DSLMethod::Argument class and the
11
+ # This class is instantaited by the DSLCompose::DSL::Arguments::Argument class and the
12
12
  # method argument definition part of our internal DSL is evaluated by passing a block
13
13
  # to `instance_eval` on this class.
14
14
  #
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class LengthValidation
8
8
  class ValidationFailedError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class LessThanOrEqualToValidation
8
8
  class InvalidValueError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class LessThanValidation
8
8
  class InvalidValueError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class NotInValidation
8
8
  class InvalidValueError < StandardError
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DSLCompose
4
4
  class DSL
5
- class DSLMethod
5
+ class Arguments
6
6
  class Argument
7
7
  class ValidationIncompatibleError < StandardError
8
8
  def message
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSLCompose
4
+ class DSL
5
+ class Arguments
6
+ class ArgumentDoesNotExistError < StandardError
7
+ def message
8
+ "This argument does not exist for this DSLMethod"
9
+ end
10
+ end
11
+
12
+ class ArgumentOrderingError < StandardError
13
+ def message
14
+ "Required arguments can not be added after optional ones"
15
+ end
16
+ end
17
+
18
+ class ArgumentAlreadyExistsError < StandardError
19
+ def message
20
+ "An argument with this name already exists for this DSL method"
21
+ end
22
+ end
23
+
24
+ class RequestedOptionalArgumentIsRequiredError < StandardError
25
+ def message
26
+ "A specific argument which was expected to be optional was requested, but the argument found was flagged as required"
27
+ end
28
+ end
29
+
30
+ class RequestedRequiredArgumentIsOptionalError < StandardError
31
+ def message
32
+ "A specific argument which was expected to be required was requested, but the argument found was flagged as optional"
33
+ end
34
+ end
35
+
36
+ def initialize
37
+ @arguments = {}
38
+ end
39
+
40
+ # Returns an array of all this DSLMethods Argument objects.
41
+ def arguments
42
+ @arguments.values
43
+ end
44
+
45
+ # Returns an array of only the optional Argument objects on this DSLMethod.
46
+ def optional_arguments
47
+ arguments.filter(&:optional?)
48
+ end
49
+
50
+ # Returns an array of only the required Argument objects on this DSLMethod.
51
+ def required_arguments
52
+ arguments.filter(&:required?)
53
+ end
54
+
55
+ # returns a specific Argument by it's name, if the Argument does not
56
+ # exist, then an error is raised
57
+ def argument name
58
+ if has_argument? name
59
+ @arguments[name]
60
+ else
61
+ raise ArgumentDoesNotExistError
62
+ end
63
+ end
64
+
65
+ # returns a specific optional Argument by it's name, if the Argument does not
66
+ # exist, or if it is required, then an error is raised
67
+ def optional_argument name
68
+ arg = argument name
69
+ if arg.optional?
70
+ @arguments[name]
71
+ else
72
+ raise RequestedOptionalArgumentIsRequiredError
73
+ end
74
+ end
75
+
76
+ # returns a specific required Argument by it's name, if the Argument does not
77
+ # exist, or if it is optional, then an error is raised
78
+ def required_argument name
79
+ arg = argument name
80
+ if arg.required?
81
+ @arguments[name]
82
+ else
83
+ raise RequestedRequiredArgumentIsOptionalError
84
+ end
85
+ end
86
+
87
+ # Returns `true` if an Argument with the provided name exists in this
88
+ # DSLMethod, otherwise it returns `false`.
89
+ def has_argument? name
90
+ @arguments.key? name
91
+ end
92
+
93
+ # Takes a method name, unique flag, required flag, and a block and creates
94
+ # a new Argument object.
95
+ #
96
+ # Argument `name` must be unique within the DSLMethod.
97
+ # `required` must be a boolean, and determines if this argument will be required
98
+ # or optional on the method which is exposed in our DSL.
99
+ def add_argument name, required, type, &block
100
+ if @arguments.key? name
101
+ raise ArgumentAlreadyExistsError
102
+ end
103
+
104
+ # required arguments may not come after optional ones
105
+ if required && optional_arguments.any?
106
+ raise ArgumentOrderingError
107
+ end
108
+
109
+ @arguments[name] = Argument.new(name, required, type, &block)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -37,9 +37,9 @@ module DSLCompose
37
37
  # name must be a symbol
38
38
  # `type` can be either :integer, :boolean, :float, :string or :symbol
39
39
  # `block` contains the argument definition and will be evaluated seperately
40
- # by the DSLMethod::Argument::Interpreter
40
+ # by the Argument::Interpreter
41
41
  def optional name, type, &block
42
- @dsl_method.add_argument name, false, type, &block
42
+ @dsl_method.arguments.add_argument name, false, type, &block
43
43
  end
44
44
 
45
45
  # adds a new required argument to the DSLMethod
@@ -47,9 +47,9 @@ module DSLCompose
47
47
  # name must be a symbol
48
48
  # `type` can be either :integer, :boolean, :float, :string or :symbol
49
49
  # `block` contains the argument definition and will be evaluated seperately
50
- # by the DSLMethod::Argument::Interpreter
50
+ # by the Argument::Interpreter
51
51
  def requires name, type, &block
52
- @dsl_method.add_argument name, true, type, &block
52
+ @dsl_method.arguments.add_argument name, true, type, &block
53
53
  end
54
54
  end
55
55
  end
@@ -66,6 +66,8 @@ module DSLCompose
66
66
  # An otional description of this DSLMethod, if provided then it must be a string.
67
67
  # The description accepts markdown and is used when generating documentation.
68
68
  attr_reader :description
69
+ # an object which represents the argument configuration
70
+ attr_reader :arguments
69
71
 
70
72
  # Create a new DSLMethod object with the provided name and class.
71
73
  #
@@ -74,7 +76,7 @@ module DSLCompose
74
76
  # `required` is a boolean which determines if this DSLMethod must be called at least once within the DSL.
75
77
  # `block` contains the instructions to further configure this DSLMethod
76
78
  def initialize name, unique, required, &block
77
- @arguments = {}
79
+ @arguments = Arguments.new
78
80
 
79
81
  if name.is_a? Symbol
80
82
 
@@ -122,59 +124,6 @@ module DSLCompose
122
124
  @description.nil? == false
123
125
  end
124
126
 
125
- # Returns an array of all this DSLMethods Argument objects.
126
- def arguments
127
- @arguments.values
128
- end
129
-
130
- # Returns an array of only the optional Argument objects on this DSLMethod.
131
- def optional_arguments
132
- arguments.filter(&:optional?)
133
- end
134
-
135
- # Returns an array of only the required Argument objects on this DSLMethod.
136
- def required_arguments
137
- arguments.filter(&:required?)
138
- end
139
-
140
- # returns a specific Argument by it's name, if the Argument does not
141
- # exist, then an error is raised
142
- def argument name
143
- if has_argument? name
144
- @arguments[name]
145
- else
146
- raise ArgumentDoesNotExistError
147
- end
148
- end
149
-
150
- # returns a specific optional Argument by it's name, if the Argument does not
151
- # exist, or if it is required, then an error is raised
152
- def optional_argument name
153
- arg = argument name
154
- if arg.optional?
155
- @arguments[name]
156
- else
157
- raise RequestedOptionalArgumentIsRequiredError
158
- end
159
- end
160
-
161
- # returns a specific required Argument by it's name, if the Argument does not
162
- # exist, or if it is optional, then an error is raised
163
- def required_argument name
164
- arg = argument name
165
- if arg.required?
166
- @arguments[name]
167
- else
168
- raise RequestedRequiredArgumentIsOptionalError
169
- end
170
- end
171
-
172
- # Returns `true` if an Argument with the provided name exists in this
173
- # DSLMethod, otherwise it returns `false`.
174
- def has_argument? name
175
- @arguments.key? name
176
- end
177
-
178
127
  # returns true if this DSLMethod is flagged as unique, otherwise returns false.
179
128
  def unique?
180
129
  @unique == true
@@ -189,25 +138,6 @@ module DSLCompose
189
138
  def optional?
190
139
  @required == false
191
140
  end
192
-
193
- # Takes a method name, unique flag, required flag, and a block and creates
194
- # a new Argument object.
195
- #
196
- # Argument `name` must be unique within the DSLMethod.
197
- # `required` must be a boolean, and determines if this argument will be required
198
- # or optional on the method which is exposed in our DSL.
199
- def add_argument name, required, type, &block
200
- if @arguments.key? name
201
- raise ArgumentAlreadyExistsError
202
- end
203
-
204
- # required arguments may not come after optional ones
205
- if required && optional_arguments.any?
206
- raise ArgumentOrderingError
207
- end
208
-
209
- @arguments[name] = Argument.new(name, required, type, &block)
210
- end
211
141
  end
212
142
  end
213
143
  end
@@ -47,6 +47,26 @@ module DSLCompose
47
47
  def add_unique_method name, required: nil, &block
48
48
  @dsl.add_method name, true, required ? true : false, &block
49
49
  end
50
+
51
+ # adds a new optional argument to the DSLMethod
52
+ #
53
+ # name must be a symbol
54
+ # `type` can be either :integer, :boolean, :float, :string or :symbol
55
+ # `block` contains the argument definition and will be evaluated seperately
56
+ # by the Argument::Interpreter
57
+ def optional name, type, &block
58
+ @dsl.arguments.add_argument name, false, type, &block
59
+ end
60
+
61
+ # adds a new required argument to the DSLMethod
62
+ #
63
+ # name must be a symbol
64
+ # `type` can be either :integer, :boolean, :float, :string or :symbol
65
+ # `block` contains the argument definition and will be evaluated seperately
66
+ # by the Argument::Interpreter
67
+ def requires name, type, &block
68
+ @dsl.arguments.add_argument name, true, type, &block
69
+ end
50
70
  end
51
71
  end
52
72
  end
@@ -49,6 +49,8 @@ module DSLCompose
49
49
  # An otional description of this DSL, if provided then it must be a string.
50
50
  # The description accepts markdown and is used when generating documentation.
51
51
  attr_reader :description
52
+ # an object which represents the argument configuration
53
+ attr_reader :arguments
52
54
 
53
55
  # Create a new DSL object with the provided name and class.
54
56
  #
@@ -57,6 +59,8 @@ module DSLCompose
57
59
  def initialize name, klass
58
60
  @dsl_methods = {}
59
61
 
62
+ @arguments = Arguments.new
63
+
60
64
  if name.is_a? Symbol
61
65
  @name = name
62
66
  else
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DSLCompose
4
+ class Interpreter
5
+ class Execution
6
+ class Arguments
7
+ class MissingRequiredArgumentsError < StandardError
8
+ def initialize required_count, provided_count
9
+ super "This method requires #{required_count} arguments, but only #{required_count} were provided"
10
+ end
11
+ end
12
+
13
+ class TooManyArgumentsError < StandardError
14
+ def message
15
+ "Too many arguments provided to this method"
16
+ end
17
+ end
18
+
19
+ class OptionalArgsShouldBeHashError < StandardError
20
+ def message
21
+ "If provided, then the optional arguments must be last, and be represented as a Hash"
22
+ end
23
+ end
24
+
25
+ class InvalidArgumentTypeError < StandardError
26
+ def message
27
+ "The provided argument is the wrong type"
28
+ end
29
+ end
30
+
31
+ attr_reader :arguments
32
+
33
+ def initialize arguments, *args
34
+ @arguments = {}
35
+
36
+ required_argument_count = arguments.required_arguments.count
37
+ has_optional_arguments = arguments.optional_arguments.any?
38
+
39
+ # the first N args, where N = required_argument_count, are the
40
+ # provided required arguments
41
+ required_args = args.slice(0, required_argument_count)
42
+ # the optional arg which comes next is the hash which represents
43
+ # all the optional arguments
44
+ optional_arg = args[required_argument_count]
45
+
46
+ # assert that a value is provided for every required argument
47
+ unless required_argument_count == required_args.count
48
+ raise MissingRequiredArgumentsError.new required_argument_count, required_args.count
49
+ end
50
+
51
+ # assert that too many arguments have not been provided
52
+ if args.count > required_argument_count + (has_optional_arguments ? 1 : 0)
53
+ raise TooManyArgumentsError
54
+ end
55
+
56
+ # asset that, if provided, then the optional argument (always the last one) is a Hash
57
+ if has_optional_arguments && optional_arg.nil? === false
58
+ unless optional_arg.is_a? Hash
59
+ raise OptionalArgsShouldBeHashError
60
+ end
61
+
62
+ # assert the each provided optional argument is valid
63
+ optional_arg.keys.each do |optional_argument_name|
64
+ optional_arg_value = optional_arg[optional_argument_name]
65
+ optional_argument = arguments.optional_argument optional_argument_name
66
+
67
+ case optional_argument.type
68
+ when :integer
69
+ unless optional_arg_value.is_a? Integer
70
+ raise InvalidArgumentTypeError
71
+ end
72
+ optional_argument.validate_integer! optional_arg_value
73
+
74
+ when :symbol
75
+ unless optional_arg_value.is_a? Symbol
76
+ raise InvalidArgumentTypeError
77
+ end
78
+ optional_argument.validate_symbol! optional_arg_value
79
+
80
+ when :string
81
+ unless optional_arg_value.is_a? String
82
+ raise InvalidArgumentTypeError
83
+ end
84
+ optional_argument.validate_string! optional_arg_value
85
+
86
+ when :boolean
87
+ unless optional_arg_value.is_a?(TrueClass) || optional_arg_value.is_a?(FalseClass)
88
+ raise InvalidArgumentTypeError
89
+ end
90
+ optional_argument.validate_boolean! optional_arg_value
91
+
92
+ else
93
+ raise InvalidArgumentTypeError
94
+ end
95
+
96
+ # the provided value appears valid for this argument, save the value
97
+ @arguments[optional_argument_name] = optional_arg_value
98
+ end
99
+
100
+ end
101
+
102
+ # validate the value provided to each required argument
103
+ arguments.required_arguments.each_with_index do |required_argument, i|
104
+ arg = args[i]
105
+ case required_argument.type
106
+ when :integer
107
+ unless arg.is_a? Integer
108
+ raise InvalidArgumentTypeError
109
+ end
110
+ required_argument.validate_integer! arg
111
+
112
+ when :symbol
113
+ unless arg.is_a? Symbol
114
+ raise InvalidArgumentTypeError
115
+ end
116
+ required_argument.validate_symbol! arg
117
+
118
+ when :string
119
+ unless arg.is_a? String
120
+ raise InvalidArgumentTypeError
121
+ end
122
+ required_argument.validate_string! arg
123
+
124
+ when :boolean
125
+ unless arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
126
+ raise InvalidArgumentTypeError
127
+ end
128
+ required_argument.validate_boolean! arg
129
+
130
+ else
131
+ raise InvalidArgumentTypeError
132
+ end
133
+
134
+ # the provided value appears valid for this argument, save the value
135
+ @arguments[required_argument.name] = arg
136
+ end
137
+ end
138
+
139
+ def to_h
140
+ @arguments
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -34,109 +34,7 @@ module DSLCompose
34
34
 
35
35
  def initialize dsl_method, *args, &block
36
36
  @dsl_method = dsl_method
37
- @arguments = {}
38
-
39
- required_argument_count = dsl_method.required_arguments.count
40
- has_optional_arguments = dsl_method.optional_arguments.any?
41
-
42
- # the first N args, where N = required_argument_count, are the
43
- # provided required arguments
44
- required_args = args.slice(0, required_argument_count)
45
- # the optional arg which comes next is the hash which represents
46
- # all the optional arguments
47
- optional_arg = args[required_argument_count]
48
-
49
- # assert that a value is provided for every required argument
50
- unless required_argument_count == required_args.count
51
- raise MissingRequiredArgumentsError.new required_argument_count, required_args.count
52
- end
53
-
54
- # assert that too many arguments have not been provided
55
- if args.count > required_argument_count + (has_optional_arguments ? 1 : 0)
56
- raise TooManyArgumentsError
57
- end
58
-
59
- # asset that, if provided, then the optional argument (always the last one) is a Hash
60
- if has_optional_arguments && optional_arg.nil? === false
61
- unless optional_arg.is_a? Hash
62
- raise OptionalArgsShouldBeHashError
63
- end
64
-
65
- # assert the each provided optional argument is valid
66
- optional_arg.keys.each do |optional_argument_name|
67
- optional_arg_value = optional_arg[optional_argument_name]
68
- optional_argument = dsl_method.optional_argument optional_argument_name
69
-
70
- case optional_argument.type
71
- when :integer
72
- unless optional_arg_value.is_a? Integer
73
- raise InvalidArgumentTypeError
74
- end
75
- optional_argument.validate_integer! optional_arg_value
76
-
77
- when :symbol
78
- unless optional_arg_value.is_a? Symbol
79
- raise InvalidArgumentTypeError
80
- end
81
- optional_argument.validate_symbol! optional_arg_value
82
-
83
- when :string
84
- unless optional_arg_value.is_a? String
85
- raise InvalidArgumentTypeError
86
- end
87
- optional_argument.validate_string! optional_arg_value
88
-
89
- when :boolean
90
- unless optional_arg_value.is_a?(TrueClass) || optional_arg_value.is_a?(FalseClass)
91
- raise InvalidArgumentTypeError
92
- end
93
- optional_argument.validate_boolean! optional_arg_value
94
-
95
- else
96
- raise InvalidArgumentTypeError
97
- end
98
-
99
- # the provided value appears valid for this argument, save the value
100
- @arguments[optional_argument_name] = optional_arg_value
101
- end
102
-
103
- end
104
-
105
- # validate the value provided to each required argument
106
- dsl_method.required_arguments.each_with_index do |required_argument, i|
107
- arg = args[i]
108
- case required_argument.type
109
- when :integer
110
- unless arg.is_a? Integer
111
- raise InvalidArgumentTypeError
112
- end
113
- required_argument.validate_integer! arg
114
-
115
- when :symbol
116
- unless arg.is_a? Symbol
117
- raise InvalidArgumentTypeError
118
- end
119
- required_argument.validate_symbol! arg
120
-
121
- when :string
122
- unless arg.is_a? String
123
- raise InvalidArgumentTypeError
124
- end
125
- required_argument.validate_string! arg
126
-
127
- when :boolean
128
- unless arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
129
- raise InvalidArgumentTypeError
130
- end
131
- required_argument.validate_boolean! arg
132
-
133
- else
134
- raise InvalidArgumentTypeError
135
- end
136
-
137
- # the provided value appears valid for this argument, save the value
138
- @arguments[required_argument.name] = arg
139
- end
37
+ @arguments = Arguments.new(dsl_method.arguments, *args)
140
38
  end
141
39
 
142
40
  def method_name
@@ -145,7 +43,7 @@ module DSLCompose
145
43
 
146
44
  def to_h
147
45
  {
148
- arguments: @arguments
46
+ arguments: @arguments.to_h
149
47
  }
150
48
  end
151
49
  end
@@ -16,12 +16,16 @@ module DSLCompose
16
16
  end
17
17
 
18
18
  attr_reader :dsl
19
+ attr_reader :klass
19
20
  attr_reader :method_calls
21
+ attr_reader :arguments
20
22
 
21
23
  # execute/process a dynamically defined DSL
22
- def initialize dsl, &block
24
+ def initialize klass, dsl, *args, &block
25
+ @klass = klass
23
26
  @dsl = dsl
24
27
  @method_calls = MethodCalls.new
28
+ @arguments = Arguments.new(dsl.arguments, *args)
25
29
 
26
30
  # dynamically process the DSL by calling the provided block
27
31
  # all methods executions will be caught and processed by the method_missing method below
@@ -10,32 +10,57 @@ module DSLCompose
10
10
  attr_reader :executions
11
11
 
12
12
  def initialize
13
- @executions = {}
13
+ @executions = []
14
14
  end
15
15
 
16
16
  # Execute/process a dynamically defined DSL on a class.
17
17
  # `klass` is the class in which the DSL is being used, not
18
18
  # the class in which the DSL was defined.
19
- def execute_dsl klass, dsl, &block
20
- @executions[klass] ||= []
21
- execution = Execution.new(dsl, &block)
22
- @executions[klass] << execution
19
+ def execute_dsl klass, dsl, *args, &block
20
+ execution = Execution.new(klass, dsl, *args, &block)
21
+ @executions << execution
23
22
  execution
24
23
  end
25
24
 
26
25
  # Returns an array of all executions for a given class.
27
26
  def class_executions klass
28
- @executions[klass] || []
27
+ @executions.filter { |e| e.klass == klass }
29
28
  end
30
29
 
31
- def to_h klass
30
+ # Returns an array of all executions for a given class.
31
+ def dsl_executions dsl_name
32
+ @executions.filter { |e| e.dsl.name == dsl_name }
33
+ end
34
+
35
+ def to_h dsl_name
36
+ h = {}
37
+ dsl_executions(dsl_name).each do |execution|
38
+ h[execution.klass] ||= {
39
+ arguments: execution.arguments.to_h,
40
+ method_calls: {}
41
+ }
42
+ execution.method_calls.method_calls.each do |method_call|
43
+ h[execution.klass][:method_calls][method_call.method_name] ||= []
44
+ h[execution.klass][:method_calls][method_call.method_name] << method_call.to_h
45
+ end
46
+ end
47
+ h
48
+ end
49
+
50
+ def executions_by_class
32
51
  h = {}
33
- class_executions(klass).each do |execution|
34
- h[execution.dsl.name] ||= {}
52
+ executions.each do |execution|
53
+ h[execution.klass] ||= {}
54
+ h[execution.klass][execution.dsl.name] ||= []
55
+ execution_h = {
56
+ arguments: execution.arguments.to_h,
57
+ method_calls: {}
58
+ }
35
59
  execution.method_calls.method_calls.each do |method_call|
36
- h[execution.dsl.name][method_call.method_name] ||= []
37
- h[execution.dsl.name][method_call.method_name] << method_call.to_h
60
+ execution_h[:method_calls][method_call.method_name] ||= []
61
+ execution_h[:method_calls][method_call.method_name] << method_call.to_h
38
62
  end
63
+ h[execution.klass][execution.dsl.name] << execution_h
39
64
  end
40
65
  h
41
66
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DSLCompose
4
- VERSION = "1.1.0"
4
+ VERSION = "1.3.0"
5
5
  end
data/lib/dsl_compose.rb CHANGED
@@ -2,18 +2,20 @@
2
2
 
3
3
  require "dsl_compose/version"
4
4
 
5
- require "dsl_compose/dsl/dsl_method/argument/equal_to_validation"
6
- require "dsl_compose/dsl/dsl_method/argument/format_validation"
7
- require "dsl_compose/dsl/dsl_method/argument/greater_than_or_equal_to_validation"
8
- require "dsl_compose/dsl/dsl_method/argument/greater_than_validation"
9
- require "dsl_compose/dsl/dsl_method/argument/in_validation"
10
- require "dsl_compose/dsl/dsl_method/argument/length_validation"
11
- require "dsl_compose/dsl/dsl_method/argument/less_than_or_equal_to_validation"
12
- require "dsl_compose/dsl/dsl_method/argument/less_than_validation"
13
- require "dsl_compose/dsl/dsl_method/argument/not_in_validation"
14
-
15
- require "dsl_compose/dsl/dsl_method/argument/interpreter"
16
- require "dsl_compose/dsl/dsl_method/argument"
5
+ require "dsl_compose/dsl/arguments/argument/equal_to_validation"
6
+ require "dsl_compose/dsl/arguments/argument/format_validation"
7
+ require "dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation"
8
+ require "dsl_compose/dsl/arguments/argument/greater_than_validation"
9
+ require "dsl_compose/dsl/arguments/argument/in_validation"
10
+ require "dsl_compose/dsl/arguments/argument/length_validation"
11
+ require "dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation"
12
+ require "dsl_compose/dsl/arguments/argument/less_than_validation"
13
+ require "dsl_compose/dsl/arguments/argument/not_in_validation"
14
+
15
+ require "dsl_compose/dsl/arguments/argument/interpreter"
16
+ require "dsl_compose/dsl/arguments/argument"
17
+ require "dsl_compose/dsl/arguments"
18
+
17
19
  require "dsl_compose/dsl/dsl_method/interpreter"
18
20
  require "dsl_compose/dsl/dsl_method"
19
21
 
@@ -23,6 +25,7 @@ require "dsl_compose/dsl"
23
25
 
24
26
  require "dsl_compose/interpreter/execution/method_calls/method_call"
25
27
  require "dsl_compose/interpreter/execution/method_calls"
28
+ require "dsl_compose/interpreter/execution/arguments"
26
29
  require "dsl_compose/interpreter/execution"
27
30
  require "dsl_compose/interpreter"
28
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dsl_compose
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Craig Ulliott
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-20 00:00:00.000000000 Z
11
+ date: 2023-06-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby gem to add dynamic DSLs to classes. DSLs are added to classes by
14
14
  including the DSLCompose module, and then calling the add_dsl singleton method within
@@ -26,23 +26,25 @@ files:
26
26
  - lib/dsl_compose.rb
27
27
  - lib/dsl_compose/composer.rb
28
28
  - lib/dsl_compose/dsl.rb
29
+ - lib/dsl_compose/dsl/arguments.rb
30
+ - lib/dsl_compose/dsl/arguments/argument.rb
31
+ - lib/dsl_compose/dsl/arguments/argument/equal_to_validation.rb
32
+ - lib/dsl_compose/dsl/arguments/argument/format_validation.rb
33
+ - lib/dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation.rb
34
+ - lib/dsl_compose/dsl/arguments/argument/greater_than_validation.rb
35
+ - lib/dsl_compose/dsl/arguments/argument/in_validation.rb
36
+ - lib/dsl_compose/dsl/arguments/argument/interpreter.rb
37
+ - lib/dsl_compose/dsl/arguments/argument/length_validation.rb
38
+ - lib/dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation.rb
39
+ - lib/dsl_compose/dsl/arguments/argument/less_than_validation.rb
40
+ - lib/dsl_compose/dsl/arguments/argument/not_in_validation.rb
29
41
  - lib/dsl_compose/dsl/dsl_method.rb
30
- - lib/dsl_compose/dsl/dsl_method/argument.rb
31
- - lib/dsl_compose/dsl/dsl_method/argument/equal_to_validation.rb
32
- - lib/dsl_compose/dsl/dsl_method/argument/format_validation.rb
33
- - lib/dsl_compose/dsl/dsl_method/argument/greater_than_or_equal_to_validation.rb
34
- - lib/dsl_compose/dsl/dsl_method/argument/greater_than_validation.rb
35
- - lib/dsl_compose/dsl/dsl_method/argument/in_validation.rb
36
- - lib/dsl_compose/dsl/dsl_method/argument/interpreter.rb
37
- - lib/dsl_compose/dsl/dsl_method/argument/length_validation.rb
38
- - lib/dsl_compose/dsl/dsl_method/argument/less_than_or_equal_to_validation.rb
39
- - lib/dsl_compose/dsl/dsl_method/argument/less_than_validation.rb
40
- - lib/dsl_compose/dsl/dsl_method/argument/not_in_validation.rb
41
42
  - lib/dsl_compose/dsl/dsl_method/interpreter.rb
42
43
  - lib/dsl_compose/dsl/interpreter.rb
43
44
  - lib/dsl_compose/dsls.rb
44
45
  - lib/dsl_compose/interpreter.rb
45
46
  - lib/dsl_compose/interpreter/execution.rb
47
+ - lib/dsl_compose/interpreter/execution/arguments.rb
46
48
  - lib/dsl_compose/interpreter/execution/method_calls.rb
47
49
  - lib/dsl_compose/interpreter/execution/method_calls/method_call.rb
48
50
  - lib/dsl_compose/version.rb