blacklight_advanced_search 6.0.2 → 6.1.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.
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
-