Fix validation extension for operations taking no input - #46
Open
aaronmallen wants to merge 1 commit into
Open
Conversation
The Validation extension wrapped step methods with `|input = {}, *rest, **kwargs, &block|`
and always forwarded `super(validated_input, ...)`. An operation defining `def call` with no
arguments therefore raised `ArgumentError: wrong number of arguments (given 1, expected 0)`
on call, even when no contract, params, or schema was defined.
Two changes:
- With no contract, there is nothing to validate, so the wrapper now forwards the arguments
it was called with untouched instead of manufacturing an empty hash.
- With a contract defined for a method that cannot receive the input, we now raise
`Dry::Operation::ValidationInputError` at class-definition time, whether the contract is
declared before or after the method, or inherited by a subclass that defines it. An
injected `#contract` dependency isn't visible then, so the same check also runs on call.
The signature reflection is extracted into a `Signature` module shared by both paths. It
walks past the generic forwarders `Dry::Operation` prepends to find the method declaring the
real signature, which also lets a no-argument call into a keyword-only method pass its
validated input as kwargs rather than as a positional hash.
Note that `def call(input)` with no contract can no longer be invoked as `operation.call`;
it raises `ArgumentError`, as the signature says it should.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Validation extension wrapped step methods with
|input = {}, *rest, **kwargs, &block|and always forwardedsuper(validated_input, ...). An operation definingdef callwith no arguments therefore raisedArgumentError: wrong number of arguments (given 1, expected 0)on call, even when no contract, params, or schema was defined.Two changes:
With no contract, there is nothing to validate, so the wrapper now forwards the arguments it was called with untouched instead of manufacturing an empty hash.
With a contract defined for a method that cannot receive the input, we now raise
Dry::Operation::ValidationInputErrorat class-definition time, whether the contract is declared before or after the method, or inherited by a subclass that defines it. An injected#contractdependency isn't visible then, so the same check also runs on call.The signature reflection is extracted into a
Signaturemodule shared by both paths. It walks past the generic forwardersDry::Operationprepends to find the method declaring the real signature, which also lets a no-argument call into a keyword-only method pass its validated input as kwargs rather than as a positional hash.Note that
def call(input)with no contract can no longer be invoked asoperation.call; it raisesArgumentError, as the signature says it should.