Skip to content

Commit

Permalink
Merge pull request #616 from dry-rb/range_arg_macro
Browse files Browse the repository at this point in the history
Fix macros expecting a range as option

[changelog]

fixed:
- Macros using predicates that accept a range argument work as expected (no need to wrap the argument in an array) (@waiting-for-dev)
  • Loading branch information
solnic authored Jan 16, 2020
2 parents b7dc088 + c2b512e commit 9126047
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/dry/validation/rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,18 @@ def parse_macros(*args)
args.each_with_object([]) do |spec, macros|
case spec
when Hash
spec.each { |k, v| macros << [k, Array(v)] }
add_macro_from_hash(macros, spec)
else
macros << Array(spec)
end
end
end

def add_macro_from_hash(macros, spec)
spec.each do |k, v|
macros << [k, v.is_a?(Array) ? v : [v]]
end
end
end
end
end
25 changes: 25 additions & 0 deletions spec/integration/macros/custom_macros_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,29 @@ class Test::BaseContract < Dry::Validation::Contract; end
.to eql(numbers: ['must have at least 3 items'])
end
end

context 'using a macro with a range option' do
before do
Test::BaseContract.register_macro(:in_range) do |macro:|
range = macro.args[0]

all_included_in_range = value.all? { |elem| range.include?(elem) }
key.failure("every item must be included in #{range}") unless all_included_in_range
end

contract_class.rule(:numbers).validate(in_range: 1..3)
end

after do
Test::BaseContract.macros._container.delete('in_range')
end

it 'succeeds with valid input' do
expect(contract.(numbers: [1, 2, 3])).to be_success
end

it 'fails with invalid input' do
expect(contract.(numbers: [1, 2, 6])).to be_failure
end
end
end

0 comments on commit 9126047

Please sign in to comment.