blacklight_advanced_search 5.3.1 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +1 -5
- data/VERSION +1 -1
- data/app/controllers/blacklight_advanced_search/advanced_controller.rb +7 -1
- data/app/views/advanced/_advanced_search_form.html.erb +2 -2
- data/app/views/advanced/_advanced_search_submit_btns.html.erb +3 -3
- data/app/views/advanced/index.html.erb +2 -2
- data/blacklight_advanced_search.gemspec +1 -1
- data/config/routes.rb +2 -2
- data/lib/blacklight_advanced_search.rb +34 -30
- data/lib/blacklight_advanced_search/advanced_search_builder.rb +27 -28
- data/lib/blacklight_advanced_search/controller.rb +1 -16
- data/lib/generators/blacklight_advanced_search/install_generator.rb +15 -3
- data/spec/lib/advanced_search_builder_spec.rb +0 -17
- data/spec/lib/deep_merge_spec.rb +31 -109
- metadata +13 -10
- data/lib/blacklight_advanced_search/parse_basic_q.rb +0 -73
- data/spec/parsing_nesting/parse_basic_q_spec.rb +0 -86
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2ca7a7c57ac86d4f3c0dc385ef79561af1c1737
|
4
|
+
data.tar.gz: ed73c2995b52f221b639d0840ee2caef4f90fbb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8dd353a79541d70fe0d026fb69d12c6957921c2805955533b2b0e181bd426a5ec0ce65f3e1feb06b7a1b9756a10ea364d1481f821127d0e91427ac187aad914
|
7
|
+
data.tar.gz: 17af4c42eb38f9649659c9667150c9a50a7bca920ce077fdaed12d90d7357be0ad3ca1aa0fd560dbd8c2ea695c340cef25d4ae9e2f342088dbb56afa484e4d7e
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -64,11 +64,7 @@ If your application uses a single Solr qt request handler for all its search fie
|
|
64
64
|
|
65
65
|
### Expression parsing in ordinary search
|
66
66
|
|
67
|
-
Turn this feature on by adding to your
|
68
|
-
|
69
|
-
self.search_params_logic << :add_advanced_parse_q_to_solr
|
70
|
-
|
71
|
-
And/or, if you've switched over to configuration in SearchBuilder, then to your ./app/models/search_builder.rb:
|
67
|
+
Turn this feature on by adding to your SearchBuilder definition:
|
72
68
|
|
73
69
|
self.default_processor_chain << :add_advanced_parse_q_to_solr
|
74
70
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
6.0.0
|
@@ -9,11 +9,17 @@ class BlacklightAdvancedSearch::AdvancedController < CatalogController
|
|
9
9
|
end
|
10
10
|
|
11
11
|
protected
|
12
|
+
|
13
|
+
# Override to use the engine routes
|
14
|
+
def search_action_url options = {}
|
15
|
+
blacklight_advanced_search_engine.url_for(options.merge(action: 'index'))
|
16
|
+
end
|
17
|
+
|
12
18
|
def get_advanced_search_facets
|
13
19
|
# We want to find the facets available for the current search, but:
|
14
20
|
# * IGNORING current query (add in facets_for_advanced_search_form filter)
|
15
21
|
# * IGNORING current advanced search facets (remove add_advanced_search_to_solr filter)
|
16
|
-
response, _ = search_results(params
|
22
|
+
response, _ = search_results(params) do |search_builder|
|
17
23
|
search_builder.except(:add_advanced_search_to_solr).append(:facets_for_advanced_search_form)
|
18
24
|
end
|
19
25
|
|
@@ -5,9 +5,9 @@
|
|
5
5
|
</div>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<%= form_tag
|
8
|
+
<%= form_tag search_catalog_path, :class => 'advanced form-horizontal', :method => :get do %>
|
9
9
|
|
10
|
-
<%= render_hash_as_hidden_fields(params_for_search(advanced_search_context
|
10
|
+
<%= render_hash_as_hidden_fields(search_state.params_for_search(advanced_search_context)) %>
|
11
11
|
|
12
12
|
<div class="input-criteria">
|
13
13
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<div class="sort-buttons pull-left">
|
2
2
|
<%= label_tag(:sort, t('blacklight_advanced_search.form.sort_label'), :class => "control-label") %>
|
3
3
|
|
4
|
-
<%= select_tag(:sort, options_for_select(sort_fields, h(
|
4
|
+
<%= select_tag(:sort, options_for_select(sort_fields, h(current_sort_field && current_sort_field.key)), :class => "form-control sort-select") %>
|
5
5
|
<%= hidden_field_tag(:search_field, blacklight_config.advanced_search[:url_key]) %>
|
6
6
|
</div>
|
7
7
|
|
8
8
|
<div class="submit-buttons pull-right">
|
9
|
-
<%= link_to t('blacklight_advanced_search.form.start_over'), advanced_search_path, :class =>"btn btn-default advanced-search-start-over" %>
|
9
|
+
<%= link_to t('blacklight_advanced_search.form.start_over'), blacklight_advanced_search_engine.advanced_search_path, :class =>"btn btn-default advanced-search-start-over" %>
|
10
10
|
|
11
11
|
<%= submit_tag t('blacklight_advanced_search.form.search_btn'), :class=>'btn btn-primary advanced-search-submit', :id => "advanced-search-submit" %>
|
12
|
-
</div>
|
12
|
+
</div>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
<h1 class="advanced page-header">
|
6
6
|
<%= t('blacklight_advanced_search.form.title') %>
|
7
|
-
<%= link_to t('blacklight_advanced_search.form.start_over'), advanced_search_path, :class =>"btn btn-default pull-right advanced-search-start-over" %>
|
7
|
+
<%= link_to t('blacklight_advanced_search.form.start_over'), blacklight_advanced_search_engine.advanced_search_path, :class =>"btn btn-default pull-right advanced-search-start-over" %>
|
8
8
|
</h1>
|
9
9
|
|
10
10
|
<div class="row">
|
@@ -18,4 +18,4 @@
|
|
18
18
|
|
19
19
|
</div>
|
20
20
|
|
21
|
-
</div>
|
21
|
+
</div>
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
s.add_dependency
|
20
|
+
s.add_dependency 'blacklight', '> 6.0.0.pre', '< 7'
|
21
21
|
s.add_dependency "parslet"
|
22
22
|
|
23
23
|
s.add_development_dependency "rails"
|
data/config/routes.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
get 'advanced' => 'advanced#index', :
|
1
|
+
BlacklightAdvancedSearch::Engine.routes.draw do
|
2
|
+
get 'advanced' => 'advanced#index', as: 'advanced_search'
|
3
3
|
end
|
@@ -6,40 +6,44 @@ module BlacklightAdvancedSearch
|
|
6
6
|
autoload :QueryParser, 'blacklight_advanced_search/advanced_query_parser'
|
7
7
|
autoload :ParsingNestingParser, 'blacklight_advanced_search/parsing_nesting_parser'
|
8
8
|
autoload :FilterParser, 'blacklight_advanced_search/filter_parser'
|
9
|
-
autoload :ParseBasicQ, 'blacklight_advanced_search/parse_basic_q'
|
10
9
|
autoload :RedirectLegacyParamsFilter, 'blacklight_advanced_search/redirect_legacy_params_filter'
|
11
10
|
|
12
11
|
require 'blacklight_advanced_search/version'
|
13
12
|
require 'blacklight_advanced_search/engine'
|
14
|
-
|
15
|
-
# Utility method used in our solr search logic.
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# - WILL deduplicate values from arrays after merging them
|
21
|
-
#
|
22
|
-
# @param [Hash|HashWithIndifferentAccess] source_hash
|
23
|
-
# @param [Hash|HashWithIndifferentAccess] new_hash
|
24
|
-
# @return [Hash] the deeply merged hash
|
25
|
-
# @see Rails #deep_merge http://apidock.com/rails/v4.2.1/Hash/deep_merge
|
26
|
-
# @example new_hash = BlacklightAdvancedSearch.deep_merge(h1, h2)
|
27
|
-
def self.deep_merge(source_hash, new_hash)
|
28
|
-
source_hash.deep_merge(new_hash, &method(:merge_conflict_resolution))
|
29
|
-
end
|
30
|
-
|
31
|
-
# this one side-effects the first param
|
32
|
-
# @see #deep_merge
|
33
|
-
# @deprecated use `new_hash = BlacklightAdvancedSearch.deep_merge(h1, h2)` instead
|
13
|
+
|
14
|
+
# Utility method used in our solr search logic.
|
15
|
+
# Merges new_hash into source_hash, but will recursively
|
16
|
+
# merge nested arrays and hashes too; also will NOT merge nil
|
17
|
+
# or blank values from new_hash into source_hash, nil or blank values
|
18
|
+
# in new_hash will not overwrite values in source_hash.
|
34
19
|
def self.deep_merge!(source_hash, new_hash)
|
35
|
-
source_hash.
|
36
|
-
|
20
|
+
# We used to use built-in source_hash.merge() with a block arg
|
21
|
+
# to customize merge behavior, but that was breaking in some
|
22
|
+
# versions of BL/Rails where source_hash was a kind of HashWithIndifferentAccess,
|
23
|
+
# and hwia is unreliable in some versions of Rails. Oh well.
|
24
|
+
# https://github.com/projectblacklight/blacklight/issues/827
|
25
|
+
|
26
|
+
new_hash.each_pair do |key, new_value|
|
27
|
+
old = source_hash.fetch(key, nil)
|
37
28
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
29
|
+
source_hash[key] =
|
30
|
+
if new_value.respond_to?(:blank) && new.blank?
|
31
|
+
old
|
32
|
+
elsif (old.kind_of?(Hash) and new_value.kind_of?(Hash))
|
33
|
+
deep_merge!(old, new_value)
|
34
|
+
old
|
35
|
+
elsif (old.kind_of?(Array) and new_value.kind_of?(Array))
|
36
|
+
old.concat(new_value).uniq
|
37
|
+
elsif new_value.nil?
|
38
|
+
# Allowing nil values to over-write on merge messes things up.
|
39
|
+
# don't set a nil value if you really want to force blank, set
|
40
|
+
# empty string.
|
41
|
+
old
|
42
|
+
else
|
43
|
+
new_value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
source_hash
|
47
|
+
end
|
48
|
+
|
45
49
|
end
|
@@ -9,8 +9,8 @@ module BlacklightAdvancedSearch
|
|
9
9
|
(blacklight_params[:search_field] == self.blacklight_config.advanced_search[:url_key]) || blacklight_params[:f_inclusive]
|
10
10
|
end
|
11
11
|
|
12
|
-
# this method should get added into the
|
13
|
-
#
|
12
|
+
# this method should get added into the processor chain
|
13
|
+
# in a position AFTER normal query handling (:add_query_to_solr),
|
14
14
|
# so it'll overwrite that if and only if it's an advanced search.
|
15
15
|
# adds a 'q' and 'fq's based on advanced search form input.
|
16
16
|
def add_advanced_search_to_solr(solr_parameters)
|
@@ -35,14 +35,14 @@ module BlacklightAdvancedSearch
|
|
35
35
|
|
36
36
|
# Different versions of Parslet raise different exception classes,
|
37
37
|
# need to figure out which one exists to rescue
|
38
|
-
|
38
|
+
@@parslet_failed_exceptions = if defined? Parslet::UnconsumedInput
|
39
39
|
[Parslet::UnconsumedInput]
|
40
40
|
else
|
41
41
|
[Parslet::ParseFailed]
|
42
42
|
end
|
43
43
|
|
44
44
|
|
45
|
-
# This method can be included in
|
45
|
+
# This method can be included in the SearchBuilder to have us
|
46
46
|
# parse an ordinary entered :q for AND/OR/NOT and produce appropriate
|
47
47
|
# Solr query.
|
48
48
|
#
|
@@ -50,31 +50,30 @@ module BlacklightAdvancedSearch
|
|
50
50
|
# parse and send it straight to solr same as if advanced_parse_q
|
51
51
|
# were not being used.
|
52
52
|
def add_advanced_parse_q_to_solr(solr_parameters)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
begin
|
69
|
-
adv_search_params = ParsingNesting::Tree.parse(blacklight_params[:q], blacklight_config.advanced_search[:query_parser]).to_single_query_params(solr_local_params)
|
53
|
+
unless scope.params[:q].blank?
|
54
|
+
field_def = search_field_def_for_key( scope.params[:search_field]) ||
|
55
|
+
default_search_field
|
56
|
+
|
57
|
+
|
58
|
+
# If the individual field has advanced_parse_q suppressed, punt
|
59
|
+
return if field_def[:advanced_parse] == false
|
60
|
+
|
61
|
+
solr_direct_params = field_def[:solr_parameters] || {}
|
62
|
+
solr_local_params = field_def[:solr_local_parameters] || {}
|
63
|
+
|
64
|
+
# See if we can parse it, if we can't, we're going to give up
|
65
|
+
# and just allow basic search, perhaps with a warning.
|
66
|
+
begin
|
67
|
+
adv_search_params = ParsingNesting::Tree.parse(scope.params[:q], blacklight_config.advanced_search[:query_parser]).to_single_query_params( solr_local_params )
|
70
68
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
69
|
+
BlacklightAdvancedSearch.deep_merge!(solr_parameters, solr_direct_params)
|
70
|
+
BlacklightAdvancedSearch.deep_merge!(solr_parameters, adv_search_params)
|
71
|
+
rescue *@@parslet_failed_exceptions => e
|
72
|
+
# do nothing, don't merge our input in, keep basic search
|
73
|
+
# optional TODO, display error message in flash here, but hard to
|
74
|
+
# display a good one.
|
75
|
+
return
|
76
|
+
end
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'blacklight_advanced_search/parsing_nesting_parser'
|
2
2
|
|
3
3
|
# This module gets included into CatalogController, or another SearchHelper
|
4
|
-
# includer, to add
|
4
|
+
# includer, to add advanced search behavior
|
5
5
|
module BlacklightAdvancedSearch::Controller
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
@@ -13,21 +13,6 @@ module BlacklightAdvancedSearch::Controller
|
|
13
13
|
blacklight_config.advanced_search[:query_parser] ||= 'dismax'
|
14
14
|
blacklight_config.advanced_search[:form_solr_parameters] ||= {}
|
15
15
|
|
16
|
-
if respond_to? :search_params_logic
|
17
|
-
# Parse app URL params used for adv searches
|
18
|
-
self.search_params_logic += [:add_advanced_search_to_solr]
|
19
|
-
end
|
20
|
-
|
21
|
-
# Silence deprecations that occur when this code is executed before blacklight
|
22
|
-
# has generated a SearchBuilder.
|
23
|
-
Deprecation.silence Blacklight::Configuration do
|
24
|
-
unless blacklight_config.search_builder_class.include? BlacklightAdvancedSearch::AdvancedSearchBuilder
|
25
|
-
blacklight_config.search_builder_class.send(:include,
|
26
|
-
BlacklightAdvancedSearch::AdvancedSearchBuilder
|
27
|
-
)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
16
|
# Display advanced search constraints properly
|
32
17
|
helper BlacklightAdvancedSearch::RenderConstraintsOverride
|
33
18
|
helper BlacklightAdvancedSearch::CatalogHelperOverride
|
@@ -7,15 +7,27 @@ module BlacklightAdvancedSearch
|
|
7
7
|
def inject_asset_requires
|
8
8
|
generate "blacklight_advanced_search:assets"
|
9
9
|
end
|
10
|
-
|
11
|
-
|
10
|
+
|
11
|
+
def inject_search_builder
|
12
|
+
inject_into_file 'app/models/search_builder.rb', after: /include Blacklight::Solr::SearchBuilderBehavior.*$/ do
|
13
|
+
"\n include BlacklightAdvancedSearch::AdvancedSearchBuilder" \
|
14
|
+
"\n self.default_processor_chain += [:add_advanced_parse_q_to_solr, :add_advanced_search_to_solr]"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def inject_routes
|
19
|
+
inject_into_file 'config/routes.rb', after: /mount Blacklight::Engine.*$/ do
|
20
|
+
"\n mount BlacklightAdvancedSearch::Engine => '/'\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
def install_localized_search_form
|
13
25
|
if options[:force] or yes?("Install local search form with advanced link? (y/N)", :green)
|
14
26
|
# We're going to copy the search from from actual currently loaded
|
15
27
|
# Blacklight into local app as custom local override -- but add our link at the end too.
|
16
28
|
source_file = File.read(File.join(Blacklight.root, "app/views/catalog/_search_form.html.erb"))
|
17
29
|
|
18
|
-
new_file_contents = source_file + "\n\n<%= link_to 'More options', advanced_search_path(params.except(:controller, :action)), :
|
30
|
+
new_file_contents = source_file + "\n\n<%= link_to 'More options', blacklight_advanced_search_engine.advanced_search_path(params.except(:controller, :action)), class: 'advanced_search'%>"
|
19
31
|
|
20
32
|
create_file("app/views/catalog/_search_form.html.erb", new_file_contents)
|
21
33
|
end
|
@@ -49,23 +49,6 @@ describe BlacklightAdvancedSearch::AdvancedSearchBuilder do
|
|
49
49
|
obj.add_advanced_parse_q_to_solr(solr_params)
|
50
50
|
expect(solr_params[:q]).to eq(unparseable_q)
|
51
51
|
end
|
52
|
-
|
53
|
-
describe 'when parslet fails' do
|
54
|
-
let(:failing_q) { ")(" }
|
55
|
-
let(:params) { double("params", params: { :q => failing_q }) }
|
56
|
-
it 'does not return the query that could not be parsed' do
|
57
|
-
obj.add_advanced_parse_q_to_solr(solr_params)
|
58
|
-
expect(solr_params[:q]).to be_nil
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe 'when `q` is a hash' do
|
63
|
-
let(:params) { double("params", params: { q: { id: ['a'] } }) }
|
64
|
-
it 'does not return the query that could not be parsed' do
|
65
|
-
obj.add_advanced_parse_q_to_solr(solr_params)
|
66
|
-
expect(solr_params[:q]).to be_nil
|
67
|
-
end
|
68
|
-
end
|
69
52
|
end
|
70
53
|
|
71
54
|
context "when advanced_parse is false" do
|
data/spec/lib/deep_merge_spec.rb
CHANGED
@@ -1,123 +1,45 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
{
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
'array2' => [3, 4],
|
10
|
-
'hash1' => { 'a' => 'a', 'array' => [1], 'b' => 'b' },
|
11
|
-
'hash2' => { 'a2' => 'a2', 'array2' => [12], 'b2' => 'b2' }
|
3
|
+
describe "BlacklightAdvancedSearch#deep_merge!" do
|
4
|
+
before do
|
5
|
+
@ahash = {"a" => "a", "b" => "b",
|
6
|
+
"array1" => [1,2], "array2" => [3,4],
|
7
|
+
"hash1" => {"a" => "a", "array" => [1], "b" => "b"},
|
8
|
+
"hash2" => {"a2" => "a2", "array2" => [12], "b2" => "b2"}
|
12
9
|
}
|
13
|
-
end
|
14
|
-
let(:hash_Y) do
|
15
|
-
{
|
16
|
-
'a' => 'NEW A',
|
17
|
-
'c' => 'NEW C',
|
18
|
-
'array1' => [3, 4],
|
19
|
-
'hash1' => { 'array' => [2], 'b' => 'NEW B' }
|
20
|
-
}
|
21
|
-
end
|
22
|
-
let(:ahash) do
|
23
|
-
BlacklightAdvancedSearch.deep_merge(hash_x, hash_y)
|
24
|
-
end
|
25
|
-
|
26
|
-
RSpec.shared_examples 'Mergable Parameters' do # this name referenced below
|
27
|
-
it 'does not modify the param hashes' do
|
28
|
-
dup_x = hash_x.dup
|
29
|
-
dup_y = hash_y.dup
|
30
|
-
expect(ahash).not_to eq hash_x # this was the old behavior
|
31
|
-
expect(dup_x).to eq hash_x
|
32
|
-
expect(dup_y).to eq hash_y
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'leaves un-collided content alone' do
|
36
|
-
expect(ahash['b']).to eq('b')
|
37
|
-
expect(ahash['array2']).to eq([3, 4])
|
38
|
-
expect(ahash['hash2']).to eq('a2' => 'a2', 'array2' => [12], 'b2' => 'b2')
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'adds new content' do
|
42
|
-
expect(ahash['c']).to eq('NEW C')
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'merges a hash, recursive like' do
|
46
|
-
expect(ahash['hash1']).to eq('a' => 'a', 'array' => [1, 2], 'b' => 'NEW B')
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'merges boolean values (false)' do
|
50
|
-
expect(BlacklightAdvancedSearch.deep_merge({ a: false }, a: true)).to eq(a: true)
|
51
|
-
expect(BlacklightAdvancedSearch.deep_merge({ a: true }, a: false)).to eq(a: false)
|
52
|
-
end
|
53
10
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
expect(BlacklightAdvancedSearch.deep_merge({ a: 1 }, a: '')).to eq(a: 1)
|
64
|
-
expect(BlacklightAdvancedSearch.deep_merge({ a: nil }, a: '')).to eq(a: nil)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'does not merge empty strings when the key is not yet present' do
|
68
|
-
expect(BlacklightAdvancedSearch.deep_merge({}, a: '')).to eq(a: '')
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'Arrays' do
|
72
|
-
it 'merges an array' do
|
73
|
-
expect(ahash['array1']).to eq([1, 2, 3, 4])
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'collapse to uniq values when merging' do
|
77
|
-
expect(BlacklightAdvancedSearch.deep_merge({ a: [1, 1, 2, 1] }, a: [3, 2])).to eq(a: [1, 2, 3])
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'does not collapse to uniq values if not merging' do
|
81
|
-
expect(BlacklightAdvancedSearch.deep_merge({ a: [1, 1, 2, 1] }, a: [])).to eq(a: [1, 1, 2, 1])
|
82
|
-
end
|
83
|
-
end
|
11
|
+
BlacklightAdvancedSearch.deep_merge!(@ahash, {
|
12
|
+
"a" => "NEW A",
|
13
|
+
"array1" => [3, 4],
|
14
|
+
"hash1" => {
|
15
|
+
"array" => [2],
|
16
|
+
"b" => "NEW B"
|
17
|
+
},
|
18
|
+
"c" => "NEW C"
|
19
|
+
})
|
84
20
|
end
|
85
21
|
|
86
|
-
describe Hash do
|
87
|
-
it_behaves_like 'Mergable Parameters' do
|
88
|
-
let(:hash_x) { hash_X }
|
89
|
-
let(:hash_y) { hash_Y }
|
90
|
-
end
|
91
|
-
end
|
92
22
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
23
|
+
it "leaves un-collided content alone" do
|
24
|
+
expect(@ahash["b"]).to eq("b")
|
25
|
+
expect(@ahash["array2"]).to eq([3,4])
|
26
|
+
expect(@ahash["hash2"]).to eq({"a2" => "a2", "array2" => [12], "b2" => "b2"})
|
98
27
|
end
|
99
28
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
let(:hash_y) { hash_Y.with_indifferent_access }
|
104
|
-
end
|
29
|
+
it "adds new content" do
|
30
|
+
expect(@ahash["c"]).to eq("NEW C")
|
31
|
+
end
|
105
32
|
|
106
|
-
|
107
|
-
|
108
|
-
let(:hash_y) { hash_Y }
|
109
|
-
end
|
33
|
+
it "merges an array" do
|
34
|
+
expect(@ahash["array1"]).to eq([1,2,3,4])
|
110
35
|
end
|
111
36
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
expect(h1.deep_merge(h2)).to eq(merged)
|
119
|
-
expect(BlacklightAdvancedSearch.deep_merge(h1, h2)).to eq(merged)
|
120
|
-
end
|
37
|
+
it "merges a hash, recursive like" do
|
38
|
+
expect(@ahash["hash1"]).to eq({
|
39
|
+
"a" => "a",
|
40
|
+
"array" => [1,2],
|
41
|
+
"b" => "NEW B"
|
42
|
+
})
|
121
43
|
end
|
122
44
|
|
123
|
-
end
|
45
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blacklight_advanced_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
@@ -9,22 +9,28 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-01-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: blacklight
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 6.0.0.pre
|
21
|
+
- - "<"
|
19
22
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
23
|
+
version: '7'
|
21
24
|
type: :runtime
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
|
-
- - "
|
28
|
+
- - ">"
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 6.0.0.pre
|
31
|
+
- - "<"
|
26
32
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
33
|
+
version: '7'
|
28
34
|
- !ruby/object:Gem::Dependency
|
29
35
|
name: parslet
|
30
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,7 +156,6 @@ files:
|
|
150
156
|
- lib/blacklight_advanced_search/controller.rb
|
151
157
|
- lib/blacklight_advanced_search/engine.rb
|
152
158
|
- lib/blacklight_advanced_search/filter_parser.rb
|
153
|
-
- lib/blacklight_advanced_search/parse_basic_q.rb
|
154
159
|
- lib/blacklight_advanced_search/parsing_nesting_parser.rb
|
155
160
|
- lib/blacklight_advanced_search/redirect_legacy_params_filter.rb
|
156
161
|
- lib/blacklight_advanced_search/render_constraints_override.rb
|
@@ -170,7 +175,6 @@ files:
|
|
170
175
|
- spec/lib/filter_parser_spec.rb
|
171
176
|
- spec/parsing_nesting/build_tree_spec.rb
|
172
177
|
- spec/parsing_nesting/consuming_spec.rb
|
173
|
-
- spec/parsing_nesting/parse_basic_q_spec.rb
|
174
178
|
- spec/parsing_nesting/to_solr_spec.rb
|
175
179
|
- spec/rcov.opts
|
176
180
|
- spec/spec.opts
|
@@ -196,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
200
|
version: '0'
|
197
201
|
requirements: []
|
198
202
|
rubyforge_project: blacklight
|
199
|
-
rubygems_version: 2.
|
203
|
+
rubygems_version: 2.4.5.1
|
200
204
|
signing_key:
|
201
205
|
specification_version: 4
|
202
206
|
summary: Blacklight Advanced Search plugin
|
@@ -209,7 +213,6 @@ test_files:
|
|
209
213
|
- spec/lib/filter_parser_spec.rb
|
210
214
|
- spec/parsing_nesting/build_tree_spec.rb
|
211
215
|
- spec/parsing_nesting/consuming_spec.rb
|
212
|
-
- spec/parsing_nesting/parse_basic_q_spec.rb
|
213
216
|
- spec/parsing_nesting/to_solr_spec.rb
|
214
217
|
- spec/rcov.opts
|
215
218
|
- spec/spec.opts
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'parslet'
|
2
|
-
require 'parsing_nesting/tree'
|
3
|
-
|
4
|
-
# A solr search logic mix-in to CatalogController.
|
5
|
-
# If mixed-in, adds Advanced Search parsing behavior
|
6
|
-
# to queries entered on basic/standard/simple search
|
7
|
-
# form too, for boolean expressions.
|
8
|
-
#
|
9
|
-
# simply:
|
10
|
-
# include BlacklightAdvancedSearch::ParseBasicQ
|
11
|
-
# in your CatalogController
|
12
|
-
module BlacklightAdvancedSearch::ParseBasicQ
|
13
|
-
extend ActiveSupport::Concern
|
14
|
-
extend Deprecation
|
15
|
-
|
16
|
-
self.deprecation_horizon = 'blacklight_advanced_search 6.0'
|
17
|
-
|
18
|
-
include Blacklight::SearchFields
|
19
|
-
|
20
|
-
included do
|
21
|
-
self.search_params_logic += [:add_advanced_parse_q_to_solr]
|
22
|
-
end
|
23
|
-
|
24
|
-
# Different versions of Parslet raise different exception classes,
|
25
|
-
# need to figure out which one exists to rescue
|
26
|
-
PARSLET_FAILED_EXCEPTIONS = if defined? Parslet::UnconsumedInput
|
27
|
-
[Parslet::UnconsumedInput]
|
28
|
-
else
|
29
|
-
[Parslet::ParseFailed]
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
# This method can be included in search_params_logic to have us
|
34
|
-
# parse an ordinary entered :q for AND/OR/NOT and produce appropriate
|
35
|
-
# Solr query. Note that it is NOT included in search_params_logic
|
36
|
-
# by default when this module is included, because it is optional behavior.
|
37
|
-
# BlacklightAdvancedSearch init code will add it to CatalogController
|
38
|
-
# if it's configured to do so. You can of course add it yourself
|
39
|
-
# manually too.
|
40
|
-
#
|
41
|
-
# Note: For syntactically invalid input, we'll just skip the adv
|
42
|
-
# parse and send it straight to solr same as if advanced_parse_q
|
43
|
-
# were not being used.
|
44
|
-
def add_advanced_parse_q_to_solr(solr_parameters, req_params = params)
|
45
|
-
unless req_params[:q].blank?
|
46
|
-
field_def = search_field_def_for_key( req_params[:search_field]) ||
|
47
|
-
default_search_field
|
48
|
-
|
49
|
-
|
50
|
-
# If the individual field has advanced_parse_q suppressed, punt
|
51
|
-
return if field_def[:advanced_parse] == false
|
52
|
-
|
53
|
-
solr_direct_params = field_def[:solr_parameters] || {}
|
54
|
-
solr_local_params = field_def[:solr_local_parameters] || {}
|
55
|
-
|
56
|
-
# See if we can parse it, if we can't, we're going to give up
|
57
|
-
# and just allow basic search, perhaps with a warning.
|
58
|
-
begin
|
59
|
-
adv_search_params = ParsingNesting::Tree.parse(req_params[:q], blacklight_config.advanced_search[:query_parser]).to_single_query_params( solr_local_params )
|
60
|
-
|
61
|
-
BlacklightAdvancedSearch.deep_merge!(solr_parameters, solr_direct_params)
|
62
|
-
BlacklightAdvancedSearch.deep_merge!(solr_parameters, adv_search_params)
|
63
|
-
rescue *PARSLET_FAILED_EXCEPTIONS => e
|
64
|
-
# do nothing, don't merge our input in, keep basic search
|
65
|
-
# optional TODO, display error message in flash here, but hard to
|
66
|
-
# display a good one.
|
67
|
-
return
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
deprecation_deprecate add_advanced_parse_q_to_solr: "use AdvancedSearchBuilder.add_advanced_parse_q_to_solr"
|
72
|
-
|
73
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe "NestingParser" do
|
4
|
-
|
5
|
-
# Our ParseBasicQ mixin assumes a SolrHelper context.
|
6
|
-
# SolrHelper is a controller layer mixin, which depends
|
7
|
-
# on being mixed into a class which has #params (from Rails)
|
8
|
-
# and #blacklight_config
|
9
|
-
#
|
10
|
-
# This technique of testing is copied from Blacklight solr_helper_spec.rb
|
11
|
-
#
|
12
|
-
# It gets kind of a mess of dependencies, sorry.
|
13
|
-
class ParseBasicQTestClass
|
14
|
-
cattr_accessor :blacklight_config
|
15
|
-
|
16
|
-
include Blacklight::SearchHelper
|
17
|
-
|
18
|
-
include BlacklightAdvancedSearch::ParseBasicQ
|
19
|
-
|
20
|
-
|
21
|
-
def initialize blacklight_config
|
22
|
-
self.blacklight_config = blacklight_config
|
23
|
-
end
|
24
|
-
|
25
|
-
def params
|
26
|
-
{}
|
27
|
-
end
|
28
|
-
|
29
|
-
def logger
|
30
|
-
Rails.logger
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "basic functionality" do
|
35
|
-
before do
|
36
|
-
@blacklight_config = Blacklight::Configuration.new do |config|
|
37
|
-
config.advanced_search = {
|
38
|
-
|
39
|
-
}
|
40
|
-
|
41
|
-
config.add_search_field "all_fields" do |field|
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
config.add_search_field "special_field" do |field|
|
46
|
-
field.advanced_parse = false
|
47
|
-
end
|
48
|
-
end
|
49
|
-
@obj = ParseBasicQTestClass.new @blacklight_config
|
50
|
-
end
|
51
|
-
|
52
|
-
it "catches a simple example" do
|
53
|
-
expect(Deprecation).to receive(:warn)
|
54
|
-
solr_params = {}
|
55
|
-
@obj.add_advanced_parse_q_to_solr(solr_params, :q => "one two AND three OR four")
|
56
|
-
|
57
|
-
expect(solr_params[:defType]).to eq("lucene")
|
58
|
-
# We're not testing succesful parsing here, just that it's doing
|
59
|
-
# something that looks like we expect with subqueries.
|
60
|
-
expect(solr_params[:q]).to start_with("_query_:")
|
61
|
-
end
|
62
|
-
|
63
|
-
it "passes through an unparseable example" do
|
64
|
-
expect(Deprecation).to receive(:warn)
|
65
|
-
solr_params = {}
|
66
|
-
unparseable_q = "foo bar\'s AND"
|
67
|
-
@obj.add_advanced_parse_q_to_solr(solr_params, :q => unparseable_q)
|
68
|
-
|
69
|
-
expect(solr_params[:q]).to eq(unparseable_q)
|
70
|
-
end
|
71
|
-
|
72
|
-
it "ignores field with advanced_parse=false" do
|
73
|
-
expect(Deprecation).to receive(:warn)
|
74
|
-
solr_params = {}
|
75
|
-
original_q = "one two AND three OR four"
|
76
|
-
@obj.add_advanced_parse_q_to_solr(solr_params,
|
77
|
-
:search_field => "special_field",
|
78
|
-
:q => original_q
|
79
|
-
)
|
80
|
-
|
81
|
-
expect(solr_params).not_to have_key(:q)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|