1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
# 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
|