Class: Pinspec::Validate::MutationAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/pinspec/validate/mutation_adapter.rb

Defined Under Namespace

Classes: Outcome

Constant Summary collapse

REQUIRED_RUBY =
"3.4"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_path:, subject:, cwd: ".", env: {}, test_command: nil) ⇒ MutationAdapter

Returns a new instance of MutationAdapter.



38
39
40
41
42
43
44
# File 'lib/pinspec/validate/mutation_adapter.rb', line 38

def initialize(source_path:, subject:, cwd: ".", env: {}, test_command: nil)
  @source_path = source_path
  @subject = subject
  @cwd = cwd
  @env = env
  @test_command = test_command
end

Class Method Details

.available?Boolean

Returns:

  • (Boolean)


12
13
14
15
# File 'lib/pinspec/validate/mutation_adapter.rb', line 12

def self.available?
  Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(REQUIRED_RUBY) &&
    !find_executable.nil?
end

.find_executableObject



17
18
19
20
# File 'lib/pinspec/validate/mutation_adapter.rb', line 17

def self.find_executable
  ENV.fetch("PATH", "").split(File::PATH_SEPARATOR).map { |dir| File.join(dir, "mutineer") }
     .find { |candidate| File.executable?(candidate) }
end

.refuse_unless_available!Object



22
23
24
25
26
27
28
29
30
# File 'lib/pinspec/validate/mutation_adapter.rb', line 22

def self.refuse_unless_available!
  return if available?

  raise UnsupportedRailsVersion,
        "`--validate` needs the mutineer backend, which requires Ruby >= " \
        "#{REQUIRED_RUBY} (this is #{RUBY_VERSION}) and a `mutineer` on PATH. " \
        "Everything else in pinspec runs on Ruby 3.2 and up; only scoring is " \
        "gated. Install it with `gem install mutineer` on a 3.4+ Ruby."
end

Instance Method Details

#score(spec_path) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/pinspec/validate/mutation_adapter.rb', line 46

def score(spec_path)
  args = command_for(spec_path)
  stdout, stderr, status = Open3.capture3(environment, *args, chdir: @cwd)

  parsed = parse(stdout)
  return unscored(stderr.to_s.empty? ? stdout : stderr) if parsed.nil?

  summary = parsed["summary"] || {}

  Outcome.new(
    subject: @subject,
    score: summary["score"],
    killed: summary["killed"],
    survived: summary["survived"],
    total: summary["total"],
    survivors: Array(parsed["survivors"]).map { |s| { "operator" => s["operator"], "line" => s["line"], "token" => s["token"] } },
    raw: status.exitstatus
  )
end