diff --git a/config/flay.yml b/config/flay.yml index 4360d894..1a6023c3 100644 --- a/config/flay.yml +++ b/config/flay.yml @@ -1,3 +1,3 @@ --- threshold: 18 -total_score: 960 +total_score: 977 diff --git a/config/reek.yml b/config/reek.yml index fab26082..d9b66f8e 100644 --- a/config/reek.yml +++ b/config/reek.yml @@ -113,7 +113,7 @@ UncommunicativeMethodName: enabled: true exclude: - Mutant::Mutation#sha1 - - Mutant::NodeHelpers#s + - Mutant::AST::Sexp#s reject: - !ruby/regexp /^[a-z]$/ - !ruby/regexp /[0-9]$/ @@ -159,5 +159,5 @@ UtilityFunction: - Mutant::Meta::Example::Verification#format_mutation - Mutant::Mutation::Evil#success? - Mutant::Mutation::Neutral#success? - - Mutant::NodeHelpers#s + - Mutant::AST::Sexp#s max_helper_calls: 0 diff --git a/lib/mutant.rb b/lib/mutant.rb index 2fbb6888..2c5f8c6c 100644 --- a/lib/mutant.rb +++ b/lib/mutant.rb @@ -25,45 +25,8 @@ module Mutant # The frozen empty array used within mutant EMPTY_ARRAY = [].freeze - symbolset = ->(strings) { strings.map(&:to_sym).to_set.freeze } - SCOPE_OPERATOR = '::'.freeze - # Set of nodes that cannot be on the LHS of an assignment - NOT_ASSIGNABLE = symbolset.(%w[int float str dstr class module self nil]) - # Set of op-assign types - OP_ASSIGN = symbolset.call(%w[or_asgn and_asgn op_asgn]) - # Set of node types that are not valid when emitted standalone - NOT_STANDALONE = symbolset.(%w[splat restarg block_pass]) - INDEX_OPERATORS = symbolset.(%w[[] []=]) - UNARY_METHOD_OPERATORS = symbolset.(%w[~@ +@ -@ !]) - - # Operators ruby implementeds as methods - METHOD_OPERATORS = symbolset.(%w[ - <=> === []= [] <= >= == !~ != =~ << - >> ** * % / | ^ & < > + - ~@ +@ -@ ! - ]) - - BINARY_METHOD_OPERATORS = ( - METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS) - ).to_set.freeze - - OPERATOR_METHODS = ( - METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS - ).to_set.freeze - - # Nodes that are NOT handled by mutant. - # - # not - 1.8 only, mutant does not support 1.8 - # - NODE_BLACKLIST = symbolset.(%w[not]) - - # Nodes that are NOT generated by parser but used by mutant / unparser. - NODE_EXTRA = symbolset.(%w[empty]) - - # All node types mutant handles - NODE_TYPES = ((Parser::Meta::NODE_TYPES + NODE_EXTRA) - NODE_BLACKLIST).to_set.freeze - # Lookup constant for location # # @param [String] location @@ -116,9 +79,15 @@ module Mutant end # Mutant require 'mutant/version' +require 'mutant/ast' +require 'mutant/ast/sexp' +require 'mutant/ast/types' +require 'mutant/ast/nodes' +require 'mutant/ast/named_children' +require 'mutant/ast/node_predicates' +require 'mutant/ast/meta' require 'mutant/cache' require 'mutant/delegator' -require 'mutant/node_helpers' require 'mutant/warning_filter' require 'mutant/warning_expectation' require 'mutant/walker' diff --git a/lib/mutant/ast.rb b/lib/mutant/ast.rb new file mode 100644 index 00000000..6e3e4c70 --- /dev/null +++ b/lib/mutant/ast.rb @@ -0,0 +1,5 @@ +module Mutant + # AST helpers + module AST + end # AST +end # Mutant diff --git a/lib/mutant/ast/meta.rb b/lib/mutant/ast/meta.rb new file mode 100644 index 00000000..9f5ce10d --- /dev/null +++ b/lib/mutant/ast/meta.rb @@ -0,0 +1,131 @@ +module Mutant + module AST + # Node meta information mixin + module Meta + + REGISTRY = {} + + # Return meta for node + # + # @param [Parser::AST::Node] node + # + # @return [Meta] + # + # @api private + # + def self.for(node) + REGISTRY.fetch(node.type, Generic).new(node) + end + + # Generic metadata for send nodes + class Send + include Concord.new(:node), NamedChildren + + children :receiver, :selector + + REGISTRY[:send] = self + + INDEX_ASSIGNMENT_SELECTOR = :[]= + ATTRIBUTE_ASSIGNMENT_SELECTOR_SUFFIX = '='.freeze + + # Return arguments + # + # @return [Enumerable] + # + # @api private + # + alias_method :arguments, :remaining_children + + # Test if AST node is a valid assignment target + # + # @return [Boolean] + # + # @api private + # + def assignment? + index_assignment? || attribute_assignment? + end + + # Test if AST node is an attribute assignment? + # + # @return [Boolean] + # + # @api private + # + def attribute_assignment? + arguments.one? && attribute_assignment_selector? + end + + # Test if AST node is an index assign + # + # @return [Boolean] + # + # @api private + # + def index_assignment? + arguments.length.equal?(2) && index_assignment_selector? + end + + # Test for binary operator implemented as method + # + # @return [Boolean] + # + # @api private + # + def binary_method_operator? + arguments.one? && Types::BINARY_METHOD_OPERATORS.include?(selector) + end + + # Test if node is part of an mlhs + # + # @return [Boolean] + # + # @api private + # + def mlhs? + (index_assignment_selector? && arguments.one?) || (arguments.empty? && attribute_assignment_selector?) + end + + private + + # Test for index assignment operator + # + # @return [Boolean] + # + # @api private + # + def index_assignment_selector? + selector.equal?(INDEX_ASSIGNMENT_SELECTOR) + end + + # Test for attribute assignment selector + # + # @return [Boolean] + # + # @api private + # + def attribute_assignment_selector? + !Types::METHOD_OPERATORS.include?(selector) && selector.to_s.end_with?(ATTRIBUTE_ASSIGNMENT_SELECTOR_SUFFIX) + end + + end # Send + + # Generic node metatada + class Generic + include Adamantium, Concord.new(:node) + + # Test if AST node is a valid assign target + # + # @return [Boolean] + # + # @api private + # + def assignment? + Types::ASSIGNABLE_VARIABLES.include?(node.type) + end + + end # Generic + + end # + end # AST +end # Mutant diff --git a/lib/mutant/ast/named_children.rb b/lib/mutant/ast/named_children.rb new file mode 100644 index 00000000..1cadd82a --- /dev/null +++ b/lib/mutant/ast/named_children.rb @@ -0,0 +1,98 @@ +module Mutant + module AST + + # Helper methods to define named children + module NamedChildren + + # Hook called when module gets included + # + # @param [Class, Module] host + # + # @return [undefined] + # + # @api private + # + def self.included(host) + super + host.class_eval do + include InstanceMethods + extend ClassMethods + end + end + + # Methods mixed int ot instance level + module InstanceMethods + + private + + # Return children + # + # @return [Array] names + # + # @return [undefined] + # + # @api private + # + def define_remaining_children(names) + define_method(:remaining_children_with_index) do + children.each_with_index.drop(names.length) + end + + define_method(:remaining_children_indices) do + children.each_index.drop(names.length) + end + + define_method(:remaining_children) do + children.drop(names.length) + end + end + + # Create name helpers + # + # @return [undefined] + # + # @api private + # + def children(*names) + names.each_with_index do |name, index| + define_named_child(name, index) + end + define_remaining_children(names) + end + + end # ClassMethods + end # NamedChildren + end # AST +end # Mutant diff --git a/lib/mutant/ast/node_predicates.rb b/lib/mutant/ast/node_predicates.rb new file mode 100644 index 00000000..262acf82 --- /dev/null +++ b/lib/mutant/ast/node_predicates.rb @@ -0,0 +1,19 @@ +module Mutant + module AST + # Module for node predicates + module NodePredicates + + Types::ALL.each do |type| + fail "method: #{type} is already defined" if instance_methods(true).include?(type) + + name = "n_#{type.to_s.sub(/\??\z/, '?')}" + + define_method(name) do |node| + node.type.equal?(type) + end + private name + end + + end # NodePredicates + end # AST +end # Mutant diff --git a/lib/mutant/ast/nodes.rb b/lib/mutant/ast/nodes.rb new file mode 100644 index 00000000..7758898e --- /dev/null +++ b/lib/mutant/ast/nodes.rb @@ -0,0 +1,21 @@ +module Mutant + module AST + # Singleton nodes + module Nodes + extend Sexp + + N_NAN = s(:send, s(:float, 0.0), :/, s(:float, 0.0)) + N_INFINITY = s(:send, s(:float, 1.0), :/, s(:float, 0.0)) + N_NEGATIVE_INFINITY = s(:send, s(:float, -1.0), :/, s(:float, 0.0)) + N_RAISE = s(:send, nil, :raise) + N_TRUE = s(:true) + N_FALSE = s(:false) + N_NIL = s(:nil) + N_EMPTY = s(:empty) + N_SELF = s(:self) + N_ZSUPER = s(:zsuper) + N_EMPTY_SUPER = s(:super) + + end # Node + end # AST +end # Mutant diff --git a/lib/mutant/ast/sexp.rb b/lib/mutant/ast/sexp.rb new file mode 100644 index 00000000..6ab0dcaf --- /dev/null +++ b/lib/mutant/ast/sexp.rb @@ -0,0 +1,34 @@ +module Mutant + module AST + # Mixin for node sexp syntax + module Sexp + + private + + # Build node + # + # @param [Symbol] type + # + # @return [Parser::AST::Node] + # + # @api private + # + def s(type, *children) + Parser::AST::Node.new(type, children) + end + + # Build a negated boolean node + # + # @param [Parser::AST::Node] node + # + # @return [Parser::AST::Node] + # + # @api private + # + def n_not(node) + s(:send, node, :!) + end + + end # Sexp + end # AST +end # Mutant diff --git a/lib/mutant/ast/types.rb b/lib/mutant/ast/types.rb new file mode 100644 index 00000000..2af9d902 --- /dev/null +++ b/lib/mutant/ast/types.rb @@ -0,0 +1,48 @@ +module Mutant + module AST + # Groups of node types + module Types + symbolset = ->(strings) { strings.map(&:to_sym).to_set.freeze } + + ASSIGNABLE_VARIABLES = symbolset.(%w[ivasgn lvasgn cvasgn gvasgn]) + + INDEX_ASSIGN_OPERATOR = :[]= + + # Set of nodes that cannot be on the LHS of an assignment + NOT_ASSIGNABLE = symbolset.(%w[int float str dstr class module self nil]) + + # Set of op-assign types + OP_ASSIGN = symbolset.(%w[or_asgn and_asgn op_asgn]) + # Set of node types that are not valid when emitted standalone + NOT_STANDALONE = symbolset.(%w[splat restarg block_pass]) + INDEX_OPERATORS = symbolset.(%w[[] []=]) + UNARY_METHOD_OPERATORS = symbolset.(%w[~@ +@ -@ !]) + + # Operators ruby implementeds as methods + METHOD_OPERATORS = symbolset.(%w[ + <=> === []= [] <= >= == !~ != =~ << + >> ** * % / | ^ & < > + - ~@ +@ -@ ! + ]) + + BINARY_METHOD_OPERATORS = ( + METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS) + ).to_set.freeze + + OPERATOR_METHODS = ( + METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS + ).to_set.freeze + + # Nodes that are NOT handled by mutant. + # + # not - 1.8 only, mutant does not support 1.8 + # + BLACKLIST = symbolset.(%w[not]) + + # Nodes that are NOT generated by parser but used by mutant / unparser. + EXTRA = symbolset.(%w[empty]) + + # All node types mutant handles + ALL = ((Parser::Meta::NODE_TYPES + EXTRA) - BLACKLIST).to_set.freeze + end # Types + end # AST +end # Mutant diff --git a/lib/mutant/cli.rb b/lib/mutant/cli.rb index 9cb1a1f9..52918031 100644 --- a/lib/mutant/cli.rb +++ b/lib/mutant/cli.rb @@ -4,7 +4,7 @@ module Mutant # Comandline parser class CLI - include Adamantium::Flat, Equalizer.new(:config), NodeHelpers + include Adamantium::Flat, Equalizer.new(:config) # Error raised when CLI argv is invalid Error = Class.new(RuntimeError) @@ -186,7 +186,7 @@ module Mutant @builder.add_subject_ignore(Expression.parse(pattern)) end opts.on('--code CODE', 'Scope execution to subjects with CODE') do |code| - @builder.add_subject_selector(Morpher.compile(s(:eql, s(:attribute, :code), s(:static, code)))) + @builder.add_subject_selector(:code, code) end end diff --git a/lib/mutant/context/scope.rb b/lib/mutant/context/scope.rb index 058854cc..a3b4db9a 100644 --- a/lib/mutant/context/scope.rb +++ b/lib/mutant/context/scope.rb @@ -3,7 +3,7 @@ module Mutant # Scope context for mutation (Class or Module) class Scope < self include Adamantium::Flat, Concord::Public.new(:scope, :source_path) - extend NodeHelpers + extend AST::Sexp NAMESPACE_DELIMITER = '::'.freeze diff --git a/lib/mutant/expression.rb b/lib/mutant/expression.rb index 39f7e510..d95b96e3 100644 --- a/lib/mutant/expression.rb +++ b/lib/mutant/expression.rb @@ -10,7 +10,7 @@ module Mutant METHOD_NAME_PATTERN = Regexp.union( /[A-Za-z_][A-Za-z\d_]*[!?=]?/, - *OPERATOR_METHODS.map(&:to_s) + *AST::Types::OPERATOR_METHODS.map(&:to_s) ).freeze SCOPE_PATTERN = /#{SCOPE_NAME_PATTERN}(?:#{SCOPE_OPERATOR}#{SCOPE_NAME_PATTERN})*/.freeze diff --git a/lib/mutant/matcher/builder.rb b/lib/mutant/matcher/builder.rb index 4e11ebd5..1d603fb4 100644 --- a/lib/mutant/matcher/builder.rb +++ b/lib/mutant/matcher/builder.rb @@ -2,7 +2,7 @@ module Mutant class Matcher # Builder for complex matchers class Builder - include NodeHelpers, Concord.new(:cache) + include Concord.new(:cache), AST::Sexp # Initalize object # @@ -40,8 +40,8 @@ module Mutant # # @api private # - def add_subject_selector(selector) - @subject_selectors << selector + def add_subject_selector(attribute, value) + @subject_selectors << Morpher.compile(s(:eql, s(:attribute, attribute), s(:static, value))) self end diff --git a/lib/mutant/meta.rb b/lib/mutant/meta.rb index b3c31e94..b2f709d4 100644 --- a/lib/mutant/meta.rb +++ b/lib/mutant/meta.rb @@ -1,7 +1,6 @@ module Mutant # Namespace for mutant metadata module Meta - require 'mutant/meta/example' require 'mutant/meta/example/dsl' diff --git a/lib/mutant/meta/example/dsl.rb b/lib/mutant/meta/example/dsl.rb index cd95e1c4..50786d60 100644 --- a/lib/mutant/meta/example/dsl.rb +++ b/lib/mutant/meta/example/dsl.rb @@ -4,7 +4,7 @@ module Mutant # Example DSL class DSL - include NodeHelpers + include AST::Sexp # Run DSL on block # diff --git a/lib/mutant/mutator/node.rb b/lib/mutant/mutator/node.rb index e4915486..23d704b6 100644 --- a/lib/mutant/mutator/node.rb +++ b/lib/mutant/mutator/node.rb @@ -5,11 +5,13 @@ module Mutant # Abstract base class for node mutators class Node < self - include AbstractType, NodeHelpers, Unparser::Constants + include AbstractType, Unparser::Constants + include AST::NamedChildren, AST::NodePredicates, AST::Sexp, AST::Nodes - # Define named child + # Helper to define a named child + # + # @param [Parser::AST::Node] node # - # @param [Symbol] name # @param [Fixnum] index # # @return [undefined] @@ -17,9 +19,7 @@ module Mutant # @api private # def self.define_named_child(name, index) - define_method(name) do - children.at(index) - end + super define_method("emit_#{name}_mutations") do |&block| mutate_child(index, &block) @@ -29,43 +29,6 @@ module Mutant emit_child_update(index, node) end end - private_class_method :define_named_child - - # Define remaining children - # - # @param [Array] names - # - # @return [undefined] - # - # @api private - # - def self.define_remaining_children(names) - define_method(:remaining_children_with_index) do - children.each_with_index.drop(names.length) - end - - define_method(:remaining_children_indices) do - children.each_index.drop(names.length) - end - - define_method(:remaining_children) do - children.drop(names.length) - end - end - private_class_method :define_remaining_children - - # Create name helpers - # - # @return [undefined] - # - # @api private - # - def self.children(*names) - names.each_with_index do |name, index| - define_named_child(name, index) - end - define_remaining_children(names) - end private_class_method :children private @@ -98,6 +61,15 @@ module Mutant end end + # Return ast meta description + # + # @return [AST::Meta] + # + def meta + AST::Meta.for(node) + end + memoize :meta + # Return children # # @return [Array] @@ -246,7 +218,7 @@ module Mutant # @api private # def asgn_left? - OP_ASSIGN.include?(parent_type) && parent.node.children.first.equal?(node) + AST::Types::OP_ASSIGN.include?(parent_type) && parent.node.children.first.equal?(node) end end # Node diff --git a/lib/mutant/mutator/node/or_asgn.rb b/lib/mutant/mutator/node/or_asgn.rb index 9de8656c..1c99901e 100644 --- a/lib/mutant/mutator/node/or_asgn.rb +++ b/lib/mutant/mutator/node/or_asgn.rb @@ -22,7 +22,7 @@ module Mutant emit_right_mutations return if n_ivasgn?(left) emit_left_mutations do |node| - !n_self?(node) + AST::Meta.for(node).assignment? end end diff --git a/lib/mutant/mutator/node/send.rb b/lib/mutant/mutator/node/send.rb index 2e8294e4..43ae04b6 100644 --- a/lib/mutant/mutator/node/send.rb +++ b/lib/mutant/mutator/node/send.rb @@ -4,6 +4,7 @@ module Mutant # Namespace for send mutators class Send < self + include AST::Types handle(:send) @@ -19,12 +20,6 @@ module Mutant :== => [:eql?, :equal?] ) - INDEX_REFERENCE = :[] - INDEX_ASSIGN = :[]= - VARIABLE_ASSIGN = :'=' - ASSIGNMENT_OPERATORS = [INDEX_ASSIGN, VARIABLE_ASSIGN].to_set.freeze - ATTRIBUTE_ASSIGNMENT = /\A[a-z\d_]+=\z/.freeze - private # Perform dispatch @@ -35,7 +30,7 @@ module Mutant # def dispatch emit_singletons - if selector.equal?(INDEX_ASSIGN) + if meta.index_assignment? run(Index::Assign) else non_index_dispatch @@ -50,9 +45,9 @@ module Mutant # def non_index_dispatch case - when binary_operator? + when meta.binary_method_operator? run(Binary) - when attribute_assignment? + when meta.attribute_assignment? run(AttributeAssignment) else normal_dispatch @@ -103,26 +98,6 @@ module Mutant emit(receiver) if receiver && !NOT_ASSIGNABLE.include?(receiver.type) end - # Test for binary operator - # - # @return [Boolean] - # - # @api private - # - def binary_operator? - arguments.one? && BINARY_METHOD_OPERATORS.include?(selector) - end - - # Test for attribute assignment - # - # @return [Boolean] - # - # @api private - # - def attribute_assignment? - arguments.one? && ATTRIBUTE_ASSIGNMENT =~ selector - end - # Mutate arguments # # @return [undefined] @@ -173,40 +148,10 @@ module Mutant KEYWORDS.include?(selector) || METHOD_OPERATORS.include?(selector) || OP_ASSIGN.include?(parent_type) || - attribute_assignment? + meta.attribute_assignment? ) end - # Test for assignment - # - # @return [Boolean] - # - # @api private - # - def assignment? - arguments.one? && (ASSIGNMENT_OPERATORS.include?(selector) || attribute_assignment?) - end - - # Test if node is part of an mlhs - # - # @return [Boolean] - # - # @api private - # - def mlhs? - assignment? && !arguments? - end - - # Test for empty arguments - # - # @return [Boolean] - # - # @api private - # - def arguments? - arguments.any? - end - end # Send end # Node end # Mutator diff --git a/lib/mutant/mutator/node/super.rb b/lib/mutant/mutator/node/super.rb index bf578bb0..57b14915 100644 --- a/lib/mutant/mutator/node/super.rb +++ b/lib/mutant/mutator/node/super.rb @@ -7,9 +7,6 @@ module Mutant handle(:super) - Z_SUPER = NodeHelpers.s(:zsuper) - EMPTY_SUPER = NodeHelpers.s(:super) - private # Emit mutations @@ -20,8 +17,8 @@ module Mutant # def dispatch emit_singletons - emit(Z_SUPER) - emit(EMPTY_SUPER) + emit(N_ZSUPER) + emit(N_EMPTY_SUPER) children.each_index do |index| mutate_child(index) delete_child(index) diff --git a/lib/mutant/mutator/registry.rb b/lib/mutant/mutator/registry.rb index 163468ae..83e8cbd5 100644 --- a/lib/mutant/mutator/registry.rb +++ b/lib/mutant/mutator/registry.rb @@ -64,7 +64,7 @@ module Mutant # @api private # def self.assert_valid_type(type) - unless NODE_TYPES.include?(type) || type.kind_of?(Class) + unless AST::Types::ALL.include?(type) || type.kind_of?(Class) raise InvalidTypeError, "invalid type registration: #{type}" end end diff --git a/lib/mutant/node_helpers.rb b/lib/mutant/node_helpers.rb deleted file mode 100644 index 52303775..00000000 --- a/lib/mutant/node_helpers.rb +++ /dev/null @@ -1,52 +0,0 @@ -module Mutant - # Mixin for node helpers - module NodeHelpers - - # Build node - # - # @param [Symbol] type - # - # @return [Parser::AST::Node] - # - # @api private - # - def s(type, *children) - Parser::AST::Node.new(type, children) - end - module_function :s - - N_NAN = s(:send, s(:float, 0.0), :/, s(:float, 0.0)) - N_INFINITY = s(:send, s(:float, 1.0), :/, s(:float, 0.0)) - N_NEGATIVE_INFINITY = s(:send, s(:float, -1.0), :/, s(:float, 0.0)) - N_RAISE = s(:send, nil, :raise) - N_TRUE = s(:true) - N_FALSE = s(:false) - N_NIL = s(:nil) - N_EMPTY = s(:empty) - N_SELF = s(:self) - - # Build a negated boolean node - # - # @param [Parser::AST::Node] node - # - # @return [Parser::AST::Node] - # - # @api private - # - def n_not(node) - s(:send, node, :!) - end - - NODE_TYPES.each do |type| - fail "method: #{type} is already defined" if instance_methods(true).include?(type) - - name = "n_#{type.to_s.sub(/\??\z/, '?')}" - - define_method(name) do |node| - node.type.equal?(type) - end - private name - end - - end # NodeHelpers -end # Mutant diff --git a/lib/mutant/subject/method/instance.rb b/lib/mutant/subject/method/instance.rb index 0b1de410..68fd0be5 100644 --- a/lib/mutant/subject/method/instance.rb +++ b/lib/mutant/subject/method/instance.rb @@ -39,7 +39,7 @@ module Mutant # Mutator for memoized instance methods class Memoized < self - include NodeHelpers + include AST::Sexp # Return source # diff --git a/lib/mutant/zombifier/file.rb b/lib/mutant/zombifier/file.rb index 33412d5e..f2e3e4ea 100644 --- a/lib/mutant/zombifier/file.rb +++ b/lib/mutant/zombifier/file.rb @@ -2,7 +2,7 @@ module Mutant class Zombifier # File containing source beeing zombified class File - include NodeHelpers, Adamantium::Flat, Concord::Public.new(:path) + include Adamantium::Flat, Concord::Public.new(:path), AST::Sexp # Zombify contents of file # diff --git a/meta/or_asgn.rb b/meta/or_asgn.rb index 4d62e82d..5bb108b5 100644 --- a/meta/or_asgn.rb +++ b/meta/or_asgn.rb @@ -22,3 +22,14 @@ Mutant::Meta::Example.add do mutation '@a ||= -1' mutation '@a ||= 2' end + +Mutant::Meta::Example.add do + source 'foo[:bar] ||= 1' + + singleton_mutations + mutation 'foo[:bar] ||= nil' + mutation 'foo[:bar] ||= self' + mutation 'foo[:bar] ||= 0' + mutation 'foo[:bar] ||= -1' + mutation 'foo[:bar] ||= 2' +end diff --git a/meta/send.rb b/meta/send.rb index 52aaa655..e49217de 100644 --- a/meta/send.rb +++ b/meta/send.rb @@ -259,7 +259,7 @@ Mutant::Meta::Example.add do mutation 'self[*bar]' end -(Mutant::BINARY_METHOD_OPERATORS - [:==, :eql?]).each do |operator| +(Mutant::AST::Types::BINARY_METHOD_OPERATORS - [:==, :eql?]).each do |operator| Mutant::Meta::Example.add do source "true #{operator} false" diff --git a/spec/integration/mutant/test_mutator_handles_types_spec.rb b/spec/integration/mutant/test_mutator_handles_types_spec.rb index 85f89267..e18f4093 100644 --- a/spec/integration/mutant/test_mutator_handles_types_spec.rb +++ b/spec/integration/mutant/test_mutator_handles_types_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe 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)) + Mutant::AST::Types::ALL.each do |type| + Mutant::Mutator::Registry.lookup(s(type)) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 483fea1d..20e6bdd4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -46,7 +46,8 @@ end RSpec.configure do |config| config.include(CompressHelper) config.include(ParserHelper) - config.include(Mutant::NodeHelpers) + config.include(Mutant::AST::Sexp) + config.expect_with :rspec do |rspec| rspec.syntax = :expect end diff --git a/spec/unit/mutant/mutation_spec.rb b/spec/unit/mutant/mutation_spec.rb index 69e64e96..09886e08 100644 --- a/spec/unit/mutant/mutation_spec.rb +++ b/spec/unit/mutant/mutation_spec.rb @@ -6,7 +6,7 @@ describe Mutant::Mutation do SYMBOL = 'test'.freeze end - let(:object) { TestMutation.new(mutation_subject, Mutant::NodeHelpers::N_NIL) } + let(:object) { TestMutation.new(mutation_subject, Mutant::AST::Nodes::N_NIL) } let(:mutation_subject) { double('Subject', identification: 'subject', source: 'original') } let(:node) { double('Node') } diff --git a/spec/unit/mutant/subject/method/instance_spec.rb b/spec/unit/mutant/subject/method/instance_spec.rb index 679b8250..4ce343ce 100644 --- a/spec/unit/mutant/subject/method/instance_spec.rb +++ b/spec/unit/mutant/subject/method/instance_spec.rb @@ -3,8 +3,6 @@ require 'spec_helper' describe Mutant::Subject::Method::Instance do - include Mutant::NodeHelpers - let(:object) { described_class.new(context, node) } let(:context) { double } @@ -73,8 +71,6 @@ describe Mutant::Subject::Method::Instance do end describe Mutant::Subject::Method::Instance::Memoized do - include Mutant::NodeHelpers - let(:object) { described_class.new(context, node) } let(:context) { double } diff --git a/spec/unit/mutant/subject/method/singleton_spec.rb b/spec/unit/mutant/subject/method/singleton_spec.rb index 4dc96f00..ffa18e27 100644 --- a/spec/unit/mutant/subject/method/singleton_spec.rb +++ b/spec/unit/mutant/subject/method/singleton_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' describe Mutant::Subject::Method::Singleton do - include Mutant::NodeHelpers let(:object) { described_class.new(context, node) } let(:context) { double }