Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Usage of dry-types in cooperation with dry-validation. To execute run `ruby dry_validation_spec.rb`
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'dry-validation', '1.4.2'
gem 'rspec', '3.9.0'
end
require 'dry-validation'
module Types
include Dry::Types(default: :nominal)
URL_REGEX = /\Awww\.(.*)\z/
ConstrainedUrl = String.constrained(format: URL_REGEX)
ConstructorUrl = String.constructor do |input, &block|
if input.match?(URL_REGEX)
input
elsif block
block.call
else
raise Dry::Types::ConstraintError.new("format?(#{URL_REGEX.inspect}, #{input.inspect})", input)
end
end
end
RSpec.describe 'Passing errors from dry-types to dry-validation', :aggregate_failures do
let(:valid_url) { 'www.wp.pl' }
let(:invalid_url) { 'wp.pl' }
describe 'Types definitions' do
shared_examples 'dry-type interface' do |type|
describe "Type: #{type}" do
context 'with invalid input' do
let(:url) { invalid_url }
it 'Throws Dry::Types::ConstraintError' do
expect { type.call(url) }
.to raise_error(Dry::Types::ConstraintError, "#{url.inspect} violates constraints (format?(/\\Awww\\.(.*)\\z/, #{url.inspect}) failed)")
end
context 'with block provided to the type' do
let(:fallback) { :invalid }
it 'returns fallback value' do
expect(type.call(url) { fallback }).to eq(fallback)
end
end
end
context 'with valid input' do
let(:url) { valid_url }
it 'returns the input' do
expect(type.call(url)).to eq(url)
end
context 'with a block provided to the type' do
let(:fallback) { :invalid }
it 'returns the input' do
expect(type.call(url) { fallback }).to eq(url)
end
end
end
end
end
it_behaves_like 'dry-type interface', Types::ConstrainedUrl
it_behaves_like 'dry-type interface', Types::ConstructorUrl
end
describe 'Validation::Contract definition' do
shared_examples 'contract with typed input' do |type|
describe "Type: #{type}" do
subject(:result) { contract.call(url: url) }
let(:contract) do
Class.new(Dry::Validation::Contract) do
params do
required(:url).value(type)
end
end.new
end
context 'with invalid url' do
let(:url) { invalid_url }
it { is_expected.to_not be_success }
it 'returns errors' do
expect(result.errors.to_h).to eq(
url: ['is in invalid format']
)
end
end
context 'with valid url' do
let(:url) { valid_url }
it { is_expected.to be_success }
it 'returns no errors' do
expect(result.errors).to be_empty
end
end
end
end
it_behaves_like 'contract with typed input', Types::ConstrainedUrl
it_behaves_like 'contract with typed input', Types::ConstructorUrl
end
end
RSpec::Core::Runner.run(['spec', '--format', 'doc'])
# $ ruby dry_validation_spec.rb
#
# Passing errors from dry-types to dry-validation
# Types definitions
# behaves like dry-type interface
# Type: #<Dry::Types[Constrained<Nominal<String> rule=[format?(/\Awww\.(.*)\z/)]>]>
# with invalid input
# Throws Dry::Types::ConstraintError
# with block provided to the type
# returns fallback value
# with valid input
# returns the input
# with a block provided to the type
# returns the input
# behaves like dry-type interface
# Type: #<Dry::Types[Constructor<Nominal<String> fn=dry_validation_spec.rb:17>]>
# with invalid input
# Throws Dry::Types::ConstraintError
# with block provided to the type
# returns fallback value
# with valid input
# returns the input
# with a block provided to the type
# returns the input
# Validation::Contract definition
# behaves like contract with typed input
# Type: #<Dry::Types[Constrained<Nominal<String> rule=[format?(/\Awww\.(.*)\z/)]>]>
# with invalid url
# is expected not to be success
# returns errors
# with valid url
# is expected to be success
# returns no errors
# behaves like contract with typed input
# Type: #<Dry::Types[Constructor<Nominal<String> fn=dry_validation_spec.rb:17>]>
# with invalid url
# is expected not to be success (FAILED - 1)
# returns errors (FAILED - 2)
# with valid url
# is expected to be success
# returns no errors
#
# Failures:
#
# 1) Passing errors from dry-types to dry-validation Validation::Contract definition behaves like contract with typed input Type: #<Dry::Types[Constructor<Nominal<String> fn=dry_validation_spec.rb:17>]> with invalid url is expected not to be success
# Failure/Error: it { is_expected.to_not be_success }
# expected `#<Dry::Validation::Result{:url=>"wp.pl"} errors={}>.success?` to return false, got true
# Shared Example Group: "contract with typed input" called from dry_validation_spec.rb:112
# # dry_validation_spec.rb:90:in `block (6 levels) in <main>'
# # dry_validation_spec.rb:116:in `<main>'
#
# 2) Passing errors from dry-types to dry-validation Validation::Contract definition behaves like contract with typed input Type: #<Dry::Types[Constructor<Nominal<String> fn=dry_validation_spec.rb:17>]> with invalid url returns errors
# Failure/Error:
# expect(result.errors.to_h).to eq(
# url: ['is in invalid format']
# )
#
# expected: {:url=>["is in invalid format"]}
# got: {}
#
# (compared using ==)
#
# Diff:
# @@ -1,2 +1 @@
# -:url => ["is in invalid format"],
#
# Shared Example Group: "contract with typed input" called from dry_validation_spec.rb:112
# # dry_validation_spec.rb:93:in `block (6 levels) in <main>'
# # dry_validation_spec.rb:116:in `<main>'
#
# Finished in 0.04198 seconds (files took 0.08128 seconds to load)
# 16 examples, 2 failures
#
# Failed examples:
#
# rspec 'dry_validation_spec.rb[1:2:2:1:1:1]' # Passing errors from dry-types to dry-validation Validation::Contract definition behaves like contract with typed input Type: #<Dry::Types[Constructor<Nominal<String> fn=dry_validation_spec.rb:17>]> with invalid url is expected not to be success
# rspec 'dry_validation_spec.rb[1:2:2:1:1:2]' # Passing errors from dry-types to dry-validation Validation::Contract definition behaves like contract with typed input Type: #<Dry::Types[Constructor<Nominal<String> fn=dry_validation_spec.rb:17>]> with invalid url returns errors
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.