Module: ASTTransform::Testing::Assertions

Defined in:
lib/ast_transform/testing/assertions.rb

Overview

Assertions for transform authors' own test suites — the enforcement arm of the authoring contract ("textual order is source order"). Minitest-flavored. Never loaded in production; require it from test code:

require "ast_transform/testing/assertions"

class MyTransformationTest < Minitest::Test
include ASTTransform::Testing::Assertions
end

Instance Method Summary collapse

Instance Method Details

#assert_backtrace_lines(source, path:, raise_at:) ⇒ void

This method returns an undefined value.

Runtime complement of assert_line_aligned: compiles source through the full pipeline under path, executes it, and asserts the raw first backtrace frame — no filtering of any kind — is ":<raise_at>".



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ast_transform/testing/assertions.rb', line 56

def assert_backtrace_lines(source, path:, raise_at:)
  iseq = InstructionSequence.source_to_transformed_iseq(source, path)

  error = assert_raises(StandardError, "fixture at #{path} should raise when executed") do
    iseq.eval
  end

  location = error.backtrace_locations.first
  assert_equal "#{location.path}:#{raise_at}", "#{location.path}:#{location.lineno}",
    "raw backtrace should cite source line #{raise_at} of #{path}"
end

#assert_line_aligned(source, *transformations, path: 'fixture.rb') ⇒ void

This method returns an undefined value.

Transforms source through the real pipeline (transform + line-aligned emission), re-parses both sides, matches surviving statements by location, and asserts each one's emitted line equals its source line. Statements the transform deletes (e.g. description strings) are exempt; statements the transform rewrites in place keep their anchor and are checked.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ast_transform/testing/assertions.rb', line 26

def assert_line_aligned(source, *transformations, path: 'fixture.rb')
  transformer = Transformer.new(*transformations)
  emitted = transformer.transform_file_source(source, path, path)

  source_lines_by_statement = statement_lines(transformer.build_ast(source, file_path: path))
  emitted_lines_by_statement = statement_lines(transformer.build_ast(emitted, file_path: path))

  misaligned = source_lines_by_statement.filter_map do |render, source_line|
    emitted_line = emitted_lines_by_statement[render]
    next if emitted_line.nil? || emitted_line == source_line

    format('  MISALIGNED %s: source line %d, emitted line %d', render, source_line, emitted_line)
  end

  assert misaligned.empty?, "    expected every surviving statement at its source line in \#{path}:\n    \#{misaligned.join(\"\\n\")}\n\n    emitted:\n    \#{numbered_listing(emitted)}\n  MESSAGE\nend\n"