rhoconnect 6.0.11 → 6.2.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 +4 -4
- data/Gemfile +14 -11
- data/Gemfile.lock +120 -87
- data/Rakefile +4 -3
- data/bin/rhoconnect +0 -0
- data/bin/rhoconnect-benchmark +0 -0
- data/commands/dtach/dtach_install.rb +29 -24
- data/commands/rhoconnect/start.rb +5 -4
- data/generators/templates/application/rcgemfile +1 -1
- data/lib/rhoconnect/model/helpers/find_duplicates_on_update.rb +1 -1
- data/lib/rhoconnect/store.rb +3 -3
- data/lib/rhoconnect/version.rb +1 -1
- data/rhoconnect.gemspec +11 -11
- data/spec/api/client/get_client_params_spec.rb +4 -0
- data/spec/apps/rhotestapp/models/ruby/sample_adapter.rb +1 -1
- data/spec/client_sync_spec.rb +7 -7
- data/spec/dynamic_adapter_spec.rb +13 -13
- data/spec/generator/generator_spec.rb +7 -7
- data/spec/jobs/ping_job_spec.rb +162 -79
- data/spec/perf/perf_spec_helper.rb +5 -5
- data/spec/ping/apple_spec.rb +24 -26
- data/spec/ping/gcm_spec.rb +26 -28
- data/spec/ping/rhoconnect_push_spec.rb +13 -13
- data/spec/rhoconnect_spec.rb +2 -2
- data/spec/server/cors_spec.rb +22 -22
- data/spec/server/server_spec.rb +308 -310
- data/spec/server/stats_spec.rb +7 -7
- data/spec/server/x_domain_session_wrapper_spec.rb +40 -40
- data/spec/source_adapter_spec.rb +2 -2
- data/spec/source_sync_spec.rb +4 -4
- data/spec/spec_helper.rb +8 -8
- data/spec/stats/record_spec.rb +7 -7
- data/spec/store_orm_spec.rb +97 -94
- data/spec/store_spec.rb +23 -23
- data/spec/user_spec.rb +3 -3
- metadata +32 -26
data/spec/server/stats_spec.rb
CHANGED
@@ -13,11 +13,11 @@ describe "Middleware" do
|
|
13
13
|
@now = 10.0
|
14
14
|
Store.flush_all
|
15
15
|
app = double('app')
|
16
|
-
app.
|
16
|
+
allow(app).to receive(:call)
|
17
17
|
Rhoconnect.stats = true
|
18
18
|
Rhoconnect::Server.enable :stats
|
19
19
|
@middleware_new_routes = Rhoconnect::Middleware::Stats.new(app)
|
20
|
-
Store.
|
20
|
+
allow(Store).to receive(:lock).and_yield
|
21
21
|
end
|
22
22
|
|
23
23
|
after(:each) do
|
@@ -27,7 +27,7 @@ describe "Middleware" do
|
|
27
27
|
|
28
28
|
it "should compute http average" do
|
29
29
|
@incr = 0
|
30
|
-
Time.
|
30
|
+
allow(Time).to receive(:now) do
|
31
31
|
if @incr > 0
|
32
32
|
@now += 0.3
|
33
33
|
@incr -= 1
|
@@ -43,15 +43,15 @@ describe "Middleware" do
|
|
43
43
|
}
|
44
44
|
10.times { @incr = 3; @middleware_new_routes.call(env) }
|
45
45
|
metric = 'http:GET:/api/application/query:SampleAdapter'
|
46
|
-
Rhoconnect::Stats::Record.key(metric).
|
46
|
+
expect(Rhoconnect::Stats::Record.key(metric)).to eq("stat:#{metric}")
|
47
47
|
|
48
48
|
# The conversion algorithm (float to string) currently checks two precisions.
|
49
49
|
# it tries 16 digits and if that's not enough it then uses 17.
|
50
|
-
Rhoconnect::Stats::Record.range(metric, 0, -1).
|
50
|
+
expect(Rhoconnect::Stats::Record.range(metric, 0, -1)).to eq([
|
51
51
|
"2.0,0.6000000000000014:12",
|
52
52
|
"2.0,0.6000000000000014:14",
|
53
53
|
"2.0,0.6000000000000014:16",
|
54
54
|
"2.0,0.6000000000000014:18"
|
55
|
-
]
|
55
|
+
])
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
@@ -50,11 +50,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
50
50
|
'QUERY_STRING' => PROPER_QUERY_STRING
|
51
51
|
}
|
52
52
|
status, headers, body = @middleware_new_routes.call(env)
|
53
|
-
|
54
|
-
COOKIE_ANOTHER_NV.
|
55
|
-
COOKIE_NV.
|
56
|
-
headers['Content-Length'].
|
57
|
-
|
53
|
+
expect(status).to eq(200)
|
54
|
+
expect(COOKIE_ANOTHER_NV). to eq(headers['Set-Cookie'])
|
55
|
+
expect(COOKIE_NV).not_to eq(env['HTTP_COOKIE'])
|
56
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
57
|
+
expect(body[0]).to eq('')
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should skip if it isn't a sync protocol URI, for old REST routes" do
|
@@ -63,11 +63,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
63
63
|
'QUERY_STRING' => PROPER_QUERY_STRING
|
64
64
|
}
|
65
65
|
status, headers, body = @middleware_old_routes.call(env)
|
66
|
-
|
67
|
-
COOKIE_ANOTHER_NV.
|
68
|
-
COOKIE_NV.
|
69
|
-
headers['Content-Length'].
|
70
|
-
|
66
|
+
expect(status).to eq(200)
|
67
|
+
expect(COOKIE_ANOTHER_NV). to eq(headers['Set-Cookie'])
|
68
|
+
expect(COOKIE_NV).not_to eq(env['HTTP_COOKIE'])
|
69
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
70
|
+
expect(body[0]).to eq('')
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should process cookie from QUERY_STRING if it is a sync protocol URI, for new REST routes" do
|
@@ -76,11 +76,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
76
76
|
'QUERY_STRING' => PROPER_QUERY_STRING
|
77
77
|
}
|
78
78
|
status, headers, body = @middleware_new_routes.call(env)
|
79
|
-
|
80
|
-
COOKIE_ANOTHER_NV.
|
81
|
-
env['HTTP_COOKIE'].
|
82
|
-
headers['Content-Length'].
|
83
|
-
|
79
|
+
expect(status).to eq(200)
|
80
|
+
expect(COOKIE_ANOTHER_NV). to eq(headers['Set-Cookie'])
|
81
|
+
expect(env['HTTP_COOKIE']).to eq(COOKIE_VALUE)
|
82
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
83
|
+
expect(body[0]).to eq('')
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should process cookie from QUERY_STRING if it is a sync protocol URI, for old REST routes" do
|
@@ -89,11 +89,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
89
89
|
'QUERY_STRING' => PROPER_QUERY_STRING
|
90
90
|
}
|
91
91
|
status, headers, body = @middleware_old_routes.call(env)
|
92
|
-
|
93
|
-
COOKIE_ANOTHER_NV.
|
94
|
-
env['HTTP_COOKIE'].
|
95
|
-
headers['Content-Length'].
|
96
|
-
|
92
|
+
expect(status).to eq(200)
|
93
|
+
expect(COOKIE_ANOTHER_NV). to eq(headers['Set-Cookie'])
|
94
|
+
expect(env['HTTP_COOKIE']).to eq(COOKIE_VALUE)
|
95
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
96
|
+
expect(body[0]).to eq('')
|
97
97
|
end
|
98
98
|
|
99
99
|
it "shouldn't process cookie from QUERY_STRING if there is no appropriate parameter name or value, for new REST routes" do
|
@@ -102,11 +102,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
102
102
|
'QUERY_STRING' => WRONG_QUERY_STRING
|
103
103
|
}
|
104
104
|
status, headers, body = @middleware_new_routes.call(env)
|
105
|
-
|
106
|
-
COOKIE_ANOTHER_NV.
|
107
|
-
env['HTTP_COOKIE'].
|
108
|
-
headers['Content-Length'].
|
109
|
-
|
105
|
+
expect(status).to eq(200)
|
106
|
+
expect(COOKIE_ANOTHER_NV). to eq(headers['Set-Cookie'])
|
107
|
+
expect(env['HTTP_COOKIE']).not_to eq(COOKIE_VALUE)
|
108
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
109
|
+
expect(body[0]).to eq('')
|
110
110
|
end
|
111
111
|
|
112
112
|
it "shouldn't process cookie from QUERY_STRING if there is no appropriate parameter name or value, for old REST routes" do
|
@@ -115,11 +115,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
115
115
|
'QUERY_STRING' => WRONG_QUERY_STRING
|
116
116
|
}
|
117
117
|
status, headers, body = @middleware_old_routes.call(env)
|
118
|
-
|
119
|
-
COOKIE_ANOTHER_NV.
|
120
|
-
env['HTTP_COOKIE'].
|
121
|
-
headers['Content-Length'].
|
122
|
-
|
118
|
+
expect(status).to eq(200)
|
119
|
+
expect(COOKIE_ANOTHER_NV). to eq(headers['Set-Cookie'])
|
120
|
+
expect(env['HTTP_COOKIE']).not_to eq(COOKIE_VALUE)
|
121
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
122
|
+
expect(body[0]).to eq('')
|
123
123
|
end
|
124
124
|
|
125
125
|
it "should respond with cookie in a body if it is a login URI, for new REST routes" do
|
@@ -128,11 +128,11 @@ describe "XDomainSessionWrapper middleware" do
|
|
128
128
|
'QUERY_STRING' => PROPER_QUERY_STRING
|
129
129
|
}
|
130
130
|
status, headers, body = @middleware_new_routes.call(env)
|
131
|
-
|
132
|
-
headers['Set-Cookie'].
|
133
|
-
env['HTTP_COOKIE'].
|
134
|
-
headers['Content-Length'].
|
135
|
-
''.
|
131
|
+
expect(status).to eq(200)
|
132
|
+
expect(headers['Set-Cookie']).to eq(COOKIE_ANOTHER_NV)
|
133
|
+
expect(env['HTTP_COOKIE']).to eq(COOKIE_VALUE)
|
134
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
135
|
+
expect('').not_to eq(body[0])
|
136
136
|
end
|
137
137
|
|
138
138
|
it "should respond with cookie in a body if it is a login URI, for old REST routes" do
|
@@ -141,10 +141,10 @@ describe "XDomainSessionWrapper middleware" do
|
|
141
141
|
'QUERY_STRING' => PROPER_QUERY_STRING
|
142
142
|
}
|
143
143
|
status, headers, body = @middleware_old_routes.call(env)
|
144
|
-
|
145
|
-
headers['Set-Cookie'].
|
146
|
-
env['HTTP_COOKIE'].
|
147
|
-
headers['Content-Length'].
|
148
|
-
''.
|
144
|
+
expect(status).to eq(200)
|
145
|
+
expect(headers['Set-Cookie']).to eq(COOKIE_ANOTHER_NV)
|
146
|
+
expect(env['HTTP_COOKIE']).to eq(COOKIE_VALUE)
|
147
|
+
expect(headers['Content-Length']).to eq(body[0].length.to_s)
|
148
|
+
expect('').not_to eq(body[0])
|
149
149
|
end
|
150
150
|
end
|
data/spec/source_adapter_spec.rb
CHANGED
@@ -61,7 +61,7 @@ describe "Model" do
|
|
61
61
|
|
62
62
|
it "should create model with trailing spaces" do
|
63
63
|
s = setup_adapter('SimpleAdapter ')
|
64
|
-
Rhoconnect::Model::Base.create(s).is_a?(SimpleAdapter).should
|
64
|
+
Rhoconnect::Model::Base.create(s).is_a?(SimpleAdapter).should be true
|
65
65
|
end
|
66
66
|
|
67
67
|
describe "model methods" do
|
@@ -152,4 +152,4 @@ describe "Model" do
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
end
|
155
|
-
end
|
155
|
+
end
|
data/spec/source_sync_spec.rb
CHANGED
@@ -578,7 +578,7 @@ describe "SourceSync" do
|
|
578
578
|
set_source_queue_state(@s, {@create_queue_name => [[@s.name, [['5', { 'name' => 'Android', 'link' => '1', 'force_duplicate_error' => '1' }]]]]},@c.id,true)
|
579
579
|
@sscud.do_cud
|
580
580
|
verify_source_queue_data(@s, @create_queue_name => [])
|
581
|
-
verify_doc_result(@c, :create_errors => {"5-error"=>{"message"=>"Error during create: object
|
581
|
+
verify_doc_result(@c, :create_errors => {"5-error"=>{"message"=>"Error during create: object conflict detected"}, "5"=>{"name"=>"Android", "link"=>"1", 'force_duplicate_error' => '1'}} )
|
582
582
|
end
|
583
583
|
|
584
584
|
it "should detect create conflict in the intermediate state create and skip the duplicate record create" do
|
@@ -609,7 +609,7 @@ describe "SourceSync" do
|
|
609
609
|
@sscud.do_cud
|
610
610
|
|
611
611
|
verify_source_queue_data(@s, @update_queue_name => [])
|
612
|
-
verify_doc_result(@c, :update_errors => {"4-error"=>{"message"=>"Error during update: object
|
612
|
+
verify_doc_result(@c, :update_errors => {"4-error"=>{"message"=>"Error during update: object conflict detected"}, "4"=>{"name"=>"ErrorName", 'force_duplicate_error' => '1'}})
|
613
613
|
verify_doc_result(@c, :update_rollback => {'4'=> {'name' => 'Apple'}})
|
614
614
|
end
|
615
615
|
|
@@ -644,7 +644,7 @@ describe "SourceSync" do
|
|
644
644
|
@sscud.do_cud
|
645
645
|
|
646
646
|
verify_source_queue_data(@s, @update_queue_name => [])
|
647
|
-
verify_doc_result(@c, :update_errors => {"4-error"=>{"message"=>"Error during update: object
|
647
|
+
verify_doc_result(@c, :update_errors => {"4-error"=>{"message"=>"Error during update: object conflict detected"}, "4"=>{"name"=>"ErrorName", 'force_duplicate_error' => '1'}})
|
648
648
|
verify_doc_result(@c, :update_rollback => {'4'=> {'name' => 'Apple'}})
|
649
649
|
end
|
650
650
|
|
@@ -704,7 +704,7 @@ describe "SourceSync" do
|
|
704
704
|
@sscud.do_cud
|
705
705
|
|
706
706
|
verify_source_queue_data(@s, @delete_queue_name => [])
|
707
|
-
verify_doc_result(@c, :delete_errors => {"4-error"=>{"message"=>"Error during delete: object
|
707
|
+
verify_doc_result(@c, :delete_errors => {"4-error"=>{"message"=>"Error during delete: object conflict detected"}, "4"=>{"name"=>"Apple", 'force_duplicate_error' => '1'}})
|
708
708
|
end
|
709
709
|
end
|
710
710
|
|
data/spec/spec_helper.rb
CHANGED
@@ -143,7 +143,7 @@ module TestHelpers
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def setup_post_yield(response)
|
146
|
-
RestClient.
|
146
|
+
allow(RestClient).to receive(:post).and_yield(response, nil, nil)
|
147
147
|
end
|
148
148
|
|
149
149
|
def set_state(state,append=false)
|
@@ -186,11 +186,11 @@ module TestHelpers
|
|
186
186
|
expected = result[dockey]
|
187
187
|
begin
|
188
188
|
if expected.is_a?(Hash)
|
189
|
-
Store.get_data(dockey).
|
189
|
+
expect(Store.get_data(dockey)).to eq(expected)
|
190
190
|
elsif expected.is_a?(Array)
|
191
|
-
Store.get_data(dockey,Array).
|
191
|
+
expect(Store.get_data(dockey, Array)).to eq(expected)
|
192
192
|
else
|
193
|
-
Store.get_value(dockey).
|
193
|
+
expect(Store.get_value(dockey)).to eq(expected)
|
194
194
|
end
|
195
195
|
rescue RSpec::Expectations::ExpectationNotMetError => e
|
196
196
|
message = "\nVerifying `#{dockey}`\n\n" + e.to_s
|
@@ -204,11 +204,11 @@ module TestHelpers
|
|
204
204
|
expected = result[dockey]
|
205
205
|
begin
|
206
206
|
if expected.is_a?(Hash)
|
207
|
-
docobj.get_data(dockey).
|
207
|
+
expect(docobj.get_data(dockey)).to eq(expected)
|
208
208
|
elsif expected.is_a?(Array)
|
209
|
-
docobj.get_data(dockey,Array).
|
209
|
+
expect(docobj.get_data(dockey,Array)).to eq(expected)
|
210
210
|
else
|
211
|
-
docobj.get_value(dockey).
|
211
|
+
expect(docobj.get_value(dockey)).to eq(expected)
|
212
212
|
end
|
213
213
|
rescue RSpec::Expectations::ExpectationNotMetError => e
|
214
214
|
message = "\nVerifying `#{dockey}`\n\n" + e.to_s
|
@@ -222,7 +222,7 @@ module TestHelpers
|
|
222
222
|
expected = result[dockey]
|
223
223
|
begin
|
224
224
|
data,assoc_keys = source.get_queue(dockey)
|
225
|
-
data.
|
225
|
+
expect(data).to eq(expected)
|
226
226
|
rescue RSpec::Expectations::ExpectationNotMetError => e
|
227
227
|
message = "\nVerifying `#{dockey}`\n\n" + e.to_s
|
228
228
|
Kernel::raise(RSpec::Expectations::ExpectationNotMetError.new(message))
|
data/spec/stats/record_spec.rb
CHANGED
@@ -16,13 +16,13 @@ describe "Record" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should add metric to the record and trim record size" do
|
19
|
-
Time.
|
19
|
+
allow(Time).to receive(:now) { @now }
|
20
20
|
10.times { @now += 1; Rhoconnect::Stats::Record.add('foo') }
|
21
21
|
Store.zrange('stat:foo', 0, -1).should == ["2:12", "2:14", "2:16", "2:18"]
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should add single record" do
|
25
|
-
Time.
|
25
|
+
allow(Time).to receive(:now) { @now += 1; @now }
|
26
26
|
Rhoconnect::Stats::Record.add('foo')
|
27
27
|
Store.zrange('stat:foo', 0, -1).should == ["1:10"]
|
28
28
|
end
|
@@ -49,7 +49,7 @@ describe "Record" do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should add absolute metric value" do
|
52
|
-
Time.
|
52
|
+
allow(Time).to receive(:now) { @now }
|
53
53
|
time = 0
|
54
54
|
4.times do
|
55
55
|
@now += 1
|
@@ -62,7 +62,7 @@ describe "Record" do
|
|
62
62
|
it "should update metric" do
|
63
63
|
Rhoconnect.stats = true
|
64
64
|
@incr = 0
|
65
|
-
Time.
|
65
|
+
allow(Time).to receive(:now) do
|
66
66
|
if @incr > 0
|
67
67
|
@now += 1
|
68
68
|
@incr -= 1
|
@@ -80,13 +80,13 @@ describe "Record" do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should get range of metric values" do
|
83
|
-
Time.
|
83
|
+
allow(Time).to receive(:now) { @now }
|
84
84
|
10.times { @now += 1; Rhoconnect::Stats::Record.add('foo') }
|
85
85
|
Rhoconnect::Stats::Record.range('foo', 0, 1).should == ["2:12", "2:14"]
|
86
86
|
end
|
87
87
|
|
88
88
|
it "should reset metric" do
|
89
|
-
Time.
|
89
|
+
allow(Time).to receive(:now) { @now }
|
90
90
|
10.times { @now += 1; Rhoconnect::Stats::Record.add('foo') }
|
91
91
|
Store.zrange('stat:foo', 0, -1).should == ["2:12", "2:14", "2:16", "2:18"]
|
92
92
|
Rhoconnect::Stats::Record.reset('foo')
|
@@ -99,4 +99,4 @@ describe "Record" do
|
|
99
99
|
Rhoconnect::Stats::Record.reset_all
|
100
100
|
Store.keys('stat:*').should == []
|
101
101
|
end
|
102
|
-
end
|
102
|
+
end
|
data/spec/store_orm_spec.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# Taken from http://github.com/voloko/redis-model
|
2
|
-
require File.join(File.dirname(__FILE__),'spec_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
3
|
|
4
4
|
describe Rhoconnect::StoreOrm do
|
5
5
|
|
6
6
|
context "DSL" do
|
7
7
|
class TestDSL < Rhoconnect::StoreOrm
|
8
8
|
field :foo
|
9
|
-
list
|
10
|
-
set
|
9
|
+
list :bar
|
10
|
+
set :sloppy
|
11
11
|
end
|
12
12
|
|
13
13
|
before(:each) do
|
@@ -15,37 +15,37 @@ describe Rhoconnect::StoreOrm do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should define rw accessors for field" do
|
18
|
-
@x.
|
19
|
-
@x.
|
18
|
+
expect(@x).to respond_to(:foo)
|
19
|
+
expect(@x).to respond_to(:foo=)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should define r accessor for list" do
|
23
|
-
@x.
|
23
|
+
expect(@x).to respond_to(:bar)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should define r accessor for set" do
|
27
|
-
@x.
|
27
|
+
expect(@x).to respond_to(:sloppy)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should raise error on invalid type" do
|
31
|
-
lambda do
|
31
|
+
expect(lambda do
|
32
32
|
class TestInvalidType < Rhoconnect::StoreOrm
|
33
33
|
field :invalid, :invalid_type
|
34
34
|
end
|
35
|
-
end.
|
35
|
+
end).to raise_error(ArgumentError, 'Unknown type invalid_type for field invalid')
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
context "field type cast" do
|
40
40
|
class TestType < Rhoconnect::StoreOrm
|
41
41
|
field :foo_string, :string
|
42
|
-
field :foo_json,
|
43
|
-
field :foo_date,
|
44
|
-
field :foo_int,
|
45
|
-
field :foo_float,
|
42
|
+
field :foo_json, :json
|
43
|
+
field :foo_date, :datetime
|
44
|
+
field :foo_int, :int
|
45
|
+
field :foo_float, :float
|
46
46
|
|
47
|
-
list
|
48
|
-
set
|
47
|
+
list :list_date, :datetime
|
48
|
+
set :set_date, :datetime
|
49
49
|
end
|
50
50
|
|
51
51
|
class TestValidateType < Rhoconnect::StoreOrm
|
@@ -61,135 +61,135 @@ describe Rhoconnect::StoreOrm do
|
|
61
61
|
before(:each) do
|
62
62
|
Store.create
|
63
63
|
Store.flush_all
|
64
|
+
=begin
|
64
65
|
@xRedisMock = RSpec::Mocks::Mock.new
|
65
66
|
@yRedisMock = RSpec::Mocks::Mock.new
|
66
67
|
@xRedisDbMock = RSpec::Mocks::Mock.new
|
67
68
|
@yRedisDbMock = RSpec::Mocks::Mock.new
|
69
|
+
=end
|
68
70
|
@x = TestType.with_key(1)
|
69
71
|
@y = TestType.with_key(1)
|
70
|
-
@x.
|
71
|
-
@y.
|
72
|
-
@xRedisMock.
|
73
|
-
@yRedisMock.
|
72
|
+
allow(@x).to receive(:store).and_return(@xRedisMock)
|
73
|
+
allow(@y).to receive(:store).and_return(@yRedisMock)
|
74
|
+
allow(@xRedisMock).to receive(:db).and_return(@xRedisDbMock)
|
75
|
+
allow(@yRedisMock).to receive(:db).and_return(@yRedisDbMock)
|
74
76
|
end
|
75
77
|
|
76
78
|
it "should create with string id" do
|
77
79
|
@x = TestType.create(:id => 'test')
|
78
|
-
@x.id.
|
80
|
+
expect(@x.id).to eq('test')
|
79
81
|
end
|
80
82
|
|
81
83
|
it "should create with auto-increment id" do
|
82
84
|
@x = TestType.create
|
83
85
|
@x1 = TestType.create
|
84
|
-
@x1.id.
|
86
|
+
expect(@x1.id).to eq(@x.id + 1)
|
85
87
|
end
|
86
88
|
|
87
89
|
it "should raise ArgumentError on create with duplicate id" do
|
88
90
|
@x = TestType.create(:id => 'test1')
|
89
|
-
lambda {
|
90
|
-
raise_error(ArgumentError, "Record already exists for 'test1'")
|
91
|
+
expect(lambda {TestType.create(:id => 'test1') }).to raise_error(ArgumentError, "Record already exists for 'test1'")
|
91
92
|
end
|
92
93
|
|
93
94
|
it "should validate_presence_of v_field" do
|
94
|
-
lambda {
|
95
|
-
raise_error(ArgumentError, "Missing required field 'v_field'")
|
95
|
+
expect(lambda {TestValidateType.create(:id => 'test2')}).to raise_error(ArgumentError, "Missing required field 'v_field'")
|
96
96
|
end
|
97
97
|
|
98
98
|
it "should load with attributes set" do
|
99
99
|
TestLoadType.create(:id => 'test2')
|
100
|
-
@x = TestLoadType.load('test2',{:foo => 'bar'})
|
101
|
-
@x.foo.
|
100
|
+
@x = TestLoadType.load('test2', {:foo => 'bar'})
|
101
|
+
expect(@x.foo).to eq('bar')
|
102
102
|
end
|
103
103
|
|
104
104
|
it "should save string as is" do
|
105
|
-
@xRedisMock.
|
106
|
-
@yRedisMock.
|
105
|
+
expect(@xRedisMock).to receive(:put_value).with('test_type:1:foo_string', 'xxx')
|
106
|
+
expect(@yRedisMock).to receive(:get_value).with('test_type:1:foo_string').and_return('xxx')
|
107
107
|
@x.foo_string = 'xxx'
|
108
|
-
@y.foo_string.
|
108
|
+
expect(@y.foo_string).to be_instance_of(String)
|
109
109
|
end
|
110
110
|
|
111
111
|
it "should marshal integer fields" do
|
112
|
-
@xRedisMock.
|
113
|
-
@yRedisMock.
|
112
|
+
expect(@xRedisMock).to receive(:put_value).with('test_type:1:foo_int', '12')
|
113
|
+
expect(@yRedisMock).to receive(:get_value).with('test_type:1:foo_int').and_return('12')
|
114
114
|
@x.foo_int = 12
|
115
|
-
@y.foo_int.
|
116
|
-
@y.foo_int.
|
115
|
+
expect(@y.foo_int).to be_kind_of(Integer)
|
116
|
+
expect(@y.foo_int).to eq(12)
|
117
117
|
end
|
118
118
|
|
119
119
|
it "should marshal float fields" do
|
120
|
-
@xRedisMock.
|
121
|
-
@yRedisMock.
|
120
|
+
expect(@xRedisMock).to receive(:put_value).with('test_type:1:foo_float', '12.1')
|
121
|
+
expect(@yRedisMock).to receive(:get_value).with('test_type:1:foo_float').and_return('12.1')
|
122
122
|
@x.foo_float = 12.1
|
123
|
-
@y.foo_float.
|
124
|
-
@y.foo_float.
|
123
|
+
expect(@y.foo_float).to be_kind_of(Float)
|
124
|
+
expect(@y.foo_float).to eq(12.1)
|
125
125
|
end
|
126
126
|
|
127
127
|
it "should marshal datetime fields" do
|
128
128
|
time = DateTime.now
|
129
|
-
str
|
130
|
-
@xRedisMock.
|
131
|
-
@yRedisMock.
|
129
|
+
str = time.strftime('%FT%T%z')
|
130
|
+
expect(@xRedisMock).to receive(:put_value).with('test_type:1:foo_date', str)
|
131
|
+
expect(@yRedisMock).to receive(:get_value).with('test_type:1:foo_date').and_return(str)
|
132
132
|
@x.foo_date = time
|
133
|
-
@y.foo_date.
|
134
|
-
@y.foo_date.
|
133
|
+
expect(@y.foo_date).to be_kind_of(DateTime)
|
134
|
+
expect(@y.foo_date.to_s).to eq(time.to_s)
|
135
135
|
end
|
136
136
|
|
137
137
|
it "should marshal json structs" do
|
138
138
|
data = {'foo' => 'bar', 'x' => 2}
|
139
|
-
str
|
140
|
-
@xRedisMock.
|
141
|
-
@yRedisMock.
|
139
|
+
str = JSON.dump(data)
|
140
|
+
expect(@xRedisMock).to receive(:put_value).with('test_type:1:foo_json', str)
|
141
|
+
expect(@yRedisMock).to receive(:get_value).with('test_type:1:foo_json').and_return(str)
|
142
142
|
@x.foo_json = data
|
143
|
-
@y.foo_json.
|
144
|
-
@y.foo_json.
|
143
|
+
expect(@y.foo_json).to be_kind_of(Hash)
|
144
|
+
expect(@y.foo_json.inspect).to eq(data.inspect)
|
145
145
|
end
|
146
146
|
|
147
147
|
it "should return nil for empty fields" do
|
148
|
-
@xRedisMock.
|
149
|
-
@x.foo_date.
|
148
|
+
expect(@xRedisMock).to receive(:get_value).with('test_type:1:foo_date').and_return(nil)
|
149
|
+
expect(@x.foo_date).to be_nil
|
150
150
|
end
|
151
151
|
|
152
152
|
it "should marshal list values" do
|
153
153
|
data = DateTime.now
|
154
|
-
str
|
155
|
-
|
156
|
-
@xRedisDbMock.
|
157
|
-
@xRedisDbMock.
|
158
|
-
@xRedisDbMock.
|
159
|
-
@xRedisDbMock.
|
160
|
-
@xRedisDbMock.
|
161
|
-
@xRedisDbMock.
|
162
|
-
@xRedisDbMock.
|
163
|
-
@xRedisDbMock.
|
164
|
-
@xRedisDbMock.
|
154
|
+
str = data.strftime('%FT%T%z')
|
155
|
+
|
156
|
+
expect(@xRedisDbMock).to receive('rpush').with('test_type:1:list_date', str)
|
157
|
+
expect(@xRedisDbMock).to receive('lset').with('test_type:1:list_date', 1, str)
|
158
|
+
expect(@xRedisDbMock).to receive('exists').with('test_type:1:list_date', str)
|
159
|
+
expect(@xRedisDbMock).to receive('lrem').with('test_type:1:list_date', 0, str)
|
160
|
+
expect(@xRedisDbMock).to receive('lpush').with('test_type:1:list_date', str)
|
161
|
+
expect(@xRedisDbMock).to receive('lrange').with('test_type:1:list_date', 0, 1).and_return([str])
|
162
|
+
expect(@xRedisDbMock).to receive('rpop').with('test_type:1:list_date').and_return(str)
|
163
|
+
expect(@xRedisDbMock).to receive('lpop').with('test_type:1:list_date').and_return(str)
|
164
|
+
expect(@xRedisDbMock).to receive('lindex').with('test_type:1:list_date', 0).and_return(str)
|
165
165
|
@x.list_date << data
|
166
166
|
@x.list_date[1] = data
|
167
167
|
@x.list_date.include?(data)
|
168
168
|
@x.list_date.remove(0, data)
|
169
169
|
@x.list_date.push_head(data)
|
170
|
-
@x.list_date[0].
|
171
|
-
@x.list_date[0, 1][0].
|
172
|
-
@x.list_date.pop_tail.
|
173
|
-
@x.list_date.pop_head.
|
170
|
+
expect(@x.list_date[0]).to be_kind_of(DateTime)
|
171
|
+
expect(@x.list_date[0, 1][0]).to be_kind_of(DateTime)
|
172
|
+
expect(@x.list_date.pop_tail).to be_kind_of(DateTime)
|
173
|
+
expect(@x.list_date.pop_head).to be_kind_of(DateTime)
|
174
174
|
end
|
175
175
|
|
176
176
|
it "should marshal set values" do
|
177
177
|
data = DateTime.now
|
178
|
-
str
|
178
|
+
str = data.strftime('%FT%T%z')
|
179
179
|
|
180
|
-
@xRedisDbMock.
|
181
|
-
@xRedisDbMock.
|
182
|
-
@xRedisDbMock.
|
183
|
-
@xRedisDbMock.
|
180
|
+
expect(@xRedisDbMock).to receive('sadd').with('test_type:1:set_date', str)
|
181
|
+
expect(@xRedisDbMock).to receive('srem').with('test_type:1:set_date', str)
|
182
|
+
expect(@xRedisDbMock).to receive('sismember').with('test_type:1:set_date', str)
|
183
|
+
expect(@xRedisDbMock).to receive('smembers').with('test_type:1:set_date').and_return([str])
|
184
184
|
@x.set_date << data
|
185
185
|
@x.set_date.delete(data)
|
186
186
|
@x.set_date.include?(data)
|
187
|
-
@x.set_date.members[0].
|
187
|
+
expect(@x.set_date.members[0]).to be_kind_of(DateTime)
|
188
188
|
end
|
189
189
|
|
190
190
|
it "should handle empty members" do
|
191
|
-
@xRedisDbMock.
|
192
|
-
@x.set_date.members.
|
191
|
+
allow(@xRedisDbMock).to receive(:smembers).and_return(nil)
|
192
|
+
expect(@x.set_date.members).to eq([])
|
193
193
|
end
|
194
194
|
end
|
195
195
|
|
@@ -201,25 +201,26 @@ describe Rhoconnect::StoreOrm do
|
|
201
201
|
end
|
202
202
|
|
203
203
|
before do
|
204
|
-
|
204
|
+
#@redisMock = RSpec::Mocks::Mock.new
|
205
|
+
@redisMock
|
205
206
|
@x = TestIncrements.with_key(1)
|
206
|
-
@x.
|
207
|
+
allow(@x).to receive(:store).and_return(@redisMock)
|
207
208
|
end
|
208
209
|
|
209
210
|
it "should send INCR when #increment! is called on an integer" do
|
210
|
-
@redisMock.
|
211
|
+
expect(@redisMock).to receive(:update_count).with("test_increments:1:foo", 1)
|
211
212
|
@x.increment!(:foo)
|
212
213
|
end
|
213
214
|
|
214
215
|
it "should send DECR when #decrement! is called on an integer" do
|
215
|
-
@redisMock.
|
216
|
+
expect(@redisMock).to receive(:update_count).with("test_increments:1:foo", -1)
|
216
217
|
@x.decrement!(:foo)
|
217
218
|
end
|
218
219
|
|
219
220
|
it "should raise an ArgumentError when called on non-integers" do
|
220
221
|
[:bar, :baz].each do |f|
|
221
|
-
lambda{@x.increment!(f)}.
|
222
|
-
lambda{@x.decrement!(f)}.
|
222
|
+
expect(lambda {@x.increment!(f)}).to raise_error(ArgumentError)
|
223
|
+
expect(lambda {@x.decrement!(f)}).to raise_error(ArgumentError)
|
223
224
|
end
|
224
225
|
end
|
225
226
|
end
|
@@ -227,48 +228,50 @@ describe Rhoconnect::StoreOrm do
|
|
227
228
|
context "redis commands" do
|
228
229
|
class TestCommands < Rhoconnect::StoreOrm
|
229
230
|
field :foo
|
230
|
-
list
|
231
|
-
set
|
231
|
+
list :bar
|
232
|
+
set :sloppy
|
232
233
|
end
|
233
234
|
|
234
235
|
before(:each) do
|
235
|
-
@redisMock = RSpec::Mocks::Mock.new
|
236
|
-
@redisDbMock = RSpec::Mocks::Mock.new
|
236
|
+
# @redisMock = RSpec::Mocks::Mock.new
|
237
|
+
# @redisDbMock = RSpec::Mocks::Mock.new
|
238
|
+
@redisMock
|
239
|
+
@redisDbMock
|
237
240
|
@x = TestCommands.with_key(1)
|
238
|
-
@x.
|
239
|
-
@redisMock.
|
241
|
+
allow(@x).to receive(:store).and_return(@redisMock)
|
242
|
+
allow(@redisMock).to receive(:db).and_return(@redisDbMock)
|
240
243
|
end
|
241
244
|
|
242
245
|
it "should send GET on field read" do
|
243
|
-
@redisMock.
|
246
|
+
expect(@redisMock).to receive(:get_value).with('test_commands:1:foo')
|
244
247
|
@x.foo
|
245
248
|
end
|
246
249
|
|
247
250
|
it "should send SET on field write" do
|
248
|
-
@redisMock.
|
251
|
+
expect(@redisMock).to receive(:put_value).with('test_commands:1:foo', 'bar')
|
249
252
|
@x.foo = 'bar'
|
250
253
|
end
|
251
254
|
|
252
255
|
it "should send RPUSH on list <<" do
|
253
|
-
@redisDbMock.
|
256
|
+
expect(@redisDbMock).to receive(:rpush).with('test_commands:1:bar', 'bar')
|
254
257
|
@x.bar << 'bar'
|
255
258
|
end
|
256
259
|
|
257
260
|
it "should send SADD on set <<" do
|
258
|
-
@redisDbMock.
|
261
|
+
expect(@redisDbMock).to receive(:sadd).with('test_commands:1:sloppy', 'bar')
|
259
262
|
@x.sloppy << 'bar'
|
260
263
|
end
|
261
264
|
|
262
265
|
it "should delete separate fields" do
|
263
|
-
@redisMock.
|
266
|
+
expect(@redisMock).to receive(:delete_value).with('test_commands:1:foo')
|
264
267
|
@x.delete :foo
|
265
268
|
end
|
266
269
|
|
267
270
|
it "should delete all field" do
|
268
|
-
@redisMock.
|
269
|
-
@redisMock.
|
270
|
-
@redisMock.
|
271
|
-
@redisMock.
|
271
|
+
expect(@redisMock).to receive(:delete_value).with('test_commands:1:foo')
|
272
|
+
expect(@redisMock).to receive(:delete_value).with('test_commands:1:rho__id')
|
273
|
+
expect(@redisMock).to receive(:delete_value).with('test_commands:1:bar')
|
274
|
+
expect(@redisMock).to receive(:delete_value).with('test_commands:1:sloppy')
|
272
275
|
@x.delete
|
273
276
|
end
|
274
277
|
end
|