From 3e527c5f998c022d628557c82e47407758837cfe Mon Sep 17 00:00:00 2001 From: Dmytro Lomako Date: Thu, 6 Jul 2023 01:19:08 +0300 Subject: [PATCH] added custom outputs binary state methods --- .byebug_history | 11 ++++++++ .gitignore | 1 + lib/trailblazer/operation/public_call.rb | 2 +- lib/trailblazer/operation/railway.rb | 14 +++++---- test/custom_output_test.rb | 36 ++++++++++++++++++++++++ test/result_test.rb | 6 ++-- 6 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 .byebug_history create mode 100644 test/custom_output_test.rb diff --git a/.byebug_history b/.byebug_history new file mode 100644 index 0000000..34347aa --- /dev/null +++ b/.byebug_history @@ -0,0 +1,11 @@ +c +success +c +event +Result.new(Create, {"x" => String}, event) +success.inspect +success +c +success.inspect +quit +success.inspect diff --git a/.gitignore b/.gitignore index cbb29a0..df9e0c1 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ test/version_tmp tmp /**/*.log .rubocop-*yml +.idea diff --git a/lib/trailblazer/operation/public_call.rb b/lib/trailblazer/operation/public_call.rb index 8841f5a..6a775f8 100644 --- a/lib/trailblazer/operation/public_call.rb +++ b/lib/trailblazer/operation/public_call.rb @@ -46,7 +46,7 @@ def call_with_public_interface(options, flow_options, invoke_class: Activity::Ta ) # Result is successful if the activity ended with an End event derived from Railway::End::Success. - Operation::Railway::Result(signal, ctx, flow_options) + Operation::Railway::Result(self, signal, ctx, flow_options) end # This interface is used for all nested OPs (and the outer-most, too). diff --git a/lib/trailblazer/operation/railway.rb b/lib/trailblazer/operation/railway.rb index 6dc9f5c..1959a96 100644 --- a/lib/trailblazer/operation/railway.rb +++ b/lib/trailblazer/operation/railway.rb @@ -11,16 +11,20 @@ def self.fail_fast!; Activity::FastTrack::FailFast end def self.pass_fast!; Activity::FastTrack::PassFast end # @param options Context # @param end_event The last emitted signal in a circuit is usually the end event. - def self.Result(end_event, options, *) - Result.new(end_event.kind_of?(End::Success), options, end_event) + def self.Result(activity, end_event, options, *) + Result.new(activity, options, end_event) end # The Railway::Result knows about its binary state, the context (data), and the last event in the circuit. class Result < Result # Operation::Result - def initialize(success, data, event) - super(success, data) - + def initialize(activity, data, event) + super(event.kind_of?(End::Success), data) @event = event + + # generate [:success?, :pass_fast?, :fail_fast?, :failure?, :?] methods + activity.to_h[:outputs].each do |output| + define_singleton_method("#{output[:semantic]}?") { event.to_h[:semantic] == output[:semantic] } + end end attr_reader :event diff --git a/test/custom_output_test.rb b/test/custom_output_test.rb new file mode 100644 index 0000000..d3ee25e --- /dev/null +++ b/test/custom_output_test.rb @@ -0,0 +1,36 @@ +require "test_helper" + +class CustomOutputTest < Minitest::Spec + # #success passes fast. + class Execute < Trailblazer::Operation + UsePaypal = Class.new(Trailblazer::Activity::Signal) + + step :find_provider, Output(UsePaypal, :paypal) => End(:paypal) + step :charge_creditcard + + def find_provider(ctx, params:, **) + return true unless params[:provider] == :paypal + UsePaypal + end + + def charge_creditcard(ctx, **) + ctx[:charged] = true + end + end + + describe "if a custom output is used in an operation" do + it "adds `?` method to the result object which returns true if the operation takes the correspondent track" do + result = Execute.(params: {provider: :paypal}) + assert result.paypal? + assert !result.success? + assert !result.failure? + refute_respond_to result, :papa_johns? + + result = Execute.(params: {provider: :not_paypal}) + assert !result.paypal? + assert result.success? + assert !result.failure? + end + end + +end diff --git a/test/result_test.rb b/test/result_test.rb index 9df1fd0..62e49d2 100644 --- a/test/result_test.rb +++ b/test/result_test.rb @@ -4,8 +4,8 @@ class RailwayResultTest < Minitest::Spec Result = Trailblazer::Operation::Railway::Result Success = Trailblazer::Operation::Railway::End::Success - let(:event) { Success.new(semantic: nil) } - let(:success) { Result.new(true, {"x" => String}, event) } + let(:event) { Success.new(semantic: :success) } + let(:success) { Result.new(Create, {"x" => String}, event) } it { success.success?.must_equal true } it { success.failure?.must_equal false } @@ -20,7 +20,7 @@ class RailwayResultTest < Minitest::Spec #--- # inspect it { success.inspect.must_equal %{String} >} } - it { Result.new(true, {"x" => true, "y" => 1, "z" => 2}, event).inspect("z", "y").must_equal %{} } + it { Result.new(Create, {"x" => true, "y" => 1, "z" => 2}, event).inspect("z", "y").must_equal %{} } class Create < Trailblazer::Operation pass :call