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.
- checksums.yaml +7 -0
- data/LICENSE.md +16 -0
- data/README.md +249 -0
- data/RELEASE_NOTES.md +26 -0
- data/Rakefile +39 -0
- data/lib/rrrmatey.rb +8 -0
- data/lib/rrrmatey/crud_controller.rb +97 -0
- data/lib/rrrmatey/discrete_result.rb +31 -0
- data/lib/rrrmatey/errors.rb +11 -0
- data/lib/rrrmatey/retryable.rb +28 -0
- data/lib/rrrmatey/string_model/connection_methods.rb +47 -0
- data/lib/rrrmatey/string_model/consumer_adapter_methods.rb +9 -0
- data/lib/rrrmatey/string_model/delete_methods.rb +12 -0
- data/lib/rrrmatey/string_model/field_definition_methods.rb +101 -0
- data/lib/rrrmatey/string_model/find_methods.rb +85 -0
- data/lib/rrrmatey/string_model/index_methods.rb +90 -0
- data/lib/rrrmatey/string_model/namespaced_key_methods.rb +21 -0
- data/lib/rrrmatey/string_model/string_model.rb +92 -0
- data/lib/rrrmatey/type_coercion.rb +61 -0
- data/lib/rrrmatey/version.rb +3 -0
- data/spec/rrrmatey/crud_controller/crud_controller_spec.rb +258 -0
- data/spec/rrrmatey/crud_controller/model_methods_spec.rb +26 -0
- data/spec/rrrmatey/discrete_result_spec.rb +104 -0
- data/spec/rrrmatey/retryable_spec.rb +95 -0
- data/spec/rrrmatey/string_model/connection_methods_spec.rb +64 -0
- data/spec/rrrmatey/string_model/consumer_adapter_methods_spec.rb +43 -0
- data/spec/rrrmatey/string_model/delete_methods_spec.rb +36 -0
- data/spec/rrrmatey/string_model/field_definition_methods_spec.rb +51 -0
- data/spec/rrrmatey/string_model/find_methods_spec.rb +147 -0
- data/spec/rrrmatey/string_model/index_methods_spec.rb +231 -0
- data/spec/rrrmatey/string_model/namespaced_key_methods_spec.rb +34 -0
- data/spec/rrrmatey/string_model/string_model_spec.rb +208 -0
- data/spec/spec_helper.rb +16 -0
- 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
|