msfl_visitors 1.2.0 → 1.2.1.dev0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4fcb0f385bb41b619dad3d25724604bf43796e7
4
- data.tar.gz: 3c51e3af9013e32a0b423da17f0b9926108dd9c6
3
+ metadata.gz: e43425b31d0774b6b7bfef7b7a47dd8914195729
4
+ data.tar.gz: b3fdf922ea429c522a77258ca40e5955d53373f3
5
5
  SHA512:
6
- metadata.gz: b6626c6471bfeab9c8d1056fd2d23cbb6ccb2bf14409ef0589b7e0b4687c5fa3a0455f7596f223687a0bd8995449c548a5ee93617351b392491704878c3060be
7
- data.tar.gz: 33d2578796d206d74757c9d587a34d1d46a148c777ac005599cebd51d8d28727ff231176000a4eedee15f47e20ab0f559842f92a0f5f2866511bcf62c44bd45d
6
+ metadata.gz: cc796e4b08f79201048cf37715f50cba54abc9026ebbb96669a5c8f4b3e8ef93505a65e2f5e1790494d3775521a65bfdcb30092ba1c7d1fffec329855684a8e7
7
+ data.tar.gz: 142acb13b5679b278a9c2487ecace20e8917d3673a715b9ecbfa91ee1ea5ab71f131a49a2237851cdb50855e28b1ee8aa1468a831b548736eeb0700b02ffaa09
@@ -49,6 +49,13 @@ module MSFLVisitors
49
49
  [{clause: root.accept(self)}].concat(clauses).reject { |c| c[:clause] == "" }
50
50
  end
51
51
 
52
+ # Note that the ES documentation also indicates that # is a special character that requires
53
+ # escaping and that this behavior is not part of the PERL regex; however Ruby automatically escapes
54
+ # literal hashes when constructing regices
55
+ def escape_es_special_regex_chars(str)
56
+ str.gsub(/([@&<>~])/) { |m| "\\#{m}" }
57
+ end
58
+
52
59
  private
53
60
 
54
61
  attr_reader :mode
@@ -68,12 +75,19 @@ module MSFLVisitors
68
75
  Nodes::Match => '=~',
69
76
  }
70
77
 
78
+ def escaped_regex_helper(escaped_str)
79
+ exp = visitor.escape_es_special_regex_chars "#{escaped_str}"
80
+ # why you must use #inspect, not #to_s. @link http://ruby-doc.org/core-1.9.3/Regexp.html#method-i-3D-7E
81
+ %r[.*#{exp}.*]
82
+ end
83
+
71
84
  def visit(node)
72
85
  case node
73
86
  when Nodes::Field
74
87
  node.value.to_s
75
88
  when Nodes::Regex
76
- %(Regexp.new( '.*' + Regexp.escape( "#{node.value.to_s}" ) + '.*' ))
89
+ esc = Regexp.escape("#{node.value.to_s}")
90
+ escaped_regex_helper esc
77
91
  when Nodes::Word
78
92
  "\"#{node.value}\""
79
93
  when Nodes::Date, Nodes::Time
@@ -86,10 +100,10 @@ module MSFLVisitors
86
100
 
87
101
  when Nodes::Match
88
102
  if node.right.is_a? Nodes::Set
89
- regex = node.right.contents.map { |right_child| MSFLVisitors::Nodes::Regex.new(right_child.value.to_s).accept(visitor)[15..-6] }.join('|')
90
- "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} Regexp.new( '.*' + #{regex[4..-5]} + '.*' )"
103
+ escaped_str = node.right.contents.map { |right_child| MSFLVisitors::Nodes::Regex.new(right_child.value.to_s).accept(visitor).inspect[3..-4] }.join('|')
104
+ "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} " + escaped_regex_helper(escaped_str).inspect
91
105
  else
92
- "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} #{MSFLVisitors::Nodes::Regex.new(node.right.value.to_s).accept(visitor)}"
106
+ "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} " + MSFLVisitors::Nodes::Regex.new(node.right.value.to_s).accept(visitor).inspect
93
107
  end
94
108
  when Nodes::Containment,
95
109
  Nodes::GreaterThan,
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'msfl_visitors'
3
- s.version = '1.2.0'
3
+ s.version = '1.2.1.dev0'
4
4
  s.date = '2015-06-19'
5
5
  s.summary = "Convert MSFL to other forms"
6
6
  s.description = "Visitor pattern approach to converting MSFL to other forms."
@@ -11,4 +11,20 @@ describe MSFLVisitors::Visitor do
11
11
  expect(subject.send(:mode)).to eq :term
12
12
  end
13
13
  end
14
+
15
+ describe "#escape_es_special_regex_chars" do
16
+
17
+ {
18
+ 'ab@cd' => 'ab\@cd',
19
+ 'ab&cd' => 'ab\&cd',
20
+ 'ab<cd' => 'ab\<cd',
21
+ 'ab>cd' => 'ab\>cd',
22
+ 'ab~cd' => 'ab\~cd',
23
+ }.each do |str, expected|
24
+
25
+ it "escapes '#{str}' as '#{expected}'" do
26
+ expect(MSFLVisitors::Visitor.new.escape_es_special_regex_chars str).to eq expected
27
+ end
28
+ end
29
+ end
14
30
  end
@@ -198,12 +198,23 @@ describe MSFLVisitors::Visitor do
198
198
 
199
199
  describe "a Regex node" do
200
200
 
201
- let(:node) { MSFLVisitors::Nodes::Regex.new "foobar" }
201
+ let(:node) { MSFLVisitors::Nodes::Regex.new regex }
202
+
203
+ let(:regex) { "foobar" }
202
204
 
203
205
  context "when using the TermFilter visitor" do
204
206
 
205
- it "results in: 'Regexp.new( '.*' + Regexp.escape( \"foobar\" ) + '.*' )'" do
206
- expect(result).to eq %(Regexp.new( '.*' + Regexp.escape( "foobar" ) + '.*' ))
207
+ it "results in: /.*foobar.*/" do
208
+ expect(result).to eq /.*foobar.*/
209
+ end
210
+
211
+ context "when the node requires escaping" do
212
+
213
+ let(:node) { MSFLVisitors::Nodes::Regex.new "foo*bar" }
214
+
215
+ it "results in: #{/.*foo\*bar.*/.inspect}" do
216
+ expect(result).to eq /.*foo\*bar.*/
217
+ end
207
218
  end
208
219
  end
209
220
 
@@ -215,6 +226,36 @@ describe MSFLVisitors::Visitor do
215
226
  expect(result).to eq "foobar"
216
227
  end
217
228
  end
229
+
230
+ context "when the expression contains `#`, `@`, `&`, `<`, `>`, or `~`" do
231
+
232
+ let(:regex) { "a #sentence@ contain&ing <lucene> cha~rs" }
233
+
234
+ it "escapes lucene specific special characters" do
235
+ expected = /.*a\ \#sentence\@\ contain\&ing\ \<lucene\>\ cha\~rs.*/
236
+ expect(result).to eq expected
237
+ end
238
+ end
239
+
240
+ context "when the regex contains characters that require escaping" do
241
+
242
+ let(:regex) { 'this / needs to % {be,escaped} *. ^[or] | \else' }
243
+
244
+ let(:node) { MSFLVisitors::Nodes::Regex.new regex }
245
+
246
+ it "returns: #{/.*this\ \/\ needs\ to\ %\ \{be,escaped\}\ \*\.\ \^\[or\]\ \|\ \\else.*/.inspect}" do
247
+ expect(result).to eq /.*this\ \/\ needs\ to\ %\ \{be,escaped\}\ \*\.\ \^\[or\]\ \|\ \\else.*/
248
+ end
249
+
250
+ context "when using the Aggregations visitor" do
251
+
252
+ before { visitor.mode = :aggregations }
253
+
254
+ it "returns: 'this\\ /\\ needs\\ to\\ %\\ \\{be,escaped\\}\\ \\*\\.\\ \\^\\[or\\]\\ \\|\\ \\\\else'" do
255
+ expect(result).to eq "this\\ /\\ needs\\ to\\ %\\ \\{be,escaped\\}\\ \\*\\.\\ \\^\\[or\\]\\ \\|\\ \\\\else"
256
+ end
257
+ end
258
+ end
218
259
  end
219
260
 
220
261
  describe "a Match node" do
@@ -223,8 +264,8 @@ describe MSFLVisitors::Visitor do
223
264
 
224
265
  context "when using the TermFilter visitor" do
225
266
 
226
- it "results in: 'left =~ Regexp.new( '.*' + Regexp.parse( \"rhs\" ) + '.*' )'" do
227
- expect(result).to eq %(lhs =~ Regexp.new( '.*' + Regexp.escape( "rhs" ) + '.*' ))
267
+ it "results in: 'left =~ /.*rhs.*/'" do
268
+ expect(result).to eq %(lhs =~ /.*rhs.*/)
228
269
  end
229
270
  end
230
271
 
@@ -243,8 +284,8 @@ describe MSFLVisitors::Visitor do
243
284
 
244
285
  context "when using the TermFilter visitor" do
245
286
 
246
- it "results in: 'left =~ Regexp.new( '.*' + Regexp.escape( \"this (needs) to be* escaped\" ) + '.*' )'" do
247
- expect(result).to eq %(lhs =~ Regexp.new( '.*' + Regexp.escape( "this (needs) to be* escaped" ) + '.*' ))
287
+ it "results in: 'left =~ /.*this\ \(needs\)\ to\ be\*\ escaped.*/'" do
288
+ expect(result).to eq %(lhs =~ ) + /.*this\ \(needs\)\ to\ be\*\ escaped.*/.inspect
248
289
  end
249
290
  end
250
291
 
@@ -262,8 +303,8 @@ describe MSFLVisitors::Visitor do
262
303
 
263
304
  context "when using the TermFilter visitor" do
264
305
 
265
- it "results in: 'left =~ Regexp.new( '.*' + Regexp.escape( \"foo\" ) + '|' + Regexp.escape( \"bar\" ) + '|' + Regexp.escape( \"baz\" ) + '.*' )'" do
266
- expect(result).to eq %(lhs =~ Regexp.new( '.*' + Regexp.escape( "foo" ) + '|' + Regexp.escape( "bar" ) + '|' + Regexp.escape( "baz" ) + '.*' ))
306
+ it "results in: 'left =~ /.*foo|bar|baz.*/'" do
307
+ expect(result).to eq %(lhs =~ ) + /.*foo|bar|baz.*/.inspect
267
308
  end
268
309
  end
269
310
 
@@ -719,46 +760,6 @@ describe MSFLVisitors::Visitor do
719
760
  end
720
761
  end
721
762
  end
722
-
723
- describe "a Regex node" do
724
-
725
- let(:regex) { "content" }
726
-
727
- let(:node) { MSFLVisitors::Nodes::Regex.new regex }
728
-
729
- it "returns: 'Regexp.new( '.*' + Regexp.escape( \"content\" ) + '.*' )'" do
730
- expect(result).to eq %(Regexp.new( '.*' + Regexp.escape( "#{regex}" ) + '.*' ))
731
- end
732
-
733
- context "when using the Aggregations visitor" do
734
-
735
- before { visitor.mode = :aggregations }
736
-
737
- it "returns: the elasticsearch regular expression formatted string \"content\"" do
738
- expect(result).to eq "#{regex}"
739
- end
740
- end
741
-
742
- context "when the regex contains characters that require escaping" do
743
-
744
- let(:regex) { 'this / needs to % {be,escaped} *. ^[or] | \else' }
745
-
746
- let(:node) { MSFLVisitors::Nodes::Regex.new regex }
747
-
748
- it "returns: 'Regexp.new( '.*' + Regexp.escape( \"this / needs to % {be,escaped} *. ^[or] | \\else\" ) + '.*' )'" do
749
- expect(result).to eq %(Regexp.new( '.*' + Regexp.escape( "this / needs to % {be,escaped} *. ^[or] | \\else" ) + '.*' ))
750
- end
751
-
752
- context "when using the Aggregations visitor" do
753
-
754
- before { visitor.mode = :aggregations }
755
-
756
- it "returns: 'this\\ /\\ needs\\ to\\ %\\ \\{be,escaped\\}\\ \\*\\.\\ \\^\\[or\\]\\ \\|\\ \\\\else'" do
757
- expect(result).to eq "this\\ /\\ needs\\ to\\ %\\ \\{be,escaped\\}\\ \\*\\.\\ \\^\\[or\\]\\ \\|\\ \\\\else"
758
- end
759
- end
760
- end
761
- end
762
763
  end
763
764
 
764
765
  describe "range value nodes" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msfl_visitors
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1.dev0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtland Caldwell
@@ -173,9 +173,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
173
  version: '0'
174
174
  required_rubygems_version: !ruby/object:Gem::Requirement
175
175
  requirements:
176
- - - ">="
176
+ - - ">"
177
177
  - !ruby/object:Gem::Version
178
- version: '0'
178
+ version: 1.3.1
179
179
  requirements: []
180
180
  rubyforge_project:
181
181
  rubygems_version: 2.2.2