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

Fix bugs with coercing input to arrays of struct types #193

Merged
merged 2 commits into from
Jan 6, 2025
Merged
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: 4 additions & 0 deletions Gemfile.devtools
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ group :tools do
gem "rubocop", "~> 1.69.2"
gem "byebug"
gem "yard"

if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
gem "debug"
end
end
5 changes: 5 additions & 0 deletions changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
- version: 1.7.0
summary:
date: 2025-01-04
fixed:
- 'Fixed coercion errors for structs (issue #192 via #193)
(@flash-gordon)'
changed:
- 'Missing attribute error now includes the name of the class (issue #170 via #191)
(@phillipoertel + @cllns)'
- '3.1 is now the minimum Ruby version (@flash-gordon)'
- '`Dry::Struct::Error` is now a subclass of `Dry::Types::CoercionError` (in #193)
(@flash-gordon)'
- version: 1.6.0
date: 2022-11-04
changed:
Expand Down
2 changes: 1 addition & 1 deletion lib/dry/struct/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Dry
class Struct
# Raised when given input doesn't conform schema and constructor type
Error = Class.new(TypeError)
Error = Class.new(::Dry::Types::CoercionError)

# Raised when defining duplicate attributes
class RepeatedAttributeError < ::ArgumentError
Expand Down
2 changes: 1 addition & 1 deletion lib/dry/struct/sum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def call(input)
# @return [Dry::Types::Result]
def try(input)
if input.is_a?(Struct)
try_struct(input) { super }
::Dry::Types::Result::Success.new(try_struct(input) { return super })
else
super
end
Expand Down
44 changes: 44 additions & 0 deletions spec/integration/array_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

RSpec.describe Dry::Types::Array do
before do
module Test
class Street < Dry::Struct
attribute :street_name, "string"
end

class City < Dry::Struct
attribute :city_name, "string"
end

CityOrStreet = City | Street
end
end

describe "#try" do
context "simple struct" do
subject(:array) { Dry::Types["array"].of(Test::Street) }
it "returns success for valid array" do
expect(array.try([{street_name: "Oxford"}, {street_name: "London"}])).to be_success
end

it "returns failure for invalid array" do
expect(array.try([{name: "Oxford"}, {name: 123}])).to be_failure
expect(array.try([{}])).to be_failure
end
end

context "sum struct" do
subject(:array) { Dry::Types["array"].of(Test::CityOrStreet) }

it "returns success for valid array" do
expect(array.try([{city_name: "London"}, {street_name: "Oxford"}])).to be_success
expect(array.try([Test::Street.new(street_name: "Oxford")])).to be_success
end

it "returns failure for invalid array" do
expect(array.try([{city_name: "London"}, {street_name: 123}])).to be_failure
end
end
end
end
8 changes: 5 additions & 3 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ module DryStructSpec

require "dry-struct"

begin
require "pry"
require "pry-byebug"
%w[debug pry-byebug pry byebug].each do |gem|
require gem
rescue LoadError
nil
else
break
end

Dir[Pathname(__dir__).join("shared/*.rb")].each(&method(:require))
Expand Down
Loading