dry-rb / dry-schema

Coercion and validation for data structures
https://dry-rb.org/gems/dry-schema
MIT License
415 stars 108 forks source link

Upgrade past 1.9.3 introduces KeyError to Production App #423

Closed ADStrovers closed 2 years ago

ADStrovers commented 2 years ago

Describe the bug

When attempting to programmatically add a custom type to a schema, we are receiving the following error:

Dry::Container::KeyError:
  key not found: "{:type?=>Types::CalendarDate}"

I believe this was introduced when extract_type_spec was wrapped around the value and filled internals within Schema::Macros::DSL.

To Reproduce

The minimal amount of code to reproduce using RSpec tests:

# frozen_string_literal: true

require 'dry-schema'
require 'dry-container'
require 'dry-types'

module Types
  include Dry.Types()

  class CalendarDate < ::Date
    def to_json(*_a)
      strftime("--%m-%d")
    end
    alias_method :as_json, :to_json

    def self.parse(date)
      mon, mday = Date._iso8601(date).values_at(:mon, :mday)
      raise ArgumentError, "invalid ISO8601 calendar day string, expected format \"--MM-DD\"" unless mon && mday

      new(2000, mon, mday)
    end
  end

  def self.to_calendar_date(input, &block)
    CalendarDate.parse(input)
  end

  CalendarDay = Nominal(CalendarDate).constructor(method(:to_calendar_date))

  Container = Dry::Schema::TypeContainer.new
  Container.register(:calendar_day) { Types::CalendarDay }
end

Schema = Dry::Schema.JSON do
  config.types = Types::Container
  optional(:date).maybe(:calendar_day)
end

RSpec.describe Schema do
  let!(:data) { { "date" => "--02-09" } }
  let(:result) { described_class.(data) }

  context "call" do
    it "is expected to succeed" do
      expect(result).to be_a_success
    end
  end
end

Expected behavior

The above test passes on version 1.9.3 but now fails on versions 1.10.1 and 1.10.2

I would expect this to pass as written in 1.10.2.

My environment

flash-gordon commented 2 years ago

It's likely related https://github.com/dry-rb/dry-schema/pull/419