synvert-core 1.2.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,141 +1,138 @@
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
10
-
11
- it 'parses one selector' do
12
- source = '.send[message=:create]'
13
- assert_parser(source)
14
- end
15
-
16
- it 'parses two selectors' do
17
- source = '.class[name=Synvert] .def[name="foobar"]'
18
- assert_parser(source)
19
- end
11
+ describe '#toString' do
12
+ it 'parses one selector' do
13
+ source = '.send[message=:create]'
14
+ assert_parser(source)
15
+ end
20
16
 
21
- it 'parses three selectors' do
22
- source = '.class[name=Synvert] .def[name="foobar"] .send[message=create]'
23
- assert_parser(source)
24
- end
17
+ it 'parses two selectors' do
18
+ source = '.class[name=Synvert] .def[name="foobar"]'
19
+ assert_parser(source)
20
+ end
25
21
 
26
- it 'parses child selector' do
27
- source = '.class[name=Synvert] > .def[name="foobar"]'
28
- assert_parser(source)
29
- end
22
+ it 'parses three selectors' do
23
+ source = '.class[name=Synvert] .def[name="foobar"] .send[message=create]'
24
+ assert_parser(source)
25
+ end
30
26
 
31
- it 'parses scope' do
32
- source = '.block <body> > .send'
33
- assert_parser(source)
34
- end
27
+ it 'parses child selector' do
28
+ source = '.class[name=Synvert] > .def[name="foobar"]'
29
+ assert_parser(source)
30
+ end
35
31
 
36
- it 'parses :first-child' do
37
- source = '.class .def:first-child'
38
- assert_parser(source)
39
- end
32
+ it 'parses scope' do
33
+ source = '.block body > .send'
34
+ assert_parser(source)
35
+ end
40
36
 
41
- it 'parses :last-child' do
42
- source = '.class .def:last-child'
43
- assert_parser(source)
44
- end
37
+ it 'parses :has selector' do
38
+ source = '.class :has(> .def)'
39
+ assert_parser(source)
40
+ end
45
41
 
46
- it 'parses :nth-child(n)' do
47
- source = '.class .def:nth-child(2)'
48
- assert_parser(source)
49
- end
42
+ it 'parses :not_has selector' do
43
+ source = '.class :not_has(> .def)'
44
+ assert_parser(source)
45
+ end
50
46
 
51
- it 'parses :nth-last-child(n)' do
52
- source = '.class .def:nth-last-child(2)'
53
- assert_parser(source)
54
- end
47
+ it 'parses root :has selector' do
48
+ source = ':has(.def)'
49
+ assert_parser(source)
50
+ end
55
51
 
56
- it 'parses :has selector' do
57
- source = '.class :has(> .def)'
58
- assert_parser(source)
59
- end
52
+ it 'parses multiple attributes' do
53
+ source = '.send[receiver=nil][message=:create]'
54
+ assert_parser(source)
55
+ end
60
56
 
61
- it 'parses :not_has selector' do
62
- source = '.class :not_has(> .def)'
63
- assert_parser(source)
64
- end
57
+ it 'parses nested attributes' do
58
+ source = '.send[receiver.message=:create]'
59
+ assert_parser(source)
60
+ end
65
61
 
66
- it 'parses root :has selector' do
67
- source = ':has(.def)'
68
- assert_parser(source)
69
- end
62
+ it 'parses selector value' do
63
+ source = '.send[receiver=.send[message=:create]]'
64
+ assert_parser(source)
65
+ end
70
66
 
71
- it 'parses multiple attributes' do
72
- source = '.send[receiver=nil][message=:create]'
73
- assert_parser(source)
74
- end
67
+ it 'parses start with operator' do
68
+ source = '.def[name^=synvert]'
69
+ assert_parser(source)
70
+ end
75
71
 
76
- it 'parses nested attributes' do
77
- source = '.send[receiver.message=:create]'
78
- assert_parser(source)
79
- end
72
+ it 'parses end with operator' do
73
+ source = '.def[name$=synvert]'
74
+ assert_parser(source)
75
+ end
80
76
 
81
- it 'parses selector value' do
82
- source = '.send[receiver=.send[message=:create]]'
83
- assert_parser(source)
84
- end
77
+ it 'parses contain operator' do
78
+ source = '.def[name*=synvert]'
79
+ assert_parser(source)
80
+ end
85
81
 
86
- it 'parses not equal operator' do
87
- source = '.send[receiver=.send[message!=:create]]'
88
- assert_parser(source)
89
- end
82
+ it 'parses not equal operator' do
83
+ source = '.send[receiver=.send[message!=:create]]'
84
+ assert_parser(source)
85
+ end
90
86
 
91
- it 'parses greater than operator' do
92
- source = '.send[receiver=.send[arguments.size>1]]'
93
- assert_parser(source)
94
- end
87
+ it 'parses greater than operator' do
88
+ source = '.send[receiver=.send[arguments.size>1]]'
89
+ assert_parser(source)
90
+ end
95
91
 
96
- it 'parses greater than or equal operator' do
97
- source = '.send[receiver=.send[arguments.size>=1]]'
98
- assert_parser(source)
99
- end
92
+ it 'parses greater than or equal operator' do
93
+ source = '.send[receiver=.send[arguments.size>=1]]'
94
+ assert_parser(source)
95
+ end
100
96
 
101
- it 'parses less than operator' do
102
- source = '.send[receiver=.send[arguments.size<1]]'
103
- assert_parser(source)
104
- end
97
+ it 'parses less than operator' do
98
+ source = '.send[receiver=.send[arguments.size<1]]'
99
+ assert_parser(source)
100
+ end
105
101
 
106
- it 'parses less than or equal operator' do
107
- source = '.send[receiver=.send[arguments.size<=1]]'
108
- assert_parser(source)
109
- end
102
+ it 'parses less than or equal operator' do
103
+ source = '.send[receiver=.send[arguments.size<=1]]'
104
+ assert_parser(source)
105
+ end
110
106
 
111
- it 'parses in operator' do
112
- source = '.def[name in (foo bar)]'
113
- assert_parser(source)
114
- end
107
+ it 'parses in operator' do
108
+ source = '.def[name in (foo bar)]'
109
+ assert_parser(source)
110
+ end
115
111
 
116
- it 'parses not_in operator' do
117
- source = '.def[name not in (foo bar)]'
118
- assert_parser(source)
119
- end
112
+ it 'parses not_in operator' do
113
+ source = '.def[name not in (foo bar)]'
114
+ assert_parser(source)
115
+ end
120
116
 
121
- it 'parses includes operator' do
122
- source = '.def[arguments includes &block]'
123
- assert_parser(source)
124
- end
117
+ it 'parses includes operator' do
118
+ source = '.def[arguments includes &block]'
119
+ assert_parser(source)
120
+ end
125
121
 
126
- it 'parses empty string' do
127
- source = '.send[arguments.first=""]'
128
- assert_parser(source)
129
- end
122
+ it 'parses empty string' do
123
+ source = '.send[arguments.first=""]'
124
+ assert_parser(source)
125
+ end
130
126
 
131
- it 'parses []=' do
132
- source = '.send[message=[]=]'
133
- assert_parser(source)
134
- end
127
+ it 'parses []=' do
128
+ source = '.send[message=[]=]'
129
+ assert_parser(source)
130
+ end
135
131
 
136
- it 'parses :[]' do
137
- source = '.send[message=:[]]'
138
- assert_parser(source)
132
+ it 'parses :[]' do
133
+ source = '.send[message=:[]]'
134
+ assert_parser(source)
135
+ end
139
136
  end
140
137
 
141
138
  describe '#query_nodes' do
@@ -178,31 +175,21 @@ module Synvert::Core::NodeQuery
178
175
  expect(expression.query_nodes(node)).to eq node.body
179
176
  end
180
177
 
181
- it 'matches first def node' do
182
- expression = parser.parse('.def:first-child')
183
- expect(expression.query_nodes(node)).to eq [node.body.first]
178
+ it 'matches start with' do
179
+ expression = parser.parse('.def[name^=foo]')
180
+ expect(expression.query_nodes(node)).to eq [node.body.first, node.body.last]
184
181
  end
185
182
 
186
- it 'matches nested first node' do
187
- expression = parser.parse('.def[arguments.size=0] .send:first-child')
188
- expect(expression.query_nodes(node)).to eq [node.body.first.body.first, node.body.second.body.first]
183
+ it 'matches end with' do
184
+ expression = parser.parse('.def[name$=bar]')
185
+ expect(expression.query_nodes(node)).to eq [node.body.second, node.body.last]
189
186
  end
190
187
 
191
- it 'matches last def node' do
192
- expression = parser.parse('.def:last-child')
188
+ it 'matches contain' do
189
+ expression = parser.parse('.def[name*=oob]')
193
190
  expect(expression.query_nodes(node)).to eq [node.body.last]
194
191
  end
195
192
 
196
- it 'matches nth-child node' do
197
- expression = parser.parse('.def:nth-child(2)')
198
- expect(expression.query_nodes(node)).to eq [node.body.second]
199
- end
200
-
201
- it 'matches nth-last-child node' do
202
- expression = parser.parse('.def:nth-last-child(2)')
203
- expect(expression.query_nodes(node)).to eq [node.body[-2]]
204
- end
205
-
206
193
  it 'matches not equal' do
207
194
  expression = parser.parse('.def[name!=foobar]')
208
195
  expect(expression.query_nodes(node)).to eq [node.body.first, node.body.second]
@@ -265,15 +252,15 @@ module Synvert::Core::NodeQuery
265
252
  end
266
253
 
267
254
  it 'matches goto scope' do
268
- expression = parser.parse('.def <body> > .send[message=:create]')
255
+ expression = parser.parse('.def body > .send[message=:create]')
269
256
  expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
270
257
 
271
- expression = parser.parse('.def <body> .send[message=:create]')
258
+ expression = parser.parse('.def body .send[message=:create]')
272
259
  expect(expression.query_nodes(node)).to eq [node.body.first.body.last, node.body.second.body.last]
273
260
  end
274
261
 
275
262
  it 'matches multiple goto scope' do
276
- expression = parser.parse('.block <caller.arguments> .const[name=Synvert]')
263
+ expression = parser.parse('.block caller.arguments .const[name=Synvert]')
277
264
  expect(expression.query_nodes(test_node)).to eq [test_node.caller.arguments.first]
278
265
  end
279
266
 
@@ -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)
@@ -167,16 +167,21 @@ module Synvert::Core
167
167
 
168
168
  it 'parses remove' do
169
169
  action = double
170
- expect(Rewriter::RemoveAction).to receive(:new).with(instance).and_return(action)
170
+ expect(Rewriter::RemoveAction).to receive(:new).with(instance, { and_comma: true }).and_return(action)
171
171
  expect(action).to receive(:process)
172
- instance.remove
172
+ instance.remove and_comma: true
173
173
  end
174
174
 
175
175
  it 'parses remove' do
176
176
  action = double
177
- expect(Rewriter::DeleteAction).to receive(:new).with(instance, :dot, :message).and_return(action)
177
+ expect(Rewriter::DeleteAction).to receive(:new).with(
178
+ instance,
179
+ :dot,
180
+ :message,
181
+ { and_comma: true }
182
+ ).and_return(action)
178
183
  expect(action).to receive(:process)
179
- instance.delete :dot, :message
184
+ instance.delete :dot, :message, and_comma: true
180
185
  end
181
186
 
182
187
  it 'parses wrap with' do
@@ -59,16 +59,23 @@ 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, '.block <caller.arguments> .hash') {}
68
68
  expect {
69
69
  scope.process
70
70
  }.to raise_error(NodeQuery::Compiler::ParseError)
71
71
  end
72
+
73
+ it 'raises InvalidOperatorError' do
74
+ scope = described_class.new(instance, '.send[receiver IN FactoryGirl]') {}
75
+ expect {
76
+ scope.process
77
+ }.to raise_error(NodeQuery::Compiler::InvalidOperatorError)
78
+ end
72
79
  end
73
80
  end
74
81
  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.2.1
4
+ version: 1.4.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-05-01 00:00:00.000000000 Z
11
+ date: 2022-05-21 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
@@ -206,6 +80,7 @@ files:
206
80
  - lib/synvert/core/node_query/compiler/array.rb
207
81
  - lib/synvert/core/node_query/compiler/attribute.rb
208
82
  - lib/synvert/core/node_query/compiler/attribute_list.rb
83
+ - lib/synvert/core/node_query/compiler/basic_selector.rb
209
84
  - lib/synvert/core/node_query/compiler/boolean.rb
210
85
  - lib/synvert/core/node_query/compiler/comparable.rb
211
86
  - lib/synvert/core/node_query/compiler/dynamic_attribute.rb