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
109
110
111
112
113
114
115
116
117
118
119
|
# frozen_string_literal: true
require_relative "test_helper"
module Prism
class ErrorsTest < TestCase
base = File.expand_path("errors", __dir__)
filepaths = Dir["*.txt", base: base]
if RUBY_VERSION < "3.0"
filepaths -= [
"cannot_assign_to_a_reserved_numbered_parameter.txt",
"writing_numbered_parameter.txt",
"targeting_numbered_parameter.txt",
"defining_numbered_parameter.txt",
"defining_numbered_parameter_2.txt",
"numbered_parameters_in_block_arguments.txt",
"numbered_and_write.txt",
"numbered_or_write.txt",
"numbered_operator_write.txt"
]
end
if RUBY_VERSION < "3.4"
filepaths -= [
"it_with_ordinary_parameter.txt",
"block_args_in_array_assignment.txt",
"keyword_args_in_array_assignment.txt"
]
end
if RUBY_VERSION < "3.4" || RUBY_RELEASE_DATE < "2024-07-24"
filepaths -= ["dont_allow_return_inside_sclass_body.txt"]
end
filepaths.each do |filepath|
define_method(:"test_#{File.basename(filepath, ".txt")}") do
assert_errors(File.join(base, filepath))
end
end
def test_newline_preceding_eof
err = Prism.parse("foo(").errors.first
assert_equal 1, err.location.start_line
err = Prism.parse("foo(\n").errors.first
assert_equal 1, err.location.start_line
err = Prism.parse("foo(\n\n\n\n\n").errors.first
assert_equal 5, err.location.start_line
end
def test_embdoc_ending
source = <<~RUBY
=begin\n=end
=begin\n=end\0
=begin\n=end\C-d
=begin\n=end\C-z
RUBY
source.each_line do |line|
assert_valid_syntax(source)
assert_predicate Prism.parse(source), :success?
end
end
def test_unterminated_string_closing
statement = Prism.parse_statement("'hello")
assert_equal statement.unescaped, "hello"
assert_empty statement.closing
end
def test_unterminated_interpolated_string_closing
statement = Prism.parse_statement('"hello')
assert_equal statement.unescaped, "hello"
assert_empty statement.closing
end
def test_unterminated_empty_string_closing
statement = Prism.parse_statement('"')
assert_empty statement.unescaped
assert_empty statement.closing
end
def test_invalid_message_name
assert_equal :"", Prism.parse_statement("+.@foo,+=foo").write_name
end
def test_circular_parameters
source = <<~RUBY
def foo(bar = bar) = 42
def foo(bar: bar) = 42
proc { |foo = foo| }
proc { |foo: foo| }
RUBY
source.each_line do |line|
assert_predicate Prism.parse(line, version: "3.3.0"), :failure?
assert_predicate Prism.parse(line), :success?
end
end
private
def assert_errors(filepath)
expected = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
source = expected.lines.grep_v(/^\s*\^/).join.gsub(/\n*\z/, "")
refute_valid_syntax(source)
result = Prism.parse(source)
errors = result.errors
refute_empty errors, "Expected errors in #{filepath}"
actual = result.errors_format
assert_equal expected, actual, "Expected errors to match for #{filepath}"
end
end
end
|