slingshot-rb 0.0.1
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.
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +164 -0
- data/Rakefile +52 -0
- data/examples/dsl.rb +70 -0
- data/lib/slingshot/client.rb +25 -0
- data/lib/slingshot/configuration.rb +15 -0
- data/lib/slingshot/dsl.rb +17 -0
- data/lib/slingshot/index.rb +42 -0
- data/lib/slingshot/results/collection.rb +22 -0
- data/lib/slingshot/rubyext/hash.rb +3 -0
- data/lib/slingshot/search/facet.rb +34 -0
- data/lib/slingshot/search/query.rb +33 -0
- data/lib/slingshot/search/sort.rb +24 -0
- data/lib/slingshot/search.rb +70 -0
- data/lib/slingshot/slingshot-rb.rb +1 -0
- data/lib/slingshot/version.rb +3 -0
- data/lib/slingshot.rb +18 -0
- data/slingshot.gemspec +41 -0
- data/test/fixtures/articles/1.json +1 -0
- data/test/fixtures/articles/2.json +1 -0
- data/test/fixtures/articles/3.json +1 -0
- data/test/fixtures/articles/4.json +1 -0
- data/test/fixtures/articles/5.json +1 -0
- data/test/integration/facets_test.rb +47 -0
- data/test/integration/query_string_test.rb +43 -0
- data/test/integration/sort_test.rb +36 -0
- data/test/test_helper.rb +46 -0
- data/test/unit/client_test.rb +35 -0
- data/test/unit/configuration_test.rb +34 -0
- data/test/unit/index_test.rb +71 -0
- data/test/unit/results_collection_test.rb +31 -0
- data/test/unit/search_facet_test.rb +44 -0
- data/test/unit/search_query_test.rb +40 -0
- data/test/unit/search_sort_test.rb +42 -0
- data/test/unit/search_test.rb +106 -0
- data/test/unit/slingshot_test.rb +17 -0
- metadata +241 -0
@@ -0,0 +1 @@
|
|
1
|
+
{"title" : "One", "tags" : ["ruby"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"title" : "Two", "tags" : ["ruby", "python"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"title" : "Three", "tags" : ["java"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"title" : "Four", "tags" : ["erlang"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"title" : "Five", "tags" : ["javascript", "java"]}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class FacetsIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Facets" do
|
9
|
+
|
10
|
+
should "return results scoped to current query" do
|
11
|
+
q = 'tags:ruby'
|
12
|
+
s = Slingshot.search('articles-test') do
|
13
|
+
query { string q }
|
14
|
+
facet 'tags' do
|
15
|
+
terms :tags
|
16
|
+
end
|
17
|
+
end
|
18
|
+
facets = s.results.facets['tags']['terms']
|
19
|
+
assert_equal 2, facets.count
|
20
|
+
assert_equal 'ruby', facets.first['term']
|
21
|
+
assert_equal 2, facets.first['count']
|
22
|
+
end
|
23
|
+
|
24
|
+
should "allow to specify global facets and query-scoped facets" do
|
25
|
+
q = 'tags:ruby'
|
26
|
+
s = Slingshot.search('articles-test') do
|
27
|
+
query { string q }
|
28
|
+
facet 'scoped-tags' do
|
29
|
+
terms :tags
|
30
|
+
end
|
31
|
+
facet 'global-tags', :global => true do
|
32
|
+
terms :tags
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
scoped_facets = s.results.facets['scoped-tags']['terms']
|
37
|
+
global_facets = s.results.facets['global-tags']['terms']
|
38
|
+
|
39
|
+
assert_equal 2, scoped_facets.count
|
40
|
+
assert_equal 5, global_facets.count
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class QueryStringIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Searching for query string" do
|
9
|
+
|
10
|
+
should "find article by title" do
|
11
|
+
q = 'title:one'
|
12
|
+
assert_equal 1, search(q).results.count
|
13
|
+
assert_equal 'One', search(q).results.first['_source']['title']
|
14
|
+
end
|
15
|
+
|
16
|
+
should "find articles by title with boosting" do
|
17
|
+
q = 'title:one^100 OR title:two'
|
18
|
+
assert_equal 2, search(q).results.count
|
19
|
+
assert_equal 'One', search(q).results.first['_source']['title']
|
20
|
+
end
|
21
|
+
|
22
|
+
should "find articles by tags" do
|
23
|
+
q = 'tags:ruby AND tags:python'
|
24
|
+
assert_equal 1, search(q).results.count
|
25
|
+
assert_equal 'Two', search(q).results.first['_source']['title']
|
26
|
+
end
|
27
|
+
|
28
|
+
should "find any article with tags" do
|
29
|
+
q = 'tags:ruby OR tags:python OR tags:java'
|
30
|
+
assert_equal 4, search(q).results.count
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def search(q)
|
38
|
+
Slingshot.search('articles-test') { query { string q } }
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class SortIntegrationTest < Test::Unit::TestCase
|
6
|
+
include Test::Integration
|
7
|
+
|
8
|
+
context "Sort" do
|
9
|
+
|
10
|
+
should "sort by title" do
|
11
|
+
q = '*'
|
12
|
+
s = Slingshot.search('articles-test') do
|
13
|
+
query { string q }
|
14
|
+
sort { title }
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_equal 5, s.results.count
|
18
|
+
assert_equal 'Five', s.results.first['_source']['title']
|
19
|
+
end
|
20
|
+
|
21
|
+
should "sort by title, descending" do
|
22
|
+
q = '*'
|
23
|
+
s = Slingshot.search('articles-test') do
|
24
|
+
query { string q }
|
25
|
+
sort { title :desc }
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_equal 5, s.results.count
|
29
|
+
assert_equal 'Two', s.results.first['_source']['title']
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'mocha'
|
5
|
+
require 'turn' unless ENV["TM_FILEPATH"]
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
require 'slingshot'
|
9
|
+
|
10
|
+
class Test::Unit::TestCase
|
11
|
+
|
12
|
+
def fixtures_path
|
13
|
+
Pathname( File.expand_path( 'fixtures', File.dirname(__FILE__) ) )
|
14
|
+
end
|
15
|
+
|
16
|
+
def fixture_file(path)
|
17
|
+
File.read File.expand_path( path, fixtures_path )
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
module Test::Integration
|
23
|
+
URL = "http://localhost:9200"
|
24
|
+
|
25
|
+
def setup
|
26
|
+
begin
|
27
|
+
::RestClient.get URL
|
28
|
+
rescue Errno::ECONNREFUSED
|
29
|
+
abort "\n\n#{'-'*87}\n[ABORTED] You have to run ElasticSearch on #{URL} for integration tests\n#{'-'*87}\n\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
::RestClient.delete "#{URL}/articles-test" rescue nil
|
33
|
+
::RestClient.post "#{URL}/articles-test", ''
|
34
|
+
fixtures_path.join('articles').entries.each do |f|
|
35
|
+
filename = f.to_s
|
36
|
+
next if filename =~ /^\./
|
37
|
+
::RestClient.put "#{URL}/articles-test/article/#{File.basename(filename, '.*')}",
|
38
|
+
fixtures_path.join('articles').join(f).read
|
39
|
+
end
|
40
|
+
::RestClient.post "#{URL}/articles-test/_refresh", ''
|
41
|
+
end
|
42
|
+
|
43
|
+
def teardown
|
44
|
+
::RestClient.delete "#{URL}/articles-test" rescue nil
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class ClientTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Base" do
|
8
|
+
setup { @http ||= Client::Base.new }
|
9
|
+
|
10
|
+
should "have abstract methods" do
|
11
|
+
assert_raise(ArgumentError) { @http.post }
|
12
|
+
assert_raise(ArgumentError) { @http.post 'URL' }
|
13
|
+
assert_raise(NoMethodError) { @http.post 'URL', 'DATA' }
|
14
|
+
|
15
|
+
assert_raise(ArgumentError) { @http.delete }
|
16
|
+
assert_raise(NoMethodError) { @http.delete 'URL' }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "RestClient" do
|
21
|
+
|
22
|
+
should "be default" do
|
23
|
+
assert_equal Client::RestClient, Configuration.client
|
24
|
+
end
|
25
|
+
|
26
|
+
should "respond to post and delete" do
|
27
|
+
assert_respond_to Client::RestClient, :post
|
28
|
+
assert_respond_to Client::RestClient, :delete
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class ConfigurationTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Configuration" do
|
8
|
+
setup do
|
9
|
+
Configuration.instance_variable_set(:@url, nil)
|
10
|
+
Configuration.instance_variable_set(:@client, nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
should "return default URL" do
|
14
|
+
assert_equal 'http://localhost:9200', Configuration.url
|
15
|
+
end
|
16
|
+
|
17
|
+
should "allow setting and retrieving the URL" do
|
18
|
+
assert_nothing_raised { Configuration.url 'http://example.com' }
|
19
|
+
assert_equal 'http://example.com', Configuration.url
|
20
|
+
end
|
21
|
+
|
22
|
+
should "return default client" do
|
23
|
+
assert_equal Client::RestClient, Configuration.client
|
24
|
+
end
|
25
|
+
|
26
|
+
should "allow setting and retrieving the client" do
|
27
|
+
assert_nothing_raised { Configuration.client Client::Base }
|
28
|
+
assert_equal Client::Base, Configuration.client
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class IndexTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Index" do
|
8
|
+
|
9
|
+
setup do
|
10
|
+
@index = Slingshot::Index.new 'dummy'
|
11
|
+
end
|
12
|
+
|
13
|
+
should "create new index" do
|
14
|
+
Configuration.client.expects(:post).returns('{"ok":true,"acknowledged":true}')
|
15
|
+
assert @index.create
|
16
|
+
end
|
17
|
+
|
18
|
+
should "not raise exception and just return false when trying to create existing index" do
|
19
|
+
Configuration.client.expects(:post).raises(RestClient::BadRequest)
|
20
|
+
assert_nothing_raised { assert ! @index.create }
|
21
|
+
end
|
22
|
+
|
23
|
+
should "delete index" do
|
24
|
+
Configuration.client.expects(:delete).returns('{"ok":true,"acknowledged":true}')
|
25
|
+
assert @index.delete
|
26
|
+
end
|
27
|
+
|
28
|
+
should "not raise exception and just return false when deleting non-existing index" do
|
29
|
+
Configuration.client.expects(:delete).returns('{"error":"[articles] missing"}')
|
30
|
+
assert_nothing_raised { assert ! @index.delete }
|
31
|
+
Configuration.client.expects(:delete).raises(RestClient::BadRequest)
|
32
|
+
assert_nothing_raised { assert ! @index.delete }
|
33
|
+
end
|
34
|
+
|
35
|
+
should "refresh the index" do
|
36
|
+
Configuration.client.expects(:post).returns('{"ok":true,"_shards":{}}')
|
37
|
+
assert_nothing_raised { assert @index.refresh }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when storing" do
|
41
|
+
|
42
|
+
should "properly set type from args" do
|
43
|
+
Configuration.client.expects(:post).with("#{Configuration.url}/dummy/article/", '{"title":"Test"}').returns('{"ok":true,"_id":"test"}').twice
|
44
|
+
@index.store 'article', :title => 'Test'
|
45
|
+
@index.store :article, :title => 'Test'
|
46
|
+
end
|
47
|
+
|
48
|
+
should "set default type" do
|
49
|
+
Configuration.client.expects(:post).with("#{Configuration.url}/dummy/document/", '{"title":"Test"}').returns('{"ok":true,"_id":"test"}')
|
50
|
+
@index.store :title => 'Test'
|
51
|
+
end
|
52
|
+
|
53
|
+
should "call #to_indexed_json on non-String documents" do
|
54
|
+
document = { :title => 'Test' }
|
55
|
+
Configuration.client.expects(:post).returns('{"ok":true,"_id":"test"}')
|
56
|
+
document.expects(:to_indexed_json)
|
57
|
+
@index.store document
|
58
|
+
end
|
59
|
+
|
60
|
+
should "raise error when storing neither String nor object with #to_indexed_json method" do
|
61
|
+
class MyDocument;end; document = MyDocument.new
|
62
|
+
assert_raise(ArgumentError) { @index.store document }
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class ResultsCollectionTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Collection" do
|
8
|
+
setup do
|
9
|
+
@default_response = { 'hits' => { 'hits' => [1, 2, 3] } }
|
10
|
+
end
|
11
|
+
|
12
|
+
should "be iterable" do
|
13
|
+
assert_respond_to Results::Collection.new(@default_response), :each
|
14
|
+
assert_nothing_raised do
|
15
|
+
Results::Collection.new(@default_response).each { |item| item + 1 }
|
16
|
+
Results::Collection.new(@default_response).map { |item| item + 1 }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
should "be initialized with parsed json" do
|
21
|
+
assert_nothing_raised do
|
22
|
+
collection = Results::Collection.new( @default_response )
|
23
|
+
assert_equal [1,2,3], collection.results
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot::Search
|
4
|
+
|
5
|
+
class FacetTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Facet" do
|
8
|
+
|
9
|
+
should "be serialized to JSON" do
|
10
|
+
assert_respond_to Sort.new, :to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
context "generally" do
|
14
|
+
|
15
|
+
should "encode facets with defaults for current query" do
|
16
|
+
assert_equal( { :foo => { :terms => {:field=>'bar'} } }.to_json, Facet.new('foo').terms(:bar).to_json )
|
17
|
+
end
|
18
|
+
|
19
|
+
should "encode facets as global" do
|
20
|
+
assert_equal( { :foo => { :terms => {:field=>'bar'}, :global => true } }.to_json,
|
21
|
+
Facet.new('foo', :global => true).terms(:bar).to_json )
|
22
|
+
end
|
23
|
+
|
24
|
+
should "encode facet options" do
|
25
|
+
assert_equal( { :foo => { :terms => {:field=>'bar'}, :size => 5 } }.to_json,
|
26
|
+
Facet.new('foo', :size => 5).terms(:bar).to_json )
|
27
|
+
assert_equal( { :foo => { :terms => {:field=>'bar'}, :size => 5 } }.to_json,
|
28
|
+
Facet.new('foo').terms(:bar, :size => 5).to_json )
|
29
|
+
end
|
30
|
+
|
31
|
+
should "encode facets when passed as a block" do
|
32
|
+
f = Facet.new('foo') do
|
33
|
+
terms :bar
|
34
|
+
end
|
35
|
+
assert_equal( { :foo => { :terms => {:field=>'bar'} } }.to_json, f.to_json )
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot::Search
|
4
|
+
|
5
|
+
class QueryTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Query" do
|
8
|
+
|
9
|
+
should "be serialized to JSON" do
|
10
|
+
assert_respond_to Query.new, :to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
should "allow search for single term" do
|
14
|
+
assert_equal( { :term => { :foo => 'bar' } }, Query.new.term(:foo, 'bar') )
|
15
|
+
end
|
16
|
+
|
17
|
+
should "allow search for multiple terms" do
|
18
|
+
assert_equal( { :terms => { :foo => ['bar', 'baz'] } }, Query.new.terms(:foo, ['bar', 'baz']) )
|
19
|
+
end
|
20
|
+
|
21
|
+
should "allow set minimum match when searching for multiple terms" do
|
22
|
+
assert_equal( { :terms => { :foo => ['bar', 'baz'], :minimum_match => 2 } },
|
23
|
+
Query.new.terms(:foo, ['bar', 'baz'], :minimum_match => 2) )
|
24
|
+
end
|
25
|
+
|
26
|
+
should "allow search with a query string" do
|
27
|
+
assert_equal( { :query_string => { :query => 'title:foo' } },
|
28
|
+
Query.new.string('title:foo') )
|
29
|
+
end
|
30
|
+
|
31
|
+
should "allow set default field when searching with a query string" do
|
32
|
+
assert_equal( { :query_string => { :query => 'foo', :default_field => 'title' } },
|
33
|
+
Query.new.string('foo', :default_field => 'title') )
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot::Search
|
4
|
+
|
5
|
+
class SortTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Sort" do
|
8
|
+
|
9
|
+
should "be serialized to JSON" do
|
10
|
+
assert_respond_to Sort.new, :to_json
|
11
|
+
end
|
12
|
+
|
13
|
+
should "encode simple strings" do
|
14
|
+
assert_equal [:foo].to_json, Sort.new.foo.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
should "encode method arguments" do
|
18
|
+
assert_equal [:foo => 'desc'].to_json, Sort.new.foo('desc').to_json
|
19
|
+
end
|
20
|
+
|
21
|
+
should "encode hash" do
|
22
|
+
assert_equal [ :foo => { :reverse => true } ].to_json, Sort.new.foo(:reverse => true).to_json
|
23
|
+
end
|
24
|
+
|
25
|
+
should "encode multiple sort fields" do
|
26
|
+
assert_equal [:foo, :bar].to_json, Sort.new.foo.bar.to_json
|
27
|
+
end
|
28
|
+
|
29
|
+
should "encode fields when passed as a block to constructor" do
|
30
|
+
s = Sort.new do
|
31
|
+
foo
|
32
|
+
bar 'desc'
|
33
|
+
_score
|
34
|
+
end
|
35
|
+
assert_equal [ :foo, {:bar => 'desc'}, :_score ].to_json, s.to_json
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class SearchTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Search" do
|
8
|
+
|
9
|
+
should "be initialized with index/indices" do
|
10
|
+
assert_raise(ArgumentError) { Search::Search.new }
|
11
|
+
end
|
12
|
+
|
13
|
+
should "have the query method" do
|
14
|
+
assert_respond_to Search::Search.new('index'), :query
|
15
|
+
end
|
16
|
+
|
17
|
+
should "store indices as an array" do
|
18
|
+
s = Search::Search.new('index1') do;end
|
19
|
+
assert_equal ['index1'], s.indices
|
20
|
+
|
21
|
+
s = Search::Search.new('index1', 'index2') do;end
|
22
|
+
assert_equal ['index1', 'index2'], s.indices
|
23
|
+
end
|
24
|
+
|
25
|
+
should "return curl snippet for debugging" do
|
26
|
+
s = Search::Search.new('index') do
|
27
|
+
query { string 'title:foo' }
|
28
|
+
end
|
29
|
+
assert_equal %q|curl -X POST "http://localhost:9200/index/_search?pretty=true" -d | +
|
30
|
+
%q|'{"query":{"query_string":{"query":"title:foo"}}}'|,
|
31
|
+
s.to_curl
|
32
|
+
end
|
33
|
+
|
34
|
+
should "allow chaining" do
|
35
|
+
assert_nothing_raised do
|
36
|
+
Search::Search.new('index').query { }.sort { title 'desc' }.size(5).sort { name 'asc' }.from(1)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
should "perform the search" do
|
41
|
+
Configuration.client.expects(:post).returns('{"hits":[]}')
|
42
|
+
Results::Collection.expects(:new).returns([])
|
43
|
+
s = Search::Search.new('index')
|
44
|
+
s.perform
|
45
|
+
assert_not_nil s.results
|
46
|
+
assert_not_nil s.response
|
47
|
+
end
|
48
|
+
|
49
|
+
context "sort" do
|
50
|
+
|
51
|
+
should "allow sorting by multiple fields" do
|
52
|
+
s = Search::Search.new('index') do
|
53
|
+
sort do
|
54
|
+
title 'desc'
|
55
|
+
_score
|
56
|
+
end
|
57
|
+
end
|
58
|
+
hash = JSON.load( s.to_json )
|
59
|
+
assert_equal [{'title' => 'desc'}, '_score'], hash['sort']
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context "facets" do
|
65
|
+
|
66
|
+
should "allow searching for facets" do
|
67
|
+
s = Search::Search.new('index') do
|
68
|
+
facet('foo1') { terms :bar, :global => true }
|
69
|
+
facet('foo2', :global => true) { terms :bar }
|
70
|
+
facet('foo3') { terms :baz }
|
71
|
+
end
|
72
|
+
assert_equal 3, s.facets.keys.size
|
73
|
+
assert_not_nil s.facets['foo1']
|
74
|
+
assert_not_nil s.facets['foo2']
|
75
|
+
assert_not_nil s.facets['foo3']
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with from/size" do
|
81
|
+
|
82
|
+
should "set the values in request" do
|
83
|
+
s = Search::Search.new('index') do
|
84
|
+
size 5
|
85
|
+
from 3
|
86
|
+
end
|
87
|
+
hash = JSON.load( s.to_json )
|
88
|
+
assert_equal 5, hash['size']
|
89
|
+
assert_equal 3, hash['from']
|
90
|
+
end
|
91
|
+
|
92
|
+
should "set the fields limit in request" do
|
93
|
+
s = Search::Search.new('index') do
|
94
|
+
fields :title
|
95
|
+
end
|
96
|
+
hash = JSON.load( s.to_json )
|
97
|
+
assert_equal 'title', hash['fields']
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Slingshot
|
4
|
+
|
5
|
+
class SlingshotTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Slingshot" do
|
8
|
+
|
9
|
+
should "have the DSL methods available" do
|
10
|
+
assert_respond_to Slingshot, :search
|
11
|
+
assert_respond_to Slingshot, :index
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|