Class: Canon::Rebaseliner::CallSiteResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/canon/rebaseliner/call_site_resolver.rb

Overview

Parse a spec file with Prism, locate the matcher invocation at a specific line, and return enough context (matcher AST + enclosing it/example block + full source) for the locator and rewriter to work against.

Defined Under Namespace

Classes: Result

Constant Summary collapse

MATCHER_NAMES =
%i[
  be_equivalent_to
  be_xml_equivalent_to
  be_html_equivalent_to
  be_json_equivalent_to
  be_yaml_equivalent_to
  be_serialization_equivalent_to
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source:, root:, line:) ⇒ CallSiteResolver

Returns a new instance of CallSiteResolver.



45
46
47
48
49
# File 'lib/canon/rebaseliner/call_site_resolver.rb', line 45

def initialize(source:, root:, line:)
  @source = source
  @root = root
  @line = line
end

Class Method Details

.resolve(spec_path:, line:) ⇒ Result?

Returns nil if the file can't be parsed or no matcher call is found at that line.

Parameters:

  • spec_path (String)
  • line (Integer)

    1-indexed line number where the matcher invocation lives (typically from caller_locations)

Returns:

  • (Result, nil)

    nil if the file can't be parsed or no matcher call is found at that line



35
36
37
38
39
40
41
42
43
# File 'lib/canon/rebaseliner/call_site_resolver.rb', line 35

def self.resolve(spec_path:, line:)
  source = File.read(spec_path)
  parse_result = Prism.parse(source)
  return nil unless parse_result.success?

  new(source: source,
      root: parse_result.value,
      line: line).resolve
end

Instance Method Details

#resolveObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/canon/rebaseliner/call_site_resolver.rb', line 51

def resolve
  call_node = find_matcher_call(@root)
  return nil unless call_node

  expected = call_node.arguments&.arguments&.first
  return nil unless expected

  enclosing = find_enclosing_block(@root, call_node)
  return nil unless enclosing

  Result.new(
    source: @source,
    matcher_call_node: call_node,
    expected_node: expected,
    enclosing_block: enclosing,
    matcher_line: call_node.location.start_line,
  )
end