Class: Henitai::Mutant

Inherits:
Object
  • Object
show all
Includes:
UnparseHelper
Defined in:
lib/henitai/mutant.rb,
lib/henitai/mutant/activator.rb,
lib/henitai/mutant/parameter_source.rb,
sig/henitai.rbs

Overview

Represents a single syntactic mutation applied to a Subject.

A Mutant holds:

- the original and mutated AST nodes
- the operator that generated it
- the source location of the mutation
- its current status in the pipeline

Statuses follow the Stryker mutation-testing-report-schema vocabulary:

:pending, :killed, :survived, :timeout, :compile_error, :runtime_error,
:ignored, :no_coverage

Defined Under Namespace

Classes: Activator, ParameterSource

Constant Summary collapse

STATUSES =

Status-Vokabular folgt dem Stryker mutation-testing-report-schema. :equivalent ist ein Henitai-interner Status (wird im JSON als "Ignored" serialisiert, aber in der Scoring-Berechnung separat behandelt: confirmed equivalent mutants werden aus dem Nenner der MS-Berechnung herausgenommen).

Returns:

  • (Array[Symbol])
%i[
  pending
  killed
  survived
  timeout
  compile_error
  runtime_error
  ignored
  no_coverage
  equivalent
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from UnparseHelper

#fallback_source, #safe_unparse

Constructor Details

#initialize(subject:, operator:, nodes:, description:, location:, precomputed_stable_id: nil, precomputed_activation_source: nil) ⇒ Mutant

rubocop:disable Metrics/ParameterLists

Parameters:

  • subject (Subject)

    the subject being mutated

  • operator (Symbol)

    operator name, e.g. :ArithmeticOperator

  • nodes (Hash)

    AST nodes with :original and :mutated entries

  • description (String)

    human-readable description of the mutation

  • location (Hash)

    { file:, start_line:, end_line:, start_col:, end_col: }

  • subject: (Subject)
  • operator: (String)
  • nodes: (Hash[Symbol, untyped])
  • description: (String)
  • location: (Hash[Symbol, untyped])
  • precomputed_stable_id: (String, nil) (defaults to: nil)
  • precomputed_activation_source: (String, nil) (defaults to: nil)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/henitai/mutant.rb', line 53

def initialize(subject:, operator:, nodes:, description:, location:,
               precomputed_stable_id: nil, precomputed_activation_source: nil)
  @id            = SecureRandom.uuid
  @subject       = subject
  @operator      = operator
  @original_node = nodes.fetch(:original)
  @mutated_node  = nodes.fetch(:mutated)
  @description   = description
  @location      = location
  @precomputed_stable_id = precomputed_stable_id
  @precomputed_activation_source = precomputed_activation_source
  @status = :pending
  @killing_test = @duration = @covered_by = @tests_completed = @ignore_reason = nil
  @from_cache = false
end

Instance Attribute Details

#covered_byArray[String]?

Returns the value of attribute covered_by.

Returns:

  • (Array[String], nil)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def covered_by
  @covered_by
end

#descriptionString (readonly)

Returns the value of attribute description.

Returns:

  • (String)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def description
  @description
end

#durationFloat?

Returns the value of attribute duration.

Returns:

  • (Float, nil)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def duration
  @duration
end

#from_cacheBoolean

Returns the value of attribute from_cache.

Returns:

  • (Boolean)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def from_cache
  @from_cache
end

#idString (readonly)

Returns the value of attribute id.

Returns:

  • (String)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def id
  @id
end

#ignore_reasonString?

Returns the value of attribute ignore_reason.

Returns:

  • (String, nil)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def ignore_reason
  @ignore_reason
end

#killing_testString?

Returns the value of attribute killing_test.

Returns:

  • (String, nil)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def killing_test
  @killing_test
end

#locationHash[Symbol, untyped] (readonly)

Returns the value of attribute location.

Returns:

  • (Hash[Symbol, untyped])


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def location
  @location
end

#mutated_nodeObject (readonly)

Returns the value of attribute mutated_node.

Returns:

  • (Object)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def mutated_node
  @mutated_node
end

#mutation_typeObject (readonly)

Returns the value of attribute mutation_type.

Returns:

  • (Object)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def mutation_type
  @mutation_type
end

#operatorString (readonly)

Returns the value of attribute operator.

Returns:

  • (String)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def operator
  @operator
end

#original_nodeObject (readonly)

Returns the value of attribute original_node.

Returns:

  • (Object)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def original_node
  @original_node
end

#precomputed_activation_sourceString? (readonly)

Returns the value of attribute precomputed_activation_source.

Returns:

  • (String, nil)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def precomputed_activation_source
  @precomputed_activation_source
end

#precomputed_stable_idString? (readonly)

Returns the value of attribute precomputed_stable_id.

Returns:

  • (String, nil)


41
42
43
# File 'lib/henitai/mutant.rb', line 41

def precomputed_stable_id
  @precomputed_stable_id
end

#statusSymbol

Returns the value of attribute status.

Returns:

  • (Symbol)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def status
  @status
end

#subjectSubject (readonly)

Returns the value of attribute subject.

Returns:



41
42
43
# File 'lib/henitai/mutant.rb', line 41

def subject
  @subject
end

#tests_completedInteger?

Returns the value of attribute tests_completed.

Returns:

  • (Integer, nil)


44
45
46
# File 'lib/henitai/mutant.rb', line 44

def tests_completed
  @tests_completed
end

Instance Method Details

#equivalent?Boolean

Returns:

  • (Boolean)


83
# File 'lib/henitai/mutant.rb', line 83

def equivalent?  = @status == :equivalent

#from_cache?Boolean

Returns:

  • (Boolean)


79
# File 'lib/henitai/mutant.rb', line 79

def from_cache?  = @from_cache == true

#ignored?Boolean

Returns:

  • (Boolean)


82
# File 'lib/henitai/mutant.rb', line 82

def ignored?     = @status == :ignored

#killed?Boolean

Returns:

  • (Boolean)


78
# File 'lib/henitai/mutant.rb', line 78

def killed?      = @status == :killed

#mutated_sourceString

Unparsing is expensive and the value is needed by both the JSON and the terminal reporter — compute once per mutant.

Returns:

  • (String)


76
# File 'lib/henitai/mutant.rb', line 76

def mutated_source = @mutated_source ||= safe_unparse(mutated_node)

#pending?Boolean

Returns:

  • (Boolean)


81
# File 'lib/henitai/mutant.rb', line 81

def pending?     = @status == :pending

#stable_idString

rubocop:enable Metrics/ParameterLists

Returns:

  • (String)


70
71
72
# File 'lib/henitai/mutant.rb', line 70

def stable_id
  @stable_id ||= @precomputed_stable_id || MutantIdentity.stable_id(self)
end

#survived?Boolean

Returns:

  • (Boolean)


80
# File 'lib/henitai/mutant.rb', line 80

def survived?    = @status == :survived

#to_sString

Returns:

  • (String)


85
86
87
# File 'lib/henitai/mutant.rb', line 85

def to_s
  "#{operator}@#{location[:file]}:#{location[:start_line]}#{description}"
end