blacklight_advanced_search 6.0.2 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/.rubocop.yml +15 -0
  4. data/.rubocop_todo.yml +351 -0
  5. data/.solr_wrapper.yml +5 -0
  6. data/.travis.yml +4 -7
  7. data/Gemfile +18 -11
  8. data/Rakefile +24 -34
  9. data/VERSION +1 -1
  10. data/app/controllers/advanced_controller.rb +5 -7
  11. data/app/controllers/blacklight_advanced_search/advanced_controller.rb +5 -8
  12. data/app/helpers/advanced_helper.rb +4 -6
  13. data/blacklight_advanced_search.gemspec +11 -8
  14. data/lib/blacklight_advanced_search.rb +29 -34
  15. data/lib/blacklight_advanced_search/advanced_query_parser.rb +12 -13
  16. data/lib/blacklight_advanced_search/advanced_search_builder.rb +28 -32
  17. data/lib/blacklight_advanced_search/catalog_helper_override.rb +11 -34
  18. data/lib/blacklight_advanced_search/controller.rb +1 -1
  19. data/lib/blacklight_advanced_search/filter_parser.rb +7 -9
  20. data/lib/blacklight_advanced_search/parsing_nesting_parser.rb +5 -8
  21. data/lib/blacklight_advanced_search/redirect_legacy_params_filter.rb +23 -25
  22. data/lib/blacklight_advanced_search/render_constraints_override.rb +46 -33
  23. data/lib/blacklight_advanced_search/version.rb +0 -1
  24. data/lib/generators/blacklight_advanced_search/assets_generator.rb +4 -8
  25. data/lib/generators/blacklight_advanced_search/blacklight_advanced_search_generator.rb +0 -2
  26. data/lib/generators/blacklight_advanced_search/install_generator.rb +9 -5
  27. data/lib/generators/blacklight_advanced_search/templates/advanced_controller.rb +0 -2
  28. data/lib/parsing_nesting/grammar.rb +22 -25
  29. data/lib/parsing_nesting/tree.rb +156 -168
  30. data/solr/conf/_rest_managed.json +3 -0
  31. data/solr/conf/admin-extra.html +31 -0
  32. data/solr/conf/elevate.xml +36 -0
  33. data/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  34. data/solr/conf/protwords.txt +21 -0
  35. data/solr/conf/schema.xml +635 -0
  36. data/solr/conf/scripts.conf +24 -0
  37. data/solr/conf/solrconfig.xml +411 -0
  38. data/solr/conf/spellings.txt +2 -0
  39. data/solr/conf/stopwords.txt +58 -0
  40. data/solr/conf/stopwords_en.txt +58 -0
  41. data/solr/conf/synonyms.txt +31 -0
  42. data/solr/conf/xslt/example.xsl +132 -0
  43. data/solr/conf/xslt/example_atom.xsl +67 -0
  44. data/solr/conf/xslt/example_rss.xsl +66 -0
  45. data/solr/conf/xslt/luke.xsl +337 -0
  46. data/solr/sample_solr_documents.yml +2692 -0
  47. data/spec/features/blacklight_advanced_search_form_spec.rb +0 -2
  48. data/spec/helpers/advanced_helper_spec.rb +0 -2
  49. data/spec/integration/blacklight_stub_spec.rb +0 -2
  50. data/spec/lib/advanced_search_builder_spec.rb +7 -14
  51. data/spec/lib/blacklight_advanced_search/render_constraints_override_spec.rb +39 -0
  52. data/spec/lib/deep_merge_spec.rb +109 -34
  53. data/spec/lib/filter_parser_spec.rb +8 -14
  54. data/spec/parsing_nesting/build_tree_spec.rb +73 -81
  55. data/spec/parsing_nesting/consuming_spec.rb +2 -12
  56. data/spec/parsing_nesting/to_solr_spec.rb +93 -130
  57. data/spec/spec_helper.rb +0 -3
  58. data/spec/test_app_templates/app/controllers/catalog_controller.rb +3 -3
  59. data/spec/test_app_templates/lib/generators/test_app_generator.rb +3 -3
  60. metadata +63 -13
  61. data/spec/spec.opts +0 -4
@@ -1,19 +1,10 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
- #require 'rubygems'
3
- #require 'parslet'
4
- #require 'spec'
5
- #require 'spec/autorun'
6
-
7
- #load '../../nesting_parser/grammar.rb'
8
- #load '../../nesting_parser/tree.rb'
9
-
10
1
  describe "NestingParser" do
11
2
  describe "Consuming" do
12
3
  before do
13
4
  @parser = ParsingNesting::Grammar.new
14
5
  end
15
6
  # Whole bunch of things we just want to make sure they are consumed
16
- # without error, not checking the generated tree yet.
7
+ # without error, not checking the generated tree yet.
17
8
  ["foo",
18
9
  "foo bar",
19
10
  " foo bar ",
@@ -41,9 +32,8 @@ describe "NestingParser" do
41
32
  "(foo bar one AND two) AND (three four ten OR twelve)"
42
33
  ].each do |query|
43
34
  it "should consume<<#{query}>>" do
44
- expect {@parser.parse(query)}.not_to raise_error
35
+ expect { @parser.parse(query) }.not_to raise_error
45
36
  end
46
37
  end
47
38
  end
48
39
  end
49
-
@@ -1,31 +1,22 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
- #require 'rubygems'
3
- #require 'parslet'
4
- #require 'spec'
5
- #require 'spec/autorun'
6
-
7
- #load '../../lib/parsing_nesting/grammar.rb'
8
- #load '../../lib/parsing_nesting/tree.rb'
9
-
10
1
  module SolrQuerySpecHelper
11
- def parse(s, arg=nil)
2
+ def parse(s, arg = nil)
12
3
  if arg
13
4
  ParsingNesting::Tree.parse(s, arg)
14
5
  else
15
6
  ParsingNesting::Tree.parse(s)
16
7
  end
17
8
  end
18
-
9
+
19
10
  # yields localparam string, and the actual internal query
20
11
  def local_param_match(query)
21
12
  expect(query).to match(/^ *_query_:\"\{([^}]+)\}(.*)" *$/)
22
13
  query =~ /^ *_query_:\"\{([^}]+)\}(.*)" *$/
23
14
  expect(param_str = $1).not_to be_nil
24
15
  expect(query = $2).not_to be_nil
25
-
16
+
26
17
  yield [param_str, query] if block_given?
27
18
  end
28
-
19
+
29
20
  def bare_local_param_match(query)
30
21
  expect(query).to match(/ *\{([^}]+)\}(.*)/)
31
22
  query =~ /\{([^}]+)\}(.*)/
@@ -33,51 +24,51 @@ module SolrQuerySpecHelper
33
24
  expect(query = $2).not_to be_nil
34
25
  yield [param_str, query] if block_given?
35
26
  end
36
-
27
+
37
28
  # Convenience for matching a lucene query combining nested queries,
38
- # and getting out the nested queries as matches.
29
+ # and getting out the nested queries as matches.
39
30
  # pass in a string representing a regexp that uses $QUERY as placeholder where
40
- # a nested _query_: will be.
31
+ # a nested _query_: will be.
41
32
  #
42
33
  # * Any parens in your passed in regexp will
43
34
  # be paren literals, don't escape em yourself -- you can't do your
44
35
  # own captures, because if the regexp passes, it'll yield to a block
45
36
  # with a list, in order, of nested queries.
46
- #
37
+ #
47
38
  #
48
39
  # * Can include $ALL to represent literal "*:*"
49
40
  #
50
41
  # Yes, the regexp matching isn't as robust as it could be, hard
51
42
  # to deal with like escaped end-quotes and stuff in a regexp, but
52
- # should mostly work.
43
+ # should mostly work.
53
44
  def query_template_matcher(top_query, regexp_str)
54
45
  nested_re = '(_query_:".+")'
55
46
  regexp_str = regexp_str.gsub("(", '\(').gsub(')', '\)').gsub("$QUERY", nested_re).gsub("$ALL", "\\*\\:\\*")
56
47
  regexp = Regexp.new('^ *' + regexp_str + ' *$')
57
48
 
58
- expect(top_query).to match( regexp )
59
-
60
- yield *regexp.match(top_query).captures if block_given?
49
+ expect(top_query).to match(regexp)
50
+
51
+ yield *regexp.match(top_query).captures if block_given?
61
52
  end
62
53
  end
63
54
 
64
55
  describe "NestingParser" do
65
- describe "Translating to Solr" do
56
+ describe "Translating to Solr" do
66
57
  include SolrQuerySpecHelper
67
-
58
+
68
59
  describe "with basic simple query" do
69
60
  before do
70
- @query = parse("one two three").to_query(:qf => "field field2^5", :pf=>"$pf_title")
61
+ @query = parse("one two three").to_query(:qf => "field field2^5", :pf => "$pf_title")
71
62
  end
72
63
  it "should include LocalParams" do
73
- local_param_match(@query) do |params, query|
64
+ local_param_match(@query) do |params, _query|
74
65
  expect(params).to include("pf=$pf_title")
75
- expect(params).to include('qf=\'field field2^5\'')
76
- end
66
+ expect(params).to include('qf=\'field field2^5\'')
67
+ end
77
68
  end
78
-
69
+
79
70
  it "should include the query" do
80
- local_param_match(@query) do |params, query|
71
+ local_param_match(@query) do |_params, query|
81
72
  expect(query).to eq("one two three")
82
73
  end
83
74
  end
@@ -85,200 +76,184 @@ describe "NestingParser" do
85
76
 
86
77
  describe "with custom qf" do
87
78
  it "should insist on dismax for nested query" do
88
- query = parse("one two three").to_query(:defType => "field", :qf=>"$qf")
89
- local_param_match(query) do |params, query|
79
+ query = parse("one two three").to_query(:defType => "field", :qf => "$qf")
80
+ local_param_match(query) do |params, _query|
90
81
  expect(params).to match(/^\!dismax /)
91
82
  expect(params).not_to match(/field/)
92
83
  end
93
84
  end
94
85
 
95
86
  it "should insist on edismax for nested query" do
96
- query = parse("one two three", 'edismax').to_query(:defType => "field", :qf=>"$qf")
97
- local_param_match(query) do |params, query|
87
+ query = parse("one two three", 'edismax').to_query(:defType => "field", :qf => "$qf")
88
+ local_param_match(query) do |params, _query|
98
89
  expect(params).to match(/^\!edismax qf=\$qf/)
99
90
  expect(params).not_to match(/field/)
100
91
  end
101
92
  end
102
93
  end
103
-
104
-
94
+
105
95
  describe "with simple mandatory/excluded terms" do
106
96
  before do
107
97
  @inner_query = 'red +army -"soviet union" germany'
108
- @full_query = parse(@inner_query).to_query(:qf => "foo", :pf=>"bar")
98
+ @full_query = parse(@inner_query).to_query(:qf => "foo", :pf => "bar")
109
99
  end
110
100
  it "should include query" do
111
- local_param_match(@full_query) do |params, query|
101
+ local_param_match(@full_query) do |_params, query|
112
102
  expect(query).to eq(@inner_query.gsub('"', '\\\\"'))
113
103
  end
114
104
  end
115
105
  end
116
-
106
+
117
107
  describe "with embeddable AND query" do
118
108
  before do
119
- @query = parse("one two AND three").to_query({:qf => "$qf"})
109
+ @query = parse("one two AND three").to_query(:qf => "$qf")
120
110
  end
121
111
  it "should flatten to one dismax query" do
122
- local_param_match(@query) do |params, query|
112
+ local_param_match(@query) do |_params, query|
123
113
  expect(query).to eq("one +two +three")
124
114
  end
125
115
  end
126
-
116
+
127
117
  describe ", with mandatory/excluded" do
128
118
  before do
129
- @query = parse("one -two AND +three").to_query({:qf=>"$qf"})
119
+ @query = parse("one -two AND +three").to_query(:qf => "$qf")
130
120
  end
131
121
  it "should preserve +/- operators" do
132
- local_param_match(@query) do |params, query|
122
+ local_param_match(@query) do |_params, query|
133
123
  expect(query).to eq("one -two +three")
134
124
  end
135
125
  end
136
126
  end
137
-
127
+
138
128
  describe ", deeply nested" do
139
129
  before do
140
- @query = parse("blue (green AND -violet) AND (+big AND (-small AND medium))").to_query({:qf=>"$qf"})
130
+ @query = parse("blue (green AND -violet) AND (+big AND (-small AND medium))").to_query(:qf => "$qf")
141
131
  end
142
132
  it "should flatten into dismax" do
143
- local_param_match(@query) do |params, query|
133
+ local_param_match(@query) do |_params, query|
144
134
  expect(query).to eq("blue +green -violet +big -small +medium")
145
135
  end
146
136
  end
147
- end
148
-
137
+ end
138
+
149
139
  it "for simple OR list, forcing mm=1" do
150
- query = parse("one OR two OR three").to_query(:qf => "$qf", :mm=>"50%")
140
+ query = parse("one OR two OR three").to_query(:qf => "$qf", :mm => "50%")
151
141
  local_param_match(query) do |params, query|
152
142
  expect(params).to include("mm=1")
153
143
  expect(query).to eq("one two three")
154
- end
144
+ end
155
145
  end
156
146
  end
157
-
158
-
159
- describe "that needs to create multiple nested queries" do
160
147
 
161
-
148
+ describe "that needs to create multiple nested queries" do
162
149
  it "for two lists, OR'd" do
163
- query = parse("(one two three) OR (red -green +blue)").to_query(:qf => "$qf")
164
-
165
- query_template_matcher(query, "( *$QUERY +OR +$QUERY *)" ) do |first_half, second_half|
166
-
150
+ query = parse("(one two three) OR (red -green +blue)").to_query(:qf => "$qf")
151
+ query_template_matcher(query, "( *$QUERY +OR +$QUERY *)") do |first_half, second_half|
167
152
  local_param_match(first_half) do |params, query|
168
153
  expect(params).to include("qf=$qf")
169
154
  expect(query).to eq("one two three")
170
155
  end
171
-
156
+
172
157
  local_param_match(second_half) do |params, query|
173
158
  expect(params).to include("qf=$qf")
174
159
  expect(query).to eq("red -green +blue")
175
160
  end
176
161
  end
177
162
  end
178
-
163
+
179
164
  it "for AND list that can not be flattened" do
180
- params = {:qf=>"$qf", :pf=>"$pf", :mm=>"50%"}
181
- query = parse("a OR b AND x OR y").to_query( params )
182
-
183
- query_template_matcher(query, "( *$QUERY +AND +$QUERY *)" ) do |first, second|
165
+ params = { :qf => "$qf", :pf => "$pf", :mm => "50%" }
166
+ query = parse("a OR b AND x OR y").to_query(params)
167
+
168
+ query_template_matcher(query, "( *$QUERY +AND +$QUERY *)") do |first, second|
184
169
  expect(first).to eq(parse("a OR b").to_query(params))
185
170
  expect(second).to eq(parse("x OR y").to_query(params))
186
171
  end
187
172
  end
188
-
173
+
189
174
  it "for AND of two lists" do
190
- params = {:qf => "$qf", :pf=>"$pf", :mm=>"50%"}
191
- query = parse("(one +two three) AND (four five -six)").to_query( params )
192
-
193
- query_template_matcher(query, "( *$QUERY +AND +$QUERY *)" ) do |first, second|
175
+ params = { :qf => "$qf", :pf => "$pf", :mm => "50%" }
176
+ query = parse("(one +two three) AND (four five -six)").to_query(params)
177
+
178
+ query_template_matcher(query, "( *$QUERY +AND +$QUERY *)") do |first, second|
194
179
  expect(first).to eq(parse("one +two three").to_query(params))
195
- expect(second).to eq(parse("four five -six").to_query(params))
180
+ expect(second).to eq(parse("four five -six").to_query(params))
196
181
  end
197
-
198
182
  end
199
-
183
+
200
184
  it "for crazy complicated query" do
201
- query = parse("red AND dawn OR (-night -afternoon) AND NOT (moscow OR beach) ").to_query(:qf => "$qf", :pf =>"$pf", :mm=>"50%")
202
-
185
+ query = parse("red AND dawn OR (-night -afternoon) AND NOT (moscow OR beach) ").to_query(:qf => "$qf", :pf => "$pf", :mm => "50%")
186
+
203
187
  query_template_matcher(query, "( *$QUERY +AND +( *$QUERY +OR +($ALL AND NOT $QUERY *) *) +AND NOT $QUERY *)") do |red_q, dawn_q, night_q, moscow_q|
204
-
205
- local_param_match(red_q) { |params, query| expect(query).to eq("red") }
206
-
207
- local_param_match(dawn_q) { |params, query| expect(query).to eq("dawn")}
208
-
188
+ local_param_match(red_q) { |_params, query| expect(query).to eq("red") }
189
+
190
+ local_param_match(dawn_q) { |_params, query| expect(query).to eq("dawn") }
191
+
209
192
  local_param_match(night_q) do |params, query|
210
193
  expect(params).to include("mm=1")
211
194
  expect(query).to eq("night afternoon")
212
195
  end
213
-
196
+
214
197
  local_param_match(moscow_q) do |params, query|
215
198
  expect(params).to include("mm=1")
216
199
  expect(query).to eq("moscow beach")
217
200
  end
218
-
219
201
  end
220
-
221
202
  end
222
-
223
-
224
203
  end
225
-
204
+
226
205
  describe "for NOT operator" do
227
206
  it "simple" do
228
207
  query = parse("NOT frog").to_query
229
-
208
+
230
209
  query_template_matcher(query, "NOT $QUERY") do |q|
231
210
  expect(q).to eq(parse("frog").to_query)
232
- end
211
+ end
233
212
  end
234
213
  it "binds tightly" do
235
214
  query = parse("one NOT two three").to_query
236
-
215
+
237
216
  query_template_matcher(query, "$QUERY AND NOT $QUERY") do |q1, q2|
238
-
239
- local_param_match(q1) do |params, query|
217
+ local_param_match(q1) do |_params, query|
240
218
  expect(query).to eq("one three")
241
219
  end
242
-
243
- local_param_match(q2) do |params, query|
220
+
221
+ local_param_match(q2) do |_params, query|
244
222
  expect(query).to eq("two")
245
223
  end
246
224
  end
247
-
248
225
  end
249
226
  it "complicated operand" do
250
227
  query = parse("one OR two NOT (three OR four AND five)").to_query
251
- #"_query_:'{!dismax mm=1}one two' AND NOT ( _query_:'{!dismax mm=1}three four' AND _query_:'{!dismax }five' )"
228
+ # "_query_:'{!dismax mm=1}one two' AND NOT ( _query_:'{!dismax mm=1}three four' AND _query_:'{!dismax }five' )"
252
229
  query_template_matcher(query, "$QUERY +AND NOT +( *$QUERY +AND +$QUERY *)") do |external_or, internal_or, internal_term|
253
230
  expect(external_or).to eq(parse("one OR two").to_query)
254
- expect(internal_or).to eq(parse("three OR four").to_query)
255
- expect(internal_term).to eq(parse("five").to_query)
256
- end
231
+ expect(internal_or).to eq(parse("three OR four").to_query)
232
+ expect(internal_term).to eq(parse("five").to_query)
233
+ end
257
234
  end
258
-
235
+
259
236
  it "uses workaround on NOT as operand to OR" do
260
237
  query = parse("two OR (NOT (three))").to_query
261
- query_template_matcher(query, "( *$QUERY +OR +($ALL +AND +NOT +$QUERY) *)")
238
+ query_template_matcher(query, "( *$QUERY +OR +($ALL +AND +NOT +$QUERY) *)")
262
239
  end
263
-
264
240
  end
265
-
241
+
266
242
  describe "for pure negative" do
267
243
  it "should convert simple pure negative" do
268
244
  query = parse('-one -two -"a phrase"').to_query(:qf => "$qf", :mm => "100%")
269
-
245
+
270
246
  query_template_matcher(query, " *NOT $QUERY") do |query|
271
247
  local_param_match(query) do |params, query|
272
248
  expect(params).to include("mm=1")
273
249
  expect(query).to eq('one two \\"a phrase\\"')
274
250
  end
275
251
  end
276
-
277
252
  end
278
-
253
+
279
254
  it "should convert pure negative AND" do
280
255
  query = parse("-one AND -two AND -three").to_query(:qf => "$qf", :mm => "100%")
281
-
256
+
282
257
  query_template_matcher(query, "NOT $QUERY") do |query|
283
258
  local_param_match(query) do |params, query|
284
259
  expect(params).to match(/mm=1 |$/)
@@ -286,32 +261,30 @@ describe "NestingParser" do
286
261
  end
287
262
  end
288
263
  end
289
-
264
+
290
265
  it "should convert pure negative OR" do
291
- query = parse("-one OR -two OR -three").to_query
292
-
266
+ query = parse("-one OR -two OR -three").to_query
267
+
293
268
  query_template_matcher(query, "NOT $QUERY") do |query|
294
269
  local_param_match(query) do |params, query|
295
270
  expect(params).to include("mm=100%")
296
271
  expect(query).to eq("one two three")
297
272
  end
298
273
  end
299
-
300
274
  end
301
-
302
- it "should convert crazy pure negative combo" do
275
+
276
+ it "should convert crazy pure negative combo" do
303
277
  query = parse("(-one -two) OR -three OR (-five AND -six)").to_query
304
-
305
- query_template_matcher(query, "( *($ALL +AND +NOT +$QUERY) +OR +( *$ALL +AND +NOT +$QUERY *) +OR +( *$ALL +AND +NOT +$QUERY *) *)")
278
+
279
+ query_template_matcher(query, "( *($ALL +AND +NOT +$QUERY) +OR +( *$ALL +AND +NOT +$QUERY *) +OR +( *$ALL +AND +NOT +$QUERY *) *)")
306
280
  end
307
281
  end
308
-
309
-
282
+
310
283
  # When a single parse will be the whole query, we use
311
284
  # different more compact production
312
285
  describe "Single Query" do
313
286
  before do
314
- @solr_local_params = {"qf" => "$title_qf", "pf" => "$title_pf"}
287
+ @solr_local_params = { "qf" => "$title_qf", "pf" => "$title_pf" }
315
288
  end
316
289
  describe "simple search" do
317
290
  it "should work with local params" do
@@ -323,11 +296,11 @@ describe "NestingParser" do
323
296
  expect(params).to include("qf=$title_qf")
324
297
  end
325
298
  end
326
-
299
+
327
300
  it "should work without local params" do
328
301
  hash = parse("one +two -three").to_single_query_params({})
329
302
  expect(hash[:defType]).to eq("dismax")
330
- expect(hash[:q]).to eq("one +two -three")
303
+ expect(hash[:q]).to eq("one +two -three")
331
304
  end
332
305
  end
333
306
  describe "simple pure negative" do
@@ -338,7 +311,7 @@ describe "NestingParser" do
338
311
  local_param_match(query) do |params, query|
339
312
  expect(query).to eq("one two")
340
313
  expect(params).to include("mm=1")
341
- end
314
+ end
342
315
  end
343
316
  end
344
317
  end
@@ -359,16 +332,6 @@ describe "NestingParser" do
359
332
  end
360
333
  end
361
334
  end
362
-
363
-
364
- end
365
-
366
-
335
+ end
367
336
  end
368
-
369
-
370
-
371
-
372
337
  end
373
-
374
-