Merge pull request #376 from mbj/fix/refactor-matcher-config
Refactor matcher config
This commit is contained in:
commit
5ff5936ff6
13 changed files with 123 additions and 119 deletions
|
@ -1,3 +1,3 @@
|
|||
---
|
||||
threshold: 18
|
||||
total_score: 1185
|
||||
total_score: 1178
|
||||
|
|
|
@ -153,7 +153,7 @@ module Mutant
|
|||
# @api private
|
||||
def add_filter_options(opts)
|
||||
opts.on('--ignore-subject PATTERN', 'Ignore subjects that match PATTERN') do |pattern|
|
||||
add_matcher(:subject_ignores, config.expression_parser.(pattern))
|
||||
add_matcher(:ignore_expressions, config.expression_parser.(pattern))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ module Mutant
|
|||
def result
|
||||
Filter.new(
|
||||
Chain.build(config.match_expressions.map(&method(:matcher))),
|
||||
predicate
|
||||
ignored_subjects
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -34,60 +34,23 @@ module Mutant
|
|||
|
||||
private
|
||||
|
||||
# Predicate constraining matches
|
||||
# Predicate returning false on ignored subject
|
||||
#
|
||||
# @return [#call]
|
||||
#
|
||||
# rubocop:disable MethodLength
|
||||
#
|
||||
# @api private
|
||||
def predicate
|
||||
if subject_selector && subject_rejector
|
||||
Morpher::Evaluator::Predicate::Boolean::And.new([
|
||||
subject_selector,
|
||||
Morpher::Evaluator::Predicate::Negation.new(subject_rejector)
|
||||
])
|
||||
elsif subject_selector
|
||||
subject_selector
|
||||
elsif subject_rejector
|
||||
Morpher::Evaluator::Predicate::Negation.new(subject_rejector)
|
||||
def ignored_subjects
|
||||
rejectors = config.ignore_expressions.map(&SubjectPrefix.method(:new))
|
||||
|
||||
if rejectors.any?
|
||||
Morpher::Evaluator::Predicate::Boolean::Negation.new(
|
||||
Morpher::Evaluator::Predicate::Boolean::Or.new(rejectors)
|
||||
)
|
||||
else
|
||||
Morpher::Evaluator::Predicate::Tautology.new
|
||||
end
|
||||
end
|
||||
|
||||
# the subject selector predicate
|
||||
#
|
||||
# @return [#call]
|
||||
# if selector is present
|
||||
#
|
||||
# @return [nil]
|
||||
# otherwise
|
||||
#
|
||||
# @api private
|
||||
def subject_selector
|
||||
selectors = config.subject_selects.map do |attribute, value|
|
||||
Morpher.compile(s(:eql, s(:attribute, attribute), s(:static, value)))
|
||||
end
|
||||
|
||||
Morpher::Evaluator::Predicate::Boolean::Or.new(selectors) if selectors.any?
|
||||
end
|
||||
|
||||
# Subject rejector predicate
|
||||
#
|
||||
# @return [#call]
|
||||
# if there is a subject rejector
|
||||
#
|
||||
# @return [nil]
|
||||
# otherwise
|
||||
#
|
||||
# @api private
|
||||
def subject_rejector
|
||||
rejectors = config.subject_ignores.map(&SubjectPrefix.method(:new))
|
||||
|
||||
Morpher::Evaluator::Predicate::Boolean::Or.new(rejectors) if rejectors.any?
|
||||
end
|
||||
|
||||
# Matcher for expression on env
|
||||
#
|
||||
# @param [Mutant::Expression] expression
|
||||
|
|
|
@ -1,15 +1,31 @@
|
|||
module Mutant
|
||||
class Matcher
|
||||
# Match configuration
|
||||
# Subject matcher configuration
|
||||
class Config
|
||||
include Adamantium, Anima::Update, Anima.new(
|
||||
:match_expressions,
|
||||
:subject_ignores,
|
||||
:subject_selects
|
||||
:ignore_expressions
|
||||
)
|
||||
|
||||
INSPECT_FORMAT = "#<#{self} %s>".freeze
|
||||
ATTRIBUTE_DELIMITER = ' '.freeze
|
||||
ATTRIBUTE_FORMAT = '%s: [%s]'.freeze
|
||||
ENUM_DELIMITER = ','.freeze
|
||||
EMPTY_ATTRIBUTES = 'empty'.freeze
|
||||
private_constant(*constants(false))
|
||||
|
||||
DEFAULT = new(Hash[anima.attribute_names.map { |name| [name, []] }])
|
||||
|
||||
# Inspection string
|
||||
#
|
||||
# @return [String]
|
||||
#
|
||||
# @api private
|
||||
def inspect
|
||||
INSPECT_FORMAT % inspect_attributes
|
||||
end
|
||||
memoize :inspect
|
||||
|
||||
# Add value to configurable collection
|
||||
#
|
||||
# @param [Symbol] attribute
|
||||
|
@ -22,6 +38,43 @@ module Mutant
|
|||
update(attribute => public_send(attribute).dup << value)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Present attributes
|
||||
#
|
||||
# @return [Array<Symbol>]
|
||||
#
|
||||
# @api private
|
||||
def present_attributes
|
||||
to_h.reject { |_key, value| value.empty? }.keys
|
||||
end
|
||||
|
||||
# Formatted attributes
|
||||
#
|
||||
# @return [String]
|
||||
#
|
||||
# @api private
|
||||
def inspect_attributes
|
||||
attributes = present_attributes
|
||||
.map(&method(:format_attribute))
|
||||
.join(ATTRIBUTE_DELIMITER)
|
||||
|
||||
attributes.empty? ? EMPTY_ATTRIBUTES : attributes
|
||||
end
|
||||
|
||||
# Format attribute
|
||||
#
|
||||
# @param [Symbol] attribute_name
|
||||
#
|
||||
# @return [String]
|
||||
def format_attribute(attribute_name)
|
||||
ATTRIBUTE_FORMAT %
|
||||
[
|
||||
attribute_name,
|
||||
public_send(attribute_name).map(&:syntax).join(ENUM_DELIMITER)
|
||||
]
|
||||
end
|
||||
|
||||
end # Config
|
||||
end # Matcher
|
||||
end # Mutant
|
||||
|
|
|
@ -11,13 +11,11 @@ module Mutant
|
|||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# rubocop:disable AbcSize
|
||||
#
|
||||
# @api private
|
||||
def run
|
||||
info 'Mutant configuration:'
|
||||
info 'Matcher: %s', object.matcher.inspect
|
||||
info 'Integration: %s', object.integration.name
|
||||
info 'Integration: %s', object.integration
|
||||
info 'Expect Coverage: %0.2f%%', (object.expected_coverage * 100)
|
||||
info 'Jobs: %d', object.jobs
|
||||
info 'Includes: %s', object.includes
|
||||
|
|
|
@ -234,7 +234,7 @@ Options:
|
|||
let(:flags) { %w[--ignore-subject Foo::Bar] }
|
||||
|
||||
let(:expected_matcher_config) do
|
||||
default_matcher_config.update(subject_ignores: [parse_expression('Foo::Bar')])
|
||||
default_matcher_config.update(ignore_expressions: [parse_expression('Foo::Bar')])
|
||||
end
|
||||
|
||||
it_should_behave_like 'a cli parser'
|
||||
|
|
|
@ -41,11 +41,11 @@ RSpec.describe Mutant::Matcher::Compiler do
|
|||
it { should eql(expected_matcher) }
|
||||
end
|
||||
|
||||
context 'and a subject filter' do
|
||||
context 'and a subject ignore' do
|
||||
let(:attributes) do
|
||||
{
|
||||
match_expressions: [expression_a],
|
||||
subject_ignores: [expression_b]
|
||||
match_expressions: [expression_a],
|
||||
ignore_expressions: [expression_b]
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -61,52 +61,6 @@ RSpec.describe Mutant::Matcher::Compiler do
|
|||
|
||||
it { should eql(expected_matcher) }
|
||||
end
|
||||
|
||||
context 'and an attribute filter' do
|
||||
let(:attributes) do
|
||||
{
|
||||
match_expressions: [expression_a],
|
||||
subject_selects: [[:code, 'foo']]
|
||||
}
|
||||
end
|
||||
|
||||
let(:expected_positive_matcher) { Mutant::Matcher::Chain.new([matcher_a]) }
|
||||
|
||||
let(:expected_predicate) do
|
||||
Morpher::Evaluator::Predicate::Boolean::Or.new([
|
||||
Morpher.compile(s(:eql, s(:attribute, :code), s(:static, 'foo')))
|
||||
])
|
||||
end
|
||||
|
||||
it { should eql(expected_matcher) }
|
||||
end
|
||||
|
||||
context 'and subject and attribute filter' do
|
||||
let(:attributes) do
|
||||
{
|
||||
match_expressions: [expression_a],
|
||||
subject_ignores: [expression_b],
|
||||
subject_selects: [[:code, 'foo']]
|
||||
}
|
||||
end
|
||||
|
||||
let(:expected_positive_matcher) { Mutant::Matcher::Chain.new([matcher_a]) }
|
||||
|
||||
let(:expected_predicate) do
|
||||
Morpher::Evaluator::Predicate::Boolean::And.new([
|
||||
Morpher::Evaluator::Predicate::Boolean::Or.new([
|
||||
Morpher.compile(s(:eql, s(:attribute, :code), s(:static, 'foo')))
|
||||
]),
|
||||
Morpher::Evaluator::Predicate::Negation.new(
|
||||
Morpher::Evaluator::Predicate::Boolean::Or.new([
|
||||
described_class::SubjectPrefix.new(expression_b)
|
||||
])
|
||||
)
|
||||
])
|
||||
end
|
||||
|
||||
it { should eql(expected_matcher) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'on config with multiple match expressions' do
|
||||
|
|
36
spec/unit/mutant/matcher/config_spec.rb
Normal file
36
spec/unit/mutant/matcher/config_spec.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
RSpec.describe Mutant::Matcher::Config do
|
||||
describe '#inspect' do
|
||||
subject { object.inspect }
|
||||
|
||||
context 'on default config' do
|
||||
let(:object) { described_class::DEFAULT }
|
||||
|
||||
it { should eql('#<Mutant::Matcher::Config empty>') }
|
||||
end
|
||||
|
||||
context 'with one expression' do
|
||||
let(:object) { described_class::DEFAULT.add(:match_expressions, parse_expression('Foo')) }
|
||||
it { should eql('#<Mutant::Matcher::Config match_expressions: [Foo]>') }
|
||||
end
|
||||
|
||||
context 'with many expressions' do
|
||||
let(:object) do
|
||||
described_class::DEFAULT
|
||||
.add(:match_expressions, parse_expression('Foo'))
|
||||
.add(:match_expressions, parse_expression('Bar'))
|
||||
end
|
||||
|
||||
it { should eql('#<Mutant::Matcher::Config match_expressions: [Foo,Bar]>') }
|
||||
end
|
||||
|
||||
context 'with match and ignore expression' do
|
||||
let(:object) do
|
||||
described_class::DEFAULT
|
||||
.add(:match_expressions, parse_expression('Foo'))
|
||||
.add(:ignore_expressions, parse_expression('Bar'))
|
||||
end
|
||||
|
||||
it { should eql('#<Mutant::Matcher::Config match_expressions: [Foo] ignore_expressions: [Bar]>') }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,7 +7,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Config do
|
|||
context 'on default config' do
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
@ -21,7 +21,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Config do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 10.00%
|
||||
Jobs: 1
|
||||
|
|
|
@ -11,7 +11,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::EnvProgress do
|
|||
|
||||
it_reports <<-'STR'
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 10.00%
|
||||
Jobs: 1
|
||||
|
@ -32,7 +32,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::EnvProgress do
|
|||
context 'on full coverage' do
|
||||
it_reports <<-'STR'
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 10.00%
|
||||
Jobs: 1
|
||||
|
@ -55,7 +55,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::EnvProgress do
|
|||
|
||||
it_reports <<-'STR'
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 10.00%
|
||||
Jobs: 1
|
||||
|
|
|
@ -15,7 +15,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::EnvResult do
|
|||
+false
|
||||
-----------------------
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
|
|
@ -9,7 +9,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|||
|
||||
it_reports <<-REPORT
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
@ -32,7 +32,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|||
|
||||
it_reports <<-REPORT
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 10.00%
|
||||
Jobs: 1
|
||||
|
@ -58,7 +58,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
@ -85,7 +85,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
@ -114,7 +114,7 @@ RSpec.describe Mutant::Reporter::CLI::Printer::Status do
|
|||
context 'on success' do
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
|
|
@ -121,7 +121,7 @@ RSpec.describe Mutant::Reporter::CLI do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
@ -136,7 +136,7 @@ RSpec.describe Mutant::Reporter::CLI do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 10.00%
|
||||
Jobs: 1
|
||||
|
@ -155,7 +155,7 @@ RSpec.describe Mutant::Reporter::CLI do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
@ -181,7 +181,7 @@ RSpec.describe Mutant::Reporter::CLI do
|
|||
|
||||
it_reports(<<-REPORT)
|
||||
[tput-restore]Mutant configuration:
|
||||
Matcher: #<Mutant::Matcher::Config match_expressions=[] subject_ignores=[] subject_selects=[]>
|
||||
Matcher: #<Mutant::Matcher::Config empty>
|
||||
Integration: Mutant::Integration::Null
|
||||
Expect Coverage: 100.00%
|
||||
Jobs: 1
|
||||
|
|
Loading…
Add table
Reference in a new issue