2023-09-05 17:22:57 +03:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require_relative "test_helper"
|
|
|
|
|
2023-09-27 19:24:48 +03:00
|
|
|
module Prism
|
2023-09-06 17:30:47 +03:00
|
|
|
class PatternTest < TestCase
|
2023-09-05 17:22:57 +03:00
|
|
|
def test_invalid_syntax
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", "<>") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_invalid_constant
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", "Foo") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_invalid_nested_constant
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", "Foo::Bar") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_regexp_with_interpolation
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", "/\#{foo}/") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_string_with_interpolation
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", '"#{foo}"') }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_symbol_with_interpolation
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", ":\"\#{foo}\"") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_invalid_node
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", "IntegerNode[^foo]") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_self
|
2023-09-06 17:30:47 +03:00
|
|
|
assert_raise(Pattern::CompilationError) { scan("", "self") }
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_array_pattern_no_constant
|
|
|
|
results = scan("1 + 2", "[IntegerNode]")
|
|
|
|
|
|
|
|
assert_equal 1, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_array_pattern
|
2023-10-01 13:34:55 +03:00
|
|
|
results = scan("1 + 2", "CallNode[name: :+, receiver: IntegerNode, arguments: [IntegerNode]]")
|
2023-09-05 17:22:57 +03:00
|
|
|
|
|
|
|
assert_equal 1, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_alternation_pattern
|
|
|
|
results = scan("Foo + Bar + 1", "ConstantReadNode | IntegerNode")
|
|
|
|
|
|
|
|
assert_equal 3, results.length
|
|
|
|
assert_equal 1, results.grep(IntegerNode).first.value
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_constant_read_node
|
|
|
|
results = scan("Foo + Bar + Baz", "ConstantReadNode")
|
|
|
|
|
|
|
|
assert_equal 3, results.length
|
|
|
|
assert_equal %w[Bar Baz Foo], results.map(&:slice).sort
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_object_const
|
|
|
|
results = scan("1 + 2 + 3", "IntegerNode[]")
|
|
|
|
|
|
|
|
assert_equal 3, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_constant_path
|
2023-09-27 19:24:48 +03:00
|
|
|
results = scan("Foo + Bar + Baz", "Prism::ConstantReadNode")
|
2023-09-05 17:22:57 +03:00
|
|
|
|
|
|
|
assert_equal 3, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_hash_pattern_no_constant
|
2023-10-01 13:34:55 +03:00
|
|
|
results = scan("Foo + Bar + Baz", "{ name: :+ }")
|
2023-09-05 17:22:57 +03:00
|
|
|
|
|
|
|
assert_equal 2, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_hash_pattern_regexp
|
|
|
|
results = scan("Foo + Bar + Baz", "{ name: /^[[:punct:]]$/ }")
|
|
|
|
|
|
|
|
assert_equal 2, results.length
|
2023-09-27 19:24:48 +03:00
|
|
|
assert_equal ["Prism::CallNode"], results.map { |node| node.class.name }.uniq
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_nil
|
|
|
|
results = scan("foo", "{ receiver: nil }")
|
|
|
|
|
|
|
|
assert_equal 1, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_regexp_options
|
|
|
|
results = scan("@foo + @bar + @baz", "InstanceVariableReadNode[name: /^@B/i]")
|
|
|
|
|
|
|
|
assert_equal 2, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_string_empty
|
|
|
|
results = scan("", "''")
|
|
|
|
|
|
|
|
assert_empty results
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_symbol_empty
|
|
|
|
results = scan("", ":''")
|
|
|
|
|
|
|
|
assert_empty results
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_symbol_plain
|
|
|
|
results = scan("@foo", "{ name: :\"@foo\" }")
|
|
|
|
|
|
|
|
assert_equal 1, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_symbol
|
|
|
|
results = scan("@foo", "{ name: :@foo }")
|
|
|
|
|
|
|
|
assert_equal 1, results.length
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def scan(source, query)
|
2023-09-27 19:24:48 +03:00
|
|
|
Prism::Pattern.new(query).scan(Prism.parse(source).value).to_a
|
2023-09-05 17:22:57 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|