module Flows::Plugin::OutputContract
Allows to make a contract check and transformation for `#call` method execution in any class.
Plugin
applies a wrapper to a `#call` instance method. This wrapper will do the following:
-
check that {Result} instance is returned by `#call`
-
check that returned {Result#status} is expected
-
check that returned result data conforms {Contract} assigned to a particular result type and status
-
applies contract transform to the returned data
-
returns {Result} with the same status and type, wraps transformed data inside.
Plugin
provides DSL
to express expected result statuses and assigned contracts. Contracts definition reuses {Contract.make} to execute block and get a contract.
-
`success_with(status, &block)` - defines contract for a successful result with status `status`.
-
`failure_with(status, &block)` - defines contract for a failure result with status `status`.
-
`skip_output_contract` - disables contract check and transformation for current class and children.
@example with one possible output contract
class DoJob include Flows::Result::Helpers include Flows::Plugin::OutputContract success_with :ok do Integer end def call(a, b) ok_data(a + b) end end DoJob.new.call(1, 2).unwrap # => 3 DoJob.new.call('a', 'b') # Flows::Contract::Error exception raised
@example with multiple contracts
class DoJob include Flows::Result::Helpers include Flows::Plugin::OutputContract success_with :int_sum do Integer end success_with :float_sum do Float end failure_with :err do hash_of( key: Symbol, msg: String ) end def call(a, b) if a.is_a?(Float) || b.is_a?(Float) ok_data(a + b, status: :float_sum) elsif a.is_a?(Integer) && b.is_a?(Integer) ok_data(a + b, status: :int_sum) else err(key: :unexpected_type, msg: "Unexpected argument types") end end end
Public Class Methods
@api private
# File lib/flows/plugin/output_contract.rb, line 79 def self.included(mod) mod.extend(DSL) mod.prepend(Wrapper) end