From eccdc228ecccfa33bfc32b52b7152299073b2961 Mon Sep 17 00:00:00 2001 From: Ignacio Baixas Date: Thu, 14 Jul 2016 17:46:17 -0400 Subject: [PATCH] feat(): adds service pattern --- lib/power_types.rb | 1 + lib/power_types/patterns/command.rb | 40 +++++------------------------ lib/power_types/patterns/service.rb | 37 ++++++++++++++++++++++++++ spec/lib/patterns/service_spec.rb | 23 +++++++++++++++++ 4 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 lib/power_types/patterns/service.rb create mode 100644 spec/lib/patterns/service_spec.rb diff --git a/lib/power_types.rb b/lib/power_types.rb index 2cf8652..65413d4 100644 --- a/lib/power_types.rb +++ b/lib/power_types.rb @@ -1,4 +1,5 @@ require "power_types/version" +require "power_types/patterns/service" require "power_types/patterns/command" module PowerTypes diff --git a/lib/power_types/patterns/command.rb b/lib/power_types/patterns/command.rb index 4d05dc1..e0b5dce 100644 --- a/lib/power_types/patterns/command.rb +++ b/lib/power_types/patterns/command.rb @@ -1,45 +1,17 @@ module PowerTypes module Command - # rubocop:disable Metrics/MethodLength def self.new(*_attributes) - attr_names = [] - attr_defaults = {} - - _attributes.each do |att| - if att.is_a? Hash - attr_defaults.merge! att - attr_names += att.keys - else - attr_names << att - end - end - - Class.new do - def self.for(kwargs = {}) - new(kwargs).perform - end - - def logger - Rails.logger - end - - def perform - raise NotImplementedError, "Command must implement `perform`" - end - - define_method(:initialize) do |kwargs = {}| - unless (kwargs.keys - attr_names).empty? - raise ArgumentError, "Unexpected arguments: #{(kwargs.keys - attr_names).join(', ')}" + Service.new(*_attributes).tap do |klass| + klass.class_eval do + def self.for(kwargs = {}) + new(kwargs).perform end - kwargs = attr_defaults.merge kwargs - attr_names.map do |a| - raise ArgumentError, "Missing parameter: #{a}" unless kwargs.key? a - instance_variable_set "@#{a}", kwargs[a] + def perform + raise NotImplementedError, "Command must implement `perform`" end end end end - # rubocop:enable Metrics/MethodLength end end diff --git a/lib/power_types/patterns/service.rb b/lib/power_types/patterns/service.rb new file mode 100644 index 0000000..867b903 --- /dev/null +++ b/lib/power_types/patterns/service.rb @@ -0,0 +1,37 @@ +module PowerTypes + module Service + # rubocop:disable Metrics/MethodLength + def self.new(*_attributes) + attr_names = [] + attr_defaults = {} + + _attributes.each do |att| + if att.is_a? Hash + attr_defaults.merge! att + attr_names += att.keys + else + attr_names << att + end + end + + Class.new do + def logger + Rails.logger + end + + define_method(:initialize) do |kwargs = {}| + unless (kwargs.keys - attr_names).empty? + raise ArgumentError, "Unexpected arguments: #{(kwargs.keys - attr_names).join(', ')}" + end + + kwargs = attr_defaults.merge kwargs + attr_names.map do |a| + raise ArgumentError, "Missing parameter: #{a}" unless kwargs.key? a + instance_variable_set "@#{a}", kwargs[a] + end + end + end + end + # rubocop:enable Metrics/MethodLength + end +end diff --git a/spec/lib/patterns/service_spec.rb b/spec/lib/patterns/service_spec.rb new file mode 100644 index 0000000..ecae7c9 --- /dev/null +++ b/spec/lib/patterns/service_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe PowerTypes::Service do + let(:service) do + Class.new(described_class.new(:foo, bar: nil)) do + end + end + + describe "new" do + it "fails if argument it not declared in argument list" do + expect { service.new(teapot: 'bar') }.to raise_error(ArgumentError) + end + + it "fails if required argument is not provided" do + expect { service.new(bar: 'bar') }.to raise_error(ArgumentError) + end + + it { expect(service.new(foo: 'bar').instance_variable_defined?(:@foo)).to be true } + it { expect(service.new(foo: 'bar').instance_variable_defined?(:@bar)).to be true } + it { expect(service.new(foo: 'bar').instance_variable_defined?(:@fur)).to be false } + it { expect(service.new(foo: 'bar').instance_variable_get(:@foo)).to eq 'bar' } + end +end