Add specs for Mutator::Registry and simplify it
This commit is contained in:
parent
f3720a6366
commit
9623cd27ab
6 changed files with 83 additions and 65 deletions
|
@ -1,3 +1,3 @@
|
|||
---
|
||||
threshold: 18
|
||||
total_score: 1126
|
||||
total_score: 1121
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -5,8 +5,6 @@ module Mutant
|
|||
# Mutators that mutates an array of inputs
|
||||
class Array < self
|
||||
|
||||
handle(::Array)
|
||||
|
||||
# Element presence mutator
|
||||
class Presence < Util
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ module Mutant
|
|||
# Utility symbol mutator
|
||||
class Symbol < self
|
||||
|
||||
handle(::Symbol)
|
||||
|
||||
POSTFIX = '__mutant__'.freeze
|
||||
|
||||
private
|
||||
|
|
57
spec/unit/mutant/mutator/registry_spec.rb
Normal file
57
spec/unit/mutant/mutator/registry_spec.rb
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue