From 9623cd27abb290949493b6ea56a5c2e891f2d274 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Mon, 17 Nov 2014 17:05:02 +0000 Subject: [PATCH] Add specs for Mutator::Registry and simplify it --- config/flay.yml | 2 +- lib/mutant/mutator.rb | 4 +- lib/mutant/mutator/registry.rb | 81 +++++++---------------- lib/mutant/mutator/util/array.rb | 2 - lib/mutant/mutator/util/symbol.rb | 2 - spec/unit/mutant/mutator/registry_spec.rb | 57 ++++++++++++++++ 6 files changed, 83 insertions(+), 65 deletions(-) create mode 100644 spec/unit/mutant/mutator/registry_spec.rb diff --git a/config/flay.yml b/config/flay.yml index 88376657..01bcef9d 100644 --- a/config/flay.yml +++ b/config/flay.yml @@ -1,3 +1,3 @@ --- threshold: 18 -total_score: 1126 +total_score: 1121 diff --git a/lib/mutant/mutator.rb b/lib/mutant/mutator.rb index a8cd0250..a2608315 100644 --- a/lib/mutant/mutator.rb +++ b/lib/mutant/mutator.rb @@ -16,7 +16,7 @@ module Mutant # def self.each(input, parent = nil, &block) return to_enum(__method__, input, parent) unless block_given? - Registry.lookup(input).new(input, parent, block) + REGISTRY.lookup(input).new(input, parent, block) self end @@ -29,7 +29,7 @@ module Mutant # def self.handle(*types) types.each do |type| - Registry.register(type, self) + REGISTRY.register(type, self) end end private_class_method :handle diff --git a/lib/mutant/mutator/registry.rb b/lib/mutant/mutator/registry.rb index dfe96664..a1d8391a 100644 --- a/lib/mutant/mutator/registry.rb +++ b/lib/mutant/mutator/registry.rb @@ -1,27 +1,34 @@ module Mutant class Mutator # Registry for mutators - module Registry + class Registry + + # Initialize object + # + # @return [undefined] + # + # @api private + # + def initialize + @registry = {} + end # Raised when the type is an invalid type - InvalidTypeError = Class.new(TypeError) - - # Raised when the type is a duplicate - DuplicateTypeError = Class.new(ArgumentError) + RegistryError = Class.new(TypeError) # Register mutator class for AST node class # # @param [Symbol] type - # @param [Class] mutator_class + # @param [Class:Mutator] mutator # # @api private # # @return [self] # - def self.register(type, mutator_class) - assert_valid_type(type) - assert_unique_type(type) - registry[type] = mutator_class + def register(type, mutator) + fail RegistryError, "Invalid type registration: #{type}" unless AST::Types::ALL.include?(type) + fail RegistryError, "Duplicate type registration: #{type}" if @registry.key?(type) + @registry[type] = mutator self end @@ -36,58 +43,16 @@ module Mutant # # @api private # - def self.lookup(node) + def lookup(node) type = node.type - registry.fetch(type) do - fail ArgumentError, "No mutator to handle: #{type.inspect}" + @registry.fetch(type) do + fail RegistryError, "No mutator to handle: #{type.inspect}" end end - # Return registry state - # - # @return [Hash] - # - # @api private - # - def self.registry - @registry ||= {} - end - private_class_method :registry - - # Assert the node type is valid - # - # @param [Symbol] type - # - # @return [undefined] - # - # @raise [InvalidTypeError] - # raised when the node type is invalid - # - # @api private - # - def self.assert_valid_type(type) - unless AST::Types::ALL.include?(type) || type.is_a?(Class) - fail InvalidTypeError, "invalid type registration: #{type}" - end - end - private_class_method :assert_valid_type - - # Assert the node type is unique and not already registered - # - # @return [undefined] - # - # @raise [DuplicateTypeError] - # raised when the node type is a duplicate - # - # @api private - # - def self.assert_unique_type(type) - if registry.key?(type) - fail DuplicateTypeError, "duplicate type registration: #{type}" - end - end - private_class_method :assert_unique_type - end # Registry + + REGISTRY = Registry.new + end # Mutator end # Mutant diff --git a/lib/mutant/mutator/util/array.rb b/lib/mutant/mutator/util/array.rb index 00ac4fb2..508e985a 100644 --- a/lib/mutant/mutator/util/array.rb +++ b/lib/mutant/mutator/util/array.rb @@ -5,8 +5,6 @@ module Mutant # Mutators that mutates an array of inputs class Array < self - handle(::Array) - # Element presence mutator class Presence < Util diff --git a/lib/mutant/mutator/util/symbol.rb b/lib/mutant/mutator/util/symbol.rb index 74779124..f58332a9 100644 --- a/lib/mutant/mutator/util/symbol.rb +++ b/lib/mutant/mutator/util/symbol.rb @@ -5,8 +5,6 @@ module Mutant # Utility symbol mutator class Symbol < self - handle(::Symbol) - POSTFIX = '__mutant__'.freeze private diff --git a/spec/unit/mutant/mutator/registry_spec.rb b/spec/unit/mutant/mutator/registry_spec.rb new file mode 100644 index 00000000..37db8b63 --- /dev/null +++ b/spec/unit/mutant/mutator/registry_spec.rb @@ -0,0 +1,57 @@ +RSpec.describe Mutant::Mutator::Registry do + describe '#lookup' do + subject { Mutant::Mutator::REGISTRY.lookup(node) } + + context 'on registred node' do + let(:node) { s(:true) } + + it { should eql(Mutant::Mutator::Node::Literal::Boolean) } + end + + context 'on unknown node' do + let(:node) { s(:unknown) } + + it 'raises error' do + expect { subject }.to raise_error(described_class::RegistryError, "No mutator to handle: :unknown") + end + end + end + + describe '#register' do + let(:object) { described_class.new } + + let(:mutator) { double('Mutator') } + + subject { object.register(type, mutator) } + + context 'when registring an invalid node type' do + let(:type) { :invalid } + + it 'raises error' do + expect { subject }.to raise_error(described_class::RegistryError, 'Invalid type registration: invalid') + end + end + + context 'when registring a valid node type' do + let(:type) { :true } + + it 'allows to lookup mutator' do + subject + expect(object.lookup(s(type))).to be(mutator) + end + + it_behaves_like 'a command method' + end + + context 'when duplicate the registration of a valid node type' do + let(:type) { :true } + + it 'allows to lookup mutator' do + object.register(type, mutator) + expect { subject }.to raise_error(described_class::RegistryError, 'Duplicate type registration: true') + end + + it_behaves_like 'a command method' + end + end +end