Class: TreeHaver::RSpec::TestableNode

Inherits:
Node
  • Object
show all
Defined in:
lib/tree_haver/rspec/testable_node.rb

Overview

A real TreeHaver::Node that wraps a MockInnerNode.

This gives us full TreeHaver::Node behavior (#text, #type, #source_position, etc.) while allowing us to control the underlying data for testing.

TestableNode is designed for testing code that works with TreeHaver nodes without requiring an actual parser backend. It creates real TreeHaver::Node instances with controlled, predictable data.

Examples:

Creating a testable node

node = TreeHaver::RSpec::TestableNode.create(
  type: :heading,
  text: "## My Heading",
  start_line: 1
)
node.text       # => "## My Heading"
node.type       # => "heading"
node.start_line # => 1

Creating with children

parent = TreeHaver::RSpec::TestableNode.create(
  type: :document,
  text: "# Title\n\nParagraph",
  children: [
    { type: :heading, text: "# Title", start_line: 1 },
    { type: :paragraph, text: "Paragraph", start_line: 3 },
  ]
)

Using the convenience constant

# After requiring tree_haver/rspec/testable_node, you can use:
node = TestableNode.create(type: :paragraph, text: "Hello")

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

#<=>, #==, #child, #child_by_field_name, #child_count, #children, #each, #end_byte, #end_line, #end_point, #first_child, #has_error?, #hash, #initialize, #inspect, #kind, #method_missing, #missing?, #named?, #named_child, #named_child_count, #named_children, #next_sibling, #parent, #prev_sibling, #respond_to_missing?, #source_position, #start_byte, #start_line, #start_point, #structural?, #text, #to_s, #type

Constructor Details

This class inherits a constructor from TreeHaver::Node

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class TreeHaver::Node

Class Method Details

.create(type:, text: "", start_line: 1, end_line: nil, start_column: 0, end_column: nil, start_byte: 0, end_byte: nil, children: [], source: nil) ⇒ TestableNode

Create a TestableNode with the given attributes.

Parameters:

  • type (Symbol, String)

    Node type (e.g., :heading, :paragraph)

  • text (String) (defaults to: "")

    The text content of the node

  • start_line (Integer) (defaults to: 1)

    1-based start line number (default: 1)

  • end_line (Integer, nil) (defaults to: nil)

    1-based end line number (default: calculated from text)

  • start_column (Integer) (defaults to: 0)

    0-based start column (default: 0)

  • end_column (Integer, nil) (defaults to: nil)

    0-based end column (default: calculated from text)

  • start_byte (Integer) (defaults to: 0)

    Start byte offset (default: 0)

  • end_byte (Integer, nil) (defaults to: nil)

    End byte offset (default: calculated from text)

  • children (Array<Hash>) (defaults to: [])

    Child node specifications

  • source (String, nil) (defaults to: nil)

    Full source text (default: uses text param)

Returns:



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/tree_haver/rspec/testable_node.rb', line 150

def create(
  type:,
  text: "",
  start_line: 1,
  end_line: nil,
  start_column: 0,
  end_column: nil,
  start_byte: 0,
  end_byte: nil,
  children: [],
  source: nil
)
  # Convert 1-based line to 0-based row
  start_row = start_line - 1
  end_row = end_line ? end_line - 1 : start_row + text.count("\n")

  # Calculate end_column if not provided
  if end_column.nil?
    lines = text.split("\n", -1)
    end_column = lines.last&.length || 0
  end

  # Build children as MockInnerNodes
  child_nodes = children.map do |child_spec|
    MockInnerNode.new(**child_spec)
  end

  inner = MockInnerNode.new(
    type: type,
    text: text,
    start_byte: start_byte,
    end_byte: end_byte,
    start_row: start_row,
    start_column: start_column,
    end_row: end_row,
    end_column: end_column,
    children: child_nodes,
  )

  # Create a real TreeHaver::Node wrapping our mock
  # Pass source so TreeHaver::Node can extract text if needed
  new(inner, source: source || text)
end

.create_list(*specs) ⇒ Array<TestableNode>

Create multiple nodes from an array of specifications.

Parameters:

  • specs (Array<Hash>)

    Array of node specifications

Returns:



198
199
200
# File 'lib/tree_haver/rspec/testable_node.rb', line 198

def create_list(*specs)
  specs.flatten.map { |spec| create(**spec) }
end

Instance Method Details

#testable?Boolean

Check if this is a testable node (for test assertions)

Returns:

  • (Boolean)

    true



208
209
210
# File 'lib/tree_haver/rspec/testable_node.rb', line 208

def testable?
  true
end