File: tree_regexp_spec.rb

package info (click to toggle)
ruby-cucumber-expressions 8.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 248 kB
  • sloc: ruby: 1,594; sh: 15; makefile: 4
file content (133 lines) | stat: -rw-r--r-- 4,830 bytes parent folder | download
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
133
require 'cucumber/cucumber_expressions/tree_regexp'

module Cucumber
  module CucumberExpressions
    describe TreeRegexp do
      it 'exposes group source' do
        tr = TreeRegexp.new(/(a(?:b)?)(c)/)
        expect(tr.group_builder.children.map{|gb| gb.source}).to eq(['a(?:b)?', 'c'])
      end

      it 'builds tree' do
        tr = TreeRegexp.new(/(a(?:b)?)(c)/)
        group = tr.match('ac')
        expect(group.value).to eq('ac')
        expect(group.children[0].value).to eq('a')
        expect(group.children[0].children).to eq([])
        expect(group.children[1].value).to eq('c')
      end

      it 'ignores `?:` as a non-capturing group' do
        tr = TreeRegexp.new(/a(?:b)(c)/)
        group = tr.match('abc')
        expect(group.value).to eq('abc')
        expect(group.children.length).to eq 1
      end

      it 'ignores `?!` as a non-capturing group' do
        tr = TreeRegexp.new(/a(?!b)(.+)/)
        group = tr.match('aBc')
        expect(group.value).to eq('aBc')
        expect(group.children.length).to eq 1
      end

      it 'ignores `?=` as a non-capturing group' do
        tr = TreeRegexp.new(/a(?=b)(.+)$/)
        group = tr.match('abc')
        expect(group.value).to eq('abc')
        expect(group.children[0].value).to eq('bc')
        expect(group.children.length).to eq 1
      end

      it 'ignores `?<=` as a non-capturing group' do
        tr = TreeRegexp.new(/a(.+)(?<=c)$/)
        group = tr.match('abc')
        expect(group.value).to eq('abc')
        expect(group.children[0].value).to eq('bc')
        expect(group.children.length).to eq 1
      end

      it 'ignores `?<!` as a non-capturing group' do
        tr = TreeRegexp.new(/a(.+)(?<!b)$/)
        group = tr.match('abc')
        expect(group.value).to eq('abc')
        expect(group.children[0].value).to eq('bc')
        expect(group.children.length).to eq 1
      end

      it 'matches optional group' do
        tr = TreeRegexp.new(/^Something( with an optional argument)?/)
        group = tr.match('Something')
        expect(group.children[0].value).to eq(nil)
      end

      it 'matches nested groups' do
        tr = TreeRegexp.new(/^A (\d+) thick line from ((\d+),\s*(\d+),\s*(\d+)) to ((\d+),\s*(\d+),\s*(\d+))/)
        group = tr.match('A 5 thick line from 10,20,30 to 40,50,60')

        expect(group.children[0].value).to eq('5')
        expect(group.children[1].value).to eq('10,20,30')
        expect(group.children[1].children[0].value).to eq('10')
        expect(group.children[1].children[1].value).to eq('20')
        expect(group.children[1].children[2].value).to eq('30')
        expect(group.children[2].value).to eq('40,50,60')
        expect(group.children[2].children[0].value).to eq('40')
        expect(group.children[2].children[1].value).to eq('50')
        expect(group.children[2].children[2].value).to eq('60')
      end

      it 'detects multiple non capturing groups' do
        tr = TreeRegexp.new(/(?:a)(:b)(\?c)(d)/)
        group = tr.match("a:b?cd")
        expect(group.children.length).to eq(3)
      end

      it 'works with escaped backslash' do
        tr = TreeRegexp.new(/foo\\(bar|baz)/)
        group = tr.match("foo\\bar")
        expect(group.children.length).to eq(1)
      end

      it 'works with escaped slash' do
        tr = TreeRegexp.new(/^I go to '\/(.+)'$/)
        group = tr.match("I go to '/hello'")
        expect(group.children.length).to eq(1)
      end

      it 'works with digit and word' do
        tr = TreeRegexp.new(/^(\d) (\w+)$/)
        group = tr.match("2 you")
        expect(group.children.length).to eq(2)
      end

      it 'captures non capturing groups with capturing groups inside' do
        tr = TreeRegexp.new(/the stdout(?: from "(.*?)")?/)
        group = tr.match("the stdout")
        expect(group.value).to eq("the stdout")
        expect(group.children[0].value).to eq(nil)
        expect(group.children.length).to eq(1)
      end

      it 'works with flags' do
        tr = TreeRegexp.new(/HELLO/i)
        group = tr.match("hello")
        expect(group.value).to eq("hello")
      end

      it('does not consider parenthesis in character class as group') do
        tr = TreeRegexp.new(/^drawings: ([A-Z_, ()]+)$/)
        group = tr.match('drawings: ONE, TWO(ABC)')
        expect(group.value).to eq('drawings: ONE, TWO(ABC)')
        expect(group.children[0].value).to eq('ONE, TWO(ABC)')
        expect(group.children.length).to eq(1)
      end

      it 'throws an error when there are named capture groups because they are buggy in Ruby' do
        # https://github.com/cucumber/cucumber/issues/329
        expect {
          TreeRegexp.new(/^I am a person( named "(?<first_name>.+) (?<last_name>.+)")?$/)
        }.to raise_error(/Named capture groups are not supported/)
      end
    end
  end
end