From a7c3dc53393656cf8d079d41e48f52f978ea9d58 Mon Sep 17 00:00:00 2001 From: Markus Schirp Date: Sun, 29 Dec 2013 22:44:30 +0100 Subject: [PATCH] Improve AST coverage of mutant * Uses a monkeypach extension to parser with a list of valid node types. * Add nodes, found to be uncovered to generic mutator. --- Gemfile | 2 ++ lib/mutant.rb | 25 ++++++++++++++++ lib/mutant/constants.rb | 30 ++++++++----------- lib/mutant/node_helpers.rb | 2 +- .../mutant/test_mutator_handles_types_spec.rb | 1 + 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Gemfile b/Gemfile index d74f9cdb..542d85e8 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,8 @@ source 'https://rubygems.org' +gem 'unparser', git: 'https://github.com/mbj/unparser' + gemspec gem 'mutant', path: '.' diff --git a/lib/mutant.rb b/lib/mutant.rb index 666930db..d5071062 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -22,6 +22,30 @@ require 'anima' require 'concord' require 'rspec' +# Monkeypatch on parser with a list of allowed nodes. +# Will be pushed upstream once turning out to be correct. +module Parser + module Meta + NODE_TYPES = + %w( + true false nil int float str dstr str + sym dsym xstr regopt regexp array splat + array pair kwsplat hash irange erange self + lvar ivar cvar gvar const defined? lvasgn + ivasgn cvasgn gvasgn casgn mlhs masgn op_asgn + op_asgn and_asgn ensure rescue arg_expr + or_asgn and_asgn or_asgn back_ref nth_ref + match_with_lvasgn match_current_line + module class sclass def defs undef alias args + cbase arg optarg restarg blockarg block_pass args def kwarg kwoptarg + kwrestarg send super zsuper yield block send + and not or if when case while until while_post + until_post for break next redo return resbody + kwbegin begin retry preexe postexe iflipflop eflipflop + ).map(&:to_sym).to_set.freeze + end # Meta +end # Parser + # Library namespace module Mutant # The empty string used within this namespace @@ -139,3 +163,4 @@ require 'mutant/reporter/cli/printer/subject' require 'mutant/reporter/cli/printer/killer' require 'mutant/reporter/cli/printer/mutation' require 'mutant/zombifier' + diff --git a/lib/mutant/constants.rb b/lib/mutant/constants.rb index 64048501..a2b76152 100644 --- a/lib/mutant/constants.rb +++ b/lib/mutant/constants.rb @@ -35,25 +35,19 @@ module Mutant METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS ).to_set.freeze - # Hopefully all node types parser does generate. + # Nodes that are NOT handled by mutant. # - # FIXME: Maintain this list only in unparser / parser! + # not - 1.8 only, mutant does not support 1.8 # - NODE_TYPES = [ - :lvasgn, :ivasgn, :cvasgn, :gvasgn, - :casgn, :masgn, :mlhs, :break, :rescue, - :ensure, :resbody, :begin, :retry, :arg_expr, - :args, :blockarg, :optarg, :kwrestarg, :kwoptarg, - :kwarg, :restarg, :arg, :block_pass, :or, :and, - :next, :undef, :if, :module, :cbase, :block, :send, - :zsuper, :super, :empty, :alias, :for, :redo, - :return, :splat, :defined?, :op_asgn, :self, - :true, :false, :nil, :dstr, :dsym, :regexp, - :regopt, :int, :str, :float, :sym, :pair, :hash, :array, - :xstr, :def, :defs, :case, :when, :ivar, :lvar, :cvar, :gvar, - :back_ref, :const, :nth_ref, :class, :sclass, :yield, - :match_with_lvasgn, :match_current_line, :irange, :erange, - :or_asgn, :kwbegin, :and_asgn, :while - ].to_set.freeze + NODE_BLACKLIST = %w( + not + ).map(&:to_sym).freeze + + # Nodes that are NOT generated by parser but used by mutant / unparser. + NODE_EXTRA = %w( + empty + ).map(&:to_sym).freeze + + NODE_TYPES = ((Parser::Meta::NODE_TYPES + NODE_EXTRA) - NODE_BLACKLIST).to_set.freeze end # Mutant diff --git a/lib/mutant/node_helpers.rb b/lib/mutant/node_helpers.rb index 06381972..c538f441 100644 --- a/lib/mutant/node_helpers.rb +++ b/lib/mutant/node_helpers.rb @@ -13,7 +13,7 @@ module Mutant # @api private # def s(type, *children) - Parser::AST::Node.new(type, children) + ::Parser::AST::Node.new(type, children) end module_function :s diff --git a/spec/integration/mutant/test_mutator_handles_types_spec.rb b/spec/integration/mutant/test_mutator_handles_types_spec.rb index 8e1662c8..fb04ab22 100644 --- a/spec/integration/mutant/test_mutator_handles_types_spec.rb +++ b/spec/integration/mutant/test_mutator_handles_types_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe Mutant do + specify 'mutant should not crash for any node parser can generate' do Mutant::NODE_TYPES.each do |type| Mutant::Mutator::Registry.lookup(Mutant::NodeHelpers.s(type))