dsl_compose 2.14.2 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f89114eef0fe1f670d05bfe9cb2b8fe7964285f8dfbc60638f979ec125ad5e88
4
- data.tar.gz: 0ab64341226e7069d50016415a786b8525b93006d84378911d215b911f8526a1
3
+ metadata.gz: af6d832ff6a9dbe899f76297a60555caf170045743dd6cf83cbabb6b26e87892
4
+ data.tar.gz: a9628422e02b4cac58263ad72938c0297f42c75d81dd3337e43d227ec71ba664
5
5
  SHA512:
6
- metadata.gz: 97f0cbe329fb957589f395cfdc7ee75c1b195ac897e01a494578efc45409375d5435ff17507b241d8d1f0b65bc014b1a50d2d9b2ec673c1b039cc937052d87a5
7
- data.tar.gz: 235bf2593f1ef5e0309973eb45189dc7c634e8b959dde94c8a52673b933d0ddb996a2065d29707901ccc94466754d3c2f6d29cf4f0ad237d305d1d21c050aeea
6
+ metadata.gz: 82ee9d6210446826e52dec60de79f414d9769e4e571e2d95ccf41c66da3231728ad6ffecb9f55beedeceecbf651c286fc0499b076301d3c7f858fa84bd0d5106
7
+ data.tar.gz: d30c48922a712e86138867c4b4de9daee988bf99b3af052a407a8b8bc739f292c974a143ea6b93c0de35b84a981d763c08e3da799114a17ca68f1ff4e6b086f4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.15.0](https://github.com/craigulliott/dsl_compose/compare/v2.14.3...v2.15.0) (2023-10-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * added option to skip certain provided classes within dsl parsers ([c2be111](https://github.com/craigulliott/dsl_compose/commit/c2be111289f4ca0b84b95e641c18bdbd784b5b6f))
9
+ * adding default values for dsl arguments ([b89bd69](https://github.com/craigulliott/dsl_compose/commit/b89bd697eb6598f5f723a28533bd3e67e4ab9207))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * passing classes to skip to the parser as class names (strings) instead of the actual classes. This prevents this library holding a reference to those classes and preventing garbage collection of the classes when they are dynamically created/destroyed within a test suite. ([74b332a](https://github.com/craigulliott/dsl_compose/commit/74b332ab99b7cf96bb8468a06634ee217cd5c58b))
15
+
16
+ ## [2.14.3](https://github.com/craigulliott/dsl_compose/compare/v2.14.2...v2.14.3) (2023-09-27)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * better error if passing a scalar arg instead of kwargs ([7a47775](https://github.com/craigulliott/dsl_compose/commit/7a47775e7b13329c82c2497a017d2d67c5c56d75))
22
+
3
23
  ## [2.14.2](https://github.com/craigulliott/dsl_compose/compare/v2.14.1...v2.14.2) (2023-09-11)
4
24
 
5
25
 
data/README.md CHANGED
@@ -106,8 +106,9 @@ class Foo
106
106
 
107
107
  # You can also add optional arguments to your DSL methods. All optional
108
108
  # arguments must be added after required ones. An error will be raised if
109
- # you define a required argument after an optional one.
110
- optional :optional_argument, :integer do
109
+ # you define a required argument after an optional one. Optional arguments can
110
+ # have an default value, if a default is not provided then nil will be assumed.
111
+ optional :optional_argument, :integer, default: 123 do
111
112
  description "A description of an optional argument"
112
113
 
113
114
  # You can add validation to your arguments. A full list is provided later in this document
@@ -281,6 +282,9 @@ class MyParser < DSLCompose::Parser
281
282
  # If you only want to process classes at the end of the class hierarchy (classes
282
283
  # which extend the provided base class, but do not have their own children) then
283
284
  # use `for_final_children_of` instead of `for_children_of`
285
+ #
286
+ # Both `for_children_of` and `for_final_children_of` accept an optional parameter
287
+ # named skip_classes which accepts an array of class names which should be skipped.
284
288
  for_children_of SomeBaseClass do |child_class:|
285
289
  add_documentation <<~DESCRIPTION
286
290
  You can optionally provide a description of anything specific that your parser
@@ -52,6 +52,8 @@ module DSLCompose
52
52
  # If true, then this argument accepts an array of values. It will also accept a single value,
53
53
  # but that single value will be automatically converted to an array
54
54
  attr_reader :array
55
+ # The default value for optional arguments, if one is not provided then nil will be assumed.
56
+ attr_reader :default
55
57
  # An otional description of this Attribute, if provided then it must be a string.
56
58
  # The description accepts markdown and is used when generating documentation.
57
59
  attr_reader :description
@@ -81,7 +83,7 @@ module DSLCompose
81
83
  # `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
82
84
  # `type` can be either :integer, :boolean, :float, :string or :symbol
83
85
  # `block` contains the instructions to further configure this Attribute
84
- def initialize name, required, kwarg, type, array: false, &block
86
+ def initialize name, required, kwarg, type, array: false, default: nil, &block
85
87
  if name.is_a? Symbol
86
88
 
87
89
  if RESERVED_ARGUMENT_NAMES.include? name
@@ -109,6 +111,13 @@ module DSLCompose
109
111
 
110
112
  @array = array ? true : false
111
113
 
114
+ unless default.nil?
115
+ if @required
116
+ raise ImpossibleKwargError, "The argument `#{name}` is required, so can not be given a default value."
117
+ end
118
+ @default = default
119
+ end
120
+
112
121
  # If a block was provided, then we evaluate it using a seperate
113
122
  # interpreter class. We do this because the interpreter class contains
114
123
  # no other methods or variables, if it was evaluated in the context of
@@ -85,9 +85,11 @@ module DSLCompose
85
85
  #
86
86
  # Argument `name` must be unique within the DSLMethod.
87
87
  # `required` must be a boolean, and determines if this argument will be required
88
+ # `array` is a boolean which determines if this argument will accept an array of the given type or a single item
89
+ # `default` contains the default value, if one is not provided then nil will be assumed (it is only available for optional arguments)
88
90
  # `kwarg` is a boolean which determines if a required Attribute must be provided as a keyword argument.
89
91
  # or optional on the method which is exposed in our DSL.
90
- def add_argument name, required, kwarg, type, array: false, &block
92
+ def add_argument name, required, kwarg, type, array: false, default: nil, &block
91
93
  if @arguments.key? name
92
94
  raise ArgumentAlreadyExistsError, "An argument with the name `#{name}` already exists for this DSL method"
93
95
  end
@@ -97,7 +99,7 @@ module DSLCompose
97
99
  raise ArgumentOrderingError, "Required arguments can not be added after optional ones"
98
100
  end
99
101
 
100
- @arguments[name] = Argument.new(name, required, kwarg, type, array: array, &block)
102
+ @arguments[name] = Argument.new(name, required, kwarg, type, array: array, default: default, &block)
101
103
  end
102
104
  end
103
105
  end
@@ -63,10 +63,12 @@ module DSLCompose
63
63
  #
64
64
  # name must be a symbol
65
65
  # `type` can be either :integer, :boolean, :float, :string, :symbol, :class or :object
66
+ # `array` is a boolean which determines if this argument will accept an array of the given type or a single item
67
+ # `default` contains the default value, if one is not provided then nil will be assumed
66
68
  # `block` contains the argument definition and will be evaluated seperately
67
69
  # by the Argument::Interpreter
68
- def optional name, type, array: false, &block
69
- @dsl.arguments.add_argument name, false, false, type, array: array, &block
70
+ def optional name, type, array: false, default: nil, &block
71
+ @dsl.arguments.add_argument name, false, false, type, array: array, default: default, &block
70
72
  end
71
73
 
72
74
  # adds a new required argument to the DSLMethod
@@ -38,6 +38,11 @@ module DSLCompose
38
38
 
39
39
  # process all the required arguments which are kwargs
40
40
  required_kwargs = arguments.required_arguments.filter { |a| a.kwarg }
41
+
42
+ if required_kwargs.any? && !all_kwargs.is_a?(Hash)
43
+ raise MissingRequiredArgumentsError, "This has required keyword arguments, but no keyword arguments were provided"
44
+ end
45
+
41
46
  required_kwargs.each do |required_kwarg|
42
47
  if all_kwargs.key? required_kwarg.name
43
48
  # add the keyword argument to the required args
@@ -64,17 +69,17 @@ module DSLCompose
64
69
  raise TooManyArgumentsError, "Too many arguments provided"
65
70
  end
66
71
 
67
- # Assume all optonal arguments are nil (except booleans, which default to false).
72
+ # Assume all optonal arguments are their defaults (except booleans, which default to false).
68
73
  # If actual values were provided, then they will be set further below.
69
74
  if arguments.optional_arguments.any?
70
75
  arguments.optional_arguments.each do |optional_argument|
71
76
  # assume it is nil
72
- @arguments[optional_argument.name] = nil
77
+ @arguments[optional_argument.name] = optional_argument.default
73
78
  # unless the argument is an array or a boolean, in which case it defaults
74
79
  # to an empty array or false
75
80
  if optional_argument.array
76
81
  @arguments[optional_argument.name] = [].freeze
77
- elsif optional_argument.type == :boolean
82
+ elsif optional_argument.type == :boolean && optional_argument.default.nil?
78
83
  @arguments[optional_argument.name] = false
79
84
  end
80
85
  end
@@ -4,9 +4,10 @@ module DSLCompose
4
4
  class Parser
5
5
  class ForChildrenOfParser
6
6
  class Descendents
7
- def initialize base_class, final_children_only
7
+ def initialize base_class, final_children_only, skip_classes = []
8
8
  @base_class = base_class
9
9
  @final_children_only = final_children_only
10
+ @skip_classes = skip_classes
10
11
  end
11
12
 
12
13
  def classes
@@ -19,6 +20,11 @@ module DSLCompose
19
20
  "#{child_class.name.split("::").count}_#{has_descendents(child_class) ? 0 : 1}_#{child_class.name}"
20
21
  end
21
22
 
23
+ # reject any classes which we are skipping
24
+ extending_classes.reject! do |child_class|
25
+ @skip_classes.include? child_class.name
26
+ end
27
+
22
28
  # if this is not a final child, but we are processing final children only, then skip it
23
29
  if @final_children_only
24
30
  # reject any classes which have descendents
@@ -35,7 +35,7 @@ module DSLCompose
35
35
  # parser.for_children_of BaseClass do |child_class:|
36
36
  # # this will yield for ChildClass and GrandchildClass
37
37
  # and
38
- def initialize base_class, final_children_only, &block
38
+ def initialize base_class, final_children_only, skip_classes = [], &block
39
39
  # assert the provided class has the DSLCompose::Composer module installed
40
40
  unless base_class.respond_to? :dsls
41
41
  raise ClassDoesNotUseDSLComposeError, base_class
@@ -57,7 +57,7 @@ module DSLCompose
57
57
  end
58
58
 
59
59
  # yeild the block for all descendents of the provided base_class
60
- Descendents.new(base_class, final_children_only).classes.each do |child_class|
60
+ Descendents.new(base_class, final_children_only, skip_classes).classes.each do |child_class|
61
61
  # determine which arguments to send to the block
62
62
  args = {}
63
63
  if BlockArguments.accepts_argument?(:child_class, &block)
@@ -30,27 +30,28 @@ module DSLCompose
30
30
  # If `final_children_only` is true, then this will cause the parser to only return
31
31
  # classes which are at the end of their class hierachy (meaning they dont have any
32
32
  # children of their own)
33
- def self.for_children_of base_class, final_children_only: false, rerun: false, &block
33
+ def self.for_children_of base_class, final_children_only: false, skip_classes: [], rerun: false, &block
34
34
  unless rerun
35
35
  @runs ||= []
36
36
  @runs << {
37
37
  base_class: base_class,
38
38
  final_children_only: final_children_only,
39
+ skip_classes: skip_classes,
39
40
  block: block
40
41
  }
41
42
  end
42
43
 
43
44
  # we parse the provided block in the context of the ForChildrenOfParser class
44
45
  # to help make this code more readable, and to limit polluting the current namespace
45
- ForChildrenOfParser.new(base_class, final_children_only, &block)
46
+ ForChildrenOfParser.new(base_class, final_children_only, skip_classes, &block)
46
47
  end
47
48
 
48
49
  # this is a wrapper for the `for_children_of` method, but it provides a value
49
50
  # of true for the `final_children_only` argument. This will cause the parser to only
50
51
  # return classes which are at the end of the class hierachy (meaning they dont have
51
52
  # any children of their own)
52
- def self.for_final_children_of base_class, &block
53
- for_children_of base_class, final_children_only: true, &block
53
+ def self.for_final_children_of base_class, skip_classes: [], &block
54
+ for_children_of base_class, final_children_only: true, skip_classes: skip_classes, &block
54
55
  end
55
56
 
56
57
  # this method is used to rerun the parser, this is most useful from within a test suite
@@ -61,7 +62,8 @@ module DSLCompose
61
62
  base_class = run[:base_class]
62
63
  block = run[:block]
63
64
  final_children_only = run[:final_children_only]
64
- for_children_of base_class, rerun: true, final_children_only: final_children_only, &block
65
+ skip_classes = run[:skip_classes]
66
+ for_children_of base_class, rerun: true, final_children_only: final_children_only, skip_classes: skip_classes, &block
65
67
  end
66
68
  end
67
69
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DSLCompose
4
- VERSION = "2.14.2"
4
+ VERSION = "2.15.0"
5
5
  end
@@ -11,6 +11,7 @@ module DSLCompose
11
11
  attr_reader required: bool
12
12
  attr_reader kwarg: bool
13
13
  attr_reader array: bool
14
+ attr_reader default: untyped
14
15
  attr_reader description: String
15
16
 
16
17
  attr_reader greater_than_validation: GreaterThanValidation
@@ -28,7 +29,7 @@ module DSLCompose
28
29
  attr_reader length_validation: LengthValidation
29
30
  attr_reader is_a_validation: IsAValidation
30
31
 
31
- def initialize: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool) -> void
32
+ def initialize: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool, ?default: untyped) -> void
32
33
  def set_description: (String description) -> void
33
34
  def has_description?: () -> bool
34
35
  def required?: -> bool
@@ -12,7 +12,7 @@ module DSLCompose
12
12
  def optional_argument: (Symbol name) -> Argument
13
13
  def required_argument: (Symbol name) -> Argument
14
14
  def has_argument?: (Symbol name) -> bool
15
- def add_argument: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool) -> Argument
15
+ def add_argument: (Symbol name, bool required, bool kwarg, argument_type `type`, ?array: bool, ?default: untyped) -> Argument
16
16
 
17
17
  class ArgumentDoesNotExistError < StandardError
18
18
  end
@@ -13,7 +13,7 @@ module DSLCompose
13
13
  def title: (String title) -> void
14
14
  def add_method: (Symbol name, ?required: nil) -> void
15
15
  def add_unique_method: (Symbol name, ?required: nil) -> void
16
- def optional: (Symbol name, argument_type `type`, ?array: bool) -> void
16
+ def optional: (Symbol name, argument_type `type`, ?array: bool, ?default: untyped) -> void
17
17
  def requires: (Symbol name, argument_type `type`, ?kwarg: bool, ?array: bool) -> void
18
18
  end
19
19
  end
@@ -4,9 +4,10 @@ module DSLCompose
4
4
  class ForChildrenOfParser
5
5
  class Descendents
6
6
  @base_class: singleton(Object)
7
+ @skip_classes: Array[String]
7
8
  @final_children_only: bool
8
9
 
9
- def initialize: (singleton(Object) base_class, bool final_children_only) -> void
10
+ def initialize: (singleton(Object) base_class, bool final_children_only, ?Array[String] skip_classes) -> void
10
11
  def classes: -> Array[singleton(Object)]
11
12
 
12
13
  private
@@ -5,7 +5,7 @@ module DSLCompose
5
5
  @base_class: singleton(Object)
6
6
  @child_class: singleton(Object)
7
7
 
8
- def initialize: (singleton(Object) base_class, bool final_children_only) -> void
8
+ def initialize: (singleton(Object) base_class, bool final_children_only, ?Array[String] skip_classes) -> void
9
9
 
10
10
  # overriding this method because steep doesn't
11
11
  # correctly infer that a block is being passed to this method
@@ -4,7 +4,8 @@ module DSLCompose
4
4
  self.@runs: untyped
5
5
 
6
6
  def initialize: -> void
7
- def self.for_children_of: (singleton(Object) base_class, ?final_children_only: bool, ?rerun: bool) -> void
7
+ def self.for_children_of: (singleton(Object) base_class, ?final_children_only: bool, ?skip_classes: Array[String], ?rerun: bool) -> void
8
+ def self.for_final_children_of: (singleton(Object) base_class, ?skip_classes: Array[String]) -> void
8
9
 
9
10
  class NotInitializable < StandardError
10
11
  end
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: 2.14.2
4
+ version: 2.15.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-09-11 00:00:00.000000000 Z
11
+ date: 2023-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: class_spec_helper