summaryrefslogtreecommitdiff
path: root/test/prism/result
diff options
context:
space:
mode:
Diffstat (limited to 'test/prism/result')
-rw-r--r--test/prism/result/breadth_first_search_test.rb11
-rw-r--r--test/prism/result/continuable_test.rb124
-rw-r--r--test/prism/result/error_recovery_test.rb237
-rw-r--r--test/prism/result/named_capture_test.rb29
-rw-r--r--test/prism/result/numeric_value_test.rb11
-rw-r--r--test/prism/result/overlap_test.rb9
-rw-r--r--test/prism/result/source_location_test.rb16
-rw-r--r--test/prism/result/string_test.rb32
-rw-r--r--test/prism/result/warnings_test.rb120
9 files changed, 543 insertions, 46 deletions
diff --git a/test/prism/result/breadth_first_search_test.rb b/test/prism/result/breadth_first_search_test.rb
index e2e043a902..7e7962f172 100644
--- a/test/prism/result/breadth_first_search_test.rb
+++ b/test/prism/result/breadth_first_search_test.rb
@@ -14,5 +14,16 @@ module Prism
refute_nil found
assert_equal 8, found.start_offset
end
+
+ def test_breadth_first_search_all
+ result = Prism.parse("[1 + 2, 2]")
+ found_nodes =
+ result.value.breadth_first_search_all do |node|
+ node.is_a?(IntegerNode)
+ end
+
+ assert_equal 3, found_nodes.size
+ assert_equal 8, found_nodes[0].start_offset
+ end
end
end
diff --git a/test/prism/result/continuable_test.rb b/test/prism/result/continuable_test.rb
new file mode 100644
index 0000000000..3533552167
--- /dev/null
+++ b/test/prism/result/continuable_test.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require_relative "../test_helper"
+
+module Prism
+ class ContinuableTest < TestCase
+ def test_valid_input
+ # Valid input is not continuable (nothing to continue).
+ refute_predicate Prism.parse("1 + 1"), :continuable?
+ refute_predicate Prism.parse(""), :continuable?
+ end
+
+ def test_stray_closing_tokens
+ # Stray closing tokens make input non-continuable regardless of what
+ # follows (matches the feature-request examples exactly).
+ refute_predicate Prism.parse("1 + ]"), :continuable?
+ refute_predicate Prism.parse("end.tap do"), :continuable?
+
+ # A mix: stray end plus an unclosed block is not continuable because the
+ # stray end cannot be fixed by appending more input.
+ refute_predicate Prism.parse("end\ntap do"), :continuable?
+ end
+
+ def test_unclosed_constructs
+ # Unclosed constructs are continuable.
+ assert_predicate Prism.parse("1 + ["), :continuable?
+ assert_predicate Prism.parse("tap do"), :continuable?
+ end
+
+ def test_unclosed_keywords
+ assert_predicate Prism.parse("def foo"), :continuable?
+ assert_predicate Prism.parse("class Foo"), :continuable?
+ assert_predicate Prism.parse("module Foo"), :continuable?
+ assert_predicate Prism.parse("if true"), :continuable?
+ assert_predicate Prism.parse("while true"), :continuable?
+ assert_predicate Prism.parse("begin"), :continuable?
+ assert_predicate Prism.parse("for x in [1]"), :continuable?
+ end
+
+ def test_unclosed_delimiters
+ assert_predicate Prism.parse("{"), :continuable?
+ assert_predicate Prism.parse("foo("), :continuable?
+ assert_predicate Prism.parse('"hello'), :continuable?
+ assert_predicate Prism.parse("'hello"), :continuable?
+ assert_predicate Prism.parse("<<~HEREDOC\nhello"), :continuable?
+ end
+
+ def test_trailing_whitespace
+ # Trailing whitespace or newlines should not affect continuability.
+ assert_predicate Prism.parse("class A\n"), :continuable?
+ assert_predicate Prism.parse("def f "), :continuable?
+ assert_predicate Prism.parse("def f\n"), :continuable?
+ assert_predicate Prism.parse("def f\n "), :continuable?
+ assert_predicate Prism.parse("( "), :continuable?
+ assert_predicate Prism.parse("(\n"), :continuable?
+ assert_predicate Prism.parse("1 +\n"), :continuable?
+ end
+
+ def test_incomplete_expressions
+ assert_predicate Prism.parse("-"), :continuable?
+ assert_predicate Prism.parse("[1,"), :continuable?
+ assert_predicate Prism.parse("f arg1,"), :continuable?
+ assert_predicate Prism.parse("def f ="), :continuable?
+ assert_predicate Prism.parse("def $a"), :continuable?
+ assert_predicate Prism.parse("a ="), :continuable?
+ assert_predicate Prism.parse("a,b"), :continuable?
+ end
+
+ def test_modifier_keywords
+ assert_predicate Prism.parse("return if"), :continuable?
+ assert_predicate Prism.parse("return unless"), :continuable?
+ assert_predicate Prism.parse("while"), :continuable?
+ assert_predicate Prism.parse("until"), :continuable?
+ end
+
+ def test_ternary_operator
+ assert_predicate Prism.parse("x ?"), :continuable?
+ assert_predicate Prism.parse("x ? y :"), :continuable?
+ end
+
+ def test_class_with_superclass
+ assert_predicate Prism.parse("class Foo <"), :continuable?
+ end
+
+ def test_keyword_expressions
+ assert_predicate Prism.parse("not"), :continuable?
+ assert_predicate Prism.parse("defined?"), :continuable?
+ assert_predicate Prism.parse("module"), :continuable?
+ end
+
+ def test_for_loops
+ assert_predicate Prism.parse("for"), :continuable?
+ assert_predicate Prism.parse("for x in"), :continuable?
+ end
+
+ def test_pattern_matching
+ assert_predicate Prism.parse("foo => ["), :continuable?
+ assert_predicate Prism.parse("case foo; when"), :continuable?
+ end
+
+ def test_splat_and_block_pass
+ assert_predicate Prism.parse("[*"), :continuable?
+ assert_predicate Prism.parse("f(**"), :continuable?
+ assert_predicate Prism.parse("f(&"), :continuable?
+ end
+
+ def test_default_parameter_value
+ assert_predicate Prism.parse("def f(x ="), :continuable?
+ end
+
+ def test_line_continuation
+ assert_predicate Prism.parse("1 +\\"), :continuable?
+ assert_predicate Prism.parse("\"foo\" \\"), :continuable?
+ end
+
+ def test_embedded_document
+ # Embedded document (=begin) truncated at various points.
+ assert_predicate Prism.parse("=b"), :continuable?
+ assert_predicate Prism.parse("=beg"), :continuable?
+ assert_predicate Prism.parse("=begin"), :continuable?
+ assert_predicate Prism.parse("foo\n=b"), :continuable?
+ end
+ end
+end
diff --git a/test/prism/result/error_recovery_test.rb b/test/prism/result/error_recovery_test.rb
new file mode 100644
index 0000000000..d07c858d1b
--- /dev/null
+++ b/test/prism/result/error_recovery_test.rb
@@ -0,0 +1,237 @@
+# frozen_string_literal: true
+
+require_relative "../test_helper"
+
+module Prism
+ class ErrorRecoveryTest < TestCase
+ def test_alias_global_variable_node_old_name_symbol
+ result = Prism.parse("alias $a b")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.old_name
+ assert_kind_of SymbolNode, node.old_name.unexpected
+ end
+
+ def test_alias_global_variable_node_old_name_missing
+ result = Prism.parse("alias $a 42")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.old_name
+ assert_nil node.old_name.unexpected
+ end
+
+ def test_alias_method_node_old_name_global_variable
+ result = Prism.parse("alias a $b")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.old_name
+ assert_kind_of GlobalVariableReadNode, node.old_name.unexpected
+ end
+
+ def test_alias_method_node_old_name_missing
+ result = Prism.parse("alias a 42")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.old_name
+ assert_nil node.old_name.unexpected
+ end
+
+ def test_class_node_constant_path_call
+ result = Prism.parse("class 0.X; end")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.constant_path
+ assert_kind_of CallNode, node.constant_path.unexpected
+ end
+
+ def test_for_node_index_back_reference
+ result = Prism.parse("for $& in a; end")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.index
+ assert_kind_of BackReferenceReadNode, node.index.unexpected
+ end
+
+ def test_for_node_index_numbered_reference
+ result = Prism.parse("for $1 in a; end")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.index
+ assert_kind_of NumberedReferenceReadNode, node.index.unexpected
+ end
+
+ def test_for_node_index_missing
+ result = Prism.parse("for in 1..10; end")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.index
+ assert_nil node.index.unexpected
+ end
+
+ def test_interpolated_string_node_parts_xstring
+ result = Prism.parse("<<~`FOO` \"bar\"\nls\nFOO\n")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert node.parts.any? { |part| part.is_a?(ErrorRecoveryNode) && part.unexpected.is_a?(XStringNode) }
+ end
+
+ def test_interpolated_string_node_parts_interpolated_xstring
+ result = Prism.parse("<<~`FOO` \"bar\"\n\#{ls}\nFOO\n")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert node.parts.any? { |part| part.is_a?(ErrorRecoveryNode) && part.unexpected.is_a?(InterpolatedXStringNode) }
+ end
+
+ def test_module_node_constant_path_def
+ result = Prism.parse("module def foo; end")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert_kind_of ErrorRecoveryNode, node.constant_path
+ assert_kind_of DefNode, node.constant_path.unexpected
+ end
+
+ def test_module_node_constant_path_missing
+ result = Prism.parse("module Parent module end")
+ refute result.success?
+
+ node = result.value.statements.body.first.body.body.first
+ assert_kind_of ErrorRecoveryNode, node.constant_path
+ assert_nil node.constant_path.unexpected
+ end
+
+ def test_multi_target_node_lefts_back_reference
+ result = Prism.parse("a, (b, $&) = z")
+ refute result.success?
+
+ node = result.value.statements.body.first.lefts.last
+ assert node.lefts.any? { |left| left.is_a?(ErrorRecoveryNode) && left.unexpected.is_a?(BackReferenceReadNode) }
+ end
+
+ def test_multi_target_node_lefts_numbered_reference
+ result = Prism.parse("a, (b, $1) = z")
+ refute result.success?
+
+ node = result.value.statements.body.first.lefts.last
+ assert node.lefts.any? { |left| left.is_a?(ErrorRecoveryNode) && left.unexpected.is_a?(NumberedReferenceReadNode) }
+ end
+
+ def test_multi_target_node_rights_back_reference
+ result = Prism.parse("a, (*, $&) = z")
+ refute result.success?
+
+ node = result.value.statements.body.first.lefts.last
+ assert node.rights.any? { |right| right.is_a?(ErrorRecoveryNode) && right.unexpected.is_a?(BackReferenceReadNode) }
+ end
+
+ def test_multi_target_node_rights_numbered_reference
+ result = Prism.parse("a, (*, $1) = z")
+ refute result.success?
+
+ node = result.value.statements.body.first.lefts.last
+ assert node.rights.any? { |right| right.is_a?(ErrorRecoveryNode) && right.unexpected.is_a?(NumberedReferenceReadNode) }
+ end
+
+ def test_multi_write_node_lefts_back_reference
+ result = Prism.parse("$&, = z")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert node.lefts.any? { |left| left.is_a?(ErrorRecoveryNode) && left.unexpected.is_a?(BackReferenceReadNode) }
+ end
+
+ def test_multi_write_node_lefts_numbered_reference
+ result = Prism.parse("$1, = z")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert node.lefts.any? { |left| left.is_a?(ErrorRecoveryNode) && left.unexpected.is_a?(NumberedReferenceReadNode) }
+ end
+
+ def test_multi_write_node_rights_back_reference
+ result = Prism.parse("*, $& = z")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert node.rights.any? { |right| right.is_a?(ErrorRecoveryNode) && right.unexpected.is_a?(BackReferenceReadNode) }
+ end
+
+ def test_multi_write_node_rights_numbered_reference
+ result = Prism.parse("*, $1 = z")
+ refute result.success?
+
+ node = result.value.statements.body.first
+ assert node.rights.any? { |right| right.is_a?(ErrorRecoveryNode) && right.unexpected.is_a?(NumberedReferenceReadNode) }
+ end
+
+ def test_parameters_node_posts_keyword_rest
+ result = Prism.parse("def f(**kwargs, ...); end")
+ refute result.success?
+
+ node = result.value.statements.body.first.parameters
+ assert node.posts.any? { |post| post.is_a?(ErrorRecoveryNode) && post.unexpected.is_a?(KeywordRestParameterNode) }
+ end
+
+ def test_parameters_node_posts_no_keywords
+ result = Prism.parse("def f(**nil, ...); end")
+ refute result.success?
+
+ node = result.value.statements.body.first.parameters
+ assert node.posts.any? { |post| post.is_a?(ErrorRecoveryNode) && post.unexpected.is_a?(NoKeywordsParameterNode) }
+ end
+
+ def test_parameters_node_posts_forwarding
+ result = Prism.parse("def f(..., ...); end")
+ refute result.success?
+
+ node = result.value.statements.body.first.parameters
+ assert node.posts.any? { |post| post.is_a?(ErrorRecoveryNode) && post.unexpected.is_a?(ForwardingParameterNode) }
+ end
+
+ def test_pinned_variable_node_variable_missing
+ result = Prism.parse("foo in ^Bar")
+ refute result.success?
+
+ node = result.value.statements.body.first.pattern
+ assert_kind_of ErrorRecoveryNode, node.variable
+ assert_nil node.variable.unexpected
+ end
+
+ def test_rescue_node_reference_back_reference
+ result = Prism.parse("begin; rescue => $&; end")
+ refute result.success?
+
+ node = result.value.statements.body.first.rescue_clause
+ assert_kind_of ErrorRecoveryNode, node.reference
+ assert_kind_of BackReferenceReadNode, node.reference.unexpected
+ end
+
+ def test_rescue_node_reference_numbered_reference
+ result = Prism.parse("begin; rescue => $1; end")
+ refute result.success?
+
+ node = result.value.statements.body.first.rescue_clause
+ assert_kind_of ErrorRecoveryNode, node.reference
+ assert_kind_of NumberedReferenceReadNode, node.reference.unexpected
+ end
+
+ def test_rescue_node_reference_missing
+ result = Prism.parse("begin; rescue =>; end")
+ refute result.success?
+
+ node = result.value.statements.body.first.rescue_clause
+ assert_kind_of ErrorRecoveryNode, node.reference
+ assert_nil node.reference.unexpected
+ end
+ end
+end
diff --git a/test/prism/result/named_capture_test.rb b/test/prism/result/named_capture_test.rb
new file mode 100644
index 0000000000..36cb910899
--- /dev/null
+++ b/test/prism/result/named_capture_test.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require_relative "../test_helper"
+
+module Prism
+ class NamedCaptureTest < TestCase
+ def test_hex_escapes
+ assert_equal :😀, parse_name("\\xf0\\x9f\\x98\\x80")
+ end
+
+ def test_unicode_escape
+ assert_equal :し, parse_name("\\u3057")
+ end
+
+ def test_unicode_escapes_bracess
+ assert_equal :😀, parse_name("\\u{1f600}")
+ end
+
+ def test_octal_escapes
+ assert_equal :😀, parse_name("\\xf0\\x9f\\x98\\200")
+ end
+
+ private
+
+ def parse_name(content)
+ Prism.parse_statement("/(?<#{content}>)/ =~ ''").targets.first.name
+ end
+ end
+end
diff --git a/test/prism/result/numeric_value_test.rb b/test/prism/result/numeric_value_test.rb
index 5c89230a1f..0207fa6a86 100644
--- a/test/prism/result/numeric_value_test.rb
+++ b/test/prism/result/numeric_value_test.rb
@@ -6,16 +6,27 @@ module Prism
class NumericValueTest < TestCase
def test_numeric_value
assert_equal 123, Prism.parse_statement("123").value
+ assert_equal 123, Prism.parse_statement("1_23").value
assert_equal 3.14, Prism.parse_statement("3.14").value
+ assert_equal 3.14, Prism.parse_statement("3.1_4").value
assert_equal 42i, Prism.parse_statement("42i").value
+ assert_equal 42i, Prism.parse_statement("4_2i").value
assert_equal 42.1ri, Prism.parse_statement("42.1ri").value
+ assert_equal 42.1ri, Prism.parse_statement("42.1_0ri").value
assert_equal 3.14i, Prism.parse_statement("3.14i").value
+ assert_equal 3.14i, Prism.parse_statement("3.1_4i").value
assert_equal 42r, Prism.parse_statement("42r").value
+ assert_equal 42r, Prism.parse_statement("4_2r").value
assert_equal 0.5r, Prism.parse_statement("0.5r").value
+ assert_equal 0.5r, Prism.parse_statement("0.5_0r").value
assert_equal 42ri, Prism.parse_statement("42ri").value
+ assert_equal 42ri, Prism.parse_statement("4_2ri").value
assert_equal 0.5ri, Prism.parse_statement("0.5ri").value
+ assert_equal 0.5ri, Prism.parse_statement("0.5_0ri").value
assert_equal 0xFFr, Prism.parse_statement("0xFFr").value
+ assert_equal 0xFFr, Prism.parse_statement("0xF_Fr").value
assert_equal 0xFFri, Prism.parse_statement("0xFFri").value
+ assert_equal 0xFFri, Prism.parse_statement("0xF_Fri").value
end
end
end
diff --git a/test/prism/result/overlap_test.rb b/test/prism/result/overlap_test.rb
index 155bc870d3..d605eeca44 100644
--- a/test/prism/result/overlap_test.rb
+++ b/test/prism/result/overlap_test.rb
@@ -33,8 +33,13 @@ module Prism
queue << child
if compare
- assert_operator current.location.start_offset, :<=, child.location.start_offset
- assert_operator current.location.end_offset, :>=, child.location.end_offset
+ assert_operator current.location.start_offset, :<=, child.location.start_offset, -> {
+ "[#{fixture.full_path}] Parent node #{current.class} at #{current.location} does not start before child node #{child.class} at #{child.location}"
+ }
+
+ assert_operator current.location.end_offset, :>=, child.location.end_offset, -> {
+ "[#{fixture.full_path}] Parent node #{current.class} at #{current.location} does not end after child node #{child.class} at #{child.location}"
+ }
end
end
end
diff --git a/test/prism/result/source_location_test.rb b/test/prism/result/source_location_test.rb
index 7bdc707658..a8d27b95a8 100644
--- a/test/prism/result/source_location_test.rb
+++ b/test/prism/result/source_location_test.rb
@@ -13,7 +13,7 @@ module Prism
end
def test_AlternationPatternNode
- assert_location(AlternationPatternNode, "foo => bar | baz", 7...16, &:pattern)
+ assert_location(AlternationPatternNode, "foo => 0 | 1", 7...12, &:pattern)
end
def test_AndNode
@@ -650,6 +650,10 @@ module Prism
assert_location(NilNode, "nil")
end
+ def test_NoBlockParameterNode
+ assert_location(NoBlockParameterNode, "def foo(&nil); end", 8...12) { |node| node.parameters.block }
+ end
+
def test_NoKeywordsParameterNode
assert_location(NoKeywordsParameterNode, "def foo(**nil); end", 8...13) { |node| node.parameters.keyword_rest }
end
@@ -920,7 +924,7 @@ module Prism
end
def test_all_tested
- expected = Prism.constants.grep(/.Node$/).sort - %i[MissingNode ProgramNode]
+ expected = Prism.constants.grep(/.Node$/).sort - %i[ErrorRecoveryNode ProgramNode]
actual = SourceLocationTest.instance_methods(false).grep(/.Node$/).map { |name| name[5..].to_sym }.sort
assert_equal expected, actual
end
@@ -935,16 +939,16 @@ module Prism
node = yield node if block_given?
if expected.begin == 0
- assert_equal 0, node.location.start_column
+ assert_equal 0, node.location.start_column, "#{kind} start_column"
end
if expected.end == source.length
- assert_equal source.split("\n").last.length, node.location.end_column
+ assert_equal source.split("\n").last.length, node.location.end_column, "#{kind} end_column"
end
assert_kind_of kind, node
- assert_equal expected.begin, node.location.start_offset
- assert_equal expected.end, node.location.end_offset
+ assert_equal expected.begin, node.location.start_offset, "#{kind} start_offset"
+ assert_equal expected.end, node.location.end_offset, "#{kind} end_offset"
end
end
end
diff --git a/test/prism/result/string_test.rb b/test/prism/result/string_test.rb
new file mode 100644
index 0000000000..48c7f592eb
--- /dev/null
+++ b/test/prism/result/string_test.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require_relative "../test_helper"
+
+module Prism
+ class StringTest < TestCase
+ def test_regular_expression_node_unescaped_frozen
+ node = Prism.parse_statement("/foo/")
+ assert_predicate node.unescaped, :frozen?
+ end
+
+ def test_source_file_node_filepath_frozen
+ node = Prism.parse_statement("__FILE__")
+ assert_predicate node.filepath, :frozen?
+ end
+
+ def test_string_node_unescaped_frozen
+ node = Prism.parse_statement('"foo"')
+ assert_predicate node.unescaped, :frozen?
+ end
+
+ def test_symbol_node_unescaped_frozen
+ node = Prism.parse_statement(":foo")
+ assert_predicate node.unescaped, :frozen?
+ end
+
+ def test_xstring_node_unescaped_frozen
+ node = Prism.parse_statement("`foo`")
+ assert_predicate node.unescaped, :frozen?
+ end
+ end
+end
diff --git a/test/prism/result/warnings_test.rb b/test/prism/result/warnings_test.rb
index aeac7f80e6..27f1119b98 100644
--- a/test/prism/result/warnings_test.rb
+++ b/test/prism/result/warnings_test.rb
@@ -22,6 +22,15 @@ module Prism
assert_warning("a /b/", "wrap regexp in parentheses")
end
+ def test_ambiguous_ampersand
+ assert_warning("a &b", "argument prefix")
+ assert_warning("a &:+", "argument prefix")
+
+ refute_warning("a &:b")
+ refute_warning("a &:'b'")
+ refute_warning("a &:\"b\"")
+ end
+
def test_binary_operator
[
[:**, "argument prefix"],
@@ -115,6 +124,9 @@ module Prism
assert_warning("case 1; when 2\n end", "mismatched indentations at 'end' with 'case'")
assert_warning("case 1; in 2\n end", "mismatched indentations at 'end' with 'case'")
+ assert_warning(" case 1\nwhen 2\n end", "mismatched indentations at 'when' with 'case'")
+ refute_warning("case 1\n when 2\n when 3\nend") # case/when allows more indentation
+
assert_warning("-> {\n }", "mismatched indentations at '}' with '->'")
assert_warning("-> do\n end", "mismatched indentations at 'end' with '->'")
assert_warning("-> do\n rescue\nend", "mismatched indentations at 'rescue' with '->'")
@@ -174,6 +186,10 @@ module Prism
assert_warning("if true\nelsif\nfalse; end", "end of line")
end
+ def test_numbered_reference
+ assert_warning("_ = _ = $999999999999999999999", "too big for a number variable, always nil")
+ end
+
def test_shareable_constant_value
assert_warning("foo # shareable_constant_value: none", "ignored")
assert_warning("\v # shareable_constant_value: none", "ignored")
@@ -214,6 +230,8 @@ module Prism
refute_warning("foo = 1", compare: false, command_line: "e")
refute_warning("foo = 1", compare: false, scopes: [[]])
+ refute_warning("foo(bar = 1)")
+
assert_warning("def foo; bar = 1; end", "unused")
assert_warning("def foo; bar, = 1; end", "unused")
@@ -243,6 +261,25 @@ module Prism
refute_warning("def foo; bar = 1; tap { bar }; end")
refute_warning("def foo; bar = 1; tap { baz = bar; baz }; end")
+
+ refute_warning("def foo; bar = 1; end", line: -2, compare: false)
+ end
+
+ def test_unused_local_variable_or_assign_with_begin_node
+ assert_warning(<<~RUBY, "assigned but unused variable - foo", compare: false)
+ var ||= begin
+ foo = bar
+ baz
+ end
+ RUBY
+
+ assert_warning(<<~RUBY, "assigned but unused variable - foo", compare: false)
+ foo = false
+ var ||= begin
+ foo = true
+ bar
+ end
+ RUBY
end
def test_void_statements
@@ -321,42 +358,49 @@ module Prism
assert_warning("tap { redo; foo }", "statement not reached")
end
- def test_shebang_ending_with_carriage_return
- msg = "shebang line ending with \\r may cause problems"
-
- assert_warning(<<~RUBY, msg, compare: false)
- #!ruby\r
- p(123)
- RUBY
-
- assert_warning(<<~RUBY, msg, compare: false)
- #!ruby \r
- p(123)
- RUBY
-
- assert_warning(<<~RUBY, msg, compare: false)
- #!ruby -Eutf-8\r
- p(123)
- RUBY
-
- # Used with the `-x` object, to ignore the script up until the first shebang that mentioned "ruby".
- assert_warning(<<~SCRIPT, msg, compare: false)
- #!/usr/bin/env bash
- # Some initial shell script or other content
- # that Ruby should ignore
- echo "This is shell script part"
- exit 0
-
- #! /usr/bin/env ruby -Eutf-8\r
- # Ruby script starts here
- puts "Hello from Ruby!"
- SCRIPT
-
- refute_warning("#ruby not_a_shebang\r\n", compare: false)
-
- # CRuby doesn't emit the warning if a malformed file only has `\r` and not `\n`.
- # https://bugs.ruby-lang.org/issues/20700
- refute_warning("#!ruby\r", compare: false)
+ if windows?
+ def test_shebang_ending_with_carriage_return
+ refute_warning("#!ruby\r\np(123)\n", compare: false)
+ end
+ else
+ def test_shebang_ending_with_carriage_return
+ msg = "shebang line ending with \\r may cause problems"
+
+ assert_warning(<<~RUBY, msg, compare: false, main_script: true)
+ #!ruby\r
+ p(123)
+ RUBY
+
+ assert_warning(<<~RUBY, msg, compare: false, main_script: true)
+ #!ruby \r
+ p(123)
+ RUBY
+
+ assert_warning(<<~RUBY, msg, compare: false, main_script: true)
+ #!ruby -Eutf-8\r
+ p(123)
+ RUBY
+
+ # Used with the `-x` object, to ignore the script up until the first
+ # shebang that mentioned "ruby".
+ assert_warning(<<~SCRIPT, msg, compare: false, main_script: true)
+ #!/usr/bin/env bash
+ # Some initial shell script or other content
+ # that Ruby should ignore
+ echo "This is shell script part"
+ exit 0
+
+ #! /usr/bin/env ruby -Eutf-8\r
+ # Ruby script starts here
+ puts "Hello from Ruby!"
+ SCRIPT
+
+ refute_warning("#ruby not_a_shebang\r\n", compare: false, main_script: true)
+
+ # CRuby doesn't emit the warning if a malformed file only has `\r` and
+ # not `\n`. https://bugs.ruby-lang.org/issues/20700.
+ refute_warning("#!ruby\r", compare: false, main_script: true)
+ end
end
def test_warnings_verbosity
@@ -371,8 +415,8 @@ module Prism
private
- def assert_warning(source, *messages, compare: true)
- warnings = Prism.parse(source).warnings
+ def assert_warning(source, *messages, compare: true, **options)
+ warnings = Prism.parse(source, **options).warnings
assert_equal messages.length, warnings.length, "Expected #{messages.length} warning(s) in #{source.inspect}, got #{warnings.map(&:message).inspect}"
warnings.zip(messages).each do |warning, message|