dsl_compose 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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