slingshot-rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|