Last active
May 3, 2019 02:20
-
-
Save dnagir/71907e1b09e8be817d0644b5be1c29eb to your computer and use it in GitHub Desktop.
Dry Transaction Inheritance Repro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'bundler/inline' | |
gemfile do | |
gem 'dry-validation', '=1.0.0.rc1' | |
gem 'dry-transaction', '=0.13.0' | |
gem 'minitest', '=5.11.3' | |
end | |
require 'dry-validation' | |
require 'dry/transaction' | |
require 'minitest/autorun' | |
# Generilise any API commands | |
class ApiCommand | |
include Dry::Transaction | |
def self.build(validate_with:, and_then:) | |
Class.new(ApiCommand) do | |
def validation_class | |
validate_with | |
end | |
def command_class | |
and_then | |
end | |
end | |
end | |
def self.handle(params) | |
new.call(params) | |
end | |
step :validate | |
step :build_command | |
step :execute | |
private | |
def validate(params) | |
result = validation_class.new.call(params) | |
result.errors.any? ? Failure(result.errors) : Success(result.to_h) | |
end | |
def build_command(valid_params) | |
Success command_class.new(valid_params) | |
end | |
def execute(valid_command) | |
Success 'yay' | |
end | |
end | |
class BlogValidator < Dry::Validation::Contract | |
params do | |
required(:name).filled | |
end | |
end | |
CreateBlog = Struct.new(:name, keyword_init: true) # in practice - Dry::Struct | |
# Concrete Api command | |
class CreateBlogCommandWithInheritance < ApiCommand.build(validate_with: BlogValidator, and_then: CreateBlog) | |
end | |
# Same as before logically (but is failing) - copy-paste with no inheritance | |
class CreateBlogCommandUsualUse | |
include Dry::Transaction | |
step :validate | |
step :build_command | |
step :execute | |
private | |
def validation_class | |
BlogValidator | |
end | |
def command_class | |
CreateBlog | |
end | |
def validate(params) | |
result = validation_class.new.call(params) | |
result.errors.any? ? Failure(result.errors) : Success(result.to_h) | |
end | |
def build_command(valid_params) | |
Success command_class.new(valid_params) | |
end | |
def execute(valid_command) | |
Success 'yay' | |
end | |
end | |
class DefinedDirectlyOnAClassAndWorksFine < Minitest::Test | |
include Dry::Monads::Result::Mixin | |
def test_invalid | |
assert_equal({ name: ["must be filled"] }, CreateBlogCommandUsualUse.new.call(name: '').failure.to_h) | |
end | |
def test_valid | |
assert_equal Success('yay'), CreateBlogCommandUsualUse.new.call(name: 'foo') | |
end | |
end | |
class InheritedAndHasUnexpectedBahviour < Minitest::Test | |
include Dry::Monads::Result::Mixin | |
def test_invalid | |
assert_equal({ name: ["must be filled"] }, CreateBlogCommandWithInheritance.new.call(name: '').failure.to_h) | |
end | |
def test_valid | |
assert_equal Success('yay'), CreateBlogCommandWithInheritance.new.call(name: 'foo') | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Running: | |
FF.. | |
Finished in 0.003001s, 1332.8891 runs/s, 1332.8891 assertions/s. | |
1) Failure: | |
InheritedAndHasUnexpectedBahviour#test_invalid [-:120]: | |
Expected: {:name=>["must be filled"]} | |
Actual: {} | |
2) Failure: | |
InheritedAndHasUnexpectedBahviour#test_valid [-:124]: | |
Expected: Success("yay") | |
Actual: Success({:name=>"foo"}) | |
4 runs, 4 assertions, 2 failures, 0 errors, 0 skips |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment