Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation rules treat Types.Constructor(Array) and Types::Array.constructor differently #171

Open
shepmaster opened this issue Jul 9, 2019 · 8 comments

Comments

Projects
None yet
3 participants
@shepmaster
Copy link

commented Jul 9, 2019

Describe the bug

Types created with Types.Constructor(Array) behave differently from those created with Types::Array.constructor when used with .each

To Reproduce

# frozen_string_literal: true

require 'dry-schema'

module Types
  include Dry.Types()
end

SortString = Types.Constructor(Array) do |values|
  values.split(',').map do |s|
    by, dir = s.split(':', 2)
    { by: by.to_sym, dir: dir.to_sym }
  end
end

schema = Dry::Schema.Params do
  VALID_SORTS = %i[name date].freeze
  VALID_SORT_DIRECTIONS = %i[asc desc].freeze

  optional(:sorts).value(SortString).each do
    hash do
      required(:by).value(included_in?: VALID_SORTS)
      required(:dir).value(included_in?: VALID_SORT_DIRECTIONS)
    end
  end
end

puts schema.('sorts' => 'name:asc,date:desc').inspect

Expected behavior

:sorts would be an array of hashes.

Actual behavior

It fails validation:

[{:by=>:name, :dir=>:asc}, {:by=>:date, :dir=>:desc}]
#<Dry::Schema::Result{:sorts=>"name:asc,date:desc"} errors={:sorts=>["must be an array"]}>

Your environment

  • Affects my production application: NO
  • dry-validation version: 1.1.1
  • Ruby version: 2.6.2
  • OS: macOS

@flash-gordon flash-gordon self-assigned this Jul 9, 2019

@solnic

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@flash-gordon this is....not a bug, but it's kind of a...gotcha. Types::Array is a strict type, so dry-schema infers type?(Array) whereas with Types.Constructor(Array) it does not use a strict type under the hood. This means the behavior is expected, but it's somewhat confusing.

@flash-gordon

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@solnic dry-schema can infer type checks from nominal types (right?), Types.Constructor wraps a nominal type so I would expect it to work. Or not, if there are reasons for it not to work. At this point, I don't see any but I'll have another look a little bit later.

@solnic

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@flash-gordon we could infer type checks from nominal types, it would be a bit implicit and not in-line with how dry-types work but it feels like it would be OK in this case.

@flash-gordon

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@solnic it passes:

  it 'infers type check' do
    expect(inferrer[Dry::Types['nominal.string']]).to eql([:str?])
  end
@solnic

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@flash-gordon ohh, it looks like we're having a completely different issue, because look:

contract.schema.type_schema[sorts: 'name:asc']
{:sorts=>"name:asc"}

So it looks like it doesn't coerce

@solnic solnic transferred this issue from dry-rb/dry-validation Jul 10, 2019

@flash-gordon

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@solnic yep! Last time I stopped around this place observing some unexpected output produced by dry-types schemas

@solnic

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

@flash-gordon looks like each + block overrides custom type, if you remove .each part it will work

@solnic

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

Gotcha:

(byebug) Types::Array.constructor(&:to_a).respond_to?(:of)
true

(byebug) Types.Constructor(Array, &:to_a).respond_to?(:of)
false

which causes hash macro to fail to set the schema properly

@solnic solnic added the 🐛 bug label Jul 10, 2019

@solnic solnic modified the milestones: 1.3.1, 1.3.2 Jul 10, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.