rrrmatey 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +16 -0
  3. data/README.md +249 -0
  4. data/RELEASE_NOTES.md +26 -0
  5. data/Rakefile +39 -0
  6. data/lib/rrrmatey.rb +8 -0
  7. data/lib/rrrmatey/crud_controller.rb +97 -0
  8. data/lib/rrrmatey/discrete_result.rb +31 -0
  9. data/lib/rrrmatey/errors.rb +11 -0
  10. data/lib/rrrmatey/retryable.rb +28 -0
  11. data/lib/rrrmatey/string_model/connection_methods.rb +47 -0
  12. data/lib/rrrmatey/string_model/consumer_adapter_methods.rb +9 -0
  13. data/lib/rrrmatey/string_model/delete_methods.rb +12 -0
  14. data/lib/rrrmatey/string_model/field_definition_methods.rb +101 -0
  15. data/lib/rrrmatey/string_model/find_methods.rb +85 -0
  16. data/lib/rrrmatey/string_model/index_methods.rb +90 -0
  17. data/lib/rrrmatey/string_model/namespaced_key_methods.rb +21 -0
  18. data/lib/rrrmatey/string_model/string_model.rb +92 -0
  19. data/lib/rrrmatey/type_coercion.rb +61 -0
  20. data/lib/rrrmatey/version.rb +3 -0
  21. data/spec/rrrmatey/crud_controller/crud_controller_spec.rb +258 -0
  22. data/spec/rrrmatey/crud_controller/model_methods_spec.rb +26 -0
  23. data/spec/rrrmatey/discrete_result_spec.rb +104 -0
  24. data/spec/rrrmatey/retryable_spec.rb +95 -0
  25. data/spec/rrrmatey/string_model/connection_methods_spec.rb +64 -0
  26. data/spec/rrrmatey/string_model/consumer_adapter_methods_spec.rb +43 -0
  27. data/spec/rrrmatey/string_model/delete_methods_spec.rb +36 -0
  28. data/spec/rrrmatey/string_model/field_definition_methods_spec.rb +51 -0
  29. data/spec/rrrmatey/string_model/find_methods_spec.rb +147 -0
  30. data/spec/rrrmatey/string_model/index_methods_spec.rb +231 -0
  31. data/spec/rrrmatey/string_model/namespaced_key_methods_spec.rb +34 -0
  32. data/spec/rrrmatey/string_model/string_model_spec.rb +208 -0
  33. data/spec/spec_helper.rb +16 -0
  34. metadata +148 -0
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ class Conn
4
+ def get(id)
5
+ { :id => id }
6
+ end
7
+ end
8
+
9
+ class ConnPool
10
+ def initialize(opts = {})
11
+ @conn = Conn.new()
12
+ @errors = opts[:errors] || -1
13
+ end
14
+
15
+ def with(&block)
16
+ if @errors > 0
17
+ @errors -= 1
18
+ raise "errors remaining: #{@errors}"
19
+ else
20
+ block.call(@conn)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe RRRMatey::Retryable do
26
+ describe '#initialize' do
27
+ let(:conn) { Conn.new() }
28
+ let(:conn_pool) { ConnPool.new() }
29
+ let(:default) { RRRMatey::Retryable.new(conn) }
30
+ let(:default_pool) { RRRMatey::Retryable.new(conn_pool) }
31
+ let(:optioned) { RRRMatey::Retryable.new(conn_pool,
32
+ :retries => 5,
33
+ :retry_delay => 0.01) }
34
+
35
+ it 'has sane defaults for conn_pool' do
36
+ expect(default_pool.instance_variable_get(:@retries)).to eq(3)
37
+ expect(default_pool.instance_variable_get(:@retry_delay)).to eq(0.1)
38
+ expect(default_pool.instance_variable_get(:@conn)).to eq(conn_pool)
39
+ expect(default_pool.instance_variable_get(:@conn_respond_to_with)).to be(true)
40
+ end
41
+
42
+ it 'has sane defaults for conn' do
43
+ expect(default.instance_variable_get(:@retries)).to eq(3)
44
+ expect(default.instance_variable_get(:@retry_delay)).to eq(0.1)
45
+ expect(default.instance_variable_get(:@conn)).to eq(conn)
46
+ expect(default.instance_variable_get(:@conn_respond_to_with)).to be(false)
47
+ end
48
+
49
+ it 'accepts options' do
50
+ expect(optioned.instance_variable_get(:@retries)).to eq(5)
51
+ expect(optioned.instance_variable_get(:@retry_delay)).to eq(0.01)
52
+ expect(optioned.instance_variable_get(:@conn)).to eq(conn_pool)
53
+ expect(optioned.instance_variable_get(:@conn_respond_to_with)).to be(true)
54
+ end
55
+ end
56
+
57
+ describe '#with' do
58
+ let(:conn) { Conn.new() }
59
+ let(:conn_pool) { ConnPool.new() }
60
+ let(:flappy_conn) { ConnPool.new(:errors => 2) }
61
+ let(:failing_conn) { ConnPool.new(:errors => 10) }
62
+ let(:optioned) { RRRMatey::Retryable.new(conn,
63
+ :retries => 5,
64
+ :retry_delay => 0.01) }
65
+ let(:optioned_pool) { RRRMatey::Retryable.new(conn_pool,
66
+ :retries => 5,
67
+ :retry_delay => 0.01) }
68
+ let(:flappy_optioned_pool) { RRRMatey::Retryable.new(flappy_conn,
69
+ :retries => 5,
70
+ :retry_delay => 0.01) }
71
+ let(:failing_optioned_pool) { RRRMatey::Retryable.new(failing_conn,
72
+ :retries => 5,
73
+ :retry_delay => 0.01) }
74
+
75
+ it 'yields nil if !block.given?' do
76
+ expect(optioned.with()).to be(nil)
77
+ end
78
+
79
+ it 'yields block response on no error for conn' do
80
+ expect(optioned.with { |c| c.get(3) }).to eq({:id => 3})
81
+ end
82
+
83
+ it 'yields block response on no error for conn_pool' do
84
+ expect(optioned_pool.with { |c| c.get(3) }).to eq({:id => 3})
85
+ end
86
+
87
+ it 'yields block response for flappy pool' do
88
+ expect(flappy_optioned_pool.with { |c| c.get(3) }).to eq({:id => 3})
89
+ end
90
+
91
+ it 'raises for failing pool' do
92
+ expect{failing_optioned_pool.with { |c| c.get(3) }}.to raise_error(RuntimeError)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ class ConnectionModel
4
+ extend RRRMatey::StringModel::ConnectionMethods
5
+
6
+ class ConnPool
7
+ def initialize(conn)
8
+ @conn = conn
9
+ end
10
+
11
+ def with(&block)
12
+ block.call(@conn)
13
+ end
14
+ end
15
+
16
+ class Conn
17
+ end
18
+ end
19
+
20
+ describe RRRMatey::StringModel::ConnectionMethods do
21
+ context 'with riak and cache_proxy setup' do
22
+ let(:conn) { ConnectionModel::ConnPool.new(ConnectionModel::Conn.new()) }
23
+ let(:model_klass) {
24
+ m = ConnectionModel
25
+ m.riak = conn
26
+ m.cache_proxy = conn
27
+ m
28
+ }
29
+
30
+ describe '#cache_proxy' do
31
+ it 'yields values from self' do
32
+ expect(model_klass.cache_proxy).to eq(conn)
33
+ end
34
+ end
35
+
36
+ describe '#riak' do
37
+ it 'yields values from self' do
38
+ expect(model_klass.riak).to eq(conn)
39
+ end
40
+ end
41
+ end
42
+
43
+ context 'with or without riak and cache_proxy setup' do
44
+ let(:model_klass) {
45
+ m = ConnectionModel
46
+ m.riak = nil
47
+ m.cache_proxy = nil
48
+ m
49
+ }
50
+ let(:string_model_klass) { RRRMatey::StringModel }
51
+
52
+ describe '#cache_proxy' do
53
+ it 'yields values from StringModel' do
54
+ expect(model_klass.cache_proxy).to eq(string_model_klass.cache_proxy)
55
+ end
56
+ end
57
+
58
+ describe '#riak' do
59
+ it 'yields values from StringModel' do
60
+ expect(model_klass.riak).to eq(string_model_klass.riak)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ class SomeModel
4
+ extend RRRMatey::StringModel::ConsumerAdapterMethods
5
+
6
+ attr_accessor :id, :name, :content_type
7
+
8
+ def self.object_from_hash(h, id, content_type)
9
+ sm = SomeModel.new()
10
+ sm.id = id
11
+ sm.content_type = content_type
12
+ sm.name = h[:name] || name
13
+ sm
14
+ end
15
+ end
16
+
17
+ describe RRRMatey::StringModel::ConsumerAdapterMethods do
18
+ describe '#from_params' do
19
+ let(:model_klass) { SomeModel }
20
+ let(:params) { { :id => 'di', :name => 'eman' } }
21
+ let(:model_params_id_content_type) { SomeModel.from_params(params, 'dis', :xml) }
22
+ let(:model_params_id) { SomeModel.from_params(params, 'dis') }
23
+ let(:model_params) { SomeModel.from_params(params) }
24
+
25
+ it 'yields a model from params hash, id, and content-type' do
26
+ expect(model_params_id_content_type.name).to eq(params[:name])
27
+ expect(model_params_id_content_type.id).to eq('dis')
28
+ expect(model_params_id_content_type.content_type).to eq(:xml)
29
+ end
30
+
31
+ it 'yields a model from params hash and id' do
32
+ expect(model_params_id.name).to eq(params[:name])
33
+ expect(model_params_id.id).to eq('dis')
34
+ expect(model_params_id.content_type).to eq(:json)
35
+ end
36
+
37
+ it 'yields a model from params hash' do
38
+ expect(model_params.name).to eq(params[:name])
39
+ expect(model_params.id).to eq(params[:id])
40
+ expect(model_params.content_type).to eq(:json)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe RRRMatey::StringModel::DeleteMethods do
4
+ context 'with or without cache_proxy setup' do
5
+ describe '#delete' do
6
+ let(:model) { StringModelKlass.new() }
7
+
8
+ it 'yields 0 if cache_proxy is not setup' do
9
+ model.id = 'di'
10
+ expect(model.delete()).to eq(0)
11
+ end
12
+ end
13
+ end
14
+
15
+ context 'with cache_proxy setup' do
16
+ describe '#delete' do
17
+ let(:model_klass) { StringModelKlass }
18
+ let(:model) {
19
+ m = model_klass.new()
20
+ m.class.cache_proxy = StringModelKlass::ConnPool.new(StringModelKlass::Conn.new)
21
+ m.class.cache_proxy.with { |c| c.set(model_klass.namespaced_key('di'), 'exists') }
22
+ m
23
+ }
24
+
25
+ it 'yields 0 if value was not in the store' do
26
+ model.id = 'dne'
27
+ expect(model.delete()).to eq(0)
28
+ end
29
+
30
+ it 'yields 1 if the value was in the store' do
31
+ model.id = 'di'
32
+ expect(model.delete()).to eq(1)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ class SomeFieldyModel
4
+ extend RRRMatey::StringModel::FieldDefinitionMethods
5
+
6
+ field :name, :type => :string
7
+ field :hornery, :type => :boolean
8
+ field :created, :type => :date
9
+ field :bounties, :type => :integer
10
+ field :ales, :type => :long
11
+ field :chins, :type => :double
12
+ field :corks, :type => :float
13
+ end
14
+
15
+ describe RRRMatey::StringModel::FieldDefinitionMethods do
16
+ let(:model_klass) { SomeFieldyModel }
17
+ let(:model) { SomeFieldyModel.new }
18
+
19
+ describe '#fields' do
20
+ it 'yields fields defined on the model' do
21
+ expect(model_klass.fields).to eq([:name_s, :hornery_b, :created_ti, :bounties_i, :ales_l, :chins_d, :corks_f])
22
+ end
23
+
24
+ it 'creates accessors for defined fields' do
25
+ expect(model.respond_to?(:name)).to be(true)
26
+ expect(model.respond_to?(:name=)).to be(true)
27
+ end
28
+
29
+ it 'allows fields to be defined programmatically' do
30
+ model_klass.fields(:name, :birth)
31
+ expect(model_klass.fields).to eq([:name, :birth])
32
+ end
33
+
34
+ it 'specializes initialize, mapping all opts set to field set ops' do
35
+ expect(model_klass.new(:name => 'eman').name).to eq('eman')
36
+ end
37
+ end
38
+
39
+ describe '#consumer_fields' do
40
+ it 'yields consumer fields' do
41
+ model_klass.fields(:name_s, :hornery_b, :created_ti, :bounties_i, :ales_l, :chins_d, :corks_f)
42
+ expect(model_klass.consumer_fields).to eq([:name, :hornery, :created, :bounties, :ales, :chins, :corks])
43
+ end
44
+ end
45
+
46
+ describe '#append_type' do
47
+ it 'raises for unsupported type' do
48
+ expect{model_klass.send(:append_type, :some_field, :some_unknown_type)}.to raise_error(RRRMatey::UnsupportedTypeError)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ class FindModel
4
+ extend RRRMatey::StringModel::FindMethods
5
+
6
+ @@cache_proxy = nil
7
+
8
+ def self.cache_proxy
9
+ @@cache_proxy
10
+ end
11
+
12
+ def self.cache_proxy=(v)
13
+ @@cache_proxy = v
14
+ end
15
+
16
+ def self.item_name()
17
+ 'find_model'
18
+ end
19
+
20
+ def self.namespace
21
+ 'find_models'
22
+ end
23
+
24
+ def self.namespaced_key(id)
25
+ "#{namespace}:#{id}"
26
+ end
27
+
28
+ attr_accessor :id, :content_type
29
+ attr_accessor :name
30
+ attr_accessor :field_dne_d
31
+
32
+ def self.fields
33
+ [ :name_s, :field_dne_d ]
34
+ end
35
+
36
+ def self.consumer_fields
37
+ [ :name ]
38
+ end
39
+
40
+ class ConnPool
41
+ def initialize(conn)
42
+ @conn = conn
43
+ end
44
+
45
+ def with(&block)
46
+ block.call(@conn)
47
+ end
48
+ end
49
+
50
+ class Conn
51
+ attr_accessor :result
52
+
53
+ def get(id)
54
+ @result
55
+ end
56
+ end
57
+ end
58
+
59
+ describe RRRMatey::StringModel::FindMethods do
60
+ context 'with or without cache_proxy setup' do
61
+ let(:model_klass) { FindModel }
62
+
63
+ describe '#get' do
64
+ it 'returns nil if cache_proxy is not set' do
65
+ expect(model_klass.get('di')).to be(nil)
66
+ end
67
+
68
+ it 'returns nil if id is blank' do
69
+ expect(model_klass.get(nil)).to be(nil)
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'with cache_proxy setup' do
75
+ let(:cache_proxy) { FindModel::Conn.new() }
76
+ let(:model_klass) {
77
+ m = FindModel
78
+ m.cache_proxy = FindModel::ConnPool.new(cache_proxy)
79
+ m
80
+ }
81
+
82
+ context 'with no value at key' do
83
+ let(:model) { model_klass.get('di') }
84
+
85
+ describe '#get' do
86
+ it 'returns object with id and content-type set' do
87
+ expect(model.id).to eq('di')
88
+ expect(model.content_type).to eq('application/json')
89
+ end
90
+ end
91
+ end
92
+
93
+ context 'with json value at key' do
94
+ let(:result) { '{"find_model":{"id":"di","name":"eman","field_dne_d":2.718}}' }
95
+ let(:model) {
96
+ m = model_klass
97
+ cache_proxy.result = result
98
+ m.get('di')
99
+ }
100
+
101
+ describe '#get' do
102
+ it 'returns object with fields set' do
103
+ expect(model.id).to eq('di')
104
+ expect(model.content_type).to eq('application/json')
105
+ expect(model.name).to eq('eman')
106
+ end
107
+ end
108
+ end
109
+
110
+ context 'with xml value at key' do
111
+ let(:result) { '<root><find_model><id>di</id><name>eman</name><field_dne_d>2.718</field_dne_d></find_model></root>' }
112
+ let(:model) {
113
+ m = model_klass
114
+ cache_proxy.result = result
115
+ m.get('di')
116
+ }
117
+
118
+ describe '#get' do
119
+ it 'returns object with fields set' do
120
+ expect(model.id).to eq('di')
121
+ expect(model.content_type).to eq('application/xml')
122
+ expect(model.name).to eq('eman')
123
+ end
124
+ end
125
+ end
126
+
127
+ context 'with string value at key' do
128
+ let(:result) { <<EOF
129
+ id:di
130
+ name:eman
131
+ field_dne_d:2.718
132
+ EOF
133
+ }
134
+ let(:model_klass_s) {
135
+ m = model_klass
136
+ cache_proxy.result = result
137
+ m
138
+ }
139
+
140
+ describe '#get' do
141
+ it 'raises UnparseableContentError' do
142
+ expect{model_klass_s.get('di')}.to raise_error(RRRMatey::UnparseableContentError)
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+
3
+ class IndexModel
4
+ extend RRRMatey::StringModel::IndexMethods
5
+
6
+ class ConnPool
7
+ def initialize(conn)
8
+ @conn = conn
9
+ end
10
+
11
+ def with(&block)
12
+ block.call(@conn)
13
+ end
14
+ end
15
+
16
+ class Conn
17
+ @@search_index_name =
18
+ @@search_index_term =
19
+ @@search_start =
20
+ @@search_rows =
21
+ @@search_sort = nil
22
+
23
+ def search_index_name
24
+ @@search_index_name
25
+ end
26
+
27
+ def search_index_term
28
+ @@search_index_term
29
+ end
30
+
31
+ def search_start
32
+ @@search_start
33
+ end
34
+
35
+ def search_rows
36
+ @@search_rows
37
+ end
38
+
39
+ def search_sort
40
+ @@search_sort
41
+ end
42
+
43
+ def self.mock_results(limit)
44
+ item_name_prefix = "#{IndexModel.item_name}."
45
+ {
46
+ 'num_found' => 3,
47
+ 'docs' => [
48
+ {
49
+ '_yz_rk' => 'di1',
50
+ "#{item_name_prefix}name" => 'eman1'
51
+ },
52
+ {
53
+ '_yz_rk' => 'di2',
54
+ "#{item_name_prefix}name" => 'eman2'
55
+ },
56
+ nil,
57
+ {
58
+ '_yz_rk' => 'di3',
59
+ "#{item_name_prefix}name" => 'eman3'
60
+ }
61
+ ]
62
+ }
63
+ end
64
+
65
+ def search(index_name, index_term, opts = {})
66
+ @@search_index_name = index_name
67
+ @@search_index_term = index_term
68
+ @@search_start = opts[:start]
69
+ @@search_rows = opts[:rows]
70
+ @@search_sort = opts[:sort]
71
+
72
+ self.class.mock_results(@@search_rows)
73
+ end
74
+ end
75
+
76
+ def self.namespace()
77
+ 'index_models'
78
+ end
79
+
80
+ def self.item_name()
81
+ 'index_model'
82
+ end
83
+
84
+ def self.riak()
85
+ @riak
86
+ end
87
+
88
+ def self.riak=(v)
89
+ @riak = v
90
+ end
91
+
92
+ def self.object_from_hash(h, id, content_type)
93
+ end
94
+ end
95
+
96
+ describe RRRMatey::StringModel::IndexMethods do
97
+ context 'with or without riak setup' do
98
+ context 'index_name set' do
99
+ let(:model_klass) {
100
+ IndexModel.index_name = 'something_else'
101
+ IndexModel
102
+ }
103
+
104
+ describe '#index_name' do
105
+ it 'yields values from self' do
106
+ expect(model_klass.index_name).to eq('something_else')
107
+ end
108
+ end
109
+ end
110
+
111
+ context 'index_name not set' do
112
+ let(:model_klass) {
113
+ IndexModel.index_name = nil
114
+ IndexModel
115
+ }
116
+ let(:offset) { 4 }
117
+ let(:limit) { 20 }
118
+ let(:empty_discrete_result) {
119
+ RRRMatey::DiscreteResult.new(:length => 0,
120
+ :offset => offset,
121
+ :discrete_length => limit,
122
+ :results => [])
123
+ }
124
+
125
+ describe '#index_name' do
126
+ it 'yields values from StringModel' do
127
+ expect(model_klass.index_name).to eq('index_models')
128
+ end
129
+ end
130
+
131
+ describe '#list' do
132
+ let(:list_result) { model_klass.list(offset, limit) }
133
+
134
+ it 'yields an empty DiscreteResult' do
135
+ expect(list_result.length).to eq(empty_discrete_result.length)
136
+ expect(list_result.offset).to eq(empty_discrete_result.offset)
137
+ expect(list_result.discrete_length).to eq(empty_discrete_result.discrete_length)
138
+ expect(list_result.results).to eq(empty_discrete_result.results)
139
+ end
140
+ end
141
+
142
+ describe '#list_by' do
143
+ let(:list_by_result) { model_klass.list_by(offset, limit, :name => 'ema*') }
144
+
145
+ it 'yields an empty DiscreteResult' do
146
+
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ context 'with riak setup' do
153
+ let(:riak) { IndexModel::Conn.new() }
154
+ let(:riak_pool) {
155
+ IndexModel::ConnPool.new(riak)
156
+ }
157
+ let(:model_klass) {
158
+ IndexModel.index_name = nil
159
+ IndexModel.riak = riak_pool
160
+ IndexModel
161
+ }
162
+ let(:offset) { 4 }
163
+ let(:limit) { 20 }
164
+ let(:results) { IndexModel::Conn.mock_results(limit) }
165
+ let(:result_docs) { results['docs'].select { |it| !it.nil? } }
166
+ let(:discrete_result) {
167
+ RRRMatey::DiscreteResult.new(:length => results.length,
168
+ :offset => offset,
169
+ :discrete_length => limit,
170
+ :results => results)
171
+ }
172
+
173
+ describe '#list' do
174
+ let(:list_result) { model_klass.list(offset, limit) }
175
+
176
+ it 'yields a hydrated DiscreteResult' do
177
+ expect(list_result.length).to eq(result_docs.length)
178
+ end
179
+
180
+ it 'passes the index_name to riak search' do
181
+ expect(riak.search_index_name).to eq(model_klass.index_name)
182
+ end
183
+
184
+ it 'passes the open index_term to riak search' do
185
+ expect(riak.search_index_term).to eq('*:*')
186
+ end
187
+
188
+ it 'passes the offset to riak search' do
189
+ expect(riak.search_start).to eq(offset)
190
+ end
191
+
192
+ it 'passes the limit to riak search' do
193
+ expect(riak.search_rows).to eq(limit)
194
+ end
195
+
196
+ it 'passes riak key ascending sort to riak search' do
197
+ expect(riak.search_sort).to eq('_yz_rk asc')
198
+ end
199
+ end
200
+
201
+ describe '#list_by' do
202
+ let(:list_result) { model_klass.list_by(offset, limit, :name => 'ema*',
203
+ :birth => Date.today) }
204
+ let(:birth_date) { Date.today.to_s }
205
+
206
+ it 'yields a hydrated DiscreteResult' do
207
+ expect(list_result.length).to eq(result_docs.length)
208
+ end
209
+
210
+ it 'passes the index_name to riak search' do
211
+ expect(riak.search_index_name).to eq(model_klass.index_name)
212
+ end
213
+
214
+ it 'passes the specified index_term to riak search' do
215
+ expect(riak.search_index_term).to eq("index_model.name:ema* OR index_model.birth:#{birth_date}")
216
+ end
217
+
218
+ it 'passes the offset to riak search' do
219
+ expect(riak.search_start).to eq(offset)
220
+ end
221
+
222
+ it 'passes the limit to riak search' do
223
+ expect(riak.search_rows).to eq(limit)
224
+ end
225
+
226
+ it 'passes riak key ascending sort to riak search' do
227
+ expect(riak.search_sort).to eq('_yz_rk asc')
228
+ end
229
+ end
230
+ end
231
+ end