indextank 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/indextank.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'faraday'
2
+ require 'uri'
3
+
4
+ directory = File.expand_path(File.dirname(__FILE__))
5
+ require File.join(directory, 'indextank', 'client')
6
+
7
+ module IndexTank
8
+ VERSION = "0.0.4"
9
+
10
+ def self.setup_connection(url, &block)
11
+ @conn = Faraday::Connection.new(:url => url) do |builder|
12
+ builder.adapter Faraday.default_adapter
13
+ builder.use Faraday::Response::Yajl
14
+ if block_given?
15
+ block.call builder
16
+ end
17
+ end
18
+ @uri = URI.parse(url)
19
+ @conn.basic_auth @uri.user,@uri.password
20
+ @conn
21
+ end
22
+ end
23
+
@@ -0,0 +1,36 @@
1
+ require 'indextank/index'
2
+ require 'uri'
3
+
4
+ module IndexTank
5
+ class Client
6
+ attr_reader :uri
7
+
8
+ def initialize(api_url)
9
+ @uri = api_url
10
+ @conn = IndexTank.setup_connection(api_url)
11
+ end
12
+
13
+ def indexes(name = nil)
14
+ if name.nil?
15
+ list_indexes
16
+ else
17
+ get_index(name)
18
+ end
19
+ end
20
+
21
+ private
22
+ def list_indexes
23
+ indexes = Hash.new
24
+
25
+ @conn.get("/v1/indexes").body.each do |name, metadata|
26
+ indexes[name] = Index.new("#{@uri}/v1/indexes/#{name}", metadata)
27
+ end
28
+
29
+ indexes
30
+ end
31
+
32
+ def get_index(name)
33
+ Index.new("#{@uri}/v1/indexes/#{name}")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,98 @@
1
+ require 'json'
2
+ require 'faraday'
3
+
4
+ module IndexTank
5
+ class Document
6
+ attr_reader :docid
7
+
8
+ def initialize(document_url, docid)
9
+ @docid = docid
10
+ builder = Proc.new { |builder| builder.use ResponseDocument }
11
+ @conn = IndexTank.setup_connection(document_url, &builder)
12
+ end
13
+
14
+ # the options argument may contain a :variables key
15
+ # with a Hash from variable numbers to their float values
16
+ # this variables can be used in the scoring functions
17
+ # when sorting a search
18
+ def add(fields, options = {})
19
+ options.merge!(:docid => self.docid, :fields => fields)
20
+
21
+ resp = @conn.put do |req|
22
+ req.url ""
23
+ req.body = options.to_json
24
+ end
25
+
26
+ resp.status
27
+ end
28
+
29
+ def delete(options = {})
30
+ options.merge!(:docid => self.docid)
31
+ resp = @conn.delete do |req|
32
+ req.url ""
33
+ req.body = options.to_json
34
+ end
35
+
36
+ resp.status
37
+ end
38
+
39
+ def update_variables(variables, options = {})
40
+ options.merge!(:docid => self.docid, :variables => variables)
41
+ resp = @conn.put do |req|
42
+ req.url "variables"
43
+ req.body = options.to_json
44
+ end
45
+
46
+ resp.status
47
+ end
48
+
49
+ # updates the categories of a given document
50
+ # the categories argument should be a Hash from string
51
+ # to string defining the value for each category defined
52
+ # by this document.
53
+ def update_categories(categories, options = {} )
54
+ options.merge!(:docid => self.docid, :categories => categories)
55
+ resp = @conn.put do |req|
56
+ req.url "categories"
57
+ req.body = options.to_json
58
+ end
59
+
60
+ resp.status
61
+ end
62
+ #private
63
+ # Handles standard returns status. All methods on documents should return HTTP 200,
64
+ # and the errors are 'common' for any other value
65
+ #def handle_return_status(status)
66
+ # case status
67
+ # when 400
68
+ # raise InvalidArgument
69
+ # when 409
70
+ # raise IndexInitializing
71
+ # when 404
72
+ # raise IndexNotFound
73
+ # end
74
+ #end
75
+ end
76
+
77
+ class ResponseDocument < Faraday::Response::Middleware
78
+ def self.register_on_complete(env)
79
+ env[:response].on_complete do |finished_env|
80
+ case finished_env[:status]
81
+ when 401
82
+ raise InvalidApiKey
83
+ when 409
84
+ raise IndexInitializing
85
+ when 404
86
+ raise NonExistentIndex
87
+ when 400
88
+ raise InvalidArgument
89
+ end
90
+ end
91
+ end
92
+
93
+ def initialize(app)
94
+ super
95
+ @parser = nil
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,10 @@
1
+ module IndexTank
2
+ class IndexAlreadyExists < StandardError; end
3
+ class NonExistentIndex < StandardError; end
4
+ class TooManyIndexes < StandardError; end
5
+ class MissingFunctionDefinition < StandardError; end
6
+ class InvalidApiKey < StandardError; end
7
+ class InvalidQuery < StandardError; end
8
+ class IndexInitializing < StandardError; end
9
+ class InvalidArgument < StandardError; end
10
+ end
@@ -0,0 +1,59 @@
1
+ require 'json'
2
+
3
+ module IndexTank
4
+ class Function
5
+ attr_reader :uri, :index, :definition
6
+
7
+ def initialize(function_url, index, definition)
8
+ @uri = "#{function_url}/#{index}"
9
+ @index = index
10
+ @definition = definition
11
+ builder = Proc.new { |builder| builder.use ResponseDocument }
12
+ @conn = IndexTank.setup_connection(@uri, &builder)
13
+ end
14
+
15
+ def add(options = {})
16
+ raise MissingFunctionDefinition unless self.definition
17
+
18
+ options.merge!(:definition => self.definition)
19
+ response = @conn.put do |req|
20
+ req.url ''
21
+ req.body = options.to_json
22
+ end
23
+ end
24
+
25
+ def delete(options = {})
26
+ resp = @conn.delete do |req|
27
+ req.url ''
28
+ req.body = options.to_json
29
+ end
30
+ end
31
+
32
+ def ==(other)
33
+ self.uri == other.uri and
34
+ self.index == other.index
35
+ self.definition == other.definition
36
+ end
37
+ end
38
+ class ResponseDocument < Faraday::Response::Middleware
39
+ def self.register_on_complete(env)
40
+ env[:response].on_complete do |finished_env|
41
+ case finished_env[:status]
42
+ when 401
43
+ raise InvalidApiKey
44
+ when 409
45
+ raise IndexInitializing
46
+ when 404
47
+ raise NonExistentIndex
48
+ when 400
49
+ raise InvalidArgument
50
+ end
51
+ end
52
+ end
53
+
54
+ def initialize(app)
55
+ super
56
+ @parser = nil
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,127 @@
1
+ require 'indextank/exceptions'
2
+ require 'indextank/document'
3
+ require 'indextank/function'
4
+ require 'json'
5
+
6
+ module IndexTank
7
+ class Index
8
+ def initialize(index_url, metadata = nil)
9
+ @uri = index_url
10
+ @conn = IndexTank.setup_connection(index_url)
11
+ @metadata = metadata
12
+ end
13
+
14
+ def add
15
+ response = @conn.put('')
16
+ case response.status
17
+ when 201
18
+ true
19
+ when 204
20
+ raise IndexAlreadyExists
21
+ when 409
22
+ raise TooManyIndexes
23
+ when 401
24
+ raise InvalidApiKey
25
+ end
26
+ end
27
+
28
+ def refresh
29
+ response = @conn.get('')
30
+ if response.status == 200
31
+ @metadata = response.body
32
+ end
33
+
34
+ response
35
+ end
36
+
37
+ def delete
38
+ response = @conn.delete('')
39
+ case response.status
40
+ when 204
41
+ raise NonExistentIndex
42
+ end
43
+ end
44
+
45
+ def running?
46
+ refresh
47
+ @metadata['started']
48
+ end
49
+
50
+ def method_missing(sym, *args, &block)
51
+ refresh if @metadata.nil?
52
+ @metadata[sym.to_s]
53
+ end
54
+
55
+ def exists?
56
+ refresh.status != 404
57
+ end
58
+
59
+ # the options argument may contain an :index_code definition to override
60
+ # this instance's default index_code
61
+ # it can also contain any of the following:
62
+ # :start => an int with the number of results to skip
63
+ # :len => an int with the number of results to return
64
+ # :snippet => a comma separated list of field names for which a snippet
65
+ # should be returned. (requires an index that supports snippets)
66
+ # :fetch => a comma separated list of field names for which its content
67
+ # should be returned. (requires an index that supports storage)
68
+ # :function => an int with the index of the scoring function to be used
69
+ # for this query
70
+ # :variables => a hash int => float, with variables that can be later
71
+ # used in scoring :function
72
+ def search(query, options = {})
73
+ options = {:start => 0, :len => 10 }.merge(options).merge(:q => query)
74
+ if options[:variables]
75
+ options[:variables].each_pair { |k, v| options.merge!( :"var#{k}" => v ) }
76
+ end
77
+
78
+ if options[:category_filters]
79
+ options[:category_filters] = options[:category_filters].to_json
80
+ p options[:category_filters]
81
+ end
82
+
83
+ response = @conn.get do |req|
84
+ req.url 'search', options
85
+ end
86
+ case response.status
87
+ when 400
88
+ raise InvalidQuery
89
+ when 409
90
+ raise IndexInitializing
91
+ end
92
+
93
+ response.body
94
+ end
95
+
96
+ def suggest(query, options = {})
97
+ options.merge!({:query => query})
98
+ @conn.get do |req|
99
+ req.url 'autocomplete', options
100
+ end.body
101
+ end
102
+
103
+ # the options argument may contain an :index_code definition to override
104
+ # this instance's default index_code
105
+ def promote(docid, query, options={})
106
+ options.merge!( :docid => docid, :query => query )
107
+ resp = @conn.put do |req|
108
+ req.url 'promote'
109
+ req.body = options.to_json
110
+ end
111
+ end
112
+
113
+ def document(docid)
114
+ Document.new("#{@uri}/docs", docid)
115
+ end
116
+
117
+ def functions(index = -1, formula = nil)
118
+ if index == -1
119
+ @conn.get("functions").body.sort.collect do |index, formula|
120
+ Function.new("#{@uri}/functions", index, formula)
121
+ end
122
+ else
123
+ Function.new("#{@uri}/functions", index, formula)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe IndexTank::Client do
4
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
5
+ let(:client) { IndexTank::Client.new("http://:xxxx@dstqe.api.indextank.com") }
6
+
7
+ before { stub_setup_connection }
8
+
9
+ describe "indexes" do
10
+ context "with a param" do
11
+ subject { client.indexes('crawled-index') }
12
+
13
+ it "should return a single index object" do
14
+ should be_an_instance_of(IndexTank::Index)
15
+ end
16
+ end
17
+
18
+ context "without a param" do
19
+ subject { client.indexes }
20
+
21
+ before do
22
+ stubs.get('/v1/indexes') { [200, {}, '{"crawled-index": {"started": true, "code": "dk4se", "creation_time": "2010-07-23T18:52:28", "size": 987}}'] }
23
+ end
24
+
25
+ it "should return a hash of indexes" do
26
+ indexes = subject
27
+
28
+ indexes.should be_an_instance_of(Hash)
29
+ indexes['crawled-index'].should be_an_instance_of(IndexTank::Index)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,127 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe IndexTank::Document do
4
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
5
+ let(:document) { IndexTank::Client.new("http://:xxxx@dstqe.api.indextank.com").indexes('new-index').document('document1') }
6
+ let(:path_prefix) { '/v1/indexes/new-index/docs/' }
7
+
8
+ before { stub_setup_connection }
9
+
10
+ describe "document management" do
11
+ describe "#add" do
12
+ subject { document.add(:text => 'some text') }
13
+
14
+ context "document was indexed" do
15
+ before do
16
+ stubs.put(path_prefix) { [200, {}, ''] }
17
+ end
18
+
19
+ it { subject.should be_true }
20
+ end
21
+
22
+ context "index was initializing" do
23
+ before do
24
+ stubs.put(path_prefix) { [409, {}, ''] }
25
+ end
26
+
27
+ it { subject.should be_false }
28
+ end
29
+
30
+ context "invalid or missing argument" do
31
+ before do
32
+ stubs.put(path_prefix) { [400, {}, ''] }
33
+ end
34
+
35
+ it { subject.should be_false }
36
+ end
37
+
38
+ context "no index existed for the given name" do
39
+ before do
40
+ stubs.put(path_prefix) { [404, {}, ''] }
41
+ end
42
+
43
+ it { subject.should be_false }
44
+ end
45
+ end
46
+
47
+ describe "#delete" do
48
+ subject { document.delete }
49
+
50
+ context "document was deleted" do
51
+ before do
52
+ stubs.delete(path_prefix) { [200, {}, ''] }
53
+ end
54
+
55
+ it { should be_true }
56
+ end
57
+
58
+ context "index is initializing" do
59
+ before do
60
+ stubs.delete(path_prefix) { [409, {}, ''] }
61
+ end
62
+
63
+ it { subject.should be_false }
64
+ end
65
+
66
+ context "invalid or missing argument" do
67
+ before do
68
+ stubs.delete(path_prefix) { [400, {}, ''] }
69
+ end
70
+
71
+ it { subject.should be_false }
72
+ end
73
+
74
+ context "no index existed for the given name" do
75
+ before do
76
+ stubs.delete(path_prefix) { [404, {}, ''] }
77
+ end
78
+
79
+ it { subject.should be_false }
80
+ end
81
+ end
82
+ end
83
+
84
+ describe "#update_variables" do
85
+ let(:new_variables) do
86
+ {
87
+ 0 => 'new_rating',
88
+ 1 => 'new_reputation',
89
+ 2 => 'new_visits'
90
+ }
91
+ end
92
+
93
+ subject { document.update_variables(new_variables) }
94
+
95
+ context "variables indexed" do
96
+ before do
97
+ stubs.put("#{path_prefix}variables") { [200, {}, ''] }
98
+ end
99
+
100
+ it { should be_true }
101
+ end
102
+
103
+ context "index is initializing" do
104
+ before do
105
+ stubs.put("#{path_prefix}variables") { [409, {}, ''] }
106
+ end
107
+
108
+ it { subject.should be_false }
109
+ end
110
+
111
+ context "invalid or missing argument" do
112
+ before do
113
+ stubs.put("#{path_prefix}variables") { [400, {}, ''] }
114
+ end
115
+
116
+ it { subject.should be_false }
117
+ end
118
+
119
+ context "no index existed for the given name" do
120
+ before do
121
+ stubs.put("#{path_prefix}variables") { [404, {}, ''] }
122
+ end
123
+
124
+ it { subject.should be_false }
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,90 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe IndexTank::Function do
4
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
5
+ let(:function) { IndexTank::Client.new("http://:xxxx@dstqe.api.indextank.com").indexes('new-index').functions(0, '-age') }
6
+ let(:path_prefix) { '/v1/indexes/new-index/functions/0/' }
7
+
8
+ before { stub_setup_connection }
9
+
10
+ describe "function management" do
11
+ describe "#add" do
12
+ subject { function.add }
13
+
14
+ context "no definition specified" do
15
+ let(:function) { IndexTank::Client.new("http://:xxxx@dstqe.api.indextank.com").indexes('new-index').functions(0) }
16
+ it "should raise an exception" do
17
+ expect { subject }.to raise_error(IndexTank::MissingFunctionDefinition)
18
+ end
19
+ end
20
+
21
+ context "function saved" do
22
+ before do
23
+ stubs.put(path_prefix) { [200, {}, ''] }
24
+ end
25
+
26
+ it { should be_true }
27
+ end
28
+
29
+ context "index is initializing" do
30
+ before do
31
+ stubs.put(path_prefix) { [409, {}, ''] }
32
+ end
33
+
34
+ it { subject.should be_false }
35
+ end
36
+
37
+ context "invalid or missing argument" do
38
+ before do
39
+ stubs.put(path_prefix) { [400, {}, ''] }
40
+ end
41
+
42
+ it { subject.should be_false }
43
+ end
44
+
45
+ context "no index existed for the given name" do
46
+ before do
47
+ stubs.put(path_prefix) { [404, {}, ''] }
48
+ end
49
+
50
+ it { subject.should be_false }
51
+ end
52
+ end
53
+
54
+ describe "#delete" do
55
+ subject { function.delete }
56
+
57
+ context "function deleted" do
58
+ before do
59
+ stubs.delete(path_prefix) { [200, {}, ''] }
60
+ end
61
+
62
+ it { should be_true }
63
+ end
64
+
65
+ context "index is initializing" do
66
+ before do
67
+ stubs.delete(path_prefix) { [409, {}, ''] }
68
+ end
69
+
70
+ it { subject.should be_false }
71
+ end
72
+
73
+ context "invalid or missing argument" do
74
+ before do
75
+ stubs.delete(path_prefix) { [400, {}, ''] }
76
+ end
77
+
78
+ it { subject.should be_false }
79
+ end
80
+
81
+ context "no index existed for the given name" do
82
+ before do
83
+ stubs.delete(path_prefix) { [404, {}, ''] }
84
+ end
85
+
86
+ it { subject.should be_false }
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,266 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe IndexTank::Index do
4
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
5
+ let(:index) { IndexTank::Client.new("http://:xxxx@dstqe.api.indextank.com").indexes('new-index') }
6
+ let(:path_prefix) { '/v1/indexes/new-index/' }
7
+
8
+ before { stub_setup_connection }
9
+
10
+ describe "index management" do
11
+ describe "add an index" do
12
+ subject { index.add }
13
+ # after do
14
+ # @index.delete
15
+ # end
16
+
17
+ context "the index does not exist" do
18
+ before do
19
+ stubs.put(path_prefix) { [201, {}, '{"started": false, "code": "dsyaj", "creation_time": "2010-08-14T13:01:48.454624", "size": 0}'] }
20
+ end
21
+
22
+ it { should be_true }
23
+ end
24
+
25
+ context "when an index already exists" do
26
+ before do
27
+ # @index.add
28
+ stubs.put(path_prefix) { [204, {}, ''] }
29
+ end
30
+
31
+ it "should raise an exception" do
32
+ expect { subject }.to raise_error(IndexTank::IndexAlreadyExists)
33
+ end
34
+ end
35
+
36
+ context "when the user has too many indexes" do
37
+ before do
38
+ stubs.put(path_prefix) { [409, {}, ''] }
39
+ end
40
+
41
+ it "should raise an exception" do
42
+ expect { subject }.to raise_error(IndexTank::TooManyIndexes)
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "delete an index" do
48
+ subject { index.delete }
49
+
50
+ context "the index exists" do
51
+ before do
52
+ # @index.add
53
+ stubs.delete(path_prefix) { [200, {}, ''] }
54
+ end
55
+
56
+ it { should be_true }
57
+ end
58
+
59
+ context "the index does not exist" do
60
+ before do
61
+ stubs.delete(path_prefix) { [204, {}, ''] }
62
+ end
63
+
64
+ it { subject.should be_false }
65
+ end
66
+ end
67
+ end
68
+
69
+ context "when examining the metadata" do
70
+ subject { index }
71
+
72
+ shared_examples_for "metadata" do
73
+ it "should return the code" do
74
+ subject.code.should == 'dsyaj'
75
+ end
76
+
77
+ it "should update and return the running" do
78
+ # delete any preceding stubs if they exist.
79
+ stubs.match(:get, path_prefix, nil)
80
+ stubs.get(path_prefix) { [200, {}, '{"started": true, "code": "dsyaj", "creation_time": "2010-08-14T13:01:48.454624", "size": 0}'] }
81
+ subject.running?.should be_true
82
+ end
83
+
84
+ it "should return the size" do
85
+ subject.size.should == 0
86
+ end
87
+
88
+ it "should return the creation_time" do
89
+ subject.creation_time.should == "2010-08-14T13:01:48.454624"
90
+ end
91
+ end
92
+
93
+ context "pass in metadata" do
94
+ let(:metadata) do
95
+ {
96
+ 'code' => "dsyaj",
97
+ 'started' => false,
98
+ 'size' => 0,
99
+ 'creation_time' => '2010-08-14T13:01:48.454624'
100
+ }
101
+ end
102
+ let(:index) { IndexTank::Index.new("http://api.indextank.com#{path_prefix}", metadata) }
103
+
104
+ it_should_behave_like "metadata"
105
+ end
106
+
107
+ context "metadata is not passed in" do
108
+ let(:index) { IndexTank::Client.new("http://:uiTPmHg2JTjSMD@dstqe.api.indextank.com").indexes('new-index') }
109
+
110
+ before do
111
+ stubs.get(path_prefix) { [200, {}, '{"started": false, "code": "dsyaj", "creation_time": "2010-08-14T13:01:48.454624", "size": 0}'] }
112
+ end
113
+
114
+ it_should_behave_like "metadata"
115
+ end
116
+ end
117
+
118
+ describe "#exists?" do
119
+ subject { index.exists? }
120
+
121
+ context "when an index exists" do
122
+ before do
123
+ stubs.get(path_prefix) { [200, {}, '{"started": false, "code": "dsyaj", "creation_time": "2010-08-14T13:01:48.454624", "size": 0}'] }
124
+ end
125
+
126
+ it { should be_true }
127
+ end
128
+
129
+ context "when an index doesn't exist" do
130
+ before do
131
+ stubs.get(path_prefix) { [404, {}, ''] }
132
+ end
133
+
134
+ # rspec2 bug, implicit subject is calling subject twice
135
+ it { subject.should be_false }
136
+ end
137
+ end
138
+
139
+ describe "#search" do
140
+ subject { index.search('foo') }
141
+
142
+ context "search is successful" do
143
+ before do
144
+ stubs.get("#{path_prefix}search?q=foo&start=0&len=10") { [200, {}, '{"matches": 4, "search_time": "0.022", "results": [{"docid": "http://cnn.com/HEALTH"}, {"docid": "http://www.cnn.com/HEALTH/"}, {"docid": "http://cnn.com/HEALTH/?hpt=Sbin"}, {"docid": "http://cnn.com/HEALTH/"}]}'] }
145
+ end
146
+
147
+ it "should have the number of matches" do
148
+ subject['matches'].should == 4
149
+ end
150
+
151
+ it "should a list of docs" do
152
+ results = subject['results']
153
+
154
+ %w(http://cnn.com/HEALTH
155
+ http://www.cnn.com/HEALTH/
156
+ http://cnn.com/HEALTH/?hpt=Sbin
157
+ http://cnn.com/HEALTH/).each_with_index do |docid, index|
158
+ results[index]['docid'].should == docid
159
+ end
160
+ end
161
+ end
162
+
163
+ context "index is initializing", :pending => true do
164
+ before do
165
+ stubs.get("#{path_prefix}search") { [409, {}, ''] }
166
+ end
167
+
168
+ it "should return an empty body"
169
+ end
170
+
171
+ context "index is invalid/missing argument", :pending => true do
172
+ before do
173
+ stubs.get("#{path_prefix}search") { [400, {}, ''] }
174
+ end
175
+
176
+ it "should return a descriptive error message"
177
+ end
178
+
179
+ context "no index existed for the given name", :pending => true do
180
+ before do
181
+ stubs.get("#{path_prefix}search") { [404, {}, ''] }
182
+ end
183
+
184
+ it "should return a descriptive error message"
185
+ end
186
+ end
187
+
188
+ describe "#promote" do
189
+ subject { index.promote(4, 'foo') }
190
+
191
+ context "when the document is promoted" do
192
+ before do
193
+ stubs.get("#{path_prefix}promote?docid=4&query=foo") { [200, {}, ''] }
194
+ end
195
+
196
+ it { should be_true }
197
+ end
198
+
199
+ context "when the index is initializing" do
200
+ before do
201
+ stubs.get("#{path_prefix}promote?docid=4&query=foo") { [409, {}, ''] }
202
+ end
203
+
204
+ it { subject.should be_false }
205
+ end
206
+
207
+ context "when invalid or missing argument" do
208
+ before do
209
+ stubs.get("#{path_prefix}promote?docid=4&query=foo") { [400, {}, ''] }
210
+ end
211
+
212
+ it { subject.should be_false }
213
+ end
214
+
215
+ context "when no index exists for the given name" do
216
+ before do
217
+ stubs.get("#{path_prefix}promote?docid=4&query=foo") { [404, {}, ''] }
218
+ end
219
+
220
+ it { subject.should be_false }
221
+ end
222
+ end
223
+
224
+ describe "#document" do
225
+ subject { index.document('foo') }
226
+
227
+ it "should create a document object" do
228
+ should be_an_instance_of(IndexTank::Document)
229
+ end
230
+ end
231
+
232
+ describe "#function" do
233
+ context "with no params" do
234
+ subject { index.functions }
235
+
236
+ before do
237
+ stubs.get("#{path_prefix}functions") { [200, {}, '{"0": "0-A", "1": "-age", "2": "relevance"}'] }
238
+ end
239
+
240
+ it "should return an array of functions" do
241
+ should == [
242
+ IndexTank::Function.new("#{path_prefix}functions", 0, '0-A'),
243
+ IndexTank::Function.new("#{path_prefix}functions", 1, '-age'),
244
+ IndexTank::Function.new("#{path_prefix}functions", 2, 'relevance')
245
+ ]
246
+ end
247
+ end
248
+
249
+ context "with a function name and definition" do
250
+ subject { index.functions(0, '-age') }
251
+
252
+ it "should return an instance of Function" do
253
+ should be_an_instance_of(IndexTank::Function)
254
+ end
255
+ end
256
+
257
+ context "with a function name" do
258
+ subject { index.functions(0) }
259
+
260
+ it "should return an instance of Function" do
261
+ should be_an_instance_of(IndexTank::Function)
262
+ end
263
+ end
264
+ end
265
+ end
266
+
@@ -0,0 +1,28 @@
1
+ $:.unshift File.expand_path("../../lib", __FILE__)
2
+
3
+ require 'rspec/core'
4
+ require 'rspec/expectations'
5
+ require 'rr'
6
+
7
+ require 'indextank'
8
+
9
+ def not_in_editor?
10
+ !(ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM'))
11
+ end
12
+
13
+ RSpec.configure do |c|
14
+ c.run_all_when_everything_filtered = true
15
+ c.filter_run :focused => true
16
+ c.alias_example_to :fit, :focused => true
17
+ c.color_enabled = not_in_editor?
18
+ c.mock_with :rr
19
+ end
20
+
21
+ def stub_setup_connection
22
+ stub(IndexTank).setup_connection(anything) do |url|
23
+ Faraday::Connection.new(:url => url) do |builder|
24
+ builder.adapter :test, stubs
25
+ builder.use Faraday::Response::Yajl
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,223 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: indextank
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 4
10
+ version: 0.0.4
11
+ platform: ruby
12
+ authors:
13
+ - Santiago Perez
14
+ - Terence Lee
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-08-24 00:00:00 -03:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: jeweler
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - "="
29
+ - !ruby/object:Gem::Version
30
+ hash: 7
31
+ segments:
32
+ - 1
33
+ - 4
34
+ - 0
35
+ version: 1.4.0
36
+ type: :development
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec-core
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 62196421
47
+ segments:
48
+ - 2
49
+ - 0
50
+ - 0
51
+ - beta
52
+ - 19
53
+ version: 2.0.0.beta.19
54
+ type: :development
55
+ version_requirements: *id002
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec-expectations
58
+ prerelease: false
59
+ requirement: &id003 !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 62196421
65
+ segments:
66
+ - 2
67
+ - 0
68
+ - 0
69
+ - beta
70
+ - 19
71
+ version: 2.0.0.beta.19
72
+ type: :development
73
+ version_requirements: *id003
74
+ - !ruby/object:Gem::Dependency
75
+ name: rr
76
+ prerelease: false
77
+ requirement: &id004 !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - "="
81
+ - !ruby/object:Gem::Version
82
+ hash: 33
83
+ segments:
84
+ - 0
85
+ - 10
86
+ - 11
87
+ version: 0.10.11
88
+ type: :development
89
+ version_requirements: *id004
90
+ - !ruby/object:Gem::Dependency
91
+ name: rake
92
+ prerelease: false
93
+ requirement: &id005 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - "="
97
+ - !ruby/object:Gem::Version
98
+ hash: 49
99
+ segments:
100
+ - 0
101
+ - 8
102
+ - 7
103
+ version: 0.8.7
104
+ type: :development
105
+ version_requirements: *id005
106
+ - !ruby/object:Gem::Dependency
107
+ name: ruby-debug
108
+ prerelease: false
109
+ requirement: &id006 !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ type: :development
119
+ version_requirements: *id006
120
+ - !ruby/object:Gem::Dependency
121
+ name: parka
122
+ prerelease: false
123
+ requirement: &id007 !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - "="
127
+ - !ruby/object:Gem::Version
128
+ hash: 17
129
+ segments:
130
+ - 0
131
+ - 3
132
+ - 1
133
+ version: 0.3.1
134
+ type: :development
135
+ version_requirements: *id007
136
+ - !ruby/object:Gem::Dependency
137
+ name: faraday
138
+ prerelease: false
139
+ requirement: &id008 !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 3
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ type: :runtime
149
+ version_requirements: *id008
150
+ - !ruby/object:Gem::Dependency
151
+ name: yajl-ruby
152
+ prerelease: false
153
+ requirement: &id009 !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - "="
157
+ - !ruby/object:Gem::Version
158
+ hash: 13
159
+ segments:
160
+ - 0
161
+ - 7
162
+ - 7
163
+ version: 0.7.7
164
+ type: :runtime
165
+ version_requirements: *id009
166
+ description: Ruby Client for the IndexTank API
167
+ email:
168
+ - santip@santip.com.ar
169
+ - hone02@gmail.com
170
+ executables: []
171
+
172
+ extensions: []
173
+
174
+ extra_rdoc_files: []
175
+
176
+ files:
177
+ - lib/indextank.rb
178
+ - lib/indextank/client.rb
179
+ - lib/indextank/document.rb
180
+ - lib/indextank/exceptions.rb
181
+ - lib/indextank/function.rb
182
+ - lib/indextank/index.rb
183
+ - spec/lib/indextank/client_spec.rb
184
+ - spec/lib/indextank/document_spec.rb
185
+ - spec/lib/indextank/function_spec.rb
186
+ - spec/lib/indextank/index_spec.rb
187
+ - spec/spec_helper.rb
188
+ has_rdoc: true
189
+ homepage: http://www.indextank.com
190
+ licenses: []
191
+
192
+ post_install_message:
193
+ rdoc_options: []
194
+
195
+ require_paths:
196
+ - lib
197
+ required_ruby_version: !ruby/object:Gem::Requirement
198
+ none: false
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ hash: 3
203
+ segments:
204
+ - 0
205
+ version: "0"
206
+ required_rubygems_version: !ruby/object:Gem::Requirement
207
+ none: false
208
+ requirements:
209
+ - - ">="
210
+ - !ruby/object:Gem::Version
211
+ hash: 3
212
+ segments:
213
+ - 0
214
+ version: "0"
215
+ requirements: []
216
+
217
+ rubyforge_project: nowarning
218
+ rubygems_version: 1.3.7
219
+ signing_key:
220
+ specification_version: 3
221
+ summary: Ruby Client for the IndexTank API
222
+ test_files: []
223
+