Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/dry/schema/key_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ module Schema
class KeyValidator
extend Dry::Initializer

INDEX_REGEX = /\[\d+\]/.freeze
DIGIT_REGEX = /\A\d+\z/.freeze
INDEX_REGEX = /\[\d+\]/
DIGIT_REGEX = /\A\d+\z/
BRACKETS = "[]"

# @api private
Expand Down
4 changes: 2 additions & 2 deletions lib/dry/schema/macros/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class Core
option :schema_dsl, optional: true

# @api private
def new(**options)
self.class.new(name: name, compiler: compiler, schema_dsl: schema_dsl, **options)
def new(klass: self.class, **options)
klass.new(name: name, compiler: compiler, schema_dsl: schema_dsl, **options)
end

# @api private
Expand Down
12 changes: 3 additions & 9 deletions lib/dry/schema/macros/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ def append_macro(macro_type)

# @api private
# rubocop: disable Metrics/AbcSize
# rubocop: disable Metrics/CyclomaticComplexity
# rubocop: disable Metrics/PerceivedComplexity
def extract_type_spec(args, nullable: false, set_type: true)
type_spec = args[0] unless schema_or_predicate?(args[0])
Expand All @@ -230,9 +229,9 @@ def extract_type_spec(args, nullable: false, set_type: true)

if type_spec.is_a?(::Array)
type_rule = type_spec.map { |ts| new(chain: false).value(ts) }.reduce(:|)
elsif type_spec.is_a?(Dry::Types::Sum) && set_type
elsif type_spec.is_a?(Dry::Types::Sum)
type_rule = [type_spec.left, type_spec.right].map { |ts|
new(klass: Core, chain: false).value(ts)
new(klass: DSL, chain: false).value(ts)
}.reduce(:|)
else
type_predicates = predicate_inferrer[resolved_type]
Expand All @@ -245,14 +244,9 @@ def extract_type_spec(args, nullable: false, set_type: true)

type(resolved_type) if set_type && resolved_type

if type_rule
yield(*predicates, type_spec: nil, type_rule: type_rule)
else
yield(*predicates, type_spec: type_spec, type_rule: nil)
end
yield(*predicates, type_spec: type_spec, type_rule: type_rule)
end
# rubocop: enable Metrics/AbcSize
# rubocop: enable Metrics/CyclomaticComplexity
# rubocop: enable Metrics/PerceivedComplexity

# @api private
Expand Down
6 changes: 3 additions & 3 deletions lib/dry/schema/macros/filled.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ def call(*predicates, **opts, &block)
ensure_valid_predicates(predicates)

append_macro(Macros::Value) do |macro|
if opts[:type_spec] && !filter_empty_string?
if opts[:type_rule]
macro.call(:filled?).value(*predicates, **opts, &block)
elsif opts[:type_spec] && !filter_empty_string?
macro.call(predicates[0], :filled?, *predicates[1..predicates.size - 1], **opts,
&block)
elsif opts[:type_rule]
macro.call(:filled?).value(*predicates, **opts, &block)
else
macro.call(:filled?, *predicates, **opts, &block)
end
Expand Down
22 changes: 22 additions & 0 deletions spec/integration/params/macros/array_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,27 @@
expect(result).to be_failure
expect(result.errors.to_h).to eql(nums: {1 => ["must be an integer or cannot be defined"]})
end

it "applies coercion and rules to hashes" do
schema = Dry::Schema.Params {
required(:hashes).array(
Types::Hash.schema(name: "string") | Types::Hash.schema(other_name: "string")
)
}

result = schema.(hashes: [{name: "string"}, {name: "string", other_name: "string"}, {other_name: "string"}])

expect(result).to be_success
expect(result.output).to eql(hashes: [
{name: "string"},
{name: "string"},
{other_name: "string"}
])

result = schema.(hashes: [{name: "string"}, {other_key: 1}, {name: 0}, {other_name: "string"}])

expect(result).to be_failure
expect(result.errors.to_h).to eq(hashes: {1 => {or: [{name: ["is missing"]}, {other_name: ["is missing"]}]}, 2 => {or: [{name: ["must be a string"]}, {other_name: ["is missing"]}]}})
end
end
end