summaryrefslogtreecommitdiff
path: root/test/prism/pattern_test.rb
blob: e0aa079cb9cc5fa6aba4cb23682e5c42b6288d27 (plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
# frozen_string_literal: true

require_relative "test_helper"

module Prism
  class PatternTest < TestCase
    def test_invalid_syntax
      assert_raise(Pattern::CompilationError) { scan("", "<>") }
    end

    def test_invalid_constant
      assert_raise(Pattern::CompilationError) { scan("", "Foo") }
    end

    def test_invalid_nested_constant
      assert_raise(Pattern::CompilationError) { scan("", "Foo::Bar") }
    end

    def test_regexp_with_interpolation
      assert_raise(Pattern::CompilationError) { scan("", "/\#{foo}/") }
    end

    def test_string_with_interpolation
      assert_raise(Pattern::CompilationError) { scan("", '"#{foo}"') }
    end

    def test_symbol_with_interpolation
      assert_raise(Pattern::CompilationError) { scan("", ":\"\#{foo}\"") }
    end

    def test_invalid_node
      assert_raise(Pattern::CompilationError) { scan("", "IntegerNode[^foo]") }
    end

    def test_self
      assert_raise(Pattern::CompilationError) { scan("", "self") }
    end

    def test_array_pattern_no_constant
      results = scan("1 + 2", "[IntegerNode]")

      assert_equal 1, results.length
    end

    def test_array_pattern
      results = scan("1 + 2", "CallNode[name: :+, receiver: IntegerNode, arguments: [IntegerNode]]")

      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
      results = scan("Foo + Bar + Baz", "Prism::ConstantReadNode")

      assert_equal 3, results.length
    end

    def test_hash_pattern_no_constant
      results = scan("Foo + Bar + Baz", "{ name: :+ }")

      assert_equal 2, results.length
    end

    def test_hash_pattern_regexp
      results = scan("Foo + Bar + Baz", "{ name: /^[[:punct:]]$/ }")

      assert_equal 2, results.length
      assert_equal ["Prism::CallNode"], results.map { |node| node.class.name }.uniq
    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)
      Prism::Pattern.new(query).scan(Prism.parse(source).value).to_a
    end
  end
end