summaryrefslogtreecommitdiff
path: root/test/prism/test_helper.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/prism/test_helper.rb')
-rw-r--r--test/prism/test_helper.rb126
1 files changed, 126 insertions, 0 deletions
diff --git a/test/prism/test_helper.rb b/test/prism/test_helper.rb
new file mode 100644
index 0000000000..77af7e7b45
--- /dev/null
+++ b/test/prism/test_helper.rb
@@ -0,0 +1,126 @@
+# 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