stub_solr 0.0.4
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +27 -0
- data/.travis.yml +12 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +79 -0
- data/Rakefile +37 -0
- data/dev_tasks/release.rake +4 -0
- data/dev_tasks/spec.rake +107 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails-5.0.0.1 +22 -0
- data/lib/stub_solr/sunspot_rails_stub_session_proxy.rb +363 -0
- data/lib/stub_solr/version.rb +3 -0
- data/lib/stub_solr.rb +9 -0
- data/stub_solr.gemspec +32 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0dfd9c8199e4ab5c50789791f3149ed9e2c89aac
|
4
|
+
data.tar.gz: e9ac7ef59532089aabee78d66df601068287b42c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: edcf6aaa16e0bbdca4f64e9ee76a3c1599d320461214d67c17063f682b9a392ee9df14dcd14709d3900294b023a8171e9515896fffeea9b515d298cf6c8d50dd
|
7
|
+
data.tar.gz: 13badb963b7b8303ea4476d99e379622e1b9b22c0be94ef345cfd0b011637eea64b09974702b67a23ff55d3a9600238d16f4fe5252dd62284aaea3b57bff9af0
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
AllCops:
|
3
|
+
Exclude:
|
4
|
+
- bin/**/*
|
5
|
+
- dev_tasks/*
|
6
|
+
- gemfiels/*
|
7
|
+
- test/**/*
|
8
|
+
- tmp/**/*
|
9
|
+
TargetRubyVersion: 2.3
|
10
|
+
|
11
|
+
Rails:
|
12
|
+
Enabled: true
|
13
|
+
|
14
|
+
DotPosition:
|
15
|
+
EnforcedStyle: trailing
|
16
|
+
|
17
|
+
Style/EmptyLinesAroundBlockBody:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/EmptyLinesAroundModuleBody:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/EmptyLinesAroundClassBody:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/EmptyLinesAroundMethodBody:
|
27
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Jaigouk Kim
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# StubSolr
|
2
|
+
|
3
|
+
`Sunspot.session = Sunspot::Rails::StubSessionProxy.new(Sunspot.session)` is enough for most of cases but if you want more than `allow_any_instance_of(Sunspot::Rails::StubSessionProxy::Search).to receive(:results).and_return(myExpectedResults)` this gem can be helpful. `kaminari` for pagination and plain AR to mimic resutls.
|
4
|
+
|
5
|
+
this gem depends on `2.2.6` version of sunspot, sunspot_rails.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'stub_solr'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install stub_solr
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
`test_helper` file should have `require 'stub_solr'`. In your test file, add setup and teardown like this
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
class ActivitiesControllerTest < ActionDispatch::IntegrationTest
|
29
|
+
def setup
|
30
|
+
Sunspot.session = Sunspot::Rails::StubSessionProxy.new(
|
31
|
+
Sunspot.session, Activity.all.to_a.concat(Excercise.all.to_a)
|
32
|
+
)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def teardown
|
37
|
+
Sunspot.session = ::Sunspot.session.original_session
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'search with filter' do
|
42
|
+
get search_activities_url(params: { visible: true, search: 'beer' })
|
43
|
+
expected = Activity.where(visible: true).where("title LIKE ?", "%beer%")
|
44
|
+
res = ActiveSupport::JSON.decode(response.body)["activities"]
|
45
|
+
res.size.must_equal expected.size
|
46
|
+
end
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
For searching, it finds all string / text fields for given classes and use them.
|
51
|
+
|
52
|
+
For range search like `greater_than`, it uses array to check an attribute is for range search. by default, it's `%w[time month created_at start end]` but you can change that.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
def setup
|
56
|
+
Sunspot.session = Sunspot::Rails::StubSessionProxy.new(
|
57
|
+
Sunspot.session, Activity.all.to_a.concat(Excercise.all.to_a)
|
58
|
+
)
|
59
|
+
Sunspot.session.set_range_fields(%w[time month created_at departure arrival])
|
60
|
+
super
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
|
65
|
+
## Development
|
66
|
+
|
67
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
68
|
+
|
69
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
70
|
+
|
71
|
+
## Contributing
|
72
|
+
|
73
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jaigouk/stub_solr.
|
74
|
+
|
75
|
+
|
76
|
+
## License
|
77
|
+
|
78
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
79
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/file_list'
|
4
|
+
|
5
|
+
TO_CLEAN = Rake::FileList.new do |fl|
|
6
|
+
fl.include 'tmp/**/*'
|
7
|
+
fl.include '**/.bundle'
|
8
|
+
fl.exclude 'tmp/.gitkeep'
|
9
|
+
end
|
10
|
+
|
11
|
+
CLEAN.include TO_CLEAN
|
12
|
+
|
13
|
+
task :environment do
|
14
|
+
end
|
15
|
+
|
16
|
+
FileList['dev_tasks/*.rake'].each { |file| load(file) }
|
17
|
+
task :default => [:spec]
|
18
|
+
|
19
|
+
desc 'Install bleeding edge gems locally'
|
20
|
+
task :install do
|
21
|
+
system "rm *.gem"
|
22
|
+
system "gem build *.gemspec"
|
23
|
+
system "gem install *.gem"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Release to Rubygems.org'
|
27
|
+
task :release do
|
28
|
+
require File.expand_path('../lib/stub_solr/version', __FILE__)
|
29
|
+
|
30
|
+
version_tag = "v#{StubSolr::VERSION}"
|
31
|
+
system "git tag -am 'Release version #{StubSolr::VERSION}' '#{version_tag}'"
|
32
|
+
system "git push origin #{version_tag}:#{version_tag}"
|
33
|
+
|
34
|
+
system "gem build stub_solr.gemspec"
|
35
|
+
system "gem push stub_solr-#{StubSolr::VERSION}.gem"
|
36
|
+
FileUtils.rm("stub_solr-#{StubSolr::VERSION}.gem")
|
37
|
+
end
|
data/dev_tasks/spec.rake
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
desc 'Run spec suite in all Rails versions'
|
5
|
+
task :spec do
|
6
|
+
puts "Running default task"
|
7
|
+
versions = if ENV['RAILS']
|
8
|
+
ENV['RAILS'].split(",")
|
9
|
+
else
|
10
|
+
rails_all_versions
|
11
|
+
end
|
12
|
+
|
13
|
+
versions.each do |version|
|
14
|
+
puts "Running specs against Rails #{version}..."
|
15
|
+
|
16
|
+
ENV['VERSION'] = version
|
17
|
+
reenable_spec_tasks
|
18
|
+
Rake::Task['spec:run_with_rails'].invoke
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
namespace :spec do
|
24
|
+
def rails_app_path(version)
|
25
|
+
File.join(File.dirname(__FILE__), "..", "tmp", "rails_#{version.gsub(".", "_")}_app")
|
26
|
+
end
|
27
|
+
|
28
|
+
def gemfile_path(version)
|
29
|
+
File.join(File.dirname(__FILE__), "..", "gemfiles", "rails-#{version}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def vendor_path(version)
|
33
|
+
File.expand_path("vendor/bundle", rails_app_path(version))
|
34
|
+
end
|
35
|
+
|
36
|
+
def rails_template_path
|
37
|
+
File.join(File.dirname(__FILE__), "..", "test", "rails_template")
|
38
|
+
end
|
39
|
+
|
40
|
+
def version
|
41
|
+
ENV['VERSION']
|
42
|
+
end
|
43
|
+
|
44
|
+
task :run_with_rails => [:set_gemfile, :generate_rails_app, :initialize_database, :setup_rails_app, :run]
|
45
|
+
|
46
|
+
task :set_gemfile do
|
47
|
+
ENV['BUNDLE_PATH'] = vendor_path(version)
|
48
|
+
ENV['BUNDLE_GEMFILE'] = gemfile_path(version)
|
49
|
+
unless File.exist?(ENV['BUNDLE_PATH'])
|
50
|
+
puts "Installing gems for Rails #{version} (this will only be done once)..."
|
51
|
+
sh("bundle install #{ENV['BUNDLE_ARGS']}") || exit(1)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
task :generate_rails_app do
|
56
|
+
app_path = rails_app_path(version)
|
57
|
+
|
58
|
+
unless File.exist?(File.expand_path("config/environment.rb", app_path))
|
59
|
+
puts "Generating Rails #{version} application..."
|
60
|
+
sh("bundle exec rails _#{version}_ new \"#{app_path}\" --force --skip-git --skip-javascript --skip-gemfile --skip-sprockets") || exit(1)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
task :initialize_database do
|
65
|
+
if ENV['DB'] == 'postgres'
|
66
|
+
sh "bundle exec rake db:test:prepare"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
task :setup_rails_app do
|
71
|
+
FileUtils.cp_r File.join(rails_template_path, "."), rails_app_path(version)
|
72
|
+
end
|
73
|
+
|
74
|
+
# task :load_fixtures do
|
75
|
+
# puts "loading fixtures..."
|
76
|
+
# sh "bundle exec rake db:fixtures:load RAILS_ENV=test FIXTURES_DIR='test/fixtures'"
|
77
|
+
# end
|
78
|
+
|
79
|
+
task :run do
|
80
|
+
ENV['BUNDLE_GEMFILE'] = gemfile_path(version)
|
81
|
+
ENV['RAILS_ROOT'] = rails_app_path(version)
|
82
|
+
|
83
|
+
sh "bundle exec ruby -I test #{ENV['SPEC'] || 'test/*_spec.rb'}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def rails_all_versions
|
89
|
+
versions = []
|
90
|
+
puts "getting rails versions to test"
|
91
|
+
Dir.glob(File.join(File.dirname(__FILE__), "..", "gemfiles", "rails-*")).each do |gemfile|
|
92
|
+
if !gemfile.end_with?(".lock") && gemfile =~ /rails-([0-9.]+)/
|
93
|
+
versions << $1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
puts versions.to_s
|
98
|
+
versions
|
99
|
+
end
|
100
|
+
|
101
|
+
def reenable_spec_tasks
|
102
|
+
Rake::Task.tasks.each do |task|
|
103
|
+
if task.name =~ /spec:/
|
104
|
+
task.reenable
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gem 'rails', '~> 5.0.0.1'
|
3
|
+
gem 'sunspot', '2.2.6'
|
4
|
+
gem 'sunspot_solr', '2.2.6'
|
5
|
+
gem 'sunspot_rails', '2.2.6'
|
6
|
+
gem 'kaminari'
|
7
|
+
gem 'rake', '11.2.0'
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem 'minitest-rails'
|
11
|
+
gem 'minitest-reporters'
|
12
|
+
gem 'byebug'
|
13
|
+
gem 'stub_solr', :path => File.expand_path('../..', __FILE__)
|
14
|
+
end
|
15
|
+
|
16
|
+
group :postgres do
|
17
|
+
gem 'pg'
|
18
|
+
end
|
19
|
+
|
20
|
+
group :sqlite do
|
21
|
+
gem 'sqlite3'
|
22
|
+
end
|
@@ -0,0 +1,363 @@
|
|
1
|
+
|
2
|
+
# stub solr with "dara" array for testing.
|
3
|
+
# if there is no data then it will behave like default blank search
|
4
|
+
# this stub uses Kaminari for pagination
|
5
|
+
# once the data is given, solr search block will call search
|
6
|
+
# and that will create a new Search with arguments.
|
7
|
+
# With the search, it passes the given data as @operation_context.
|
8
|
+
# And "run_proc_block" method will go through each search conditions
|
9
|
+
# in the block. while going through the block, it will change @operation_context
|
10
|
+
#
|
11
|
+
class Sunspot::Rails::StubSessionProxy
|
12
|
+
attr_reader :block, :data, :range_fields
|
13
|
+
|
14
|
+
def initialize(original_session, data = [])
|
15
|
+
@original_session = original_session
|
16
|
+
@data = data
|
17
|
+
@range_fields = %w[time month created_at start end]
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_range_fields(arr)
|
21
|
+
@range_fields = arr
|
22
|
+
end
|
23
|
+
|
24
|
+
def search(*types, &block)
|
25
|
+
Search.new(@data, types, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# with and fulltext can be called multiple times
|
29
|
+
# based on the block. that's why i am mutating @results
|
30
|
+
#
|
31
|
+
# for all and any block, we need to consult sunspot/lib/sunspot/dsl/standard_query.rb
|
32
|
+
#
|
33
|
+
class Search
|
34
|
+
attr_reader :block, :types, :page, :per_page, :grouped_results
|
35
|
+
def initialize(results = [], types = [], &block)
|
36
|
+
@facets = {}
|
37
|
+
@search_data = results
|
38
|
+
@block = block
|
39
|
+
@types = types
|
40
|
+
@page = 1
|
41
|
+
@per_page = 30
|
42
|
+
@grouped_results = {}
|
43
|
+
@group_key = ""
|
44
|
+
@range_search_field = nil
|
45
|
+
@operation_context = [{operation: "all", result: @search_data}]
|
46
|
+
@current_context_index = 0
|
47
|
+
@order_key = nil
|
48
|
+
@order_direction = nil
|
49
|
+
@textsearch_priorities = {}
|
50
|
+
@search_term = ""
|
51
|
+
run_proc_block
|
52
|
+
end
|
53
|
+
|
54
|
+
def final_results
|
55
|
+
@operation_context.last[:result]
|
56
|
+
end
|
57
|
+
|
58
|
+
def results
|
59
|
+
return PaginatedCollection.new if sorted_temp_result.empty?
|
60
|
+
return sorted_temp_result if final_results.is_a? Kaminari::PaginatableArray
|
61
|
+
Kaminari.paginate_array(sorted_temp_result).page(@page).per(@per_page)
|
62
|
+
end
|
63
|
+
|
64
|
+
def any_of(&bl)
|
65
|
+
previous_result = result_for_current_context
|
66
|
+
@operation_context.push({operation: "any", result: previous_result, temp_result: []})
|
67
|
+
@current_context_index += 1
|
68
|
+
|
69
|
+
Sunspot::Util::ContextBoundDelegate.instance_eval_with_context(self, &bl)
|
70
|
+
after_results = @operation_context[@current_context_index][:temp_result]
|
71
|
+
|
72
|
+
parent_temp_result = @operation_context[@current_context_index - 1][:temp_result]
|
73
|
+
|
74
|
+
|
75
|
+
unless @current_context_index == 0
|
76
|
+
@current_context_index -= 1
|
77
|
+
@operation_context.pop
|
78
|
+
end
|
79
|
+
# parent is now current context
|
80
|
+
if parent_temp_result
|
81
|
+
@operation_context[@current_context_index][:temp_result] = parent_temp_result.concat(after_results)
|
82
|
+
else
|
83
|
+
@operation_context[@current_context_index][:result] = after_results
|
84
|
+
end
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def all_of(&bl)
|
89
|
+
previous_result = result_for_current_context
|
90
|
+
@operation_context.push({operation: "all", result: previous_result})
|
91
|
+
@current_context_index += 1
|
92
|
+
|
93
|
+
Sunspot::Util::ContextBoundDelegate.instance_eval_with_context(self, &bl)
|
94
|
+
after_results = result_for_current_context
|
95
|
+
parent_temp_result = @operation_context[@current_context_index - 1][:temp_result]
|
96
|
+
|
97
|
+
unless @current_context_index == 0
|
98
|
+
@current_context_index -= 1
|
99
|
+
@operation_context.pop
|
100
|
+
end
|
101
|
+
|
102
|
+
# parent is now current context
|
103
|
+
if parent_temp_result
|
104
|
+
@operation_context[@current_context_index][:temp_result] = parent_temp_result.concat(after_results)
|
105
|
+
else
|
106
|
+
@operation_context[@current_context_index][:result] = (previous_result & after_results).uniq
|
107
|
+
end
|
108
|
+
|
109
|
+
self
|
110
|
+
end
|
111
|
+
|
112
|
+
def with(attribute, value = "no_value")
|
113
|
+
skip_no_value(attribute, value)
|
114
|
+
|
115
|
+
if attribute == :search_class
|
116
|
+
matches = result_for_current_context.select {|x| x.class.name == value }
|
117
|
+
operation_context_result(matches)
|
118
|
+
return self
|
119
|
+
end
|
120
|
+
|
121
|
+
if value == nil && attribute_is_about_range?(attribute)
|
122
|
+
matches = result_for_current_context.select {|x| x.has_attribute?(attribute) && (x.read_attribute(attribute) == value)}
|
123
|
+
operation_context_result(matches)
|
124
|
+
return self
|
125
|
+
end
|
126
|
+
|
127
|
+
return self if value == "no_value" || attribute == :location
|
128
|
+
|
129
|
+
matches = if value.class.name == "Array"
|
130
|
+
result_for_current_context.select {|x| value.include?(x.send(attribute)) }
|
131
|
+
elsif @types.map{|x| x.has_attribute?(attribute)}.include?(true)
|
132
|
+
result_for_current_context.select {|x| x.read_attribute(attribute) == value }
|
133
|
+
else
|
134
|
+
result_for_current_context.select {|x| x.send(attribute) == value }
|
135
|
+
end
|
136
|
+
operation_context_result(matches)
|
137
|
+
self
|
138
|
+
end
|
139
|
+
|
140
|
+
def without(attribute, value = "no_value")
|
141
|
+
skip_no_value(attribute, value)
|
142
|
+
if value == nil && attribute_is_about_range?(attribute)
|
143
|
+
matches = result_for_current_context.select {|x| x.has_attribute?(attribute) && !(x.read_attribute(attribute) == value)}
|
144
|
+
operation_context_result(matches)
|
145
|
+
return self
|
146
|
+
end
|
147
|
+
|
148
|
+
return self if value == "no_value" || attribute == :location
|
149
|
+
matches = if value.class.name == "Array"
|
150
|
+
result_for_current_context.select {|x| x.has_attribute?(attribute) && !value.include?(x.send(attribute)) }
|
151
|
+
else
|
152
|
+
result_for_current_context.select {|x| x.has_attribute?(attribute) && !x.read_attribute(attribute).nil? && (x.read_attribute(attribute) != value) }
|
153
|
+
end
|
154
|
+
operation_context_result(matches)
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
def hits
|
159
|
+
self
|
160
|
+
end
|
161
|
+
|
162
|
+
# Added to pass .group_by
|
163
|
+
# Idea is save grouped hash result seperately and then
|
164
|
+
# access it with [] method.
|
165
|
+
#
|
166
|
+
# initial_grouped_hits = initial.hits.group_by(&:class_name)
|
167
|
+
# initial_grouped_hits["Activity"]
|
168
|
+
def [](key)
|
169
|
+
return if @grouped_results.empty? || @grouped_results[key].nil?
|
170
|
+
@group_key = key
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
# possible situation
|
175
|
+
#
|
176
|
+
# initial_grouped_hits = initial.hits.group_by(&:class_name)
|
177
|
+
# initial_grouped_hits["Activity"].map(&:primary_key)
|
178
|
+
def map(&pr)
|
179
|
+
return unless @grouped_results[@group_key]
|
180
|
+
@grouped_results[@group_key].map{|x| x.id}
|
181
|
+
end
|
182
|
+
|
183
|
+
# possible situation
|
184
|
+
#
|
185
|
+
# initial_grouped_hits = initial.hits.group_by(&:class_name)
|
186
|
+
def group_by(class_name = nil)
|
187
|
+
return self if final_results.empty?
|
188
|
+
@types.each do |type|
|
189
|
+
@grouped_results[type.name] = sorted_temp_result.group_by{|i| i.class.name == type.name }[true]
|
190
|
+
end
|
191
|
+
self
|
192
|
+
end
|
193
|
+
|
194
|
+
def phrase_fields(arg)
|
195
|
+
@textsearch_priorities = arg
|
196
|
+
return self if @search_term.empty?
|
197
|
+
fulltext(@search_term)
|
198
|
+
end
|
199
|
+
|
200
|
+
def query_phrase_slop(*args)
|
201
|
+
fulltext(@search_term)
|
202
|
+
end
|
203
|
+
|
204
|
+
# with default `StubSessionProxy`, the results is blank whatever
|
205
|
+
# argument or options you put in the search block
|
206
|
+
def fulltext(term, opt={}, &bl)
|
207
|
+
matches = []
|
208
|
+
@search_term = term
|
209
|
+
Sunspot::Util::ContextBoundDelegate.instance_eval_with_context(self, &bl) if !bl.nil?
|
210
|
+
# if there is phrase_fields option then we only search for the field
|
211
|
+
# to mimic the priority search. #string_text_fields
|
212
|
+
@types.each do |type|
|
213
|
+
string_text_fields(type).each do |field|
|
214
|
+
if type.has_attribute?(field.to_sym)
|
215
|
+
matches << type.where(type.arel_table[field.to_sym].matches("%#{term}%")).to_a
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
calculated = (result_for_current_context & matches.flatten.uniq)
|
220
|
+
operation_context_result(calculated)
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
224
|
+
def order_by(attribute, direction)
|
225
|
+
@order_key = attribute
|
226
|
+
@order_direction = direction
|
227
|
+
self
|
228
|
+
end
|
229
|
+
|
230
|
+
def in_radius(*args)
|
231
|
+
calculated = result_for_current_context.select do |r|
|
232
|
+
distance = r&.location&.distance_from([args[0], args[1]])
|
233
|
+
distance && distance < args[2].to_i
|
234
|
+
end
|
235
|
+
operation_context_result(calculated)
|
236
|
+
self
|
237
|
+
end
|
238
|
+
|
239
|
+
def greater_than(time)
|
240
|
+
calculated = result_for_current_context.select do |x|
|
241
|
+
has_attribute_and_not_nil(x) &&
|
242
|
+
x.read_attribute(@range_search_field) > time
|
243
|
+
end.uniq
|
244
|
+
operation_context_result(calculated)
|
245
|
+
self
|
246
|
+
end
|
247
|
+
|
248
|
+
def greater_than_or_equal_to(time)
|
249
|
+
calculated = result_for_current_context.select do |x|
|
250
|
+
has_attribute_and_not_nil(x) &&
|
251
|
+
x.read_attribute(@range_search_field) >= time
|
252
|
+
end.uniq
|
253
|
+
operation_context_result(calculated)
|
254
|
+
self
|
255
|
+
end
|
256
|
+
|
257
|
+
def less_than(time)
|
258
|
+
calculated = result_for_current_context.select do |x|
|
259
|
+
has_attribute_and_not_nil(x) &&
|
260
|
+
x.read_attribute(@range_search_field) < time
|
261
|
+
end.uniq
|
262
|
+
operation_context_result(calculated)
|
263
|
+
self
|
264
|
+
end
|
265
|
+
|
266
|
+
def less_than_or_equal_to(time)
|
267
|
+
calculated = result_for_current_context.select do |x|
|
268
|
+
has_attribute_and_not_nil(x) &&
|
269
|
+
x.read_attribute(@range_search_field) <= time
|
270
|
+
end.uniq
|
271
|
+
operation_context_result(calculated)
|
272
|
+
self
|
273
|
+
end
|
274
|
+
|
275
|
+
def paginate(args={})
|
276
|
+
@page = args[:page]
|
277
|
+
@per_page = args[:per_page]
|
278
|
+
self
|
279
|
+
end
|
280
|
+
|
281
|
+
def total
|
282
|
+
@operation_context.last[:result].size
|
283
|
+
end
|
284
|
+
|
285
|
+
private
|
286
|
+
|
287
|
+
# iterate the given block and change @operation_context
|
288
|
+
# block may cotain with, without, fulltext, paginate, in_raius, order_by
|
289
|
+
def run_proc_block
|
290
|
+
result = @operation_context.last[:result]
|
291
|
+
return PaginatedCollection.new if result.empty?
|
292
|
+
|
293
|
+
Sunspot::Util::ContextBoundDelegate.instance_eval_with_context(self, &@block)
|
294
|
+
# @operation_context.last[:result] = @operation_context.last[:result].uniq
|
295
|
+
self
|
296
|
+
end
|
297
|
+
|
298
|
+
def current_operation
|
299
|
+
@operation_context[@current_context_index][:operation]
|
300
|
+
end
|
301
|
+
|
302
|
+
def result_for_current_context
|
303
|
+
@operation_context[@current_context_index][:result]
|
304
|
+
end
|
305
|
+
|
306
|
+
def temp_result_for_current_context
|
307
|
+
@operation_context[@current_context_index][:temp_result]
|
308
|
+
end
|
309
|
+
|
310
|
+
def operation_context_result(after_results)
|
311
|
+
previous_result = result_for_current_context
|
312
|
+
# parent_result = @operation_context[@current_context_index -1][:result]
|
313
|
+
temp_result = @operation_context[@current_context_index][:temp_result]
|
314
|
+
if current_operation == "any"
|
315
|
+
@operation_context[@current_context_index][:result] = previous_result.concat(after_results).uniq
|
316
|
+
if temp_result
|
317
|
+
@operation_context[@current_context_index][:temp_result] = temp_result.concat(after_results)
|
318
|
+
end
|
319
|
+
else
|
320
|
+
@operation_context[@current_context_index][:result] = (previous_result & after_results).uniq
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def skip_no_value(attribute, value)
|
325
|
+
if value == "no_value" && attribute_is_about_range?(attribute)
|
326
|
+
matches = result_for_current_context.select {|x| x.has_attribute?(attribute)}
|
327
|
+
operation_context_result(matches)
|
328
|
+
return self
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def has_attribute_and_not_nil(x)
|
333
|
+
x.read_attribute(@range_search_field) &&
|
334
|
+
!x.read_attribute(@range_search_field).nil?
|
335
|
+
end
|
336
|
+
|
337
|
+
def string_text_fields(type)
|
338
|
+
return @textsearch_priorities.keys unless @textsearch_priorities.keys.empty?
|
339
|
+
type.columns.collect { |c| {"#{c.type}":"#{c.name}"} }
|
340
|
+
.map{|hash| hash.select{|k,v| [:string, :text].include? k} }.uniq
|
341
|
+
.map{|x| x.values}.flatten
|
342
|
+
end
|
343
|
+
|
344
|
+
def attribute_is_about_range?(attribute)
|
345
|
+
matched = nil
|
346
|
+
Sunspot.session.range_fields.each do |x|
|
347
|
+
if attribute.to_s.include? x
|
348
|
+
matched = true
|
349
|
+
@range_search_field = attribute
|
350
|
+
break
|
351
|
+
end
|
352
|
+
end
|
353
|
+
matched
|
354
|
+
end
|
355
|
+
|
356
|
+
def sorted_temp_result
|
357
|
+
return final_results unless @order_direction
|
358
|
+
asc = final_results.sort_by{|x| x[@order_key]}
|
359
|
+
return asc if @order_direction.to_s.downcase.include?("asc")
|
360
|
+
asc.reverse
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
data/lib/stub_solr.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'kaminari'
|
2
|
+
module Kaminari::PageScopeMethods
|
3
|
+
alias_method :previous_page, :prev_page
|
4
|
+
end
|
5
|
+
require 'sunspot'
|
6
|
+
require 'sunspot_rails'
|
7
|
+
require 'rails'
|
8
|
+
require "stub_solr/version"
|
9
|
+
require File.expand_path('stub_solr/sunspot_rails_stub_session_proxy', File.dirname(__FILE__))
|
data/stub_solr.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path('../lib/stub_solr/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'stub_solr'
|
7
|
+
gem.version = StubSolr::VERSION
|
8
|
+
gem.authors = ['Jaigouk Kim']
|
9
|
+
gem.email = ['ping@jaigouk.kim']
|
10
|
+
|
11
|
+
gem.summary = %q{stub sunspot to test }
|
12
|
+
gem.description = %q{overrided StubSessionProxy with AR queries to mimic sunspot }
|
13
|
+
gem.homepage = 'https://github.com/jaigouk/stub_solr'
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
16
|
+
gem.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
gem.bindir = 'bin'
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
gem.require_paths = ['lib']
|
20
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
21
|
+
|
22
|
+
gem.add_dependency 'kaminari', '~> 0.17.0'
|
23
|
+
gem.add_dependency 'sunspot', '~> 2.2.6'
|
24
|
+
gem.add_dependency 'sunspot_solr', '~> 2.2.6'
|
25
|
+
gem.add_dependency 'sunspot_rails', '~> 2.2.6'
|
26
|
+
gem.add_dependency 'rails', '>= 4'
|
27
|
+
|
28
|
+
# gem.add_development_dependency 'simplecov', '~> 0.12.0'
|
29
|
+
gem.add_development_dependency 'bundler', '~> 1.12'
|
30
|
+
gem.add_development_dependency 'minitest', '~> 5.0'
|
31
|
+
gem.add_development_dependency 'minitest-reporters', '~> 1.1.11'
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stub_solr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jaigouk Kim
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kaminari
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.17.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.17.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sunspot
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.6
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.2.6
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sunspot_solr
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.2.6
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.2.6
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sunspot_rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.2.6
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.2.6
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.12'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: minitest
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '5.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '5.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest-reporters
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.1.11
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.1.11
|
125
|
+
description: 'overrided StubSessionProxy with AR queries to mimic sunspot '
|
126
|
+
email:
|
127
|
+
- ping@jaigouk.kim
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rubocop.yml"
|
134
|
+
- ".travis.yml"
|
135
|
+
- Gemfile
|
136
|
+
- LICENSE.txt
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- dev_tasks/release.rake
|
140
|
+
- dev_tasks/spec.rake
|
141
|
+
- gemfiles/.bundle/config
|
142
|
+
- gemfiles/rails-5.0.0.1
|
143
|
+
- lib/stub_solr.rb
|
144
|
+
- lib/stub_solr/sunspot_rails_stub_session_proxy.rb
|
145
|
+
- lib/stub_solr/version.rb
|
146
|
+
- stub_solr.gemspec
|
147
|
+
homepage: https://github.com/jaigouk/stub_solr
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.5.1
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: stub sunspot to test
|
171
|
+
test_files: []
|