Class: Henitai::Subject

Inherits:
Object
  • Object
show all
Defined in:
lib/henitai/subject.rb

Overview

Represents an addressable unit of source code to be mutated.

Subjects are expressed using a compact syntax:

Foo::Bar#instance_method    — specific instance method
Foo::Bar.class_method       — specific class method
Foo::Bar*                   — all methods on Foo::Bar
Foo*                        — all methods in the Foo namespace

The Subject is resolved from the AST before mutation begins. Test selection uses longest-prefix matching against example group descriptions in the test suite.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(expression: nil, namespace: nil, method_name: nil, method_type: :instance, source_location: nil, ast_node: nil) ⇒ Subject

The explicit keyword API matches the public call sites and keeps the metadata fields discoverable without a single options hash. rubocop:disable Metrics/ParameterLists

Parameters:

  • namespace (String) (defaults to: nil)

    fully-qualified module/class name

  • method_name (String) (defaults to: nil)

    method name (nil for wildcard subjects)

  • method_type (Symbol) (defaults to: :instance)

    :instance or :class

  • source_location (Hash) (defaults to: nil)

    file/range metadata for the subject source



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/henitai/subject.rb', line 31

def initialize(expression: nil, namespace: nil, method_name: nil,
               method_type: :instance, source_location: nil, ast_node: nil)
  if expression
    parse_expression(expression)
  else
    @namespace   = namespace
    @method_name = method_name
    @method_type = method_type
  end
  @source_file  = source_location&.fetch(:file, nil)
  @source_range = source_location&.fetch(:range, nil)
  @ast_node = ast_node
end

Instance Attribute Details

#ast_nodeObject (readonly)

Returns the value of attribute ast_node.



16
17
18
# File 'lib/henitai/subject.rb', line 16

def ast_node
  @ast_node
end

#method_nameObject (readonly)

Returns the value of attribute method_name.



16
17
18
# File 'lib/henitai/subject.rb', line 16

def method_name
  @method_name
end

#method_typeObject (readonly)

Returns the value of attribute method_type.



16
17
18
# File 'lib/henitai/subject.rb', line 16

def method_type
  @method_type
end

#namespaceObject (readonly)

Returns the value of attribute namespace.



16
17
18
# File 'lib/henitai/subject.rb', line 16

def namespace
  @namespace
end

#source_fileObject (readonly)

Returns the value of attribute source_file.



16
17
18
# File 'lib/henitai/subject.rb', line 16

def source_file
  @source_file
end

#source_rangeObject (readonly)

Returns the value of attribute source_range.



16
17
18
# File 'lib/henitai/subject.rb', line 16

def source_range
  @source_range
end

Class Method Details

.parse(expression) ⇒ Object

Parameters:

  • expression (String)

    subject expression, e.g. “Foo::Bar#method”



20
21
22
# File 'lib/henitai/subject.rb', line 20

def self.parse(expression)
  new(expression:)
end

Instance Method Details

#expressionObject

Full addressable expression, e.g. “Foo::Bar#method”



47
48
49
50
# File 'lib/henitai/subject.rb', line 47

def expression
  sep = @method_type == :class ? "." : "#"
  @method_name ? "#{@namespace}#{sep}#{@method_name}" : "#{@namespace}*"
end

#wildcard?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/henitai/subject.rb', line 52

def wildcard?
  @method_name.nil?
end