dsl_compose 1.6.0 → 1.7.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/dsl_compose/composer.rb +3 -12
- data/lib/dsl_compose/dsl/arguments/argument/equal_to_validation.rb +1 -4
- data/lib/dsl_compose/dsl/arguments/argument/format_validation.rb +1 -4
- data/lib/dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation.rb +2 -8
- data/lib/dsl_compose/dsl/arguments/argument/greater_than_validation.rb +2 -8
- data/lib/dsl_compose/dsl/arguments/argument/in_validation.rb +2 -8
- data/lib/dsl_compose/dsl/arguments/argument/length_validation.rb +3 -6
- data/lib/dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation.rb +2 -8
- data/lib/dsl_compose/dsl/arguments/argument/less_than_validation.rb +2 -8
- data/lib/dsl_compose/dsl/arguments/argument/not_in_validation.rb +2 -8
- data/lib/dsl_compose/dsl/arguments/argument.rb +38 -50
- data/lib/dsl_compose/dsl/arguments.rb +5 -20
- data/lib/dsl_compose/dsl/dsl_method.rb +6 -46
- data/lib/dsl_compose/dsl.rb +8 -24
- data/lib/dsl_compose/dsls.rb +4 -13
- data/lib/dsl_compose/interpreter/execution/arguments.rb +24 -26
- data/lib/dsl_compose/interpreter/execution/method_calls/method_call.rb +0 -24
- data/lib/dsl_compose/interpreter/execution/method_calls.rb +6 -0
- data/lib/dsl_compose/interpreter/execution.rb +3 -8
- data/lib/dsl_compose/interpreter.rb +8 -0
- data/lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser/for_method_parser.rb +4 -10
- data/lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser.rb +4 -10
- data/lib/dsl_compose/parser/for_children_of_parser.rb +3 -9
- data/lib/dsl_compose/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 461fe3b90a0a36703aee0be51b3594472d2fc55ff1eab2b6b5bfabd851446d09
|
4
|
+
data.tar.gz: 65ba43be5dfcefbaf5588744b66fcd73a8266abbea65bcb59699132c43ed47a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d2b86c2398b49217ba29152f68f6666e0bcbe926d4adadaac29b4f4a3d8500b120192c469c4fa25f68b68c58e73782459356a7845bcabb0237076521e4e0f37
|
7
|
+
data.tar.gz: 4f58959006d911cb13d75ccddc1871416736236d0e278844f6beb1c22a546d2e8d3620230931a2108c8949ad346a65ce27f3ae437fd8d55e5563603ad8421d24
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.7.0](https://github.com/craigulliott/dsl_compose/compare/v1.6.0...v1.7.0) (2023-07-07)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* better error messages ([#19](https://github.com/craigulliott/dsl_compose/issues/19)) ([a9afa6c](https://github.com/craigulliott/dsl_compose/commit/a9afa6cb1b7482d0d7a646b6872ca5e969393eb7))
|
9
|
+
|
3
10
|
## [1.6.0](https://github.com/craigulliott/dsl_compose/compare/v1.5.0...v1.6.0) (2023-07-07)
|
4
11
|
|
5
12
|
|
data/lib/dsl_compose/composer.rb
CHANGED
@@ -3,26 +3,17 @@
|
|
3
3
|
module DSLCompose
|
4
4
|
module Composer
|
5
5
|
class ComposerAlreadyInstalledError < StandardError
|
6
|
-
def message
|
7
|
-
"This module has already been included or the define_dsl singleton method already exists for this class."
|
8
|
-
end
|
9
6
|
end
|
10
7
|
|
11
8
|
class MethodAlreadyExistsWithThisDSLNameError < StandardError
|
12
|
-
def message
|
13
|
-
"The `define_dsl` singleton method already exists for this class."
|
14
|
-
end
|
15
9
|
end
|
16
10
|
|
17
11
|
class GetDSLExecutionResultsMethodAlreadyExistsError < StandardError
|
18
|
-
def message
|
19
|
-
"The `dsls` singleton method already exists for this class."
|
20
|
-
end
|
21
12
|
end
|
22
13
|
|
23
14
|
def self.included klass
|
24
15
|
if (klass.private_methods + klass.methods).include? :define_dsl
|
25
|
-
raise ComposerAlreadyInstalledError
|
16
|
+
raise ComposerAlreadyInstalledError, "This module has already been included or the define_dsl singleton method already exists for this class."
|
26
17
|
end
|
27
18
|
|
28
19
|
# create an interpreter for this class which will be shared by all child classes and all
|
@@ -31,7 +22,7 @@ module DSLCompose
|
|
31
22
|
|
32
23
|
# return a specific DSL which is defined for this class
|
33
24
|
if klass.respond_to? :dsls
|
34
|
-
raise GetDSLExecutionResultsMethodAlreadyExistsError
|
25
|
+
raise GetDSLExecutionResultsMethodAlreadyExistsError, "The `dsls` singleton method already exists for this class."
|
35
26
|
end
|
36
27
|
|
37
28
|
klass.define_singleton_method :dsls do
|
@@ -52,7 +43,7 @@ module DSLCompose
|
|
52
43
|
|
53
44
|
# ensure that creating this DSL will not override any existing methods on this class
|
54
45
|
if respond_to? name
|
55
|
-
raise MethodAlreadyExistsWithThisDSLNameError
|
46
|
+
raise MethodAlreadyExistsWithThisDSLNameError, "The `define_dsl` singleton method `#{name}` already exists for this class."
|
56
47
|
end
|
57
48
|
|
58
49
|
# add a singleton method with the name of this new DSL onto our class, this is how our new DSL will be accessed
|
@@ -6,9 +6,6 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class EqualToValidation
|
8
8
|
class ValidationFailedError < StandardError
|
9
|
-
def message
|
10
|
-
"The argument is invalid"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
def initialize value
|
@@ -16,7 +13,7 @@ module DSLCompose
|
|
16
13
|
end
|
17
14
|
|
18
15
|
def validate! value
|
19
|
-
raise ValidationFailedError unless value == @value
|
16
|
+
raise ValidationFailedError, "The argument is invalid. Expected #{@value} but received #{value}" unless value == @value
|
20
17
|
end
|
21
18
|
end
|
22
19
|
end
|
@@ -6,9 +6,6 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class FormatValidation
|
8
8
|
class ValidationFailedError < StandardError
|
9
|
-
def message
|
10
|
-
"The argument is invalid"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
def initialize regex
|
@@ -16,7 +13,7 @@ module DSLCompose
|
|
16
13
|
end
|
17
14
|
|
18
15
|
def validate! value
|
19
|
-
raise ValidationFailedError if @regex.match(value).nil?
|
16
|
+
raise ValidationFailedError, "The argument is invalid. Expected format #{@regex} but received #{value}" if @regex.match(value).nil?
|
20
17
|
end
|
21
18
|
end
|
22
19
|
end
|
@@ -6,27 +6,21 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class GreaterThanOrEqualToValidation
|
8
8
|
class InvalidValueError < StandardError
|
9
|
-
def message
|
10
|
-
"The value provided to validate_greater_than must be a number"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class ValidationFailedError < StandardError
|
15
|
-
def message
|
16
|
-
"The argument is invalid"
|
17
|
-
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def initialize value
|
21
15
|
unless value.is_a?(Numeric)
|
22
|
-
raise InvalidValueError
|
16
|
+
raise InvalidValueError, "The value `#{value}` provided to this validator must be of type number"
|
23
17
|
end
|
24
18
|
|
25
19
|
@value = value
|
26
20
|
end
|
27
21
|
|
28
22
|
def validate! value
|
29
|
-
raise ValidationFailedError unless value >= @value
|
23
|
+
raise ValidationFailedError, "The argument is invalid. Expected greater than or equal to #{@value} but received #{value}" unless value >= @value
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -6,27 +6,21 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class GreaterThanValidation
|
8
8
|
class InvalidValueError < StandardError
|
9
|
-
def message
|
10
|
-
"The value provided to validate_greater_than must be a number"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class ValidationFailedError < StandardError
|
15
|
-
def message
|
16
|
-
"The argument is invalid"
|
17
|
-
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def initialize value
|
21
15
|
unless value.is_a?(Numeric)
|
22
|
-
raise InvalidValueError
|
16
|
+
raise InvalidValueError, "The value `#{value}` provided to this validator must be of type number"
|
23
17
|
end
|
24
18
|
|
25
19
|
@value = value
|
26
20
|
end
|
27
21
|
|
28
22
|
def validate! value
|
29
|
-
raise ValidationFailedError unless value > @value
|
23
|
+
raise ValidationFailedError, "The argument is invalid. Expected greater than #{@value} but received #{value}" unless value > @value
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -6,27 +6,21 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class InValidation
|
8
8
|
class InvalidValueError < StandardError
|
9
|
-
def message
|
10
|
-
"The value provided to validate_greater_than must be a number"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class ValidationFailedError < StandardError
|
15
|
-
def message
|
16
|
-
"The argument is invalid"
|
17
|
-
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def initialize values
|
21
15
|
unless values.is_a?(Array)
|
22
|
-
raise InvalidValueError
|
16
|
+
raise InvalidValueError, "The value `#{values}` provided to this validator must be of type Array"
|
23
17
|
end
|
24
18
|
|
25
19
|
@values = values
|
26
20
|
end
|
27
21
|
|
28
22
|
def validate! value
|
29
|
-
raise ValidationFailedError unless @values.include? value
|
23
|
+
raise ValidationFailedError, "The argument is invalid. Expected in #{@values} but received #{value}" unless @values.include? value
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -6,9 +6,6 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class LengthValidation
|
8
8
|
class ValidationFailedError < StandardError
|
9
|
-
def message
|
10
|
-
"The argument is invalid"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
def initialize maximum: nil, minimum: nil, is: nil
|
@@ -20,17 +17,17 @@ module DSLCompose
|
|
20
17
|
def validate! value
|
21
18
|
maximum = @maximum
|
22
19
|
unless maximum.nil?
|
23
|
-
raise ValidationFailedError if value.length > maximum
|
20
|
+
raise ValidationFailedError, "The argument is invalid. Expected #{value} to be less than or equal to #{maximum} characters" if value.length > maximum
|
24
21
|
end
|
25
22
|
|
26
23
|
minimum = @minimum
|
27
24
|
unless minimum.nil?
|
28
|
-
raise ValidationFailedError if value.length < minimum
|
25
|
+
raise ValidationFailedError, "The argument is invalid. Expected #{value} to be greater than or equal to #{minimum} characters" if value.length < minimum
|
29
26
|
end
|
30
27
|
|
31
28
|
is = @is
|
32
29
|
unless is.nil?
|
33
|
-
raise ValidationFailedError if value.length != is
|
30
|
+
raise ValidationFailedError, "The argument is invalid. Expected #{value} to be #{is} characters long" if value.length != is
|
34
31
|
end
|
35
32
|
|
36
33
|
true
|
@@ -6,27 +6,21 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class LessThanOrEqualToValidation
|
8
8
|
class InvalidValueError < StandardError
|
9
|
-
def message
|
10
|
-
"The value provided to validate_greater_than must be a number"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class ValidationFailedError < StandardError
|
15
|
-
def message
|
16
|
-
"The argument is invalid"
|
17
|
-
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def initialize value
|
21
15
|
unless value.is_a?(Numeric)
|
22
|
-
raise InvalidValueError
|
16
|
+
raise InvalidValueError, "The value `#{value}` provided to this validator must be of type number"
|
23
17
|
end
|
24
18
|
|
25
19
|
@value = value
|
26
20
|
end
|
27
21
|
|
28
22
|
def validate! value
|
29
|
-
raise ValidationFailedError unless value <= @value
|
23
|
+
raise ValidationFailedError, "The argument is invalid. Expected less than or equal to #{@value} but received #{value}" unless value <= @value
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -6,27 +6,21 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class LessThanValidation
|
8
8
|
class InvalidValueError < StandardError
|
9
|
-
def message
|
10
|
-
"The value provided to validate_greater_than must be a number"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class ValidationFailedError < StandardError
|
15
|
-
def message
|
16
|
-
"The argument is invalid"
|
17
|
-
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def initialize value
|
21
15
|
unless value.is_a?(Numeric)
|
22
|
-
raise InvalidValueError
|
16
|
+
raise InvalidValueError, "The value `#{value}` provided to this validator must be of type number"
|
23
17
|
end
|
24
18
|
|
25
19
|
@value = value
|
26
20
|
end
|
27
21
|
|
28
22
|
def validate! value
|
29
|
-
raise ValidationFailedError unless value < @value
|
23
|
+
raise ValidationFailedError, "The argument is invalid. Expected less than #{@value} but received #{value}" unless value < @value
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -6,27 +6,21 @@ module DSLCompose
|
|
6
6
|
class Argument
|
7
7
|
class NotInValidation
|
8
8
|
class InvalidValueError < StandardError
|
9
|
-
def message
|
10
|
-
"The value provided to validate_greater_than must be a number"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class ValidationFailedError < StandardError
|
15
|
-
def message
|
16
|
-
"The argument is invalid"
|
17
|
-
end
|
18
12
|
end
|
19
13
|
|
20
14
|
def initialize values
|
21
15
|
unless values.is_a?(Array)
|
22
|
-
raise InvalidValueError
|
16
|
+
raise InvalidValueError, "The value `#{values}` provided to this validator must be of type Array"
|
23
17
|
end
|
24
18
|
|
25
19
|
@values = values
|
26
20
|
end
|
27
21
|
|
28
22
|
def validate! value
|
29
|
-
raise ValidationFailedError if @values.include?(value)
|
23
|
+
raise ValidationFailedError, "The argument is invalid. Expected not in #{@values} but received #{value}" if @values.include?(value)
|
30
24
|
end
|
31
25
|
end
|
32
26
|
end
|
@@ -5,45 +5,27 @@ module DSLCompose
|
|
5
5
|
class Arguments
|
6
6
|
class Argument
|
7
7
|
class ValidationIncompatibleError < StandardError
|
8
|
-
def message
|
9
|
-
"The validation is not compatible with this argument type"
|
10
|
-
end
|
11
8
|
end
|
12
9
|
|
13
10
|
class ValidationAlreadyExistsError < StandardError
|
14
|
-
def message
|
15
|
-
"This validation has already been applied to this method option."
|
16
|
-
end
|
17
11
|
end
|
18
12
|
|
19
13
|
class InvalidTypeError < StandardError
|
20
|
-
def message
|
21
|
-
"Argument type must be one of :integer, :boolean, :float, :string or :symbol"
|
22
|
-
end
|
23
14
|
end
|
24
15
|
|
25
16
|
class InvalidNameError < StandardError
|
26
|
-
def message
|
27
|
-
"The option name is invalid, it must be of type symbol."
|
28
|
-
end
|
29
17
|
end
|
30
18
|
|
31
19
|
class InvalidDescriptionError < StandardError
|
32
|
-
def message
|
33
|
-
"The option description is invalid, it must be of type string and have length greater than 0."
|
34
|
-
end
|
35
20
|
end
|
36
21
|
|
37
22
|
class DescriptionAlreadyExistsError < StandardError
|
38
|
-
def message
|
39
|
-
"The description has already been set"
|
40
|
-
end
|
41
23
|
end
|
42
24
|
|
43
25
|
class ArgumentNameReservedError < StandardError
|
44
|
-
|
45
|
-
|
46
|
-
|
26
|
+
end
|
27
|
+
|
28
|
+
class ValidationInvalidArgumentError < StandardError
|
47
29
|
end
|
48
30
|
|
49
31
|
RESERVED_ARGUMENT_NAMES = [
|
@@ -87,18 +69,18 @@ module DSLCompose
|
|
87
69
|
if name.is_a? Symbol
|
88
70
|
|
89
71
|
if RESERVED_ARGUMENT_NAMES.include? name
|
90
|
-
raise ArgumentNameReservedError
|
72
|
+
raise ArgumentNameReservedError, "This argument name `#{name}` is a reserved word. The names #{RESERVED_ARGUMENT_NAMES.join ", "} can not be used here because the Parser uses them to express a structural part of the DSL"
|
91
73
|
end
|
92
74
|
|
93
75
|
@name = name
|
94
76
|
else
|
95
|
-
raise InvalidNameError
|
77
|
+
raise InvalidNameError, "The option name `#{name}` is invalid, it must be of type symbol."
|
96
78
|
end
|
97
79
|
|
98
80
|
if type == :integer || type == :boolean || type == :float || type == :string || type == :symbol
|
99
81
|
@type = type
|
100
82
|
else
|
101
|
-
raise InvalidTypeError
|
83
|
+
raise InvalidTypeError, "Argument type `#{type}` must be one of :integer, :boolean, :float, :string or :symbol"
|
102
84
|
end
|
103
85
|
|
104
86
|
@required = required ? true : false
|
@@ -111,6 +93,8 @@ module DSLCompose
|
|
111
93
|
if block
|
112
94
|
Interpreter.new(self).instance_eval(&block)
|
113
95
|
end
|
96
|
+
rescue => e
|
97
|
+
raise e, "Error defining argument #{name}: #{e.message}", e.backtrace
|
114
98
|
end
|
115
99
|
|
116
100
|
# Set the description for this Argument to the provided value.
|
@@ -119,11 +103,11 @@ module DSLCompose
|
|
119
103
|
# The `description` can only be set once per Argument
|
120
104
|
def set_description description
|
121
105
|
unless description.is_a?(String) && description.length > 0
|
122
|
-
raise InvalidDescriptionError
|
106
|
+
raise InvalidDescriptionError, "The option description `#{description}` is invalid, it must be of type string and have length greater than 0."
|
123
107
|
end
|
124
108
|
|
125
109
|
if has_description?
|
126
|
-
raise DescriptionAlreadyExistsError
|
110
|
+
raise DescriptionAlreadyExistsError, "The description has already been set"
|
127
111
|
end
|
128
112
|
|
129
113
|
@description = description
|
@@ -146,11 +130,15 @@ module DSLCompose
|
|
146
130
|
|
147
131
|
def validate_greater_than value
|
148
132
|
if @greater_than_validation
|
149
|
-
raise ValidationAlreadyExistsError
|
133
|
+
raise ValidationAlreadyExistsError, "The validation `greater_than` has already been applied to this method option."
|
134
|
+
end
|
135
|
+
|
136
|
+
unless value.is_a?(Numeric)
|
137
|
+
raise ValidationInvalidArgumentError, value
|
150
138
|
end
|
151
139
|
|
152
140
|
unless @type == :integer || @type == :float
|
153
|
-
raise ValidationIncompatibleError
|
141
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
154
142
|
end
|
155
143
|
|
156
144
|
@greater_than_validation = GreaterThanValidation.new value
|
@@ -158,15 +146,15 @@ module DSLCompose
|
|
158
146
|
|
159
147
|
def validate_greater_than_or_equal_to value
|
160
148
|
if @greater_than_or_equal_to_validation
|
161
|
-
raise ValidationAlreadyExistsError
|
149
|
+
raise ValidationAlreadyExistsError, "The validation `greater_than_or_equal_to` has already been applied to this method option."
|
162
150
|
end
|
163
151
|
|
164
152
|
unless value.is_a?(Numeric)
|
165
|
-
raise ValidationInvalidArgumentError
|
153
|
+
raise ValidationInvalidArgumentError, value
|
166
154
|
end
|
167
155
|
|
168
156
|
unless @type == :integer || @type == :float
|
169
|
-
raise ValidationIncompatibleError
|
157
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
170
158
|
end
|
171
159
|
|
172
160
|
@greater_than_or_equal_to_validation = GreaterThanOrEqualToValidation.new value
|
@@ -174,15 +162,15 @@ module DSLCompose
|
|
174
162
|
|
175
163
|
def validate_less_than value
|
176
164
|
if @less_than_validation
|
177
|
-
raise ValidationAlreadyExistsError
|
165
|
+
raise ValidationAlreadyExistsError, "The validation `less_than` has already been applied to this method option."
|
178
166
|
end
|
179
167
|
|
180
168
|
unless value.is_a?(Numeric)
|
181
|
-
raise ValidationInvalidArgumentError
|
169
|
+
raise ValidationInvalidArgumentError, value
|
182
170
|
end
|
183
171
|
|
184
172
|
unless @type == :integer || @type == :float
|
185
|
-
raise ValidationIncompatibleError
|
173
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
186
174
|
end
|
187
175
|
|
188
176
|
@less_than_validation = LessThanValidation.new value
|
@@ -190,15 +178,15 @@ module DSLCompose
|
|
190
178
|
|
191
179
|
def validate_less_than_or_equal_to value
|
192
180
|
if @less_than_or_equal_to_validation
|
193
|
-
raise ValidationAlreadyExistsError
|
181
|
+
raise ValidationAlreadyExistsError, "The validation `less_than_or_equal_to` has already been applied to this method option."
|
194
182
|
end
|
195
183
|
|
196
184
|
unless value.is_a?(Numeric)
|
197
|
-
raise ValidationInvalidArgumentError
|
185
|
+
raise ValidationInvalidArgumentError, value
|
198
186
|
end
|
199
187
|
|
200
188
|
unless @type == :integer || @type == :float
|
201
|
-
raise ValidationIncompatibleError
|
189
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
202
190
|
end
|
203
191
|
|
204
192
|
@less_than_or_equal_to_validation = LessThanOrEqualToValidation.new value
|
@@ -206,26 +194,26 @@ module DSLCompose
|
|
206
194
|
|
207
195
|
def validate_format regexp
|
208
196
|
if @format_validation
|
209
|
-
raise ValidationAlreadyExistsError
|
197
|
+
raise ValidationAlreadyExistsError, "The validation `format` has already been applied to this method option."
|
210
198
|
end
|
211
199
|
|
212
200
|
unless regexp.is_a? Regexp
|
213
|
-
raise ValidationInvalidArgumentError
|
201
|
+
raise ValidationInvalidArgumentError, regexp
|
214
202
|
end
|
215
203
|
|
216
204
|
unless @type == :string || @type == :symbol
|
217
|
-
raise ValidationIncompatibleError
|
205
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
218
206
|
end
|
219
207
|
@format_validation = FormatValidation.new regexp
|
220
208
|
end
|
221
209
|
|
222
210
|
def validate_equal_to value
|
223
211
|
if @equal_to_validation
|
224
|
-
raise ValidationAlreadyExistsError
|
212
|
+
raise ValidationAlreadyExistsError, "The validation `equal_to` has already been applied to this method option."
|
225
213
|
end
|
226
214
|
|
227
215
|
unless @type == :integer || @type == :float || @type == :string || @type == :symbol || @type == :boolean
|
228
|
-
raise ValidationIncompatibleError
|
216
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
229
217
|
end
|
230
218
|
|
231
219
|
@equal_to_validation = EqualToValidation.new value
|
@@ -233,15 +221,15 @@ module DSLCompose
|
|
233
221
|
|
234
222
|
def validate_in values
|
235
223
|
if @in_validation
|
236
|
-
raise ValidationAlreadyExistsError
|
224
|
+
raise ValidationAlreadyExistsError, "The validation `in` has already been applied to this method option."
|
237
225
|
end
|
238
226
|
|
239
227
|
unless values.is_a? Array
|
240
|
-
raise ValidationInvalidArgumentError
|
228
|
+
raise ValidationInvalidArgumentError, values
|
241
229
|
end
|
242
230
|
|
243
231
|
unless @type == :integer || @type == :float || @type == :string || @type == :symbol
|
244
|
-
raise ValidationIncompatibleError
|
232
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
245
233
|
end
|
246
234
|
|
247
235
|
@in_validation = InValidation.new values
|
@@ -249,15 +237,15 @@ module DSLCompose
|
|
249
237
|
|
250
238
|
def validate_not_in values
|
251
239
|
if @not_in_validation
|
252
|
-
raise ValidationAlreadyExistsError
|
240
|
+
raise ValidationAlreadyExistsError, "The validation `not_in` has already been applied to this method option."
|
253
241
|
end
|
254
242
|
|
255
243
|
unless values.is_a? Array
|
256
|
-
raise ValidationInvalidArgumentError
|
244
|
+
raise ValidationInvalidArgumentError, values
|
257
245
|
end
|
258
246
|
|
259
247
|
unless @type == :integer || @type == :float || @type == :string || @type == :symbol
|
260
|
-
raise ValidationIncompatibleError
|
248
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
261
249
|
end
|
262
250
|
|
263
251
|
@not_in_validation = NotInValidation.new values
|
@@ -265,11 +253,11 @@ module DSLCompose
|
|
265
253
|
|
266
254
|
def validate_length maximum: nil, minimum: nil, is: nil
|
267
255
|
if @length_validation
|
268
|
-
raise ValidationAlreadyExistsError
|
256
|
+
raise ValidationAlreadyExistsError, "The validation `length` has already been applied to this method option."
|
269
257
|
end
|
270
258
|
|
271
259
|
unless @type == :string || @type == :symbol
|
272
|
-
raise ValidationIncompatibleError
|
260
|
+
raise ValidationIncompatibleError, "The validation type #{@type} is not compatible with this argument type"
|
273
261
|
end
|
274
262
|
|
275
263
|
@length_validation = LengthValidation.new(maximum: maximum, minimum: minimum, is: is)
|
@@ -4,33 +4,18 @@ module DSLCompose
|
|
4
4
|
class DSL
|
5
5
|
class Arguments
|
6
6
|
class ArgumentDoesNotExistError < StandardError
|
7
|
-
def message
|
8
|
-
"This argument does not exist for this DSLMethod"
|
9
|
-
end
|
10
7
|
end
|
11
8
|
|
12
9
|
class ArgumentOrderingError < StandardError
|
13
|
-
def message
|
14
|
-
"Required arguments can not be added after optional ones"
|
15
|
-
end
|
16
10
|
end
|
17
11
|
|
18
12
|
class ArgumentAlreadyExistsError < StandardError
|
19
|
-
def message
|
20
|
-
"An argument with this name already exists for this DSL method"
|
21
|
-
end
|
22
13
|
end
|
23
14
|
|
24
15
|
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
16
|
end
|
29
17
|
|
30
18
|
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
19
|
end
|
35
20
|
|
36
21
|
def initialize
|
@@ -58,7 +43,7 @@ module DSLCompose
|
|
58
43
|
if has_argument? name
|
59
44
|
@arguments[name]
|
60
45
|
else
|
61
|
-
raise ArgumentDoesNotExistError
|
46
|
+
raise ArgumentDoesNotExistError, "The argument `#{name}` does not exist for this DSLMethod"
|
62
47
|
end
|
63
48
|
end
|
64
49
|
|
@@ -69,7 +54,7 @@ module DSLCompose
|
|
69
54
|
if arg.optional?
|
70
55
|
@arguments[name]
|
71
56
|
else
|
72
|
-
raise RequestedOptionalArgumentIsRequiredError
|
57
|
+
raise RequestedOptionalArgumentIsRequiredError, "A specific argument `#{name}` which was expected to be optional was requested, but the argument found was flagged as required"
|
73
58
|
end
|
74
59
|
end
|
75
60
|
|
@@ -80,7 +65,7 @@ module DSLCompose
|
|
80
65
|
if arg.required?
|
81
66
|
@arguments[name]
|
82
67
|
else
|
83
|
-
raise RequestedRequiredArgumentIsOptionalError
|
68
|
+
raise RequestedRequiredArgumentIsOptionalError, "A specific argument `#{name}` which was expected to be required was requested, but the argument found was flagged as optional"
|
84
69
|
end
|
85
70
|
end
|
86
71
|
|
@@ -98,12 +83,12 @@ module DSLCompose
|
|
98
83
|
# or optional on the method which is exposed in our DSL.
|
99
84
|
def add_argument name, required, type, &block
|
100
85
|
if @arguments.key? name
|
101
|
-
raise ArgumentAlreadyExistsError
|
86
|
+
raise ArgumentAlreadyExistsError, "An argument with the name `#{name}` already exists for this DSL method"
|
102
87
|
end
|
103
88
|
|
104
89
|
# required arguments may not come after optional ones
|
105
90
|
if required && optional_arguments.any?
|
106
|
-
raise ArgumentOrderingError
|
91
|
+
raise ArgumentOrderingError, "Required arguments can not be added after optional ones"
|
107
92
|
end
|
108
93
|
|
109
94
|
@arguments[name] = Argument.new(name, required, type, &block)
|
@@ -3,58 +3,16 @@
|
|
3
3
|
module DSLCompose
|
4
4
|
class DSL
|
5
5
|
class DSLMethod
|
6
|
-
class ArgumentDoesNotExistError < StandardError
|
7
|
-
def message
|
8
|
-
"This argument does not exist for this DSLMethod"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
6
|
class InvalidNameError < StandardError
|
13
|
-
def message
|
14
|
-
"The method #{method_name} is invalid, it must be of type symbol"
|
15
|
-
end
|
16
7
|
end
|
17
8
|
|
18
9
|
class MethodNameIsReservedError < StandardError
|
19
|
-
def message
|
20
|
-
"This method already would override an existing internal method"
|
21
|
-
end
|
22
10
|
end
|
23
11
|
|
24
12
|
class InvalidDescriptionError < StandardError
|
25
|
-
def message
|
26
|
-
"The DSL method description is invalid, it must be of type string and have length greater than 0"
|
27
|
-
end
|
28
13
|
end
|
29
14
|
|
30
15
|
class DescriptionAlreadyExistsError < StandardError
|
31
|
-
def message
|
32
|
-
"The description has already been set"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class ArgumentOrderingError < StandardError
|
37
|
-
def message
|
38
|
-
"Required arguments can not be added after optional ones"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class ArgumentAlreadyExistsError < StandardError
|
43
|
-
def message
|
44
|
-
"An argument with this name already exists for this DSL method"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class RequestedOptionalArgumentIsRequiredError < StandardError
|
49
|
-
def message
|
50
|
-
"A specific argument which was expected to be optional was requested, but the argument found was flagged as required"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class RequestedRequiredArgumentIsOptionalError < StandardError
|
55
|
-
def message
|
56
|
-
"A specific argument which was expected to be required was requested, but the argument found was flagged as optional"
|
57
|
-
end
|
58
16
|
end
|
59
17
|
|
60
18
|
# The name of this DSLMethod.
|
@@ -82,12 +40,12 @@ module DSLCompose
|
|
82
40
|
|
83
41
|
# don't allow methods to override existing internal methods
|
84
42
|
if Class.respond_to? name
|
85
|
-
raise MethodNameIsReservedError
|
43
|
+
raise MethodNameIsReservedError, "This method #{name} would override an existing internal method"
|
86
44
|
end
|
87
45
|
|
88
46
|
@name = name
|
89
47
|
else
|
90
|
-
raise InvalidNameError
|
48
|
+
raise InvalidNameError, "The method name `#{name}` is invalid, it must be of type symbol"
|
91
49
|
end
|
92
50
|
|
93
51
|
@unique = unique ? true : false
|
@@ -101,6 +59,8 @@ module DSLCompose
|
|
101
59
|
if block
|
102
60
|
Interpreter.new(self).instance_eval(&block)
|
103
61
|
end
|
62
|
+
rescue => e
|
63
|
+
raise e, "Error defining method #{name}: #{e.message}", e.backtrace
|
104
64
|
end
|
105
65
|
|
106
66
|
# Set the description for this DSLMethod to the provided value.
|
@@ -109,11 +69,11 @@ module DSLCompose
|
|
109
69
|
# The `description` can only be set once per DSLMethod
|
110
70
|
def set_description description
|
111
71
|
unless description.is_a?(String) && description.length > 0
|
112
|
-
raise InvalidDescriptionError
|
72
|
+
raise InvalidDescriptionError, "The DSL method description `#{description}` is invalid, it must be of type string and have length greater than 0"
|
113
73
|
end
|
114
74
|
|
115
75
|
if has_description?
|
116
|
-
raise DescriptionAlreadyExistsError
|
76
|
+
raise DescriptionAlreadyExistsError, "The description has already been set"
|
117
77
|
end
|
118
78
|
|
119
79
|
@description = description
|
data/lib/dsl_compose/dsl.rb
CHANGED
@@ -7,39 +7,21 @@ module DSLCompose
|
|
7
7
|
# by calling `define_dsl` in a class and passing it a block which contains the DSL definition
|
8
8
|
class DSL
|
9
9
|
class MethodDoesNotExistError < StandardError
|
10
|
-
def message
|
11
|
-
"This method does not exist for this DSL"
|
12
|
-
end
|
13
10
|
end
|
14
11
|
|
15
12
|
class MethodAlreadyExistsError < StandardError
|
16
|
-
def message
|
17
|
-
"This method already exists for this DSL"
|
18
|
-
end
|
19
13
|
end
|
20
14
|
|
21
15
|
class InvalidNameError < StandardError
|
22
|
-
def message
|
23
|
-
"This DSL name is invalid, it must be of type symbol"
|
24
|
-
end
|
25
16
|
end
|
26
17
|
|
27
18
|
class InvalidDescriptionError < StandardError
|
28
|
-
def message
|
29
|
-
"This DSL description is invalid, it must be of type string and have length greater than 0"
|
30
|
-
end
|
31
19
|
end
|
32
20
|
|
33
21
|
class DescriptionAlreadyExistsError < StandardError
|
34
|
-
def message
|
35
|
-
"The DSL description has already been set"
|
36
|
-
end
|
37
22
|
end
|
38
23
|
|
39
24
|
class NoBlockProvidedError < StandardError
|
40
|
-
def message
|
41
|
-
"No block was provided for this DSL"
|
42
|
-
end
|
43
25
|
end
|
44
26
|
|
45
27
|
# The name of this DSL.
|
@@ -64,7 +46,7 @@ module DSLCompose
|
|
64
46
|
if name.is_a? Symbol
|
65
47
|
@name = name
|
66
48
|
else
|
67
|
-
raise InvalidNameError
|
49
|
+
raise InvalidNameError, "The DSL name `#{name}` is invalid, it must be of type symbol"
|
68
50
|
end
|
69
51
|
|
70
52
|
@klass = klass
|
@@ -81,8 +63,10 @@ module DSLCompose
|
|
81
63
|
# would have access to all of the methods defined in here.
|
82
64
|
Interpreter.new(self).instance_eval(&block)
|
83
65
|
else
|
84
|
-
raise NoBlockProvidedError
|
66
|
+
raise NoBlockProvidedError, "No block was provided for this DSL"
|
85
67
|
end
|
68
|
+
rescue => e
|
69
|
+
raise e, "Error defining DSL #{@name} on #{@klass}: #{e.message}", e.backtrace
|
86
70
|
end
|
87
71
|
|
88
72
|
# Set the description for this DSL to the provided value.
|
@@ -91,11 +75,11 @@ module DSLCompose
|
|
91
75
|
# The `description` can only be set once per DSL
|
92
76
|
def set_description description
|
93
77
|
unless description.is_a?(String) && description.length > 0
|
94
|
-
raise InvalidDescriptionError
|
78
|
+
raise InvalidDescriptionError, "The DSL description `#{description}` is invalid, it must be of type string and have length greater than 0"
|
95
79
|
end
|
96
80
|
|
97
81
|
if has_description?
|
98
|
-
raise DescriptionAlreadyExistsError
|
82
|
+
raise DescriptionAlreadyExistsError, "The DSL description has already been set"
|
99
83
|
end
|
100
84
|
|
101
85
|
@description = description
|
@@ -112,7 +96,7 @@ module DSLCompose
|
|
112
96
|
# Method `name` must be unique within the DSL.
|
113
97
|
def add_method name, unique, required, &block
|
114
98
|
if has_dsl_method? name
|
115
|
-
raise MethodAlreadyExistsError
|
99
|
+
raise MethodAlreadyExistsError, "The method `#{name}` already exists for this DSL"
|
116
100
|
end
|
117
101
|
|
118
102
|
@dsl_methods[name] = DSLMethod.new(name, unique, required, &block)
|
@@ -139,7 +123,7 @@ module DSLCompose
|
|
139
123
|
if has_dsl_method? name
|
140
124
|
@dsl_methods[name]
|
141
125
|
else
|
142
|
-
raise MethodDoesNotExistError
|
126
|
+
raise MethodDoesNotExistError, "The method `#{name}` does not exist for this DSL"
|
143
127
|
end
|
144
128
|
end
|
145
129
|
|
data/lib/dsl_compose/dsls.rb
CHANGED
@@ -3,21 +3,12 @@
|
|
3
3
|
module DSLCompose
|
4
4
|
module DSLs
|
5
5
|
class ClassDSLDefinitionDoesNotExistError < StandardError
|
6
|
-
def message
|
7
|
-
"The requested DSL does not exist on this class"
|
8
|
-
end
|
9
6
|
end
|
10
7
|
|
11
8
|
class DSLAlreadyExistsError < StandardError
|
12
|
-
def message
|
13
|
-
"A DSL with this name already exists"
|
14
|
-
end
|
15
9
|
end
|
16
10
|
|
17
11
|
class NoDSLDefinitionsForClassError < StandardError
|
18
|
-
def message
|
19
|
-
"No DSLs have been defined for this class"
|
20
|
-
end
|
21
12
|
end
|
22
13
|
|
23
14
|
# an object to hold all of the defined DSLs in our application, the DSLs are
|
@@ -30,7 +21,7 @@ module DSLCompose
|
|
30
21
|
@dsls[klass] ||= {}
|
31
22
|
|
32
23
|
if @dsls[klass].key? name
|
33
|
-
raise DSLAlreadyExistsError
|
24
|
+
raise DSLAlreadyExistsError, "A DSL with the name `#{name}` already exists"
|
34
25
|
end
|
35
26
|
|
36
27
|
@dsls[klass][name] = DSLCompose::DSL.new(name, klass)
|
@@ -53,7 +44,7 @@ module DSLCompose
|
|
53
44
|
if @dsls.key? klass
|
54
45
|
@dsls[klass].values
|
55
46
|
else
|
56
|
-
raise NoDSLDefinitionsForClassError
|
47
|
+
raise NoDSLDefinitionsForClassError, "No DSLs have been defined for this class"
|
57
48
|
end
|
58
49
|
end
|
59
50
|
|
@@ -64,10 +55,10 @@ module DSLCompose
|
|
64
55
|
if @dsls[klass].key? name
|
65
56
|
@dsls[klass][name]
|
66
57
|
else
|
67
|
-
raise ClassDSLDefinitionDoesNotExistError
|
58
|
+
raise ClassDSLDefinitionDoesNotExistError, "The requested DSL `#{name}` does not exist on this class"
|
68
59
|
end
|
69
60
|
else
|
70
|
-
raise NoDSLDefinitionsForClassError
|
61
|
+
raise NoDSLDefinitionsForClassError, "No DSLs have been defined for this class"
|
71
62
|
end
|
72
63
|
end
|
73
64
|
|
@@ -5,27 +5,15 @@ module DSLCompose
|
|
5
5
|
class Execution
|
6
6
|
class Arguments
|
7
7
|
class MissingRequiredArgumentsError < StandardError
|
8
|
-
def initialize required_count, provided_count
|
9
|
-
super "This requires #{required_count} arguments, but only #{provided_count} were provided"
|
10
|
-
end
|
11
8
|
end
|
12
9
|
|
13
10
|
class TooManyArgumentsError < StandardError
|
14
|
-
def message
|
15
|
-
"Too many arguments provided"
|
16
|
-
end
|
17
11
|
end
|
18
12
|
|
19
|
-
class
|
20
|
-
def message
|
21
|
-
"If provided, then the optional arguments must be last, and be represented as a Hash"
|
22
|
-
end
|
13
|
+
class OptionalArgumentsShouldBeHashError < StandardError
|
23
14
|
end
|
24
15
|
|
25
16
|
class InvalidArgumentTypeError < StandardError
|
26
|
-
def message
|
27
|
-
"The provided argument is the wrong type"
|
28
|
-
end
|
29
17
|
end
|
30
18
|
|
31
19
|
attr_reader :arguments
|
@@ -45,18 +33,18 @@ module DSLCompose
|
|
45
33
|
|
46
34
|
# assert that a value is provided for every required argument
|
47
35
|
unless required_argument_count == required_args.count
|
48
|
-
raise MissingRequiredArgumentsError
|
36
|
+
raise MissingRequiredArgumentsError, "This requires #{required_argument_count} arguments, but only #{required_args.count} were provided"
|
49
37
|
end
|
50
38
|
|
51
39
|
# assert that too many arguments have not been provided
|
52
40
|
if args.count > required_argument_count + (has_optional_arguments ? 1 : 0)
|
53
|
-
raise TooManyArgumentsError
|
41
|
+
raise TooManyArgumentsError, "Too many arguments provided"
|
54
42
|
end
|
55
43
|
|
56
44
|
# asset that, if provided, then the optional argument (always the last one) is a Hash
|
57
45
|
if has_optional_arguments && optional_arg.nil? === false
|
58
46
|
unless optional_arg.is_a? Hash
|
59
|
-
raise
|
47
|
+
raise OptionalArgumentsShouldBeHashError, "If provided, then the optional arguments must be last, and be represented as a Hash"
|
60
48
|
end
|
61
49
|
|
62
50
|
# assert the each provided optional argument is valid
|
@@ -67,72 +55,82 @@ module DSLCompose
|
|
67
55
|
case optional_argument.type
|
68
56
|
when :integer
|
69
57
|
unless optional_arg_value.is_a? Integer
|
70
|
-
raise InvalidArgumentTypeError
|
58
|
+
raise InvalidArgumentTypeError, "#{optional_arg_value} is not an Integer"
|
71
59
|
end
|
72
60
|
optional_argument.validate_integer! optional_arg_value
|
73
61
|
|
74
62
|
when :symbol
|
75
63
|
unless optional_arg_value.is_a? Symbol
|
76
|
-
raise InvalidArgumentTypeError
|
64
|
+
raise InvalidArgumentTypeError, "#{optional_arg_value} is not a Symbol"
|
77
65
|
end
|
78
66
|
optional_argument.validate_symbol! optional_arg_value
|
79
67
|
|
80
68
|
when :string
|
81
69
|
unless optional_arg_value.is_a? String
|
82
|
-
raise InvalidArgumentTypeError
|
70
|
+
raise InvalidArgumentTypeError, "#{optional_arg_value} is not a String"
|
83
71
|
end
|
84
72
|
optional_argument.validate_string! optional_arg_value
|
85
73
|
|
86
74
|
when :boolean
|
87
75
|
unless optional_arg_value.is_a?(TrueClass) || optional_arg_value.is_a?(FalseClass)
|
88
|
-
raise InvalidArgumentTypeError
|
76
|
+
raise InvalidArgumentTypeError, "#{optional_arg_value} is not a boolean"
|
89
77
|
end
|
90
78
|
optional_argument.validate_boolean! optional_arg_value
|
91
79
|
|
92
80
|
else
|
93
|
-
raise InvalidArgumentTypeError
|
81
|
+
raise InvalidArgumentTypeError, "The argument #{optional_arg_value} is not a supported type"
|
94
82
|
end
|
95
83
|
|
96
84
|
# the provided value appears valid for this argument, save the value
|
97
85
|
@arguments[optional_argument_name] = optional_arg_value
|
86
|
+
|
87
|
+
rescue => e
|
88
|
+
raise e, "Error processing optional argument #{optional_argument_name}: #{e.message}", e.backtrace
|
98
89
|
end
|
99
90
|
|
100
91
|
end
|
101
92
|
|
102
93
|
# validate the value provided to each required argument
|
103
94
|
arguments.required_arguments.each_with_index do |required_argument, i|
|
95
|
+
# make sure we always have an argument_name for the exception below
|
96
|
+
argument_name = nil
|
97
|
+
argument_name = required_argument.name
|
98
|
+
|
104
99
|
arg = args[i]
|
105
100
|
case required_argument.type
|
106
101
|
when :integer
|
107
102
|
unless arg.is_a? Integer
|
108
|
-
raise InvalidArgumentTypeError
|
103
|
+
raise InvalidArgumentTypeError, "#{arg} is not an Integer"
|
109
104
|
end
|
110
105
|
required_argument.validate_integer! arg
|
111
106
|
|
112
107
|
when :symbol
|
113
108
|
unless arg.is_a? Symbol
|
114
|
-
raise InvalidArgumentTypeError
|
109
|
+
raise InvalidArgumentTypeError, "#{arg} is not a Symbol"
|
115
110
|
end
|
116
111
|
required_argument.validate_symbol! arg
|
117
112
|
|
118
113
|
when :string
|
119
114
|
unless arg.is_a? String
|
120
|
-
raise InvalidArgumentTypeError
|
115
|
+
raise InvalidArgumentTypeError, "#{arg} is not a String"
|
121
116
|
end
|
122
117
|
required_argument.validate_string! arg
|
123
118
|
|
124
119
|
when :boolean
|
125
120
|
unless arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
|
126
|
-
raise InvalidArgumentTypeError
|
121
|
+
raise InvalidArgumentTypeError, "#{arg} is not a boolean"
|
127
122
|
end
|
128
123
|
required_argument.validate_boolean! arg
|
129
124
|
|
130
125
|
else
|
131
|
-
raise InvalidArgumentTypeError
|
126
|
+
raise InvalidArgumentTypeError, "The argument #{arg} is not a supported type"
|
132
127
|
end
|
133
128
|
|
134
129
|
# the provided value appears valid for this argument, save the value
|
135
130
|
@arguments[required_argument.name] = arg
|
131
|
+
|
132
|
+
rescue => e
|
133
|
+
raise e, "Error processing required argument #{argument_name}: #{e.message}", e.backtrace
|
136
134
|
end
|
137
135
|
end
|
138
136
|
|
@@ -8,30 +8,6 @@ module DSLCompose
|
|
8
8
|
attr_reader :dsl_method
|
9
9
|
attr_reader :arguments
|
10
10
|
|
11
|
-
class MissingRequiredArgumentsError < StandardError
|
12
|
-
def initialize required_count, provided_count
|
13
|
-
super "This method requires #{required_count} arguments, but only #{required_count} were provided"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class TooManyArgumentsError < StandardError
|
18
|
-
def message
|
19
|
-
"Too many arguments provided to this method"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class OptionalArgsShouldBeHashError < StandardError
|
24
|
-
def message
|
25
|
-
"If provided, then the optional arguments must be last, and be represented as a Hash"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class InvalidArgumentTypeError < StandardError
|
30
|
-
def message
|
31
|
-
"The provided argument is the wrong type"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
11
|
def initialize dsl_method, *args, &block
|
36
12
|
@dsl_method = dsl_method
|
37
13
|
@arguments = Arguments.new(dsl_method.arguments, *args)
|
@@ -15,9 +15,15 @@ module DSLCompose
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def add_method_call dsl_method, *args, &block
|
18
|
+
# make sure we always have a variable which can be used in the exception message
|
19
|
+
dsl_method_name = nil
|
20
|
+
dsl_method_name = dsl_method.name
|
21
|
+
|
18
22
|
method_call = MethodCall.new(dsl_method, *args, &block)
|
19
23
|
@method_calls << method_call
|
20
24
|
method_call
|
25
|
+
rescue => e
|
26
|
+
raise e, "Error while executing method #{dsl_method_name}: #{e.message}", e.backtrace
|
21
27
|
end
|
22
28
|
|
23
29
|
def method_calls_by_name method_name
|
@@ -4,15 +4,9 @@ module DSLCompose
|
|
4
4
|
class Interpreter
|
5
5
|
class Execution
|
6
6
|
class MethodIsUniqueError < StandardError
|
7
|
-
def message
|
8
|
-
"This method is unique and can only be called once within this DSL"
|
9
|
-
end
|
10
7
|
end
|
11
8
|
|
12
9
|
class RequiredMethodNotCalledError < StandardError
|
13
|
-
def message
|
14
|
-
"This method is required, but was not called within this DSL"
|
15
|
-
end
|
16
10
|
end
|
17
11
|
|
18
12
|
attr_reader :dsl
|
@@ -36,7 +30,8 @@ module DSLCompose
|
|
36
30
|
# assert that all required methods have been called at least once
|
37
31
|
dsl.required_dsl_methods.each do |dsl_method|
|
38
32
|
unless @method_calls.method_called? dsl_method.name
|
39
|
-
|
33
|
+
dsl_method_name = dsl_method&.name
|
34
|
+
raise RequiredMethodNotCalledError, "The method #{dsl_method_name} is required, but was not called within this DSL"
|
40
35
|
end
|
41
36
|
end
|
42
37
|
end
|
@@ -50,7 +45,7 @@ module DSLCompose
|
|
50
45
|
|
51
46
|
# if the method is unique, then it can only be called once per DSL
|
52
47
|
if dsl_method.unique? && @method_calls.method_called?(method_name)
|
53
|
-
raise MethodIsUniqueError
|
48
|
+
raise MethodIsUniqueError, "This method `#{method_name}` is unique and can only be called once within this DSL"
|
54
49
|
end
|
55
50
|
|
56
51
|
@method_calls.add_method_call dsl_method, *args, &block
|
@@ -17,9 +17,17 @@ module DSLCompose
|
|
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
19
|
def execute_dsl klass, dsl, *args, &block
|
20
|
+
# make sure we have these variables for the exception message below
|
21
|
+
class_name = nil
|
22
|
+
class_name = klass.name
|
23
|
+
dsl_name = nil
|
24
|
+
dsl_name = dsl.name
|
25
|
+
|
20
26
|
execution = Execution.new(klass, dsl, *args, &block)
|
21
27
|
@executions << execution
|
22
28
|
execution
|
29
|
+
rescue => e
|
30
|
+
raise e, "Error processing dsl #{dsl_name} for class #{class_name}: #{e.message}", e.backtrace
|
23
31
|
end
|
24
32
|
|
25
33
|
# Returns an array of all executions for a given class.
|
@@ -6,9 +6,6 @@ module DSLCompose
|
|
6
6
|
class ForDSLParser
|
7
7
|
class ForMethodParser
|
8
8
|
class AllBlockParametersMustBeKeywordParametersError < StandardError
|
9
|
-
def message
|
10
|
-
"All block parameters must be keyword parameters, i.e. `for_children_of FooClass do |base_class:|`"
|
11
|
-
end
|
12
9
|
end
|
13
10
|
|
14
11
|
class NoBlockProvided < StandardError
|
@@ -18,9 +15,6 @@ module DSLCompose
|
|
18
15
|
end
|
19
16
|
|
20
17
|
class MethodNamesShouldBeSymbolsError < StandardError
|
21
|
-
def message
|
22
|
-
"Method names must be provided with a symbol or array of symbols"
|
23
|
-
end
|
24
18
|
end
|
25
19
|
|
26
20
|
# This class will yield to the provided block once for each time a method
|
@@ -43,7 +37,7 @@ module DSLCompose
|
|
43
37
|
if block.parameters.any?
|
44
38
|
# all parameters must be keyword arguments
|
45
39
|
if block.parameters.filter { |p| p.first != :keyreq }.any?
|
46
|
-
raise AllBlockParametersMustBeKeywordParametersError
|
40
|
+
raise AllBlockParametersMustBeKeywordParametersError, "All block parameters must be keyword parameters, i.e. `for_children_of FooClass do |base_class:|`"
|
47
41
|
end
|
48
42
|
end
|
49
43
|
|
@@ -54,17 +48,17 @@ module DSLCompose
|
|
54
48
|
|
55
49
|
# assert that the provided dsl name is an array
|
56
50
|
unless method_names.is_a? Array
|
57
|
-
raise MethodNamesShouldBeSymbolsError
|
51
|
+
raise MethodNamesShouldBeSymbolsError, "Method names `#{method_names}` must be provided with a symbol or array of symbols"
|
58
52
|
end
|
59
53
|
|
60
54
|
# assert that the provided dsl name is an array of symbols
|
61
55
|
unless method_names.all? { |method_name| method_name.is_a? Symbol }
|
62
|
-
raise MethodNamesShouldBeSymbolsError
|
56
|
+
raise MethodNamesShouldBeSymbolsError, "Method names `#{method_names}` must be provided with a symbol or array of symbols"
|
63
57
|
end
|
64
58
|
|
65
59
|
# assert that the provided method names all exist for the scoped DSL
|
66
60
|
unless method_names.all? { |method_name| dsl_execution.dsl.has_dsl_method?(method_name) }
|
67
|
-
raise MethodDoesNotExistError
|
61
|
+
raise MethodDoesNotExistError, "Method names `#{method_names}` must all exist"
|
68
62
|
end
|
69
63
|
|
70
64
|
# for each provided dsl name, yield to the provided block
|
@@ -5,9 +5,6 @@ module DSLCompose
|
|
5
5
|
class ForChildrenOfParser
|
6
6
|
class ForDSLParser
|
7
7
|
class AllBlockParametersMustBeKeywordParametersError < StandardError
|
8
|
-
def message
|
9
|
-
"All block parameters must be keyword parameters, i.e. `for_dsl :dsl_name do |dsl_name:|`"
|
10
|
-
end
|
11
8
|
end
|
12
9
|
|
13
10
|
class NoBlockProvided < StandardError
|
@@ -17,9 +14,6 @@ module DSLCompose
|
|
17
14
|
end
|
18
15
|
|
19
16
|
class DSLNamesShouldBeSymbolsError < StandardError
|
20
|
-
def message
|
21
|
-
"DSL names must be provided with a symbol or array of symbols"
|
22
|
-
end
|
23
17
|
end
|
24
18
|
|
25
19
|
# This class will yield to the provided block once for each time a DSL
|
@@ -40,7 +34,7 @@ module DSLCompose
|
|
40
34
|
if block.parameters.any?
|
41
35
|
# all parameters must be keyword arguments
|
42
36
|
if block.parameters.filter { |p| p.first != :keyreq }.any?
|
43
|
-
raise AllBlockParametersMustBeKeywordParametersError
|
37
|
+
raise AllBlockParametersMustBeKeywordParametersError, "All block parameters must be keyword parameters, i.e. `for_dsl :dsl_name do |dsl_name:|`"
|
44
38
|
end
|
45
39
|
end
|
46
40
|
|
@@ -51,17 +45,17 @@ module DSLCompose
|
|
51
45
|
|
52
46
|
# assert that the provided dsl name is an array
|
53
47
|
unless dsl_names.is_a? Array
|
54
|
-
raise DSLNamesShouldBeSymbolsError
|
48
|
+
raise DSLNamesShouldBeSymbolsError, "DSL names `#{dsl_names}` must be provided with a symbol or array of symbols"
|
55
49
|
end
|
56
50
|
|
57
51
|
# assert that the provided dsl name is an array of symbols
|
58
52
|
unless dsl_names.all? { |dsl_name| dsl_name.is_a? Symbol }
|
59
|
-
raise DSLNamesShouldBeSymbolsError
|
53
|
+
raise DSLNamesShouldBeSymbolsError, "DSL names `#{dsl_names}` must be provided with a symbol or array of symbols"
|
60
54
|
end
|
61
55
|
|
62
56
|
# assert that the provided dsl names all exist
|
63
57
|
unless dsl_names.all? { |dsl_name| DSLs.class_dsl_exists?(base_class, dsl_name) }
|
64
|
-
raise DSLDoesNotExistError
|
58
|
+
raise DSLDoesNotExistError, "DSLs named `#{dsl_names}` must all exist"
|
65
59
|
end
|
66
60
|
|
67
61
|
# for each provided dsl name, yield to the provided block
|
@@ -4,9 +4,6 @@ module DSLCompose
|
|
4
4
|
class Parser
|
5
5
|
class ForChildrenOfParser
|
6
6
|
class AllBlockParametersMustBeKeywordParametersError < StandardError
|
7
|
-
def message
|
8
|
-
"All block parameters must be keyword parameters, i.e. `for_children_of FooClass do |base_class:|`"
|
9
|
-
end
|
10
7
|
end
|
11
8
|
|
12
9
|
class ClassDoesNotUseDSLComposeError < StandardError
|
@@ -16,9 +13,6 @@ module DSLCompose
|
|
16
13
|
end
|
17
14
|
|
18
15
|
class NoChildClassError < StandardError
|
19
|
-
def message
|
20
|
-
"No child_class was found, please call this method from within a `for_children_of` block"
|
21
|
-
end
|
22
16
|
end
|
23
17
|
|
24
18
|
# This class will yield to the provided block for each class which extends the base_class, provided
|
@@ -26,7 +20,7 @@ module DSLCompose
|
|
26
20
|
def initialize base_class, &block
|
27
21
|
# assert the provided class has the DSLCompose::Composer module installed
|
28
22
|
unless base_class.respond_to? :dsls
|
29
|
-
raise ClassDoesNotUseDSLComposeError
|
23
|
+
raise ClassDoesNotUseDSLComposeError, base_class
|
30
24
|
end
|
31
25
|
|
32
26
|
@base_class = base_class
|
@@ -40,7 +34,7 @@ module DSLCompose
|
|
40
34
|
if block.parameters.any?
|
41
35
|
# all parameters must be keyword arguments
|
42
36
|
if block.parameters.filter { |p| p.first != :keyreq }.any?
|
43
|
-
raise AllBlockParametersMustBeKeywordParametersError
|
37
|
+
raise AllBlockParametersMustBeKeywordParametersError, "All block parameters must be keyword parameters, i.e. `for_children_of FooClass do |base_class:|`"
|
44
38
|
end
|
45
39
|
end
|
46
40
|
|
@@ -78,7 +72,7 @@ module DSLCompose
|
|
78
72
|
child_class = @child_class
|
79
73
|
|
80
74
|
unless child_class
|
81
|
-
raise NoChildClassError
|
75
|
+
raise NoChildClassError, "No child_class was found, please call this method from within a `for_children_of` block"
|
82
76
|
end
|
83
77
|
|
84
78
|
ForDSLParser.new(@base_class, child_class, dsl_names, &block)
|
data/lib/dsl_compose/version.rb
CHANGED