mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 16:44:01 +02:00
126 lines
3.9 KiB
Ruby
126 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "prism"
|
|
require "ripper"
|
|
require "pp"
|
|
require "test/unit"
|
|
require "tempfile"
|
|
|
|
puts "Using prism backend: #{Prism::BACKEND}" if ENV["PRISM_FFI_BACKEND"]
|
|
|
|
# It is useful to have a diff even if the strings to compare are big
|
|
# However, ruby/ruby does not have a version of Test::Unit with access to
|
|
# max_diff_target_string_size
|
|
if defined?(Test::Unit::Assertions::AssertionMessage)
|
|
Test::Unit::Assertions::AssertionMessage.max_diff_target_string_size = 5000
|
|
end
|
|
|
|
module Prism
|
|
class TestCase < ::Test::Unit::TestCase
|
|
private
|
|
|
|
if RUBY_ENGINE == "ruby"
|
|
# Check that the given source is valid syntax by compiling it with RubyVM.
|
|
def check_syntax(source)
|
|
$VERBOSE, previous = nil, $VERBOSE
|
|
|
|
begin
|
|
RubyVM::InstructionSequence.compile(source)
|
|
ensure
|
|
$VERBOSE = previous
|
|
end
|
|
end
|
|
|
|
# Assert that the given source is valid Ruby syntax by attempting to
|
|
# compile it, and then implicitly checking that it does not raise an
|
|
# syntax errors.
|
|
def assert_valid_syntax(source)
|
|
check_syntax(source)
|
|
end
|
|
|
|
# Refute that the given source is invalid Ruby syntax by attempting to
|
|
# compile it and asserting that it raises a SyntaxError.
|
|
def refute_valid_syntax(source)
|
|
assert_raise(SyntaxError) { check_syntax(source) }
|
|
end
|
|
else
|
|
def assert_valid_syntax(source)
|
|
end
|
|
|
|
def refute_valid_syntax(source)
|
|
end
|
|
end
|
|
|
|
def assert_raises(*args, &block)
|
|
raise "Use assert_raise instead"
|
|
end
|
|
|
|
def assert_equal_nodes(expected, actual, compare_location: true, parent: nil)
|
|
assert_equal expected.class, actual.class
|
|
|
|
case expected
|
|
when Array
|
|
assert_equal(
|
|
expected.size,
|
|
actual.size,
|
|
-> { "Arrays were different sizes. Parent: #{parent.pretty_inspect}" }
|
|
)
|
|
|
|
expected.zip(actual).each do |(expected_element, actual_element)|
|
|
assert_equal_nodes(
|
|
expected_element,
|
|
actual_element,
|
|
compare_location: compare_location,
|
|
parent: actual
|
|
)
|
|
end
|
|
when SourceFileNode
|
|
expected_deconstruct = expected.deconstruct_keys(nil)
|
|
actual_deconstruct = actual.deconstruct_keys(nil)
|
|
assert_equal expected_deconstruct.keys, actual_deconstruct.keys
|
|
|
|
# Filepaths can be different if test suites were run on different
|
|
# machines. We accommodate for this by comparing the basenames, and not
|
|
# the absolute filepaths.
|
|
expected_filepath = expected_deconstruct.delete(:filepath)
|
|
actual_filepath = actual_deconstruct.delete(:filepath)
|
|
|
|
assert_equal expected_deconstruct, actual_deconstruct
|
|
assert_equal File.basename(expected_filepath), File.basename(actual_filepath)
|
|
when Node
|
|
deconstructed_expected = expected.deconstruct_keys(nil)
|
|
deconstructed_actual = actual.deconstruct_keys(nil)
|
|
assert_equal deconstructed_expected.keys, deconstructed_actual.keys
|
|
|
|
deconstructed_expected.each_key do |key|
|
|
assert_equal_nodes(
|
|
deconstructed_expected[key],
|
|
deconstructed_actual[key],
|
|
compare_location: compare_location,
|
|
parent: actual
|
|
)
|
|
end
|
|
when Location
|
|
assert_operator actual.start_offset, :<=, actual.end_offset, -> {
|
|
"start_offset > end_offset for #{actual.inspect}, parent is #{parent.pretty_inspect}"
|
|
}
|
|
|
|
if compare_location
|
|
assert_equal(
|
|
expected.start_offset,
|
|
actual.start_offset,
|
|
-> { "Start locations were different. Parent: #{parent.pretty_inspect}" }
|
|
)
|
|
|
|
assert_equal(
|
|
expected.end_offset,
|
|
actual.end_offset,
|
|
-> { "End locations were different. Parent: #{parent.pretty_inspect}" }
|
|
)
|
|
end
|
|
else
|
|
assert_equal expected, actual
|
|
end
|
|
end
|
|
end
|
|
end
|