ruby/test/prism/encoding/symbol_encoding_test.rb
2024-05-30 15:18:20 -04:00

108 lines
2.6 KiB
Ruby

# frozen_string_literal: true
return if RUBY_ENGINE != "ruby"
require_relative "../test_helper"
module Prism
class SymbolEncodingTest < TestCase
each_encoding do |encoding, _|
define_method(:"test_symbols_#{encoding.name}") do
assert_symbols(encoding)
end
define_method(:"test_escapes_#{encoding.name}") do
assert_escapes(encoding)
end
end
private
def expected_encoding(source)
eval(source).encoding
end
def actual_encoding(source, encoding)
result = Prism.parse(source)
if result.success?
symbol = result.statement
if symbol.forced_utf8_encoding?
Encoding::UTF_8
elsif symbol.forced_binary_encoding?
Encoding::ASCII_8BIT
elsif symbol.forced_us_ascii_encoding?
Encoding::US_ASCII
else
encoding
end
else
raise SyntaxError.new(result.errors.map(&:message).join("\n"))
end
end
def assert_symbols(encoding)
[:a, :ą, :+].each do |symbol|
source = "# encoding: #{encoding.name}\n#{symbol.inspect}"
expected =
begin
expected_encoding(source)
rescue SyntaxError => error
if error.message.include?("invalid multibyte")
"invalid multibyte"
else
raise
end
end
actual =
begin
actual_encoding(source, encoding)
rescue SyntaxError => error
if error.message.include?("invalid multibyte")
"invalid multibyte"
else
raise
end
end
assert_equal expected, actual
end
end
def assert_escapes(encoding)
escapes = ["\\x00", "\\x7F", "\\x80", "\\xFF", "\\u{00}", "\\u{7F}", "\\u{80}", "\\M-\\C-?"]
escapes = escapes.concat(escapes.product(escapes).map(&:join))
escapes.each do |escaped|
source = "# encoding: #{encoding.name}\n:\"#{escaped}\""
expected =
begin
expected_encoding(source)
rescue SyntaxError => error
if error.message.include?("UTF-8 mixed within")
error.message[/UTF-8 mixed within .+? source/]
else
raise
end
end
actual =
begin
actual_encoding(source, encoding)
rescue SyntaxError => error
if error.message.include?("mixed")
error.message.split("\n", 2).first
else
raise
end
end
assert_equal expected, actual
end
end
end
end