attributor 5.0.2 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +30 -0
  3. data/.travis.yml +6 -4
  4. data/CHANGELOG.md +6 -1
  5. data/Gemfile +1 -1
  6. data/Guardfile +14 -8
  7. data/Rakefile +4 -5
  8. data/attributor.gemspec +34 -29
  9. data/lib/attributor.rb +23 -29
  10. data/lib/attributor/attribute.rb +108 -127
  11. data/lib/attributor/attribute_resolver.rb +12 -26
  12. data/lib/attributor/dsl_compiler.rb +17 -21
  13. data/lib/attributor/dumpable.rb +1 -2
  14. data/lib/attributor/example_mixin.rb +5 -8
  15. data/lib/attributor/exceptions.rb +5 -6
  16. data/lib/attributor/extensions/randexp.rb +3 -5
  17. data/lib/attributor/extras/field_selector.rb +4 -4
  18. data/lib/attributor/extras/field_selector/transformer.rb +6 -7
  19. data/lib/attributor/families/numeric.rb +0 -2
  20. data/lib/attributor/families/temporal.rb +1 -4
  21. data/lib/attributor/hash_dsl_compiler.rb +22 -25
  22. data/lib/attributor/type.rb +24 -32
  23. data/lib/attributor/types/bigdecimal.rb +7 -14
  24. data/lib/attributor/types/boolean.rb +5 -8
  25. data/lib/attributor/types/class.rb +9 -10
  26. data/lib/attributor/types/collection.rb +34 -44
  27. data/lib/attributor/types/container.rb +9 -15
  28. data/lib/attributor/types/csv.rb +7 -10
  29. data/lib/attributor/types/date.rb +20 -25
  30. data/lib/attributor/types/date_time.rb +7 -14
  31. data/lib/attributor/types/float.rb +4 -6
  32. data/lib/attributor/types/hash.rb +171 -196
  33. data/lib/attributor/types/ids.rb +2 -6
  34. data/lib/attributor/types/integer.rb +12 -17
  35. data/lib/attributor/types/model.rb +39 -48
  36. data/lib/attributor/types/object.rb +2 -4
  37. data/lib/attributor/types/polymorphic.rb +118 -0
  38. data/lib/attributor/types/regexp.rb +4 -5
  39. data/lib/attributor/types/string.rb +6 -7
  40. data/lib/attributor/types/struct.rb +8 -15
  41. data/lib/attributor/types/symbol.rb +3 -6
  42. data/lib/attributor/types/tempfile.rb +5 -6
  43. data/lib/attributor/types/time.rb +11 -11
  44. data/lib/attributor/types/uri.rb +9 -10
  45. data/lib/attributor/version.rb +1 -1
  46. data/spec/attribute_resolver_spec.rb +57 -78
  47. data/spec/attribute_spec.rb +174 -216
  48. data/spec/attributor_spec.rb +11 -15
  49. data/spec/dsl_compiler_spec.rb +19 -33
  50. data/spec/dumpable_spec.rb +6 -7
  51. data/spec/extras/field_selector/field_selector_spec.rb +1 -1
  52. data/spec/families_spec.rb +1 -3
  53. data/spec/hash_dsl_compiler_spec.rb +65 -74
  54. data/spec/spec_helper.rb +9 -3
  55. data/spec/support/hashes.rb +2 -3
  56. data/spec/support/models.rb +30 -36
  57. data/spec/support/polymorphics.rb +10 -0
  58. data/spec/type_spec.rb +38 -61
  59. data/spec/types/bigdecimal_spec.rb +11 -15
  60. data/spec/types/boolean_spec.rb +12 -39
  61. data/spec/types/class_spec.rb +10 -11
  62. data/spec/types/collection_spec.rb +72 -81
  63. data/spec/types/container_spec.rb +22 -26
  64. data/spec/types/csv_spec.rb +15 -16
  65. data/spec/types/date_spec.rb +16 -33
  66. data/spec/types/date_time_spec.rb +16 -33
  67. data/spec/types/file_upload_spec.rb +1 -2
  68. data/spec/types/float_spec.rb +7 -14
  69. data/spec/types/hash_spec.rb +285 -289
  70. data/spec/types/ids_spec.rb +5 -7
  71. data/spec/types/integer_spec.rb +37 -46
  72. data/spec/types/model_spec.rb +111 -128
  73. data/spec/types/polymorphic_spec.rb +134 -0
  74. data/spec/types/regexp_spec.rb +4 -7
  75. data/spec/types/string_spec.rb +17 -21
  76. data/spec/types/struct_spec.rb +40 -47
  77. data/spec/types/tempfile_spec.rb +1 -2
  78. data/spec/types/temporal_spec.rb +9 -0
  79. data/spec/types/time_spec.rb +16 -32
  80. data/spec/types/type_spec.rb +15 -0
  81. data/spec/types/uri_spec.rb +6 -7
  82. metadata +77 -25
@@ -1,11 +1,9 @@
1
1
  require 'ostruct'
2
2
 
3
3
  module Attributor
4
-
5
-
6
4
  class AttributeResolver
7
5
  ROOT_PREFIX = '$'.freeze
8
- COLLECTION_INDEX_KEY = /^at\((\d+)\)$/.freeze
6
+ COLLECTION_INDEX_KEY = /^at\((\d+)\)$/
9
7
 
10
8
  class Data < ::Hash
11
9
  include Hashie::Extensions::MethodReader
@@ -17,8 +15,7 @@ module Attributor
17
15
  @data = Data.new
18
16
  end
19
17
 
20
-
21
- def query!(key_path, path_prefix=ROOT_PREFIX)
18
+ def query!(key_path, path_prefix = ROOT_PREFIX)
22
19
  # If the incoming key_path is not an absolute path, append the given prefix
23
20
  # NOTE: Need to index key_path by range here because Ruby 1.8 returns a
24
21
  # FixNum for the ASCII code, not the actual character, when indexing by a number.
@@ -49,7 +46,6 @@ module Attributor
49
46
  result
50
47
  end
51
48
 
52
-
53
49
  # Query for a certain key in the attribute hierarchy
54
50
  #
55
51
  # @param [String] key_path The name of the key to query and its path
@@ -57,21 +53,20 @@ module Attributor
57
53
  #
58
54
  # @return [String] The value of the specified attribute/key
59
55
  #
60
- def query(key_path,path_prefix=ROOT_PREFIX)
61
- query!(key_path,path_prefix)
62
- rescue NoMethodError => e
56
+ def query(key_path, path_prefix = ROOT_PREFIX)
57
+ query!(key_path, path_prefix)
58
+ rescue NoMethodError
63
59
  nil
64
60
  end
65
61
 
66
62
  def register(key_path, value)
67
63
  if key_path.split(SEPARATOR).size > 1
68
- raise AttributorException.new("can only register top-level attributes. got: #{key_path}")
64
+ raise AttributorException, "can only register top-level attributes. got: #{key_path}"
69
65
  end
70
66
 
71
67
  @data[key_path] = value
72
68
  end
73
69
 
74
-
75
70
  # Checks that the the condition is met. This means the attribute identified
76
71
  # by path_prefix and key_path satisfies the optional predicate, which when
77
72
  # nil simply checks for existence.
@@ -84,13 +79,11 @@ module Attributor
84
79
  #
85
80
  # @raise [AttributorException] When an unsupported predicate is passed
86
81
  #
87
- def check(path_prefix, key_path, predicate=nil)
88
- value = self.query(key_path, path_prefix)
82
+ def check(path_prefix, key_path, predicate = nil)
83
+ value = query(key_path, path_prefix)
89
84
 
90
85
  # we have a value, any value, which is good enough given no predicate
91
- if !value.nil? && predicate.nil?
92
- return true
93
- end
86
+ return true if !value.nil? && predicate.nil?
94
87
 
95
88
  case predicate
96
89
  when ::String, ::Regexp, ::Integer, ::Float, ::DateTime, true, false
@@ -101,9 +94,8 @@ module Attributor
101
94
  when nil
102
95
  return !value.nil?
103
96
  else
104
- raise AttributorException.new("predicate not supported: #{predicate.inspect}")
97
+ raise AttributorException, "predicate not supported: #{predicate.inspect}"
105
98
  end
106
-
107
99
  end
108
100
 
109
101
  # TODO: kill this when we also kill Taylor's IdentityMap.current
@@ -111,15 +103,9 @@ module Attributor
111
103
  Thread.current[:_attributor_attribute_resolver] = resolver
112
104
  end
113
105
 
114
-
115
106
  def self.current
116
- if resolver = Thread.current[:_attributor_attribute_resolver]
117
- return resolver
118
- else
119
- raise AttributorException, "No AttributeResolver set."
120
- end
107
+ raise AttributorException, 'No AttributeResolver set.' unless Thread.current[:_attributor_attribute_resolver]
108
+ Thread.current[:_attributor_attribute_resolver]
121
109
  end
122
-
123
110
  end
124
-
125
111
  end
@@ -1,6 +1,5 @@
1
- #Container of options and structure definition
1
+ # Container of options and structure definition
2
2
  module Attributor
3
-
4
3
  # RULES FOR ATTRIBUTES
5
4
  # The type of an attribute is:
6
5
  # the specified type
@@ -11,7 +10,6 @@ module Attributor
11
10
  # The reference option for an attribute is passed if a block is given
12
11
 
13
12
  class DSLCompiler
14
-
15
13
  attr_accessor :options, :target
16
14
 
17
15
  def initialize(target, **options)
@@ -21,7 +19,7 @@ module Attributor
21
19
 
22
20
  def parse(*blocks)
23
21
  blocks.push(Proc.new) if block_given?
24
- blocks.each { |block| self.instance_eval(&block) }
22
+ blocks.each { |block| instance_eval(&block) }
25
23
  self
26
24
  end
27
25
 
@@ -33,19 +31,19 @@ module Attributor
33
31
  end
34
32
  end
35
33
 
36
- def attribute(name, attr_type=nil, **opts, &block)
37
- raise AttributorException, "Attribute names must be symbols, got: #{name.inspect}" unless name.kind_of? ::Symbol
34
+ def attribute(name, attr_type = nil, **opts, &block)
35
+ raise AttributorException, "Attribute names must be symbols, got: #{name.inspect}" unless name.is_a? ::Symbol
38
36
  target.attributes[name] = define(name, attr_type, **opts, &block)
39
37
  end
40
38
 
41
- def key(name, attr_type=nil, **opts, &block)
42
- unless name.kind_of?(options.fetch(:key_type, Attributor::Object).native_type)
39
+ def key(name, attr_type = nil, **opts, &block)
40
+ unless name.is_a?(options.fetch(:key_type, Attributor::Object).native_type)
43
41
  raise "Invalid key: #{name.inspect}, must be instance of #{options[:key_type].native_type.name}"
44
42
  end
45
43
  target.keys[name] = define(name, attr_type, **opts, &block)
46
44
  end
47
45
 
48
- def extra(name, attr_type=nil, **opts, &block)
46
+ def extra(name, attr_type = nil, **opts, &block)
49
47
  if attr_type.nil?
50
48
  attr_type = Attributor::Hash.of(key: target.key_type, value: target.value_type)
51
49
  end
@@ -65,7 +63,7 @@ module Attributor
65
63
  # @param [Hash] opts describe opts param
66
64
  # @param [Block] block describe block param
67
65
  # @example
68
- # attribute :email, String, example: /[:email:]/
66
+ # attribute :email, String, example: Randgen.email
69
67
  # @overload define(name, opts, &block)
70
68
  # Assume a type of Attributor::Struct
71
69
  # @param [symbol] name describe name param
@@ -79,7 +77,7 @@ module Attributor
79
77
  # attribute :state, String
80
78
  # end
81
79
  # @api semiprivate
82
- def define(name, attr_type=nil, **opts, &block)
80
+ def define(name, attr_type = nil, **opts, &block)
83
81
  # add to existing attribute if present
84
82
  if (existing_attribute = attributes[name])
85
83
  if existing_attribute.attributes
@@ -89,8 +87,8 @@ module Attributor
89
87
  end
90
88
 
91
89
  # determine inherited attribute
92
- inherited_attribute = nil
93
- if (reference = self.options[:reference])
90
+ inherited_attribute = nil
91
+ if (reference = options[:reference])
94
92
  if (inherited_attribute = reference.attributes[name])
95
93
  opts = inherited_attribute.options.merge(opts) unless attr_type
96
94
  opts[:reference] = inherited_attribute.type if block_given?
@@ -101,12 +99,12 @@ module Attributor
101
99
  if attr_type.nil?
102
100
  if block_given?
103
101
  attr_type = if inherited_attribute && inherited_attribute.type < Attributor::Collection
104
- # override the reference to be the member_attribute's type for collections
105
- opts[:reference] = inherited_attribute.type.member_attribute.type
106
- Attributor::Collection.of(Struct)
107
- else
108
- Attributor::Struct
109
- end
102
+ # override the reference to be the member_attribute's type for collections
103
+ opts[:reference] = inherited_attribute.type.member_attribute.type
104
+ Attributor::Collection.of(Struct)
105
+ else
106
+ Attributor::Struct
107
+ end
110
108
  elsif inherited_attribute
111
109
  attr_type = inherited_attribute.type
112
110
  else
@@ -116,7 +114,5 @@ module Attributor
116
114
 
117
115
  Attributor::Attribute.new(attr_type, opts, &block)
118
116
  end
119
-
120
-
121
117
  end
122
118
  end
@@ -6,6 +6,5 @@ module Attributor
6
6
  def dump
7
7
  raise NotImplementedError, 'Dumpable requires the implementation of #dump'
8
8
  end
9
-
10
9
  end
11
- end
10
+ end
@@ -2,11 +2,9 @@
2
2
  # primarily enables support for lazy values.
3
3
 
4
4
  module Attributor
5
-
6
5
  module ExampleMixin
7
-
8
6
  def self.extended(obj)
9
- if obj.kind_of? Attributor::Model
7
+ if obj.is_a? Attributor::Model
10
8
  obj.class.attributes.each do |name, _|
11
9
  obj.define_singleton_method(name) do
12
10
  get(name)
@@ -32,7 +30,7 @@ module Attributor
32
30
  @contents[k]
33
31
  end
34
32
 
35
- def []=(k,v)
33
+ def []=(k, v)
36
34
  lazy_attributes.delete k
37
35
  @contents[k] = v
38
36
  end
@@ -41,7 +39,7 @@ module Attributor
41
39
  contents.each(&block)
42
40
  end
43
41
 
44
- alias_method :each_pair, :each
42
+ alias each_pair each
45
43
 
46
44
  def values
47
45
  contents.values
@@ -63,7 +61,7 @@ module Attributor
63
61
  @contents.key?(key) || lazy_attributes.key?(key)
64
62
  end
65
63
 
66
- def get(key, context: self.generate_subcontext(Attributor::DEFAULT_ROOT_CONTEXT,key))
64
+ def get(key, context: generate_subcontext(Attributor::DEFAULT_ROOT_CONTEXT, key))
67
65
  key = self.class.key_attribute.load(key, context)
68
66
 
69
67
  unless @contents.key? key
@@ -78,7 +76,7 @@ module Attributor
78
76
 
79
77
  def attributes
80
78
  lazy_attributes.keys.each do |name|
81
- self.__send__(name)
79
+ __send__(name)
82
80
  end
83
81
 
84
82
  super
@@ -93,5 +91,4 @@ module Attributor
93
91
  super
94
92
  end
95
93
  end
96
-
97
94
  end
@@ -6,14 +6,13 @@ module Attributor
6
6
  end
7
7
 
8
8
  class IncompatibleTypeError < LoadError
9
-
10
- def initialize(type:, value_type: , context: )
9
+ def initialize(type:, value_type:, context:)
11
10
  super "Type #{type} cannot load values of type #{value_type} while loading #{Attributor.humanize_context(context)}."
12
11
  end
13
12
  end
14
13
 
15
14
  class CoercionError < LoadError
16
- def initialize( context: , from: , to:, value: nil)
15
+ def initialize(context:, from:, to:, value: nil)
17
16
  msg = "Error coercing from #{from} to #{to} while loading #{Attributor.humanize_context(context)}."
18
17
  msg += " Received value #{Attributor.errorize_value(value)}" if value
19
18
  super msg
@@ -21,7 +20,7 @@ module Attributor
21
20
  end
22
21
 
23
22
  class DeserializationError < LoadError
24
- def initialize( context: , from:, encoding: , value: nil)
23
+ def initialize(context:, from:, encoding:, value: nil)
25
24
  msg = "Error deserializing a #{from} using #{encoding} while loading #{Attributor.humanize_context(context)}."
26
25
  msg += " Received value #{Attributor.errorize_value(value)}" if value
27
26
  super msg
@@ -29,10 +28,10 @@ module Attributor
29
28
  end
30
29
 
31
30
  class DumpError < AttributorException
32
- def initialize( context: , name: , type: , original_exception: )
31
+ def initialize(context:, name:, type:, original_exception:)
33
32
  msg = "Error while dumping attribute #{name} of type #{type} for context #{Attributor.humanize_context(context)}."
34
33
  msg << " Reason: #{original_exception}"
35
34
  super msg
36
35
  end
37
36
  end
38
- end
37
+ end
@@ -1,15 +1,13 @@
1
1
  require 'date'
2
2
 
3
-
4
3
  class Randgen
5
4
  DATE_TIME_EPOCH = ::DateTime.new(2015, 1, 1, 0, 0, 0)
6
5
 
7
6
  def self.date
8
- return DATE_TIME_EPOCH - rand(800)
7
+ DATE_TIME_EPOCH - rand(800)
9
8
  end
10
9
 
11
10
  def self.time
12
- return date.to_time
11
+ date.to_time
13
12
  end
14
-
15
- end
13
+ end
@@ -1,8 +1,8 @@
1
1
  begin
2
2
  require 'parslet'
3
3
  rescue LoadError
4
- warn "Attributor::FieldSelector requires the 'parslet' gem, which can not be found. " +
5
- "Please make sure it's in your Gemfile or installed in your system."
4
+ warn "Attributor::FieldSelector requires the 'parslet' gem, which can not be found. " \
5
+ "Please make sure it's in your Gemfile or installed in your system."
6
6
  end
7
7
 
8
8
  module Attributor
@@ -16,7 +16,7 @@ module Attributor
16
16
  ::Hash
17
17
  end
18
18
 
19
- def self.example(_context = nil, _options = {})
19
+ def self.example(_context = nil, options: {})
20
20
  3.times.each_with_object([]) do |_i, array|
21
21
  array << /\w{5,8}/.gen
22
22
  end.join(',')
@@ -24,7 +24,7 @@ module Attributor
24
24
 
25
25
  def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
26
26
  return nil if value.nil?
27
- return value if self.valid_type? value
27
+ return value if valid_type? value
28
28
  return {} if value.empty?
29
29
 
30
30
  parsed = Parser.new.parse(value)
@@ -1,15 +1,14 @@
1
1
  module Attributor
2
2
  class FieldSelector
3
3
  class Transformer < Parslet::Transform
4
-
5
4
  rule(field: simple(:field_token), children: subtree(:children_tree)) do
6
5
  cs = if children_tree.empty?
7
- true
8
- else
9
- children_tree.each_with_object({}) do |item, hash|
10
- hash.merge! item
11
- end
12
- end
6
+ true
7
+ else
8
+ children_tree.each_with_object({}) do |item, hash|
9
+ hash.merge! item
10
+ end
11
+ end
13
12
  { field_token.to_sym => cs }
14
13
  end
15
14
 
@@ -1,7 +1,6 @@
1
1
  # Abstract type for the 'numeric' family
2
2
 
3
3
  module Attributor
4
-
5
4
  class Numeric
6
5
  include Type
7
6
 
@@ -12,6 +11,5 @@ module Attributor
12
11
  def self.family
13
12
  'numeric'
14
13
  end
15
-
16
14
  end
17
15
  end
@@ -1,7 +1,6 @@
1
1
  # Abstract type for the 'temporal' family
2
2
 
3
3
  module Attributor
4
-
5
4
  class Temporal
6
5
  include Type
7
6
 
@@ -13,10 +12,8 @@ module Attributor
13
12
  'temporal'
14
13
  end
15
14
 
16
- def self.dump(value,**opts)
15
+ def self.dump(value, **_opts)
17
16
  value && value.iso8601
18
17
  end
19
-
20
-
21
18
  end
22
19
  end
@@ -1,10 +1,7 @@
1
1
  require_relative 'dsl_compiler'
2
2
 
3
-
4
3
  module Attributor
5
-
6
4
  class HashDSLCompiler < DSLCompiler
7
-
8
5
  # A class that encapsulates the definition of a requirement for Hash attributes
9
6
  # It implements the validation against incoming values and it describes its format for documentation purposes
10
7
  class Requirement
@@ -18,9 +15,9 @@ module Attributor
18
15
  @type = spec.keys.first
19
16
  case type
20
17
  when :all
21
- self.of(*spec[type])
18
+ of(*spec[type])
22
19
  when :exclusive
23
- self.of(*spec[type])
20
+ of(*spec[type])
24
21
  else
25
22
  @number = spec[type]
26
23
  end
@@ -31,7 +28,7 @@ module Attributor
31
28
  self
32
29
  end
33
30
 
34
- def validate(keys,context=Attributor::DEFAULT_ROOT_CONTEXT,_attribute=nil)
31
+ def validate(keys, context = Attributor::DEFAULT_ROOT_CONTEXT, _attribute = nil)
35
32
  result = []
36
33
  case type
37
34
  when :all
@@ -49,13 +46,13 @@ module Attributor
49
46
  when :at_most
50
47
  rest = attr_names & keys
51
48
  if rest.size > number
52
- found = rest.empty? ? "none" : rest.inspect
49
+ found = rest.empty? ? 'none' : rest.inspect
53
50
  result.push "At most #{number} keys out of #{attr_names} can be passed in for #{Attributor.humanize_context(context)}. Found #{found}"
54
51
  end
55
52
  when :at_least
56
53
  rest = attr_names & keys
57
54
  if rest.size < number
58
- found = rest.empty? ? "none" : rest.inspect
55
+ found = rest.empty? ? 'none' : rest.inspect
59
56
  result.push "At least #{number} keys out of #{attr_names} are required to be passed in for #{Attributor.humanize_context(context)}. Found #{found}"
60
57
  end
61
58
  when :exclusive
@@ -67,15 +64,14 @@ module Attributor
67
64
  result
68
65
  end
69
66
 
70
- def describe(shallow=false, example: nil)
71
- hash = {type: type, attributes: attr_names}
67
+ def describe(_shallow = false, _example: nil)
68
+ hash = { type: type, attributes: attr_names }
72
69
  hash[:count] = number unless number.nil?
73
70
  hash[:description] = description unless description.nil?
74
71
  hash
75
72
  end
76
73
  end
77
74
 
78
-
79
75
  # A class that encapsulates the available DSL under the `requires` keyword.
80
76
  # In particular it allows to define requirements like:
81
77
  # requires.all :attr1, :attr2, :attr3
@@ -91,28 +87,33 @@ module Attributor
91
87
  self.target = target
92
88
  self.options = opts
93
89
  end
90
+
94
91
  def all(*attr_names, **opts)
95
- req = Requirement.new( options.merge(opts).merge(all: attr_names) )
92
+ req = Requirement.new(options.merge(opts).merge(all: attr_names))
96
93
  target.add_requirement req
97
94
  req
98
95
  end
96
+
99
97
  def at_most(number)
100
- req = Requirement.new( options.merge(at_most: number) )
98
+ req = Requirement.new(options.merge(at_most: number))
101
99
  target.add_requirement req
102
100
  req
103
101
  end
102
+
104
103
  def at_least(number)
105
- req = Requirement.new( options.merge(at_least: number) )
104
+ req = Requirement.new(options.merge(at_least: number))
106
105
  target.add_requirement req
107
106
  req
108
107
  end
108
+
109
109
  def exactly(number)
110
- req = Requirement.new( options.merge(exactly: number) )
110
+ req = Requirement.new(options.merge(exactly: number))
111
111
  target.add_requirement req
112
112
  req
113
113
  end
114
+
114
115
  def exclusive(*attr_names, **opts)
115
- req = Requirement.new( options.merge(opts).merge(exclusive: attr_names) )
116
+ req = Requirement.new(options.merge(opts).merge(exclusive: attr_names))
116
117
  target.add_requirement req
117
118
  req
118
119
  end
@@ -122,21 +123,17 @@ module Attributor
122
123
  @requirements_dsl ||= RequiresDSL.new(@target)
123
124
  end
124
125
 
125
- def requires(*spec,**opts,&block)
126
+ def requires(*spec, **opts, &block)
126
127
  if spec.empty?
127
- unless opts.empty?
128
- self._requirements_dsl.options.merge(opts)
129
- end
128
+ _requirements_dsl.options.merge(opts) unless opts.empty?
130
129
  if block_given?
131
- self._requirements_dsl.instance_eval(&block)
130
+ _requirements_dsl.instance_eval(&block)
132
131
  else
133
- self._requirements_dsl
132
+ _requirements_dsl
134
133
  end
135
134
  else
136
- self._requirements_dsl.all(*spec,opts)
135
+ _requirements_dsl.all(*spec, opts)
137
136
  end
138
137
  end
139
-
140
-
141
138
  end
142
139
  end