Skip to content

Commit

Permalink
feat(depencency_container): introduce entry
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed Mar 31, 2023
1 parent fa39934 commit a905b6e
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/convenient_service/support/dependency_container.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require_relative "dependency_container/entities"
require_relative "dependency_container/errors"

require_relative "dependency_container/entry"
require_relative "dependency_container/export"
require_relative "dependency_container/import"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
require_relative "commands/assert_valid_container"
require_relative "commands/assert_valid_method"
require_relative "commands/create_methods_module"
require_relative "commands/define_entry"
require_relative "commands/import_method"
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module ConvenientService
module Support
module DependencyContainer
module Commands
class DefineEntry < Support::Command
##
# @!attribute [r] container
# @return [Module]
#
attr_reader :container

##
# @!attribute [r] name
# @return [String, Symbol]
#
attr_reader :name

##
# @!attribute [r] body
# @return [Proc]
#
attr_reader :body

##
# @param container [Module]
# @param name [String, Symbol]
# @param body [Proc]
#
def initialize(container:, name:, body:)
@container = container
@name = name
@body = body
end

##
# @return [String, Symbol]
#
def call
container.define_singleton_method(name, &body)

name
end
end
end
end
end
end
22 changes: 22 additions & 0 deletions lib/convenient_service/support/dependency_container/entry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module ConvenientService
module Support
module DependencyContainer
module Entry
include Support::Concern

class_methods do
##
# @param name [String, Symbol]
# @param body [Proc]
# @return [String, Symbol]
#
def entry(name, &body)
Commands::DefineEntry.call(container: self, name: name, body: body)
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true

require "spec_helper"

require "convenient_service"

# rubocop:disable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers
RSpec.describe ConvenientService::Support::DependencyContainer::Commands::DefineEntry do
example_group "class methods" do
describe ".call" do
include ConvenientService::RSpec::Matchers::DelegateTo

subject(:command_result) { described_class.call(container: container, name: name, body: body) }

let(:container) { Module.new }

let(:name) { :foo }
let(:body) { proc { |*args, **kwargs, &block| [__method__, args, kwargs, block] } }

it "returns `name`" do
expect(command_result).to eq(name)
end

it "defines class method with `name` on `container`" do
##
# NOTE: `false` in `methods(false)` means own methods.
# - https://ruby-doc.org/core-2.7.0/Object.html#method-i-methods
#
expect { command_result }.to change { container.methods(false).include?(name.to_sym) }.from(false).to(true)
end

context "when class method with `name` on `container` already exist" do
let(:container) do
Module.new do
class << self
def foo
:foo
end
end
end
end

it "overrides that already existing class method" do
command_result

expect(container.foo).to eq([name, [], {}, nil])
end
end

example_group "generated method" do
it "returns `body` value" do
command_result

expect(container.foo).to eq([name, [], {}, nil])
end

context "when `body` accepts arguments" do
let(:args) { [:foo] }
let(:kwargs) { {foo: :bar} }
let(:block) { proc { :foo } }

it "accepts same arguments as `body`" do
command_result

expect(container.foo(*args, **kwargs, &block)).to eq([name, args, kwargs, block])
end
end
end
end
end
end
# rubocop:enable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require "spec_helper"

require "convenient_service"

# rubocop:disable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers
RSpec.describe ConvenientService::Support::DependencyContainer::Entry do
include ConvenientService::RSpec::Matchers::DelegateTo

let(:container) do
Module.new.tap do |mod|
mod.module_exec(described_class) do |described_mod|
include described_mod
end
end
end

let(:entry) { container.entry(name, &body) }

let(:name) { :foo }
let(:body) { proc { :bar } }

example_group "modules" do
include ConvenientService::RSpec::Matchers::IncludeModule

subject { described_class }

it { is_expected.to include_module(ConvenientService::Support::Concern) }
end

example_group "class methods" do
describe "#entry" do
specify do
expect { entry }
.to delegate_to(ConvenientService::Support::DependencyContainer::Commands::DefineEntry, :call)
.with_arguments(container: container, name: name, body: body)
.and_return_its_value
end
end
end
end
# rubocop:enable RSpec/NestedGroups, RSpec/MultipleMemoizedHelpers

0 comments on commit a905b6e

Please sign in to comment.