Class: RSpock::AST::Parser::InteractionParser

Inherits:
Object
  • Object
show all
Includes:
ASTTransform::TransformationHelper
Defined in:
lib/rspock/ast/parser/interaction_parser.rb

Overview

Parses raw Ruby AST interaction nodes into structured :rspock_interaction nodes.

Input: 1 * receiver.message("arg", &blk) >> "result" Output: s(:rspock_interaction, cardinality, receiver, sym, args, outcome, block_pass)

:rspock_interaction children:

[0] cardinality  - e.g. s(:int, 1), s(:begin, s(:irange, ...)), s(:send, nil, :_)
[1] receiver     - e.g. s(:send, nil, :subscriber)
[2] message      - e.g. s(:sym, :receive)
[3] args         - nil if no args, s(:array, *arg_nodes) otherwise
[4] outcome      - nil if no >>, otherwise s(:rspock_stub_returns, value) or s(:rspock_stub_raises, *args)
[5] block_pass   - nil if no &, otherwise s(:block_pass, ...)

Defined Under Namespace

Classes: InteractionError

Constant Summary collapse

ALLOWED_CARDINALITY_NODES =
[:send, :lvar, :int].freeze

Instance Method Summary collapse

Instance Method Details

#interaction_node?(node) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
30
31
32
33
# File 'lib/rspock/ast/parser/interaction_parser.rb', line 27

def interaction_node?(node)
  return false if node.nil?
  return true if node.type == :send && node.children[1] == :*
  return true if return_value_node?(node)

  false
end

#parse(node) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rspock/ast/parser/interaction_parser.rb', line 35

def parse(node)
  return node unless interaction_node?(node)

  # Anchor at the full interaction expression (including >> outcome), so the Mocha setup it lowers into is
  # emitted at the interaction's line.
  anchor = node

  if return_value_node?(node)
    outcome = parse_outcome(node.children[2])
    node = node.children[0]
  end

  cardinality = node.children[0]
  validate_cardinality(cardinality)

  rhs = node.children[2]
  receiver, message, args, block_pass = parse_rhs(rhs)

  interaction = s(:rspock_interaction,
    cardinality,
    receiver,
    s(:sym, message),
    args,
    outcome,
    block_pass
  )

  anchor.loc&.expression ? s_at(anchor, interaction.type, *interaction.children) : interaction
end