slingshot-rb 0.0.3 → 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.
@@ -145,7 +145,6 @@ Todo & Plans
145
145
 
146
146
  In order of importance:
147
147
 
148
- * Getting document [by ID](http://www.elasticsearch.org/guide/reference/api/get.html)
149
148
  * Seamless _ActiveModel_ compatibility for easy usage in _Rails_ applications (this also means nearly full _ActiveRecord_ compatibility)
150
149
  * Seamless [will_paginate](https://github.com/mislav/will_paginate) compatibility for easy pagination
151
150
  * [Histogram](http://www.elasticsearch.org/guide/reference/api/search/facets/histogram-facet.html) facets
@@ -3,6 +3,9 @@ module Slingshot
3
3
  module Client
4
4
 
5
5
  class Base
6
+ def get(url)
7
+ raise NoMethodError, "Implement this method in your client class"
8
+ end
6
9
  def post(url, data)
7
10
  raise NoMethodError, "Implement this method in your client class"
8
11
  end
@@ -12,6 +15,9 @@ module Slingshot
12
15
  end
13
16
 
14
17
  class RestClient < Base
18
+ def self.get(url)
19
+ ::RestClient.get url
20
+ end
15
21
  def self.post(url, data)
16
22
  ::RestClient.post url, data
17
23
  end
@@ -20,20 +20,46 @@ module Slingshot
20
20
  end
21
21
 
22
22
  def store(*args)
23
+ # TODO: Infer type from the document (hash property, method)
24
+
23
25
  if args.size > 1
24
26
  (type, document = args)
25
27
  else
26
28
  (document = args.pop; type = :document)
27
29
  end
30
+
31
+ old_verbose, $VERBOSE = $VERBOSE, nil # Silence Object#id deprecation warnings
32
+ id = case true
33
+ when document.is_a?(Hash) then document[:id] || document['id']
34
+ when document.respond_to?(:id) && document.id != document.object_id then document.id
35
+ end
36
+ $VERBOSE = old_verbose
37
+
28
38
  document = case true
29
39
  when document.is_a?(String) then document
30
40
  when document.respond_to?(:to_indexed_json) then document.to_indexed_json
31
41
  else raise ArgumentError, "Please pass a JSON string or object with a 'to_indexed_json' method"
32
42
  end
33
- result = Configuration.client.post "#{Configuration.url}/#{@name}/#{type}/", document
43
+
44
+ if id
45
+ result = Configuration.client.post "#{Configuration.url}/#{@name}/#{type}/#{id}", document
46
+ else
47
+ result = Configuration.client.post "#{Configuration.url}/#{@name}/#{type}/", document
48
+ end
34
49
  JSON.parse(result)
35
50
  end
36
51
 
52
+ def retrieve(type, id)
53
+ result = Configuration.client.get "#{Configuration.url}/#{@name}/#{type}/#{id}"
54
+ h = JSON.parse(result)
55
+ if Configuration.wrapper == Hash then h
56
+ else
57
+ document = h['_source'] ? h['_source'] : h['fields']
58
+ h.update document if document
59
+ Configuration.wrapper.new(h)
60
+ end
61
+ end
62
+
37
63
  def refresh
38
64
  Configuration.client.post "#{Configuration.url}/#{@name}/_refresh", ''
39
65
  end
@@ -1,3 +1,3 @@
1
1
  module Slingshot
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ module Slingshot
4
+
5
+ class IndexStoreTest < Test::Unit::TestCase
6
+ include Test::Integration
7
+
8
+ context "Storing the documents in index" do
9
+
10
+ teardown { Slingshot.index('articles-test-ids').delete }
11
+
12
+ should "store hashes under their IDs" do
13
+
14
+ Slingshot.index 'articles-test-ids' do
15
+ delete
16
+ create
17
+
18
+ store :id => 1, :title => 'One'
19
+ store :id => 2, :title => 'Two'
20
+ store :id => 3, :title => 'Three'
21
+ store :id => 4, :title => 'Four'
22
+ store :id => 4, :title => 'Four'
23
+
24
+ refresh
25
+ end
26
+
27
+ s = Slingshot.search('articles-test-ids') { query { string '*' } }
28
+
29
+ assert_equal 4, s.results.count
30
+
31
+ document = Slingshot.index('articles-test-ids').retrieve :document, 4
32
+ assert_equal 'Four', document.title
33
+ assert_equal 2, document._version.to_i
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,15 @@
1
+ # Example non-ActiveModel custom wrapper for result item
2
+
3
+ class Article
4
+ attr_reader :id, :title, :body
5
+
6
+ def initialize(attributes={})
7
+ attributes.each { |k,v| instance_variable_set(:"@#{k}", v) }
8
+ end
9
+
10
+ def to_json
11
+ { :id => @id, :title => @title, :body => @body }.to_json
12
+ end
13
+
14
+ alias :to_indexed_json :to_json
15
+ end
@@ -7,6 +7,8 @@ require 'pathname'
7
7
 
8
8
  require 'slingshot'
9
9
 
10
+ Dir[File.dirname(__FILE__) + '/models/**/*.rb'].each { |m| require m }
11
+
10
12
  class Test::Unit::TestCase
11
13
 
12
14
  def fixtures_path
@@ -8,6 +8,9 @@ module Slingshot
8
8
  setup { @http ||= Client::Base.new }
9
9
 
10
10
  should "have abstract methods" do
11
+ assert_raise(ArgumentError) { @http.get }
12
+ assert_raise(NoMethodError) { @http.get 'URL' }
13
+
11
14
  assert_raise(ArgumentError) { @http.post }
12
15
  assert_raise(ArgumentError) { @http.post 'URL' }
13
16
  assert_raise(NoMethodError) { @http.post 'URL', 'DATA' }
@@ -23,7 +26,8 @@ module Slingshot
23
26
  assert_equal Client::RestClient, Configuration.client
24
27
  end
25
28
 
26
- should "respond to post and delete" do
29
+ should "respond to HTTP methods" do
30
+ assert_respond_to Client::RestClient, :get
27
31
  assert_respond_to Client::RestClient, :post
28
32
  assert_respond_to Client::RestClient, :delete
29
33
  end
@@ -62,6 +62,64 @@ module Slingshot
62
62
  assert_raise(ArgumentError) { @index.store document }
63
63
  end
64
64
 
65
+ context "document with ID" do
66
+
67
+ should "store Hash it under its ID property" do
68
+ Configuration.client.expects(:post).with("#{Configuration.url}/dummy/document/123",
69
+ {:id => 123, :title => 'Test'}.to_json).
70
+ returns('{"ok":true,"_id":"123"}')
71
+ @index.store :id => 123, :title => 'Test'
72
+ end
73
+
74
+ should "store a custom class under its ID property" do
75
+ Configuration.client.expects(:post).with("#{Configuration.url}/dummy/document/123",
76
+ {:id => 123, :title => 'Test', :body => 'Lorem'}.to_json).
77
+ returns('{"ok":true,"_id":"123"}')
78
+ @index.store Article.new(:id => 123, :title => 'Test', :body => 'Lorem')
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ context "when retrieving" do
86
+
87
+ setup do
88
+ Configuration.reset :wrapper
89
+
90
+ Configuration.client.stubs(:post).with("#{Configuration.url}/dummy/article/", '{"title":"Test"}').
91
+ returns('{"ok":true,"_id":"id-1"}')
92
+ @index.store :article, :title => 'Test'
93
+ end
94
+
95
+ should "return document in default wrapper" do
96
+ Configuration.client.expects(:get).with("#{Configuration.url}/dummy/article/id-1").
97
+ returns('{"_id":"id-1","_version":1, "_source" : {"title":"Test"}}')
98
+ article = @index.retrieve :article, 'id-1'
99
+ assert_instance_of Results::Item, article
100
+ assert_equal 'Test', article['_source']['title']
101
+ assert_equal 'Test', article.title
102
+ end
103
+
104
+ should "return document as a hash" do
105
+ Configuration.wrapper Hash
106
+
107
+ Configuration.client.expects(:get).with("#{Configuration.url}/dummy/article/id-1").
108
+ returns('{"_id":"id-1","_version":1, "_source" : {"title":"Test"}}')
109
+ article = @index.retrieve :article, 'id-1'
110
+ assert_instance_of Hash, article
111
+ end
112
+
113
+ should "return document in custom wrapper" do
114
+ Configuration.wrapper Article
115
+
116
+ Configuration.client.expects(:get).with("#{Configuration.url}/dummy/article/id-1").
117
+ returns('{"_id":"id-1","_version":1, "_source" : {"title":"Test"}}')
118
+ article = @index.retrieve :article, 'id-1'
119
+ assert_instance_of Article, article
120
+ assert_equal 'Test', article.title
121
+ end
122
+
65
123
  end
66
124
 
67
125
  end
@@ -1,17 +1,5 @@
1
1
  require 'test_helper'
2
2
 
3
- class Article
4
- attr_reader :title, :body
5
- def initialize(attributes={})
6
- @title = attributes[:title]
7
- @body = attributes[:body]
8
- end
9
- def to_json
10
- { :title => @title, :body => @body }.to_json
11
- end
12
- alias :to_indexed_json :to_json
13
- end
14
-
15
3
  module Slingshot
16
4
 
17
5
  class ResultsCollectionTest < Test::Unit::TestCase
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slingshot-rb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Karel Minarik
@@ -174,9 +174,11 @@ files:
174
174
  - test/fixtures/articles/4.json
175
175
  - test/fixtures/articles/5.json
176
176
  - test/integration/facets_test.rb
177
+ - test/integration/index_store_test.rb
177
178
  - test/integration/query_string_test.rb
178
179
  - test/integration/results_test.rb
179
180
  - test/integration/sort_test.rb
181
+ - test/models/article.rb
180
182
  - test/test_helper.rb
181
183
  - test/unit/client_test.rb
182
184
  - test/unit/configuration_test.rb
@@ -231,9 +233,11 @@ test_files:
231
233
  - test/fixtures/articles/4.json
232
234
  - test/fixtures/articles/5.json
233
235
  - test/integration/facets_test.rb
236
+ - test/integration/index_store_test.rb
234
237
  - test/integration/query_string_test.rb
235
238
  - test/integration/results_test.rb
236
239
  - test/integration/sort_test.rb
240
+ - test/models/article.rb
237
241
  - test/test_helper.rb
238
242
  - test/unit/client_test.rb
239
243
  - test/unit/configuration_test.rb