dsl_compose 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/README.md +24 -0
  4. data/lib/dsl_compose/composer.rb +3 -12
  5. data/lib/dsl_compose/dsl/arguments/argument/end_with_validation.rb +30 -0
  6. data/lib/dsl_compose/dsl/arguments/argument/equal_to_validation.rb +2 -4
  7. data/lib/dsl_compose/dsl/arguments/argument/format_validation.rb +6 -4
  8. data/lib/dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation.rb +3 -8
  9. data/lib/dsl_compose/dsl/arguments/argument/greater_than_validation.rb +3 -8
  10. data/lib/dsl_compose/dsl/arguments/argument/in_validation.rb +3 -8
  11. data/lib/dsl_compose/dsl/arguments/argument/interpreter.rb +20 -0
  12. data/lib/dsl_compose/dsl/arguments/argument/length_validation.rb +3 -6
  13. data/lib/dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation.rb +3 -8
  14. data/lib/dsl_compose/dsl/arguments/argument/less_than_validation.rb +3 -8
  15. data/lib/dsl_compose/dsl/arguments/argument/not_end_with_validation.rb +30 -0
  16. data/lib/dsl_compose/dsl/arguments/argument/not_in_validation.rb +3 -8
  17. data/lib/dsl_compose/dsl/arguments/argument/not_start_with_validation.rb +30 -0
  18. data/lib/dsl_compose/dsl/arguments/argument/start_with_validation.rb +30 -0
  19. data/lib/dsl_compose/dsl/arguments/argument.rb +114 -50
  20. data/lib/dsl_compose/dsl/arguments.rb +5 -20
  21. data/lib/dsl_compose/dsl/dsl_method.rb +6 -46
  22. data/lib/dsl_compose/dsl.rb +8 -24
  23. data/lib/dsl_compose/dsls.rb +4 -13
  24. data/lib/dsl_compose/interpreter/execution/arguments.rb +24 -26
  25. data/lib/dsl_compose/interpreter/execution/method_calls/method_call.rb +0 -24
  26. data/lib/dsl_compose/interpreter/execution/method_calls.rb +6 -0
  27. data/lib/dsl_compose/interpreter/execution.rb +3 -8
  28. data/lib/dsl_compose/interpreter.rb +8 -0
  29. data/lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser/for_method_parser.rb +4 -10
  30. data/lib/dsl_compose/parser/for_children_of_parser/for_dsl_parser.rb +4 -10
  31. data/lib/dsl_compose/parser/for_children_of_parser.rb +3 -9
  32. data/lib/dsl_compose/version.rb +1 -1
  33. data/lib/dsl_compose.rb +4 -0
  34. metadata +6 -2
@@ -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 OptionalArgsShouldBeHashError < StandardError
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.new required_argument_count, required_args.count
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 OptionalArgsShouldBeHashError
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
- raise RequiredMethodNotCalledError
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DSLCompose
4
- VERSION = "1.6.0"
4
+ VERSION = "1.8.0"
5
5
  end
data/lib/dsl_compose.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "dsl_compose/version"
4
4
 
5
5
  require "dsl_compose/dsl/arguments/argument/equal_to_validation"
6
+ require "dsl_compose/dsl/arguments/argument/end_with_validation"
6
7
  require "dsl_compose/dsl/arguments/argument/format_validation"
7
8
  require "dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation"
8
9
  require "dsl_compose/dsl/arguments/argument/greater_than_validation"
@@ -10,7 +11,10 @@ require "dsl_compose/dsl/arguments/argument/in_validation"
10
11
  require "dsl_compose/dsl/arguments/argument/length_validation"
11
12
  require "dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation"
12
13
  require "dsl_compose/dsl/arguments/argument/less_than_validation"
14
+ require "dsl_compose/dsl/arguments/argument/not_end_with_validation"
13
15
  require "dsl_compose/dsl/arguments/argument/not_in_validation"
16
+ require "dsl_compose/dsl/arguments/argument/not_start_with_validation"
17
+ require "dsl_compose/dsl/arguments/argument/start_with_validation"
14
18
 
15
19
  require "dsl_compose/dsl/arguments/argument/interpreter"
16
20
  require "dsl_compose/dsl/arguments/argument"
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.6.0
4
+ version: 1.8.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-07-07 00:00:00.000000000 Z
11
+ date: 2023-07-11 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
@@ -28,6 +28,7 @@ files:
28
28
  - lib/dsl_compose/dsl.rb
29
29
  - lib/dsl_compose/dsl/arguments.rb
30
30
  - lib/dsl_compose/dsl/arguments/argument.rb
31
+ - lib/dsl_compose/dsl/arguments/argument/end_with_validation.rb
31
32
  - lib/dsl_compose/dsl/arguments/argument/equal_to_validation.rb
32
33
  - lib/dsl_compose/dsl/arguments/argument/format_validation.rb
33
34
  - lib/dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation.rb
@@ -37,7 +38,10 @@ files:
37
38
  - lib/dsl_compose/dsl/arguments/argument/length_validation.rb
38
39
  - lib/dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation.rb
39
40
  - lib/dsl_compose/dsl/arguments/argument/less_than_validation.rb
41
+ - lib/dsl_compose/dsl/arguments/argument/not_end_with_validation.rb
40
42
  - lib/dsl_compose/dsl/arguments/argument/not_in_validation.rb
43
+ - lib/dsl_compose/dsl/arguments/argument/not_start_with_validation.rb
44
+ - lib/dsl_compose/dsl/arguments/argument/start_with_validation.rb
41
45
  - lib/dsl_compose/dsl/dsl_method.rb
42
46
  - lib/dsl_compose/dsl/dsl_method/interpreter.rb
43
47
  - lib/dsl_compose/dsl/interpreter.rb