synvert-core 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,131 +1,158 @@
1
1
  require 'spec_helper'
2
2
 
3
+ def assert_parser(source)
4
+ expect(parser.parse(source).to_s).to eq source
5
+ end
6
+
3
7
  module Synvert::Core::NodeQuery
4
8
  RSpec.describe Parser do
5
9
  let(:parser) { described_class.new }
6
10
 
7
- def assert_parser(source)
8
- expect(parser.parse(source).to_s).to eq source
9
- end
11
+ describe '#toString' do
12
+ it 'parses one selector' do
13
+ source = '.send[message=:create]'
14
+ assert_parser(source)
15
+ end
10
16
 
11
- it 'parses one selector' do
12
- source = '.send[message=:create]'
13
- assert_parser(source)
14
- end
17
+ it 'parses two selectors' do
18
+ source = '.class[name=Synvert] .def[name="foobar"]'
19
+ assert_parser(source)
20
+ end
15
21
 
16
- it 'parses two selectors' do
17
- source = '.class[name=Synvert] .def[name="foobar"]'
18
- assert_parser(source)
19
- end
22
+ it 'parses three selectors' do
23
+ source = '.class[name=Synvert] .def[name="foobar"] .send[message=create]'
24
+ assert_parser(source)
25
+ end
20
26
 
21
- it 'parses three selectors' do
22
- source = '.class[name=Synvert] .def[name="foobar"] .send[message=create]'
23
- assert_parser(source)
24
- end
27
+ it 'parses child selector' do
28
+ source = '.class[name=Synvert] > .def[name="foobar"]'
29
+ assert_parser(source)
30
+ end
25
31
 
26
- it 'parses child selector' do
27
- source = '.class[name=Synvert] > .def[name="foobar"]'
28
- assert_parser(source)
29
- end
32
+ it 'parses scope' do
33
+ source = '.block <body> > .send'
34
+ assert_parser(source)
35
+ end
30
36
 
31
- it 'parses :first-child' do
32
- source = '.class .def:first-child'
33
- assert_parser(source)
34
- end
37
+ it 'parses :first-child' do
38
+ source = '.class .def:first-child'
39
+ assert_parser(source)
40
+ end
35
41
 
36
- it 'parses :last-child' do
37
- source = '.class .def:last-child'
38
- assert_parser(source)
39
- end
42
+ it 'parses :last-child' do
43
+ source = '.class .def:last-child'
44
+ assert_parser(source)
45
+ end
40
46
 
41
- it 'parses :nth-child(n)' do
42
- source = '.class .def:nth-child(2)'
43
- assert_parser(source)
44
- end
47
+ it 'parses :nth-child(n)' do
48
+ source = '.class .def:nth-child(2)'
49
+ assert_parser(source)
50
+ end
45
51
 
46
- it 'parses :nth-last-child(n)' do
47
- source = '.class .def:nth-last-child(2)'
48
- assert_parser(source)
49
- end
52
+ it 'parses :nth-last-child(n)' do
53
+ source = '.class .def:nth-last-child(2)'
54
+ assert_parser(source)
55
+ end
50
56
 
51
- it 'parses :has selector' do
52
- source = '.class:has(> .def)'
53
- assert_parser(source)
54
- end
57
+ it 'parses :has selector' do
58
+ source = '.class:has(> .def)'
59
+ assert_parser(source)
60
+ end
55
61
 
56
- it 'parses :not_has selector' do
57
- source = '.class:not_has(> .def)'
58
- assert_parser(source)
59
- end
62
+ it 'parses :not_has selector' do
63
+ source = '.class:not_has(> .def)'
64
+ assert_parser(source)
65
+ end
60
66
 
61
- it 'parses multiple attributes' do
62
- source = '.send[receiver=nil][message=:create]'
63
- assert_parser(source)
64
- end
67
+ it 'parses root :has selector' do
68
+ source = ':has(.def)'
69
+ assert_parser(source)
70
+ end
65
71
 
66
- it 'parses nested attributes' do
67
- source = '.send[receiver.message=:create]'
68
- assert_parser(source)
69
- end
72
+ it 'parses multiple attributes' do
73
+ source = '.send[receiver=nil][message=:create]'
74
+ assert_parser(source)
75
+ end
70
76
 
71
- it 'parses selector value' do
72
- source = '.send[receiver=.send[message=:create]]'
73
- assert_parser(source)
74
- end
77
+ it 'parses nested attributes' do
78
+ source = '.send[receiver.message=:create]'
79
+ assert_parser(source)
80
+ end
75
81
 
76
- it 'parses not equal operator' do
77
- source = '.send[receiver=.send[message!=:create]]'
78
- assert_parser(source)
79
- end
82
+ it 'parses selector value' do
83
+ source = '.send[receiver=.send[message=:create]]'
84
+ assert_parser(source)
85
+ end
80
86
 
81
- it 'parses greater than operator' do
82
- source = '.send[receiver=.send[arguments.size>1]]'
83
- assert_parser(source)
84
- end
87
+ it 'parses start with operator' do
88
+ source = '.def[name^=synvert]'
89
+ assert_parser(source)
90
+ end
85
91
 
86
- it 'parses greater than or equal operator' do
87
- source = '.send[receiver=.send[arguments.size>=1]]'
88
- assert_parser(source)
89
- end
92
+ it 'parses end with operator' do
93
+ source = '.def[name$=synvert]'
94
+ assert_parser(source)
95
+ end
90
96
 
91
- it 'parses less than operator' do
92
- source = '.send[receiver=.send[arguments.size<1]]'
93
- assert_parser(source)
94
- end
97
+ it 'parses contain operator' do
98
+ source = '.def[name*=synvert]'
99
+ assert_parser(source)
100
+ end
95
101
 
96
- it 'parses less than or equal operator' do
97
- source = '.send[receiver=.send[arguments.size<=1]]'
98
- assert_parser(source)
99
- end
102
+ it 'parses not equal operator' do
103
+ source = '.send[receiver=.send[message!=:create]]'
104
+ assert_parser(source)
105
+ end
100
106
 
101
- it 'parses in operator' do
102
- source = '.def[name in (foo, bar)]'
103
- assert_parser(source)
104
- end
107
+ it 'parses greater than operator' do
108
+ source = '.send[receiver=.send[arguments.size>1]]'
109
+ assert_parser(source)
110
+ end
105
111
 
106
- it 'parses not_in operator' do
107
- source = '.def[name not in (foo, bar)]'
108
- assert_parser(source)
109
- end
112
+ it 'parses greater than or equal operator' do
113
+ source = '.send[receiver=.send[arguments.size>=1]]'
114
+ assert_parser(source)
115
+ end
110
116
 
111
- it 'parses includes operator' do
112
- source = '.def[arguments includes &block]'
113
- assert_parser(source)
114
- end
117
+ it 'parses less than operator' do
118
+ source = '.send[receiver=.send[arguments.size<1]]'
119
+ assert_parser(source)
120
+ end
115
121
 
116
- it 'parses empty string' do
117
- source = '.send[arguments.first=""]'
118
- assert_parser(source)
119
- end
122
+ it 'parses less than or equal operator' do
123
+ source = '.send[receiver=.send[arguments.size<=1]]'
124
+ assert_parser(source)
125
+ end
120
126
 
121
- it 'parses []=' do
122
- source = '.send[message=[]=]'
123
- assert_parser(source)
124
- end
127
+ it 'parses in operator' do
128
+ source = '.def[name in (foo bar)]'
129
+ assert_parser(source)
130
+ end
131
+
132
+ it 'parses not_in operator' do
133
+ source = '.def[name not in (foo bar)]'
134
+ assert_parser(source)
135
+ end
136
+
137
+ it 'parses includes operator' do
138
+ source = '.def[arguments includes &block]'
139
+ assert_parser(source)
140
+ end
125
141
 
126
- it 'parses :[]' do
127
- source = '.send[message=:[]]'
128
- assert_parser(source)
142
+ it 'parses empty string' do
143
+ source = '.send[arguments.first=""]'
144
+ assert_parser(source)
145
+ end
146
+
147
+ it 'parses []=' do
148
+ source = '.send[message=[]=]'
149
+ assert_parser(source)
150
+ end
151
+
152
+ it 'parses :[]' do
153
+ source = '.send[message=:[]]'
154
+ assert_parser(source)
155
+ end
129
156
  end
130
157
 
131
158
  describe '#query_nodes' do
@@ -142,15 +169,22 @@ module Synvert::Core::NodeQuery
142
169
 
143
170
  def foobar(a, b)
144
171
  { a: a, b: b }
145
- foo.merge(bar)
146
172
  arr[index]
147
173
  arr[index] = value
174
+ nil?
148
175
  call('')
149
176
  end
150
177
  end
151
178
  EOS
152
179
  }
153
180
 
181
+ let(:test_node) {
182
+ parse(<<~EOS)
183
+ RSpec.describe Synvert do
184
+ end
185
+ EOS
186
+ }
187
+
154
188
  it 'matches class node' do
155
189
  expression = parser.parse('.class[name=Synvert]')
156
190
  expect(expression.query_nodes(node)).to eq [node]
@@ -186,18 +220,33 @@ module Synvert::Core::NodeQuery
186
220
  expect(expression.query_nodes(node)).to eq [node.body[-2]]
187
221
  end
188
222
 
223
+ it 'matches start with' do
224
+ expression = parser.parse('.def[name^=foo]')
225
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.last]
226
+ end
227
+
228
+ it 'matches end with' do
229
+ expression = parser.parse('.def[name$=bar]')
230
+ expect(expression.query_nodes(node)).to eq [node.body.second, node.body.last]
231
+ end
232
+
233
+ it 'matches contain' do
234
+ expression = parser.parse('.def[name*=oob]')
235
+ expect(expression.query_nodes(node)).to eq [node.body.last]
236
+ end
237
+
189
238
  it 'matches not equal' do
190
239
  expression = parser.parse('.def[name!=foobar]')
191
240
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
192
241
  end
193
242
 
194
243
  it 'matches in' do
195
- expression = parser.parse('.def[name IN (foo, bar)]')
244
+ expression = parser.parse('.def[name IN (foo bar)]')
196
245
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
197
246
  end
198
247
 
199
248
  it 'matches not in' do
200
- expression = parser.parse('.def[name NOT IN (foo, bar)]')
249
+ expression = parser.parse('.def[name NOT IN (foo bar)]')
201
250
  expect(expression.query_nodes(node)).to eq [node.body.last]
202
251
  end
203
252
 
@@ -207,18 +256,18 @@ module Synvert::Core::NodeQuery
207
256
  end
208
257
 
209
258
  it 'matches equal array' do
210
- expression = parser.parse('.def[arguments=(a, b)]')
259
+ expression = parser.parse('.def[arguments=(a b)]')
211
260
  expect(expression.query_nodes(node)).to eq [node.body.last]
212
261
 
213
- expression = parser.parse('.def[arguments=(b, a)]')
262
+ expression = parser.parse('.def[arguments=(b a)]')
214
263
  expect(expression.query_nodes(node)).to eq []
215
264
  end
216
265
 
217
266
  it 'matches not equal array' do
218
- expression = parser.parse('.def[arguments!=(a, b)]')
267
+ expression = parser.parse('.def[arguments!=(a b)]')
219
268
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
220
269
 
221
- expression = parser.parse('.def[arguments!=(b, a)]')
270
+ expression = parser.parse('.def[arguments!=(b a)]')
222
271
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second, node.body.last]
223
272
  end
224
273
 
@@ -247,6 +296,19 @@ module Synvert::Core::NodeQuery
247
296
  expect(expression.query_nodes(node)).to eq [node.body.last]
248
297
  end
249
298
 
299
+ it 'matches goto scope' do
300
+ expression = parser.parse('.def <body> > .send[message=:create]')
301
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
302
+
303
+ expression = parser.parse('.def <body> .send[message=:create]')
304
+ expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
305
+ end
306
+
307
+ it 'matches multiple goto scope' do
308
+ expression = parser.parse('.block <caller.arguments> .const[name=Synvert]')
309
+ expect(expression.query_nodes(test_node)).to eq [test_node.caller.arguments.first]
310
+ end
311
+
250
312
  it 'matches has selector' do
251
313
  expression = parser.parse('.def:has(> .send[receiver=FactoryBot])')
252
314
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
@@ -257,12 +319,17 @@ module Synvert::Core::NodeQuery
257
319
  expect(expression.query_nodes(node)).to eq [node.body.last]
258
320
  end
259
321
 
322
+ it 'matches root has selector' do
323
+ expression = parser.parse(':has(.def[name=foobar])')
324
+ expect(expression.query_nodes(node)).to eq [node]
325
+ end
326
+
260
327
  it 'matches arguments.size' do
261
328
  expression = parser.parse('.def .send[arguments.size=2]')
262
329
  expect(expression.query_nodes(node)).to eq [
263
330
  node.body.first.body.last,
264
331
  node.body.second.body.last,
265
- node.body.third.body.fourth
332
+ node.body.third.body.third
266
333
  ]
267
334
  expression = parser.parse('.def .send[arguments.size>2]')
268
335
  expect(expression.query_nodes(node)).to eq []
@@ -270,12 +337,12 @@ module Synvert::Core::NodeQuery
270
337
  expect(expression.query_nodes(node)).to eq [
271
338
  node.body.first.body.last,
272
339
  node.body.second.body.last,
273
- node.body.third.body.fourth
340
+ node.body.third.body.third
274
341
  ]
275
342
  end
276
343
 
277
344
  it 'matches arguments' do
278
- expression = parser.parse('.send[arguments=[size=2][first=.sym][last=.hash]]')
345
+ expression = parser.parse('.send[arguments.size=2][arguments.first=.sym][arguments.last=.hash]')
279
346
  expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
280
347
  end
281
348
 
@@ -291,18 +358,18 @@ module Synvert::Core::NodeQuery
291
358
  expect(expression.query_nodes(node)).to eq node.body.last.body.first.children
292
359
  end
293
360
 
294
- it 'matches identifier' do
295
- expression = parser.parse('.send[receiver=foo][message=merge]')
296
- expect(expression.query_nodes(node)).to eq [node.body.last.body.second]
297
- end
298
-
299
361
  it 'matches []' do
300
362
  expression = parser.parse('.send[message=[]]')
301
- expect(expression.query_nodes(node)).to eq [node.body.last.body.third]
363
+ expect(expression.query_nodes(node)).to eq [node.body.last.body.second]
302
364
  end
303
365
 
304
366
  it 'matches []=' do
305
367
  expression = parser.parse('.send[message=:[]=]')
368
+ expect(expression.query_nodes(node)).to eq [node.body.last.body.third]
369
+ end
370
+
371
+ it 'matches nil and nil?' do
372
+ expression = parser.parse('.send[receiver=nil][message=nil?]')
306
373
  expect(expression.query_nodes(node)).to eq [node.body.last.body.fourth]
307
374
  end
308
375
 
@@ -71,7 +71,7 @@ module Synvert::Core
71
71
  condition = double
72
72
  block = proc {}
73
73
  expect(Rewriter::IfExistCondition).to receive(:new)
74
- .with(instance, type: 'send', message: 'create', &block)
74
+ .with(instance, { type: 'send', message: 'create' }, &block)
75
75
  .and_return(condition)
76
76
  expect(condition).to receive(:process)
77
77
  instance.if_exist_node(type: 'send', message: 'create', &block)
@@ -81,7 +81,7 @@ module Synvert::Core
81
81
  condition = double
82
82
  block = proc {}
83
83
  expect(Rewriter::UnlessExistCondition).to receive(:new)
84
- .with(instance, type: 'send', message: 'create', &block)
84
+ .with(instance, { type: 'send', message: 'create' }, &block)
85
85
  .and_return(condition)
86
86
  expect(condition).to receive(:process)
87
87
  instance.unless_exist_node(type: 'send', message: 'create', &block)
@@ -91,7 +91,7 @@ module Synvert::Core
91
91
  condition = double
92
92
  block = proc {}
93
93
  expect(Rewriter::IfOnlyExistCondition).to receive(:new)
94
- .with(instance, type: 'send', message: 'create', &block)
94
+ .with(instance, { type: 'send', message: 'create' }, &block)
95
95
  .and_return(condition)
96
96
  expect(condition).to receive(:process)
97
97
  instance.if_only_exist_node(type: 'send', message: 'create', &block)
@@ -59,15 +59,15 @@ module Synvert::Core
59
59
  end
60
60
 
61
61
  it 'raises ParseError' do
62
- scope = described_class.new(instance, 'hello world') {}
62
+ scope = described_class.new(instance, 'synvert') {}
63
63
  expect {
64
64
  scope.process
65
65
  }.to raise_error(NodeQuery::Compiler::ParseError)
66
66
 
67
- scope = described_class.new(instance, '.type[key IN value]') {}
67
+ scope = described_class.new(instance, '.send[receiver IN FactoryGirl]') {}
68
68
  expect {
69
69
  scope.process
70
- }.to raise_error(NodeQuery::Compiler::ParseError)
70
+ }.to raise_error(NodeQuery::Compiler::InvalidOperatorError)
71
71
  end
72
72
  end
73
73
  end
@@ -23,14 +23,4 @@ Gem::Specification.new do |spec|
23
23
  spec.add_runtime_dependency "activesupport"
24
24
  spec.add_runtime_dependency "erubis"
25
25
  spec.add_runtime_dependency "parser"
26
-
27
- spec.add_development_dependency "bundler"
28
- spec.add_development_dependency "guard"
29
- spec.add_development_dependency "guard-rspec"
30
- spec.add_development_dependency "guard-rake"
31
- spec.add_development_dependency "oedipus_lex"
32
- spec.add_development_dependency "racc"
33
- spec.add_development_dependency "rake"
34
- spec.add_development_dependency "rspec", "3.10.0"
35
- spec.add_development_dependency "rspec-mocks", "3.10.2" # rspec-mocks 3.10.3 breaks tests
36
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synvert-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-27 00:00:00.000000000 Z
11
+ date: 2022-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,132 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: bundler
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: guard
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: guard-rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: guard-rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: oedipus_lex
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: racc
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: rake
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: rspec
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - '='
158
- - !ruby/object:Gem::Version
159
- version: 3.10.0
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - '='
165
- - !ruby/object:Gem::Version
166
- version: 3.10.0
167
- - !ruby/object:Gem::Dependency
168
- name: rspec-mocks
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - '='
172
- - !ruby/object:Gem::Version
173
- version: 3.10.2
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - '='
179
- - !ruby/object:Gem::Version
180
- version: 3.10.2
181
55
  description: convert ruby code to better syntax automatically.
182
56
  email:
183
57
  - flyerhzm@gmail.com
@@ -218,6 +92,7 @@ files:
218
92
  - lib/synvert/core/node_query/compiler/parse_error.rb
219
93
  - lib/synvert/core/node_query/compiler/regexp.rb
220
94
  - lib/synvert/core/node_query/compiler/selector.rb
95
+ - lib/synvert/core/node_query/compiler/simple_selector.rb
221
96
  - lib/synvert/core/node_query/compiler/string.rb
222
97
  - lib/synvert/core/node_query/compiler/symbol.rb
223
98
  - lib/synvert/core/node_query/lexer.rex