Class: SixthSense::MutationMatrixProducer

Inherits:
Object
  • Object
show all
Defined in:
lib/sixth_sense/mutation_matrix_producer.rb

Instance Method Summary collapse

Constructor Details

#initialize(config: {}) ⇒ MutationMatrixProducer

Returns a new instance of MutationMatrixProducer.



49
50
51
# File 'lib/sixth_sense/mutation_matrix_producer.rb', line 49

def initialize(config: {})
  @config = config
end

Instance Method Details

#neutral_run!(test_files) ⇒ Object

Paper basis: Luo et al. 2014 (doi:10.1145/2635868.2635920) motivates isolating flaky/unstable baseline behavior before mutation analysis.

Raises:



55
56
57
58
59
60
61
62
63
64
# File 'lib/sixth_sense/mutation_matrix_producer.rb', line 55

def neutral_run!(test_files)
  runs = neutral_runs.times.map do
    test_cases(test_files).map do |entry|
      [entry.fetch(:test_case).id, run_test_case(entry)]
    end
  end
  failed = runs.flatten(1).find { |_id, status| status != :passed }
  raise Error, "neutral run failed for #{failed.fetch(0)}: #{failed.fetch(1)}" if failed
  raise Error, "neutral run was unstable" unless runs.uniq.length == 1
end

#run(plan) ⇒ Object

Paper basis: Jia/Harman 2011 (doi:10.1109/TSE.2010.62) defines mutation testing over generated mutants; this produces the per-test kill matrix consumed by mutation adequacy and redundancy analyzers.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/sixth_sense/mutation_matrix_producer.rb', line 69

def run(plan)
  selection = MutationMatrixMutantGenerator.new(config: @config).generate(plan)
  mutants = selection.fetch(:mutants)
  sampling = selection.fetch(:sampling)
  subjects = plan.source_units.map do |unit|
    source_mutants = mutants.select { |mutant| File.expand_path(mutant.path) == File.expand_path(unit.fetch(:path) { unit["path"] }) }
    {
      "expression" => Array(unit[:constants] || unit["constants"]).first.to_s,
      "source_digest" => digest_for(unit.fetch(:path) { unit["path"] }),
      "mutants" => source_mutants.map { |mutant| execute_mutant(mutant, plan.test_files) }
    }
  end
  MutationMatrixResult.new(
    {
      "version" => 1,
      "engine" => "sixth_sense/matrix",
      "mode" => "matrix",
      "test_files" => plan.test_files,
      "metadata" => {
        "timeout_policy" => timeout_policy,
        "sampling" => sampling,
        "warnings" => sampling.fetch("sampled") ? ["mutation sample truncated to #{sampling.fetch("selected_count")} of #{sampling.fetch("generated_count")} generated mutants"] : []
      },
      "subjects" => subjects
    }
  )
end