rrrmatey 0.1.0

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.
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