Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: Plans for the next major version (v5) #131

Open
serradura opened this issue Aug 4, 2022 · 0 comments
Open

DRAFT: Plans for the next major version (v5) #131

serradura opened this issue Aug 4, 2022 · 0 comments
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@serradura
Copy link
Owner

serradura commented Aug 4, 2022

Table of contents:

[Change] Drop support for older Ruby versions

Ruby version: >= 2.5.0

[Change] Drop support for older Rails versions

Rails version: >= 5.2.0

[Change] Allow only two ways to declare flows

Until v4, there were different ways to declare flows, but in the v5, there will be only two:

Micro::Case

class SumPositiveNumbers < Micro::Case
  def call!
    call(FilterPositiveNumbers)
      .then(SumAllNumbers)
  end
end

# or

FilterPositiveNumbers
  .call(numbers: numbers)
  .then(SumAllNumbers)
Removed Alternative
SumPositiveNumbers = Micro::Cases.flow([
  FilterPositiveNumbers,
  SumAllNumbers
])
class SumPositiveNumbers < Micro::Case
  def call!
    call(FilterPositiveNumbers)
      .then(SumAllNumbers)
  end
end

# or

FilterPositiveNumbers
  .call(numbers: numbers)
  .then(SumAllNumbers)
Removed Alternative
class SumPositiveNumbers < Micro::Case
  flow([
    FilterPositiveNumbers,
    SumAllNumbers
  ])
end
class SumPositiveNumbers < Micro::Case
  def call!
    call(FilterPositiveNumbers)
      .then(SumAllNumbers)
  end
end

# or

FilterPositiveNumbers
  .call(numbers: numbers)
  .then(SumAllNumbers)
Removed Alternative
class SumPositiveNumbers < Micro::Case
  flow([
    FilterPositiveNumbers,
    self.call!
  ])

  attributes :numbers

  def call!
    Success result: { number: numbers.sum }
  end
end
class SumPositiveNumbers < Micro::Case
  def call!
    call(FilterPositiveNumbers)
      .then(:sum_all_numbers)
  end

  private

  def sum_all_numbers(numbers:, **)
    Success result: { number: numbers.sum }
  end
end

Micro::Case::Safe

class SumPositiveNumbers < Micro::Case::Safe
  def call!
    call(FilterPositiveNumbers)
      .then(SumAllNumbers)
  end
end

# or

FilterPositiveNumbers
  .call(numbers: numbers)
  .then(SumAllNumbers)
Removed Alternative
SumPositiveNumbers = Micro::Cases.safe_flow([
  FilterPositiveNumbers,
  SumAllNumbers
])
class SumPositiveNumbers < Micro::Case::Safe
  def call!
    call(FilterPositiveNumbers)
      .then(SumAllNumbers)
  end
end

# or

FilterPositiveNumbers
  .call(numbers: numbers)
  .then(SumAllNumbers)
Removed Alternative
class SumPositiveNumbers < Micro::Case::Safe
  flow([
    FilterPositiveNumbers,
    SumAllNumbers
  ])
end
class SumPositiveNumbers < Micro::Case::Safe
  def call!
    call(FilterPositiveNumbers)
      .then(SumAllNumbers)
  end
end

# or

FilterPositiveNumbers
  .call(numbers: numbers)
  .then(SumAllNumbers)
Removed Alternative
class SumPositiveNumbers < Micro::Case::Safe
  flow([
    FilterPositiveNumbers,
    self.call!
  ])

  attributes :numbers

  def call!
    Success result: { number: numbers.sum }
  end
end
class SumPositiveNumbers < Micro::Case::Safe
  def call!
    call(FilterPositiveNumbers)
      .then(:sum_all_numbers)
  end

  private

  def sum_all_numbers(numbers:, **)
    Success result: { number: numbers.sum }
  end
end

[REMOVED] Micro::Case::Strict

Use the required: true option in all of the attributes.

Removed Alternative
class Double < Micro::Case::Strict
  attribute :numbers

  def call!
    doubled = numbers.map { _1 * 2 }

    Success result: { numbers: doubled }
  end
end

Double.call({})
# The output will be:
# ArgumentError (missing keyword: :numbers)
class Double < Micro::Case
  attribute :numbers, required: true

  def call!
    doubled = numbers.map { _1 * 2 }

    Success result: { numbers: doubled }
  end
end

Double.call({})
# The output will be:
# ArgumentError (missing keyword: :numbers)

[NEW] Allow instantiation with dependencies

class Divide < Micro::Case
  dependency :logger, kind: { respond_to: :error }

  attribute :a, kind: Numeric
  attribute :b, kind: Numeric

  def call!
    number = a / b

    Success result: { number: number }
  rescue ZeroDivisionError => exception
    logger.error(exception.message)

    Failure(:zero_division)
  end
end

divide = Divide.new(logger: Logger.new(STDOUT))

divide.call(a: 2, b: 0)

############################################
# Dependencies will be required by default #
############################################

Divide.new
# The output will be:
# ArgumentError (missing keyword: :logger)

# The definition of an attribute default will avoid this error.

[NEW] This change will allow the mock of internal steps:

module User::Register
  class Flow < Micro::Case
    def call!
      call(Step::ValidateAttributes)
        .then(Step::CreateRecord)
    end
  end
end

# Rspec

result = Micro::Case::Result::Success.new(data: {user: User.new})

register_user = User::Register::Flow.new

expect(register_user)
  .to receive(:then).with(Step::CreateRecord)
  .and_return(result)

Mocks will also work with the u-case call method.

result = Micro::Case::Result::Failure.new(type: :invalid_attributes)

register_user = User::Register::Flow.new

expect(register_user)
  .to receive(call).with(Step::ValidateAttributes)
  .and_return(result)

[NEW] Add support for pattern matching (Ruby >= 2.7) in the Micro::Case::Result

case result
in {success: _, data: {number: number}}
  # ...
in {failure: :invalid_attributes}
  # ...
end

[DEPRECATED] Use the method method and it's alias apply in the step's declaration.

Deprecated Alternative
class SumPositiveNumbers < Micro::Case
  attribute :numbers

  def call!
    filter_positive_numbers
      .then(method(:sum_all_numbers))
  end

  private

    def filter_positive_numbers
      # ..
    end

    def sum_all_numbers(numbers: **)
      # ...
    end
end
class SumPositiveNumbers < Micro::Case
  attribute :numbers

  def call!
    filter_positive_numbers
      .then(:sum_all_numbers)
  end

  private

    def filter_positive_numbers
      # ..
    end

    def sum_all_numbers(numbers: **)
      # ...
    end
end
Deprecated Alternative
class SumPositiveNumbers < Micro::Case
  attribute :numbers

  def call!
    filter_positive_numbers
      .then(apply(:sum_all_numbers))
  end

  private

    def filter_positive_numbers
      # ..
    end

    def sum_all_numbers(numbers: **)
      # ...
    end
end
class SumPositiveNumbers < Micro::Case
  attribute :numbers

  def call!
    filter_positive_numbers
      .then(:sum_all_numbers)
  end

  private

    def filter_positive_numbers
      # ..
    end

    def sum_all_numbers(numbers: **)
      # ...
    end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant