The use of index(key) on a list with duplicated keys could return the wrong one.

This commit is contained in:
mereghost 2022-06-16 18:02:42 +02:00
parent 224c2894f4
commit a4ac406b95
No known key found for this signature in database
GPG Key ID: 2A8F002685F0D8A0
2 changed files with 43 additions and 2 deletions

View File

@ -140,8 +140,9 @@ module Dry
path
.to_a[0..-2]
.any? { |key|
curr_path = Schema::Path[path.keys[0..path.keys.index(key)]]
.each_with_index
.any? { |_key, index|
curr_path = Schema::Path[path.keys[0..index]]
return false unless result.schema_error?(curr_path)

View File

@ -134,4 +134,44 @@ RSpec.describe Dry::Validation::Contract, "#call" do
expect(result).to be_failure
expect(result.errors.to_h).to eql(address: {geolocation: {lon: ["invalid longitude"]}})
end
context "duplicate key names on nested structures" do
subject(:contract) do
Class.new(Dry::Validation::Contract) do
def self.name
"RuleTestContract"
end
schema do
required(:data).hash do
required(:wrapper).hash do
required(:data).hash do
required(:id).filled(:string)
end
end
end
end
register_macro(:min_size) do |macro:|
min = macro.args[0]
key.failure("must have at least #{min} characters") unless value.size >= min
end
rule(%i[data wrapper data id]).validate(min_size: 10)
end.new
end
it "only applies the rules to" do
expected = {data: {wrapper: {data: ["must be a hash"]}}}
result = contract.(
data: {
wrapper: {
data: []
}
}
)
expect(result.errors.to_h).to eq(expected)
end
end
end