File: clone_spec.rb

package info (click to toggle)
ruby-regexp-parser 2.11.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,092 kB
  • sloc: ruby: 6,891; makefile: 6; sh: 3
file content (192 lines) | stat: -rw-r--r-- 5,717 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe('Expression::Base#clone') do
  specify('Base#clone') do
    root = RP.parse(/^(?i:a)b+$/i)
    copy = root.clone

    expect(copy.to_s).to eq root.to_s

    expect(root).not_to equal copy
    expect(root.text).to eq copy.text
    expect(root.text).not_to equal copy.text

    root_1 = root[1]
    copy_1 = copy[1]

    expect(root_1.options).to eq copy_1.options
    expect(root_1.options).not_to equal copy_1.options

    expect(root_1.parent).to eq root
    expect(root_1.parent).not_to equal copy
    expect(copy_1.parent).to eq copy
    expect(copy_1.parent).not_to equal root

    root_2 = root[2]
    copy_2 = copy[2]

    expect(root_2).to be_quantified
    expect(copy_2).to be_quantified
    expect(root_2.quantifier.text).to eq copy_2.quantifier.text
    expect(root_2.quantifier.text).not_to equal copy_2.quantifier.text
    expect(root_2.quantifier).not_to equal copy_2.quantifier

    # regression test
    expect { root_2.clone }.not_to(change { root_2.quantifier.object_id })
    expect { root_2.clone }.not_to(change { root_2.quantifier.text.object_id })
  end

  specify('Base#clone causes no shared state') do
    root = RP.parse(regexp_with_all_features)
    copy = root.clone
    shared = Leto.shared_mutables(root, copy)
    expect(shared).to be_empty, "found shared mutables:\n#{shared.join("\n")}"
  end

  specify('Subexpression#clone') do
    root = RP.parse(/^a(b([cde])f)g$/)
    copy = root.clone

    expect(copy.to_s).to eq root.to_s

    expect(root).to respond_to(:expressions)
    expect(copy).to respond_to(:expressions)
    expect(root.expressions).not_to equal copy.expressions
    copy.expressions.each_with_index do |exp, index|
      expect(root[index]).not_to equal exp
    end
    copy[2].each_with_index do |exp, index|
      expect(root[2][index]).not_to equal exp
    end

    # regression test
    expect { root.clone }.not_to(change { root.expressions.object_id })
  end

  specify('Group::Named#clone') do
    root = RP.parse('^(?<somename>a)+bc$')
    copy = root.clone

    expect(copy.to_s).to eq root.to_s

    root_1 = root[1]
    copy_1 = copy[1]

    expect(root_1.name).to eq copy_1.name
    expect(root_1.name).not_to equal copy_1.name
    expect(root_1.text).to eq copy_1.text
    expect(root_1.expressions).not_to equal copy_1.expressions
    copy_1.expressions.each_with_index do |exp, index|
      expect(root_1[index]).not_to equal exp
    end

    # regression test
    expect { root_1.clone }.not_to(change { root_1.name.object_id })
  end

  specify('Group::Options#clone') do
    root = RP.parse('foo(?i)bar')
    copy = root.clone

    expect(copy.to_s).to eq root.to_s

    root_1 = root[1]
    copy_1 = copy[1]

    expect(root_1.option_changes).to eq copy_1.option_changes
    expect(root_1.option_changes).not_to equal copy_1.option_changes

    # regression test
    expect { root_1.clone }.not_to(change { root_1.option_changes.object_id })
  end

  specify('Backreference::Base#clone') do
    root = RP.parse('(foo)\1')
    copy = root.clone

    expect(copy.to_s).to eq root.to_s

    root_1 = root[1]
    copy_1 = copy[1]

    expect(root_1.referenced_expression).to eq copy_1.referenced_expression
    expect(root_1.referenced_expression.to_s).to eq copy_1.referenced_expression.to_s
    expect(root_1.referenced_expression).not_to equal copy_1.referenced_expression

    # regression test
    expect { root_1.clone }.not_to(change { root_1.referenced_expression.object_id })
  end

  specify('Backreference::Base#clone works for recursive subexp calls') do
    root = RP.parse('a|b\g<0>')
    copy = root.clone

    expect(copy.to_s).to eq root.to_s

    root_call = root.dig(0, 1, 1)
    copy_call = copy.dig(0, 1, 1)

    expect(root).to eq copy
    expect(root).not_to equal copy

    expect(root_call).to eq copy_call
    expect(root_call).not_to equal copy_call

    expect(root_call.referenced_expression).not_to be_nil
    expect(root_call.referenced_expression.object_id).to eq root.object_id

    expect(copy_call.referenced_expression).not_to be_nil

    # Mapping the reference to the cloned referenced_expression would
    # probably require a context or 2-way bindings in the tree. Maybe later ...
    # expect(copy_call.referenced_expression.object_id).to eq copy.object_id
  end

  specify('Sequence#clone') do
    root = RP.parse(/(a|b)/)
    copy = root.clone

    # regression test
    expect(copy.to_s).to eq root.to_s

    root_seq_op = root[0][0]
    copy_seq_op = copy[0][0]
    root_seq_1 = root[0][0][0]
    copy_seq_1 = copy[0][0][0]

    expect(root_seq_op).not_to equal copy_seq_op
    expect(root_seq_1).not_to equal copy_seq_1
    copy_seq_1.expressions.each_with_index do |exp, index|
      expect(root_seq_1[index]).not_to equal exp
    end
  end

  describe('Base#unquantified_clone') do
    it 'produces a clone' do
      root = RP.parse(/^a(b([cde])f)g$/)
      copy = root.unquantified_clone

      expect(copy.to_s).to eq root.to_s

      expect(copy).not_to equal root
    end

    it 'does not carry over the callee quantifier' do
      expect(RP.parse(/a{3}/)[0]).to be_quantified
      expect(RP.parse(/a{3}/)[0].unquantified_clone).not_to be_quantified

      expect(RP.parse(/[a]{3}/)[0]).to be_quantified
      expect(RP.parse(/[a]{3}/)[0].unquantified_clone).not_to be_quantified

      expect(RP.parse(/(a|b){3}/)[0]).to be_quantified
      expect(RP.parse(/(a|b){3}/)[0].unquantified_clone).not_to be_quantified
    end

    it 'keeps quantifiers of callee children' do
      expect(RP.parse(/(a{3}){3}/)[0][0]).to be_quantified
      expect(RP.parse(/(a{3}){3}/)[0].unquantified_clone[0]).to be_quantified
    end
  end
end