From 7008de4fec23b1779c0c20d414de6a388dfa7811 Mon Sep 17 00:00:00 2001 From: thadeu Date: Fri, 7 Jun 2024 22:06:39 -0300 Subject: [PATCH] remove: eager_load include BasicObject --- lib/zx.rb | 14 +- lib/zx/eager_load.rb | 5 - spec/lib/zx/result_spec.rb | 317 ----------------------------------- spec/lib/zx_spec.rb | 322 +++++++++++++++++++++++++++++++++++- spec/spec_helper.rb | 9 +- spec/support/user_mailer.rb | 4 +- 6 files changed, 339 insertions(+), 332 deletions(-) delete mode 100644 lib/zx/eager_load.rb diff --git a/lib/zx.rb b/lib/zx.rb index 30ab9a6..6b16ba2 100644 --- a/lib/zx.rb +++ b/lib/zx.rb @@ -8,7 +8,7 @@ module Zx class AbortError < ::RuntimeError attr_reader :type - + def initialize(message: nil, type: :error) @type = type super(message) @@ -18,26 +18,26 @@ def initialize(message: nil, type: :error) module Methods Success = ->(value = nil, options = {}) { Zx.Success(value, { type: :ok }.merge(options)) } Failure = ->(value = nil, options = {}) { Zx.Failure(value, { type: :error }.merge(options)) } - + def Success(value = nil, options = {}) Zx::Result.new.success!(value, type: options.fetch(:type, :ok)) end - + def Failure(value = nil, options = {}) Zx::Result.new.failure!(value, type: options.fetch(:type, :error)) end - + def Try(default = nil, options = {}) Success[yield] - rescue StandardError => e + rescue StandardError => _e Failure[default || options.fetch(:or, nil)] end - + def Given(input) Try { input } end end - + include Methods extend Methods end diff --git a/lib/zx/eager_load.rb b/lib/zx/eager_load.rb deleted file mode 100644 index 983d74b..0000000 --- a/lib/zx/eager_load.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -class BasicObject - include ::Zx -end diff --git a/spec/lib/zx/result_spec.rb b/spec/lib/zx/result_spec.rb index e101ea8..7f846e3 100644 --- a/spec/lib/zx/result_spec.rb +++ b/spec/lib/zx/result_spec.rb @@ -3,321 +3,4 @@ require 'spec_helper' RSpec.describe Zx::Result do - describe 'inherited' do - it 'success using as base' do - result = AsInherited.new.pass(a: 1) - - expect(result.type).to eq(:ok) - expect(result.value).to eq(a: 1) - end - - it 'success using as base' do - result = AsInherited.new.passthrough(a: 1) - - expect(result.type).to eq(:ok) - expect(result.value).to eq(a: 1) - end - - it 'fail using as base' do - result = AsInherited.new.failed(message: 'was error') - - expect(result.type).to eq(:error) - expect(result.value[:message]).to eq('was error') - end - - it 'methods doesnt exists in the public_instance_methods' do - result = AsInherited.new - - expect(result.public_methods).to include(:Success) - expect(result.public_methods).to include(:Failure) - end - end - - describe 'extended' do - it 'success using as base' do - result = AsExtended.pass(a: 1) - - expect(result.type).to eq(:ok) - expect(result.value).to eq(a: 1) - end - - it 'success using as base' do - result = AsExtended.passthrough(a: 1) - - expect(result.type).to eq(:ok) - expect(result.value).to eq(a: 1) - end - - it 'fail using as base' do - result = AsExtended.failed(message: 'was error') - - expect(result.type).to eq(:error) - expect(result.value[:message]).to eq('was error') - end - end - - describe 'composition' do - it 'using as private mixin' do - result = AsComposition.new.pass(a: 1) - expect(result.value).to eq(a: 1) - end - - it 'using as concern directly' do - result = AsComposition.new.failed('error') - expect(result.error).to eq('error') - end - - it 'using on_success listeners' do - result = AsComposition.new.pass('save record!', type: :persisted) - - expect(result.type).to eq(:persisted) - expect(result.value!).to eq('save record!') - - result - .on(:success, :success) { expect(_1).to eq(a: 1) } - .on(:success, :mailer) { expect(_1).to eq(a: 1) } - .on(:success, :persisted) { expect(_1).to eq('save record!') } - .on(:success) { |value, (type)| expect([value, type]).to eq(['save record!', :persisted]) } - .on(:failure, :error) { expect(_1).to eq('on error') } - .on(:failure, :record_not_found) { expect(_1).to eq('not found user') } - end - - it 'using on_failure listeners' do - result = AsComposition.new.failed('error') - - expect(result.type).to eq(:error) - expect(result.value!).to eq('error') - - result - .on(:success, :success) { expect(_1).to eq(a: 1) } - .on(:success, :mailer) { expect(_1).to eq(a: 1) } - .on(:success, :persisted) { expect(_1).to eq('save record!') } - .on(:success) { |value, (type)| expect([value, type]).to eq(['save record!', :persisted]) } - .on(:failure, :record_not_found) { expect(_1).to eq('not found users') } - .on(:failure, :error) { expect(_1).to eq('error') } - .on(:failure) { expect(_1).to eq('error') } - .on_failure(:error) { expect(_1).to eq('error') } - .on_failure { expect(_1).to eq('error') } - end - end - - describe '#failure' do - it 'using fail directly' do - result = Zx::Result.Failure('error', type: :invalid) - - expect(result.error).to eq('error') - expect(result.type).to eq(:invalid) - end - - it 'using on_failure listeners' do - result = Zx::Result.Failure('invalid type tagged') - - expect(result.type).to eq(:error) - - result - .on_success { expect(_1).to eq(a: 1) } - .on_failure(:error) { expect(_1).to eq('invalid type tagged') } - .on_failure(:invalid) { expect(_1).to eq('invalid') } - .on_failure { expect(_1).to eq('invalid type tagged') } - end - - it 'using on_failure listeners' do - result = Zx::Result.Failure('as invalid', type: :invalid) - - expect(result.type).to eq(:invalid) - - result - .on_success { expect(_1).to eq(a: 1) } - .on_failure(:error) { expect(_1).to eq('invalid types tagged') } - .on_failure(:invalid) { expect(_1).to eq('as invalid') } - end - - it 'using on_unknown listeners' do - result = Zx::Result.Failure('as invalid', type: :invalid) - - expect(result.type).to eq(:invalid) - - result - .on_success { expect(_1).to eq(a: 1) } - .on_failure(:rescue) { expect(_1).to eq('invalid types tagged') } - .on_failure(:not_found) { expect(_1).to eq('as invalid') } - .on_unknown do |value, (type, success)| - expect(value).to eq('as invalid') - expect(type).to eq(:invalid) - expect(success).to be_falsey - end - end - - it 'using on_failure listeners' do - result = Zx::Result.Failure('not found user', type: :record_not_found) - - expect(result.type).to eq(:record_not_found) - expect(result.value!).to eq('not found user') - - result - .on(:success) { expect(_1).to eq(a: 1) } - .on(:success, :send_mailer) { expect(_1).to eq(a: 1) } - .on(:failure, :error) { expect(_1).to eq('not found') } - .on(:failure, :record_not_found) { expect(_1).to eq('not found user') } - end - - it 'using on_failure listeners' do - result = Zx::Result.Failure('on error', type: 'mailer') - - expect(result.type).to eq(:mailer) - expect(result.value!).to eq('on error') - - result - .on(:success) { expect(_1).to eq(a: 1) } - .on(:success, :mailer) { expect(_1).to eq(a: 1) } - .on(:failure, :error) { expect(_1).to eq('on errors') } - .on(:failure, :mailer) { |error, (type)| expect([error, type]).to eq(['on error', :mailer]) } - .on(:failure, :record_not_found) { expect(_1).to eq('not found user') } - end - end - - describe '#success' do - context 'as method' do - it 'using directly' do - result = Zx::Result.Success(a: 1) - expect(result.value).to eq(a: 1) - end - - it '#then' do - result = Zx::Result.Success(a: 1) - - result.then { _1[:a] + 1 } - - expect(result.value).to eq(2) - end - - it '#and_then' do - result = Zx::Result.Success(a: 1) - - result.and_then { _1[:a] + 1 } - - expect(result.value).to eq(2) - end - - it '#step' do - result = Zx::Result.Success(a: 1) - - result.step { _1[:a] + 1 } - - expect(result.value).to eq(2) - end - - it '#fmap' do - result = Zx::Result.Success(a: 1) - - result.fmap { _1[:a] + 1 } - - expect(result.value).to eq(2) - end - - context '#check' do - it 'success' do - result = Zx::Result.Success(a: 1) - - result - .check { _1[:a] == 1 } - .fmap { _1[:a] + 1 } - - expect(result.value).to eq(2) - end - - it 'failure' do - result = Zx::Result.Success(a: 1) - - result - .check { _1[:a] == 2 } - .then { _1[:a] + 1 } - - expect(result.value).to eq(nil) - end - end - - it 'using on_success listeners' do - result = Zx::Result.Success a: 1 - - expect(result.type).to eq(:ok) - - result.on_success { expect(_1).to eq(a: 1) } - end - - it 'using on_success listeners' do - result = Zx::Result.Success 1, type: :valid - - expect(result.type).to eq(:valid) - - result - .on_success(:valid) { expect(_1).to eq(1) } - .on_success(:user_found) { expect(_1).to eq(2) } - end - - it 'using on_success listeners with custom arrow method' do - result = Zx::Result.Success 1, type: :valid - - expect(result.type).to eq(:valid) - - result - .>>(:success, :valid) { expect(_1).to eq(1) } - .>>(:success, :user_found) { expect(_1).to eq(2) } - - result - .|(:success, :valid) { expect(_1).to eq(1) } - .|(:success, :user_found) { expect(_1).to eq(2) } - - result - .on(:success, :valid) { expect(_1).to eq(1) } - .on(:success, :user_found) { expect(_1).to eq(2) } - - result - .pipe(:success, :valid) { expect(_1).to eq(1) } - .pipe(:success, :user_found) { expect(_1).to eq(2) } - end - end - - context 'as callable' do - it 'using directly as Hash' do - result = Zx.Success(1) - expect(result.value).to eq(1) - end - - it 'using directly as Hash' do - result = Zx.Failure('error') - expect(result.value).to eq('error') - end - - it 'using directly as Hash' do - result = Zx::Failure['error'] - expect(result.value).to eq('error') - end - - it 'using directly as Hash' do - result = Zx::Success[1] - expect(result.value).to eq(1) - end - - it 'using directly as Hash' do - result = Zx::Result.Success(a: 1) - expect(result.value).to eq(a: 1) - end - - it 'using directly as Hash' do - result = Zx::Result::Success[a: 1] - expect(result.value).to eq(a: 1) - end - - it 'using directly as Hash' do - result = Zx::Result::Failure['invalid'] - expect(result.value).to eq('invalid') - end - - it 'using directly as Hash' do - result = Zx::Result::Failure('invalid') - expect(result.value).to eq('invalid') - end - end - end end diff --git a/spec/lib/zx_spec.rb b/spec/lib/zx_spec.rb index 6661751..860beee 100644 --- a/spec/lib/zx_spec.rb +++ b/spec/lib/zx_spec.rb @@ -2,7 +2,9 @@ require 'spec_helper' -class OrderService < Zx::Result +class OrderService + include Zx + def initialize(tax: 0.1) @tax = tax end @@ -111,4 +113,322 @@ def apply(value) expect(result.value).to eq('error') end end + + describe 'inherited' do + it 'success using as base' do + result = AsInherited.new.pass(a: 1) + + expect(result.type).to eq(:ok) + expect(result.value).to eq(a: 1) + end + + it 'success using as base' do + result = AsInherited.new.passthrough(a: 1) + + expect(result.type).to eq(:ok) + expect(result.value).to eq(a: 1) + end + + it 'fail using as base' do + result = AsInherited.new.failed(message: 'was error') + + expect(result.type).to eq(:error) + expect(result.value[:message]).to eq('was error') + end + + it 'methods doesnt exists in the public_instance_methods' do + result = AsInherited.new + + expect(result.public_methods).to include(:Success) + expect(result.public_methods).to include(:Failure) + end + end + + describe 'extended' do + it 'success using as base' do + result = AsExtended.pass(a: 1) + + expect(result.type).to eq(:ok) + expect(result.value).to eq(a: 1) + end + + it 'success using as base' do + result = AsExtended.passthrough(a: 1) + + expect(result.type).to eq(:ok) + expect(result.value).to eq(a: 1) + end + + it 'fail using as base' do + result = AsExtended.failed(message: 'was error') + + expect(result.type).to eq(:error) + expect(result.value[:message]).to eq('was error') + end + end + + describe 'composition' do + it 'using as private mixin' do + result = AsComposition.new.pass(a: 1) + expect(result.value).to eq(a: 1) + end + + it 'using as concern directly' do + result = AsComposition.new.failed('error') + expect(result.error).to eq('error') + end + + it 'using on_success listeners' do + result = AsComposition.new.pass('save record!', type: :persisted) + + expect(result.type).to eq(:persisted) + expect(result.value!).to eq('save record!') + + result + .on(:success, :success) { expect(_1).to eq(a: 1) } + .on(:success, :mailer) { expect(_1).to eq(a: 1) } + .on(:success, :persisted) { expect(_1).to eq('save record!') } + .on(:success) { |value, (type)| expect([value, type]).to eq(['save record!', :persisted]) } + .on(:failure, :error) { expect(_1).to eq('on error') } + .on(:failure, :record_not_found) { expect(_1).to eq('not found user') } + end + + it 'using on_failure listeners' do + result = AsComposition.new.failed('error') + + expect(result.type).to eq(:error) + expect(result.value!).to eq('error') + + result + .on(:success, :success) { expect(_1).to eq(a: 1) } + .on(:success, :mailer) { expect(_1).to eq(a: 1) } + .on(:success, :persisted) { expect(_1).to eq('save record!') } + .on(:success) { |value, (type)| expect([value, type]).to eq(['save record!', :persisted]) } + .on(:failure, :record_not_found) { expect(_1).to eq('not found users') } + .on(:failure, :error) { expect(_1).to eq('error') } + .on(:failure) { expect(_1).to eq('error') } + .on_failure(:error) { expect(_1).to eq('error') } + .on_failure { expect(_1).to eq('error') } + end + end + + describe '#failure' do + it 'using fail directly' do + result = Zx.Failure('error', type: :invalid) + + expect(result.error).to eq('error') + expect(result.type).to eq(:invalid) + end + + it 'using on_failure listeners' do + result = Zx.Failure('invalid type tagged') + + expect(result.type).to eq(:error) + + result + .on_success { expect(_1).to eq(a: 1) } + .on_failure(:error) { expect(_1).to eq('invalid type tagged') } + .on_failure(:invalid) { expect(_1).to eq('invalid') } + .on_failure { expect(_1).to eq('invalid type tagged') } + end + + it 'using on_failure listeners' do + result = Zx.Failure('as invalid', type: :invalid) + + expect(result.type).to eq(:invalid) + + result + .on_success { expect(_1).to eq(a: 1) } + .on_failure(:error) { expect(_1).to eq('invalid types tagged') } + .on_failure(:invalid) { expect(_1).to eq('as invalid') } + end + + it 'using on_unknown listeners' do + result = Zx.Failure('as invalid', type: :invalid) + + expect(result.type).to eq(:invalid) + + result + .on_success { expect(_1).to eq(a: 1) } + .on_failure(:rescue) { expect(_1).to eq('invalid types tagged') } + .on_failure(:not_found) { expect(_1).to eq('as invalid') } + .on_unknown do |value, (type, success)| + expect(value).to eq('as invalid') + expect(type).to eq(:invalid) + expect(success).to be_falsey + end + end + + it 'using on_failure listeners' do + result = Zx.Failure('not found user', type: :record_not_found) + + expect(result.type).to eq(:record_not_found) + expect(result.value!).to eq('not found user') + + result + .on(:success) { expect(_1).to eq(a: 1) } + .on(:success, :send_mailer) { expect(_1).to eq(a: 1) } + .on(:failure, :error) { expect(_1).to eq('not found') } + .on(:failure, :record_not_found) { expect(_1).to eq('not found user') } + end + + it 'using on_failure listeners' do + result = Zx.Failure('on error', type: 'mailer') + + expect(result.type).to eq(:mailer) + expect(result.value!).to eq('on error') + + result + .on(:success) { expect(_1).to eq(a: 1) } + .on(:success, :mailer) { expect(_1).to eq(a: 1) } + .on(:failure, :error) { expect(_1).to eq('on errors') } + .on(:failure, :mailer) { |error, (type)| expect([error, type]).to eq(['on error', :mailer]) } + .on(:failure, :record_not_found) { expect(_1).to eq('not found user') } + end + end + + describe '#success' do + context 'as method' do + it 'using directly' do + result = Zx.Success(a: 1) + expect(result.value).to eq(a: 1) + end + + it '#then' do + result = Zx.Success(a: 1) + + result.then { _1[:a] + 1 } + + expect(result.value).to eq(2) + end + + it '#and_then' do + result = Zx.Success(a: 1) + + result.and_then { _1[:a] + 1 } + + expect(result.value).to eq(2) + end + + it '#step' do + result = Zx.Success(a: 1) + + result.step { _1[:a] + 1 } + + expect(result.value).to eq(2) + end + + it '#fmap' do + result = Zx.Success(a: 1) + + result.fmap { _1[:a] + 1 } + + expect(result.value).to eq(2) + end + + context '#check' do + it 'success' do + result = Zx.Success(a: 1) + + result + .check { _1[:a] == 1 } + .fmap { _1[:a] + 1 } + + expect(result.value).to eq(2) + end + + it 'failure' do + result = Zx.Success(a: 1) + + result + .check { _1[:a] == 2 } + .then { _1[:a] + 1 } + + expect(result.value).to eq(nil) + end + end + + it 'using on_success listeners' do + result = Zx.Success a: 1 + + expect(result.type).to eq(:ok) + + result.on_success { expect(_1).to eq(a: 1) } + end + + it 'using on_success listeners' do + result = Zx.Success 1, type: :valid + + expect(result.type).to eq(:valid) + + result + .on_success(:valid) { expect(_1).to eq(1) } + .on_success(:user_found) { expect(_1).to eq(2) } + end + + it 'using on_success listeners with custom arrow method' do + result = Zx.Success 1, type: :valid + + expect(result.type).to eq(:valid) + + result + .>>(:success, :valid) { expect(_1).to eq(1) } + .>>(:success, :user_found) { expect(_1).to eq(2) } + + result + .|(:success, :valid) { expect(_1).to eq(1) } + .|(:success, :user_found) { expect(_1).to eq(2) } + + result + .on(:success, :valid) { expect(_1).to eq(1) } + .on(:success, :user_found) { expect(_1).to eq(2) } + + result + .pipe(:success, :valid) { expect(_1).to eq(1) } + .pipe(:success, :user_found) { expect(_1).to eq(2) } + end + end + + context 'as callable' do + it 'using directly as Hash' do + result = Zx.Success(1) + expect(result.value).to eq(1) + end + + it 'using directly as Hash' do + result = Zx.Failure('error') + expect(result.value).to eq('error') + end + + it 'using directly as Hash' do + result = Zx::Failure['error'] + expect(result.value).to eq('error') + end + + it 'using directly as Hash' do + result = Zx::Success[1] + expect(result.value).to eq(1) + end + + it 'using directly as Hash' do + result = Zx.Success(a: 1) + expect(result.value).to eq(a: 1) + end + + it 'using directly as Hash' do + result = Zx::Success[a: 1] + expect(result.value).to eq(a: 1) + end + + it 'using directly as Hash' do + result = Zx::Failure['invalid'] + expect(result.value).to eq('invalid') + end + + it 'using directly as Hash' do + result = Zx::Failure('invalid') + expect(result.value).to eq('invalid') + end + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f9cb4ee..8d6ec62 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,11 +1,18 @@ # frozen_string_literal: true +require 'simplecov' + +SimpleCov.start do + enable_coverage :branch + add_filter %r{^/(spec)/} +end + require 'byebug' require 'bundler/setup' require 'zx' -Dir["#{File.expand_path(__dir__)}/support/**/*.rb"].each { |f| require f } +Dir["#{File.expand_path(__dir__)}/support/**/*.rb"].sort.each { |f| require f } RSpec.configure do |config| # Enable flags like --only-failures and --next-failure diff --git a/spec/support/user_mailer.rb b/spec/support/user_mailer.rb index dab3bae..0e6b304 100644 --- a/spec/support/user_mailer.rb +++ b/spec/support/user_mailer.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true -require 'zx/eager_load' +require 'zx' class UserMailer + include Zx + Passthru = ->(input) { input } def deliver(input)