lib/crispr/mutator.rb
# frozen_string_literal: true require "parser/current" require "unparser" require_relative "mutations/boolean" require_relative "mutations/numeric" require_relative "mutations/comparison" require_relative "mutations/literal" require_relative "mutations/unary" require_relative "mutations/control_flow" require_relative "mutations/conditional" require_relative "mutations/logical" require_relative "mutations/ternary" require_relative "mutations/arithmetic" require_relative "mutations/assignment" require_relative "mutations/method_call" require_relative "mutations/array" require_relative "mutations/hash" require_relative "mutations/range" require_relative "mutations/regexp" require_relative "mutations/symbol" require_relative "mutations/string" require_relative "mutations/block" require_relative "mutations/rescue" module Crispr # Mutator performs simple AST mutations on Ruby source code. # It delegates to multiple mutation strategies (Boolean, Numeric, etc.) class Mutator MUTATORS = [ Crispr::Mutations::Boolean.new, Crispr::Mutations::Numeric.new, Crispr::Mutations::Comparison.new, Crispr::Mutations::Literal.new, Crispr::Mutations::Unary.new, Crispr::Mutations::ControlFlow.new, Crispr::Mutations::Conditional.new, Crispr::Mutations::Logical.new, Crispr::Mutations::Ternary.new, Crispr::Mutations::Arithmetic.new, Crispr::Mutations::Assignment.new, Crispr::Mutations::MethodCall.new, Crispr::Mutations::Array.new, Crispr::Mutations::Hash.new, Crispr::Mutations::Range.new, Crispr::Mutations::Regexp.new, Crispr::Mutations::Symbol.new, Crispr::Mutations::String.new, Crispr::Mutations::Block.new, Crispr::Mutations::Rescue.new ].freeze def initialize(source_code) @source_code = source_code end def mutations ast = Parser::CurrentRuby.parse(@source_code) return [] unless ast find_mutations(ast) end private def find_mutations(node) return [] unless node.is_a?(Parser::AST::Node) local_mutations = MUTATORS.flat_map { |mutator| mutator.mutations_for(node) } child_mutations = node.children.flat_map { |child| find_mutations(child) } local_mutations + child_mutations end end end