Skip to content

Commit

Permalink
feat(has_j_send_result_short_syntax): allow to pass message and code …
Browse files Browse the repository at this point in the history
…to short form of success
  • Loading branch information
marian13 committed Sep 10, 2023
1 parent 428280a commit fdf2ab2
Show file tree
Hide file tree
Showing 9 changed files with 336 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# frozen_string_literal: true

require_relative "commands/refute_kwargs_contain_data_and_extra_keys"
require_relative "commands/refute_kwargs_contain_j_send_and_extra_keys"

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# frozen_string_literal: true

module ConvenientService
module Service
module Plugins
module HasJSendResultShortSyntax
module Success
module Commands
class RefuteKwargsContainJSendAndExtraKeys < Support::Command
##
# @attribute [r] kwargs
# @return [Hash{Symbol => Object}]
#
attr_reader :kwargs

##
# @param kwargs [Hash{Symbol => Object}]
# @return [void]
#
def initialize(kwargs:)
@kwargs = kwargs
end

##
# @return [void]
# @raise [ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys]
#
# @example `kwargs.keys.difference([:data, :message, :code]).none?`.
#
# {}.keys.difference([:data, :message, :code]).none?
# # => true
#
# {a: 1}.keys.difference([:data, :message, :code]).none?
# # => false
#
# {data: {}}.keys.difference([:data, :message, :code]).none?
# # => true
#
# {data: {}, a: 1}.keys.difference([:data, :message, :code]).none?
# # => false
#
# {data: {}, message: ""}.keys.difference([:data, :message, :code]).none?
# # => true
#
# {data: {}, message: "", a: 1}.keys.difference([:data, :message, :code]).none?
# # => false
#
# {data: {}, message: "", code: :""}.keys.difference([:data, :message, :code]).none?
# # => true
#
# {data: {}, message: "", code: :"", a: 1}.keys.difference([:data, :message, :code]).none?
# # => false
#
def call
return if [:data, :message, :code].none? { |key| kwargs.has_key?(key) }

return if kwargs.keys.difference([:data, :message, :code]).none?

raise Exceptions::KwargsContainJSendAndExtraKeys.new
end
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,27 @@ module Plugins
module HasJSendResultShortSyntax
module Success
module Exceptions
class KwargsContainDataAndExtraKeys < ::ConvenientService::Exception
class KwargsContainJSendAndExtraKeys < ::ConvenientService::Exception
##
# @return [void]
#
def initialize
message = <<~TEXT
`kwargs` passed to `success` method contain `data` and extra keys. That's NOT allowed.
`kwargs` passed to `success` method contain JSend keys and extra keys. That's NOT allowed.
Please, consider something like:
# Shorter form. Assumes that all kwargs are `data`.
success(foo: :bar)
# Longer form. More explicit.
success(data: {foo: :bar})
# (Advanced) Longer form also supports any variation of `data`, `message` and `code`.
success(data: {foo: :bar}, message: "foo")
success(data: {foo: :bar}, code: :foo)
success(message: "foo", code: :foo)
success(data: {foo: :bar}, message: "foo", code: :foo)
TEXT

super(message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ module Success
class Middleware < MethodChainMiddleware
intended_for :success, entity: :service

##
# @param args [Array<Object>]
# @param kwargs [Hash{Symbol => Object}]
# @param block [Proc, nil]
# @return [ConvenientService::Service::Plugins::HasJSendResult::Entities::Result]
#
def next(*args, **kwargs, &block)
Commands::RefuteKwargsContainDataAndExtraKeys.call(kwargs: kwargs)
Commands::RefuteKwargsContainJSendAndExtraKeys[kwargs: kwargs]

kwargs.has_key?(:data) ? chain.next(**kwargs) : chain.next(data: kwargs)
([:data, :message, :code].any? { |key| kwargs.has_key?(key) }) ? chain.next(**kwargs) : chain.next(data: kwargs)
end
end
end
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# frozen_string_literal: true

require "spec_helper"

require "convenient_service"

# rubocop:disable RSpec/NestedGroups
RSpec.describe ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Commands::RefuteKwargsContainJSendAndExtraKeys do
include ConvenientService::RSpec::Matchers::Results

example_group "class methods" do
describe ".call" do
subject(:command_result) { described_class.call(kwargs: kwargs) }

context "when `kwargs` do NOT contain `:data`, `:message` and `code` keys" do
let(:kwargs) { {foo: :bar} }

it "does NOT raise" do
expect { command_result }.not_to raise_error
end
end

context "when kwargs contain `:data` key" do
context "when kwargs do NOT contain extra keys" do
let(:kwargs) { {data: {foo: :bar}} }

it "does NOT raise" do
expect { command_result }.not_to raise_error
end
end

context "when kwargs contain extra keys" do
let(:kwargs) { {data: {foo: :bar}, extra_key: anything} }

let(:exception_message) do
<<~TEXT
`kwargs` passed to `success` method contain JSend keys and extra keys. That's NOT allowed.
Please, consider something like:
# Shorter form. Assumes that all kwargs are `data`.
success(foo: :bar)
# Longer form. More explicit.
success(data: {foo: :bar})
# (Advanced) Longer form also supports any variation of `data`, `message` and `code`.
success(data: {foo: :bar}, message: "foo")
success(data: {foo: :bar}, code: :foo)
success(message: "foo", code: :foo)
success(data: {foo: :bar}, message: "foo", code: :foo)
TEXT
end

it "raises `ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys`" do
expect { command_result }
.to raise_error(ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys)
.with_message(exception_message)
end
end
end

context "when kwargs contain `:message` key" do
context "when kwargs do NOT contain extra keys" do
let(:kwargs) { {message: "foo"} }

it "does NOT raise" do
expect { command_result }.not_to raise_error
end
end

context "when kwargs contain extra keys" do
let(:kwargs) { {message: "foo", extra_key: anything} }

let(:exception_message) do
<<~TEXT
`kwargs` passed to `success` method contain JSend keys and extra keys. That's NOT allowed.
Please, consider something like:
# Shorter form. Assumes that all kwargs are `data`.
success(foo: :bar)
# Longer form. More explicit.
success(data: {foo: :bar})
# (Advanced) Longer form also supports any variation of `data`, `message` and `code`.
success(data: {foo: :bar}, message: "foo")
success(data: {foo: :bar}, code: :foo)
success(message: "foo", code: :foo)
success(data: {foo: :bar}, message: "foo", code: :foo)
TEXT
end

it "raises `ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys`" do
expect { command_result }
.to raise_error(ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys)
.with_message(exception_message)
end
end
end

context "when kwargs contain `:code` key" do
context "when kwargs do NOT contain extra keys" do
let(:kwargs) { {code: :foo} }

it "does NOT raise" do
expect { command_result }.not_to raise_error
end
end

context "when kwargs contain extra keys" do
let(:kwargs) { {code: :foo, extra_key: anything} }

let(:exception_message) do
<<~TEXT
`kwargs` passed to `success` method contain JSend keys and extra keys. That's NOT allowed.
Please, consider something like:
# Shorter form. Assumes that all kwargs are `data`.
success(foo: :bar)
# Longer form. More explicit.
success(data: {foo: :bar})
# (Advanced) Longer form also supports any variation of `data`, `message` and `code`.
success(data: {foo: :bar}, message: "foo")
success(data: {foo: :bar}, code: :foo)
success(message: "foo", code: :foo)
success(data: {foo: :bar}, message: "foo", code: :foo)
TEXT
end

it "raises `ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys`" do
expect { command_result }
.to raise_error(ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions::KwargsContainJSendAndExtraKeys)
.with_message(exception_message)
end
end
end
end
end
end
# rubocop:enable RSpec/NestedGroups
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
RSpec.describe ConvenientService::Service::Plugins::HasJSendResultShortSyntax::Success::Exceptions do
include ConvenientService::RSpec::Matchers::BeDescendantOf

specify { expect(described_class::KwargsContainDataAndExtraKeys).to be_descendant_of(ConvenientService::Exception) }
specify { expect(described_class::KwargsContainJSendAndExtraKeys).to be_descendant_of(ConvenientService::Exception) }
end
Loading

0 comments on commit fdf2ab2

Please sign in to comment.