All Versions
20
Latest Version
Avg Release Cycle
50 days
Latest Release
1229 days ago

Changelog History
Page 1

  • v0.13.0 Changes

    June 13, 2018

    0.13.0 / 2018-06-13

    πŸ”„ Changed

    • Internal step operations (steps backed by instance methods) can now be replaced via constructor arguments. Using instance methods to wrap external step operations now only works if the step is defined using the with: option (timriley in #109)

    Compare v0.12.1...v0.13.0

  • v0.12.1 Changes

    June 05, 2018

    πŸ›  Fixed

    • πŸ‘Œ Support result matching on step failures nested within around steps (flash-gordon in [#106][pr106])

    Compare v0.12.0...v0.12.1

  • v0.12.0 Changes

    May 15, 2018

    πŸ”„ Changed

    • πŸ—„ Switch to Dry::Monads::Result API (away from Either API deprecated in dry-monads 1.0 betas) (Morozzzko in [#104][pr104])

    Compare v0.11.2...v0.12.0

  • v0.11.2 Changes

    May 15, 2018

    πŸ”„ Changed

    • πŸ—„ Use Dry::Monads::Result instead of the deprecated Dry::Monads::Either in the check step adapter (PavelTkachenko in [#103][pr103])

    Compare v0.11.1...v0.11.2

  • v0.11.1 Changes

    March 14, 2018

    βž• Added

    • Include operation_name: in options passed to step adapters. This is helpful for 3rd party step adapters that need the operation's name to fetch it from the container again later. (timriley in [#94][pr94])

    Compare v0.11.0...v0.11.1

  • v0.11.0 Changes

    February 19, 2018

    βž• Added

    • πŸ‘€ Around steps, which allow control of the execution of subsequently called steps. If you know how middleware works in rack or how around callbacks can be used in RSpec, it's the same. A typical example of usage would be for DB transactions (now first class support!) or controlling side effects: rolling back the changes, cleaning garbage produced by a failed transaction, etc. See a more detailed explanation of how this works in the PR (flash-gordon in #85)
    • Broadcast when a step has started by sending the event step_called (mihairadulescu in #82)
    • βž• Add new step check that returns Success or Failure base on conditions (semenovDL in #84)
    • πŸ‘Œ Support for transaction steps without input values (GustavoCaso and timriley in #69)

    πŸ”„ Changed

    • [BREAKING] Steps no longer broadcast events with their step name followed by _success or _failure. Now, more generic names are used for the broadcast events. Before each step runs, a step event is broadcast, with the step name and its arguments. After a step runs, a step_succeeded or step_failed event is broadcast, also with the step name, the arguments and the return value (GustavoCaso in #83)
    • [BREAKING] Pub/sub support is now handled using dry-events instead of wisper. Subscriber objects should now respond to #on_step, #on_step_succeeded, or #on_step_failed to receive broadcast events (GustavoCaso in #90)
    • [BREAKING] The step adapter API has been changed in order to support around steps, although, the changes are not significant. Previously, an adapter received a step and a list of arguments for calling the operation. The list was passed as *args then you were needed to call call_operation on step and provide the list. From now on an adapter gets an operation, its options, and args (without *). operation is an ordinary callable object so a typical call is as simple as operaiton.(*args), that's it. If you want to turn your adapter into an around-like one you need to add &block parameter to the list of call arguments (e.g. def call(operation, options, args, &block)). block is responsible for calling the subsequent steps thus you can check or transform the return value and make some decisions based on it. Note capturing the block in the list of arguments is mandatory, a simple yield won't work, there are reasons, believe us. Check out the sources of around.rb for reference, it's dead simple (flash-gordon in #85)
    • ⚑️ Usages of the Either monad was updated with Result and its constructors. See the changes in dry-monads for more details (flash-gordon in #81)
    • πŸ’Ž Minimal Ruby version is 2.2 (flash-gordon in #72)

    πŸ›  Fixed

    • 0️⃣ Pass arguments to a step with keyword arguments with default values (flash-gordon in #74)
    • Steps can be wrapped with private methods (semenovDL in #70)
    • πŸ‘Œ Improved error message on missing transaction step (Morozzzko in #79)

    Compare v0.10.2...v0.11.0

  • v0.10.2 Changes

    July 10, 2017

    πŸ›  Fixed

    • Only resolve an operation object from the container if the container reports that the key is present. This prevents exceptions from being raised when using dry-container and defining a transaction that includes steps both container-based and local method steps (jonolsson in [#64][pr64])

    Compare v0.10.1...v0.10.2

  • v0.10.1 Changes

    June 29, 2017

    πŸ›  Fixed

    • Preserve step notification listeners when calling a transaction after passing extra step arguments (jcmfernandes in #65)

    Compare v0.10.0...v0.10.1

  • v0.10.0 Changes

    June 14, 2017

    πŸš€ This release makes major changes to the dry-transaction API: transactions are now defined within your own class, support instance methods for defining or wrapping steps, and operation containers are now optional.

    βž• Added

    • βž• Added Dry::Transaction::Operation convenience mixin. This gives easy access to Right and Left result builders within your operation objects, and also enables dry-matcher's block-based result matching API for when the operations are called individually. (timriley in #58)

      class MyOperation
        include Dry::Transaction::Operation
      
        def call(input)
          Right(input)
        end
      end
      
      my_op = MyOperation.new
      my_op.("hello") do |m|
        m.success do |v|
          "Success: #{v}
        end
        m.failure do |v|
          "Failure: #{v}"
        end
      end
      # => "Success: hello"
      

    πŸ”„ Changed

    • [BREAKING] Transactions are now defined within your own classes using a mixin & class-level API for step definitions (GustavoCaso & timriley in #58)

      class CreateUser
        include Dry::Transaction(container: Container)
      
        step :process, with: "operations.process"
        step :validate, with: "operations.validate"
        step :persist, with: "operations.persist"
      end
      
      create_user = CreateUser.new
      create_user.call("name" => "Jane Doe")
      

    Instance methods can wrap operations by calling super:

    ```ruby
    class CreateUser
      include Dry::Transaction(container: Container)
    
      step :process, with: "operations.process"
      step :validate, with: "operations.validate"
      step :persist, with: "operations.persist"
    
      def process(input)
        adjusted_input = do_something_with(input)
        super(adjusted_input)
      end
    end
    ```
    

    Substitute operations can be injected when initializing objects (helpful for testing):

    ```ruby
    create_user = CreateUser.new(process: substitute_process_operation)
    ```
    
    • Transactions can be defined without an operations container, using instance methods only.

      class CreateUser
        include Dry::Transaction
      
        step :process
        step :validate
      
        def process(input)
          input = do_something_with(input)
          Right(input)
        end
      
        def validate(input)
          if input[:email].include?("@")
            Right(input)
          else
            Left(:not_valid)
          end
        end
      end
      
    • πŸ— [BREAKING] You can no longer extend existing transactions with #prepend, #append, #insert, or #remove. Since transactions will now be instances of your own classes, with their own different behaviors, there’s no predictable way to combine the behaviors of two different classes. If you need the ability to add or remove steps, you can create separate transactions for the different behaviours you need to offer, or build into your own transaction class a way to skip steps based on input or step arguments.

    • πŸ‘€ [BREAKING] Blocks in step definitions are no longer accepted. If you want to wrap a step with some local behavior, wrap it with an instance method (see above).

    • πŸ”§ [BREAKING] There is no longer an option for configuring the result matcher block API - we now use Dry::Transaction::ResultMatcher by default. If you want to provide your own matcher, you can do this by overriding #call in your transaction classes and using your own matcher when a block is given.

    Compare v0.9.0...v0.10.0

  • v0.9.0 Changes

    December 18, 2016

    βž• Added

    • Procs (or any callable objects) can be passed as a step's with: option instead of a container identifier string (AMHOL in #44)

      Dry.Transaction(container: MyContainer) do
        step :some_step, with: "operations.some_thing"
        step :another, with: -> input {
          # your code here
        }
      end
      
    • πŸ‘Œ Support for passing blocks to step adapters (am-kantox in #36)

      Dry.Transaction(container: MyContainer) do
        my_custom_step :some_step do
          # this code is captured as a block and passed to the step adapter
        end
      end
      

    πŸ”„ Changed

    • Whole step object is passed to StepFailure upon failure, which provides more information to custom matchers (mrbongiolo in #35)
    • #call argument order for step operations is now #call(input, *args), not #call(*args, input) (timriley in #48)
    • Dry::Transaction::Sequence renamed to Dry::Transaction (timriley in #49)

    Compare v0.8.0...v0.9.0