Skip to content

Instantly share code, notes, and snippets.

@WojciechKo
Last active February 22, 2020 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WojciechKo/d40cf9b040b25e287794dbc1cf88a029 to your computer and use it in GitHub Desktop.
Save WojciechKo/d40cf9b040b25e287794dbc1cf88a029 to your computer and use it in GitHub Desktop.
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