stormpath-sdk 0.4.0 → 1.0.0.beta
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.
- data/.gitignore +6 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +27 -0
- data/CHANGES.md +21 -1
- data/Gemfile +1 -2
- data/README.md +457 -11
- data/Rakefile +15 -1
- data/lib/stormpath-sdk.rb +52 -33
- data/lib/stormpath-sdk/{resource/group_list.rb → api_key.rb} +5 -9
- data/lib/stormpath-sdk/auth/authentication_result.rb +3 -13
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +5 -11
- data/lib/stormpath-sdk/auth/basic_login_attempt.rb +6 -8
- data/lib/stormpath-sdk/auth/username_password_request.rb +2 -5
- data/lib/stormpath-sdk/cache/cache.rb +54 -0
- data/lib/stormpath-sdk/cache/cache_entry.rb +33 -0
- data/lib/stormpath-sdk/cache/cache_manager.rb +22 -0
- data/lib/stormpath-sdk/cache/cache_stats.rb +35 -0
- data/lib/stormpath-sdk/cache/memory_store.rb +29 -0
- data/lib/stormpath-sdk/cache/redis_store.rb +32 -0
- data/lib/stormpath-sdk/client.rb +111 -0
- data/lib/stormpath-sdk/data_store.rb +241 -0
- data/lib/stormpath-sdk/{client/api_key.rb → error.rb} +16 -10
- data/lib/stormpath-sdk/{util → ext}/hash.rb +1 -2
- data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +8 -4
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +8 -7
- data/lib/stormpath-sdk/http/request.rb +4 -8
- data/lib/stormpath-sdk/{util/request_utils.rb → http/utils.rb} +17 -38
- data/lib/stormpath-sdk/resource/account.rb +12 -108
- data/lib/stormpath-sdk/resource/application.rb +35 -171
- data/lib/stormpath-sdk/resource/associations.rb +97 -0
- data/lib/stormpath-sdk/resource/base.rb +256 -0
- data/lib/stormpath-sdk/resource/collection.rb +94 -0
- data/lib/stormpath-sdk/resource/directory.rb +11 -68
- data/lib/stormpath-sdk/resource/email_verification_token.rb +3 -9
- data/lib/stormpath-sdk/resource/error.rb +4 -38
- data/lib/stormpath-sdk/resource/expansion.rb +28 -0
- data/lib/stormpath-sdk/resource/group.rb +8 -66
- data/lib/stormpath-sdk/resource/group_membership.rb +4 -55
- data/lib/stormpath-sdk/resource/{application_list.rb → instance.rb} +7 -13
- data/lib/stormpath-sdk/resource/password_reset_token.rb +5 -23
- data/lib/stormpath-sdk/resource/status.rb +22 -28
- data/lib/stormpath-sdk/resource/tenant.rb +5 -52
- data/lib/stormpath-sdk/resource/utils.rb +43 -13
- data/lib/stormpath-sdk/util/assert.rb +5 -15
- data/lib/stormpath-sdk/version.rb +3 -3
- data/spec/api_key_spec.rb +19 -0
- data/spec/auth/basic_authenticator_spec.rb +25 -0
- data/spec/auth/sauthc1_signer_spec.rb +42 -0
- data/spec/cache/cache_entry_spec.rb +157 -0
- data/spec/cache/cache_spec.rb +89 -0
- data/spec/cache/cache_stats_spec.rb +106 -0
- data/spec/client_spec.rb +538 -0
- data/spec/data_store_spec.rb +130 -0
- data/spec/resource/account_spec.rb +74 -0
- data/spec/resource/application_spec.rb +148 -0
- data/spec/resource/base_spec.rb +114 -0
- data/spec/resource/collection_spec.rb +169 -0
- data/spec/resource/directory_spec.rb +30 -0
- data/spec/resource/expansion_spec.rb +100 -0
- data/spec/resource/group_spec.rb +49 -0
- data/spec/spec_helper.rb +135 -0
- data/spec/support/resource_factory.rb +48 -0
- data/spec/support/resource_matchers.rb +27 -0
- data/spec/support/test_cache_stores.rb +9 -0
- data/spec/support/test_request_executor.rb +11 -0
- data/stormpath-sdk.gemspec +14 -4
- data/support/api.rb +55 -0
- metadata +214 -44
- data/lib/stormpath-sdk/client/client.rb +0 -38
- data/lib/stormpath-sdk/client/client_application.rb +0 -38
- data/lib/stormpath-sdk/client/client_application_builder.rb +0 -351
- data/lib/stormpath-sdk/client/client_builder.rb +0 -305
- data/lib/stormpath-sdk/ds/data_store.rb +0 -210
- data/lib/stormpath-sdk/ds/resource_factory.rb +0 -37
- data/lib/stormpath-sdk/resource/account_list.rb +0 -32
- data/lib/stormpath-sdk/resource/collection_resource.rb +0 -91
- data/lib/stormpath-sdk/resource/directory_list.rb +0 -30
- data/lib/stormpath-sdk/resource/group_membership_list.rb +0 -32
- data/lib/stormpath-sdk/resource/instance_resource.rb +0 -28
- data/lib/stormpath-sdk/resource/resource.rb +0 -327
- data/lib/stormpath-sdk/resource/resource_error.rb +0 -47
- data/test/client/client.yml +0 -16
- data/test/client/client_application_builder_spec.rb +0 -114
- data/test/client/client_builder_spec.rb +0 -176
- data/test/client/read_spec.rb +0 -254
- data/test/client/write_spec.rb +0 -420
- data/test/resource/resource_spec.rb +0 -41
- data/test/resource/test_resource.rb +0 -28
@@ -14,35 +14,25 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
module Stormpath
|
17
|
-
|
18
17
|
module Util
|
19
|
-
|
20
18
|
module Assert
|
21
19
|
|
22
|
-
def assert_not_nil
|
23
|
-
|
20
|
+
def assert_not_nil(object, message)
|
24
21
|
raise ArgumentError, message, caller unless !object.nil?
|
25
|
-
|
26
22
|
end
|
27
23
|
|
28
|
-
def assert_kind_of
|
29
|
-
|
24
|
+
def assert_kind_of(clazz, object, message)
|
30
25
|
raise ArgumentError, message, caller unless object.kind_of? clazz
|
31
|
-
|
32
26
|
end
|
33
27
|
|
34
|
-
def assert_true
|
35
|
-
|
28
|
+
def assert_true(arg, message)
|
36
29
|
raise ArgumentError, message, caller unless arg
|
37
|
-
|
38
30
|
end
|
39
31
|
|
40
|
-
def assert_false
|
41
|
-
|
32
|
+
def assert_false(arg, message)
|
42
33
|
raise ArgumentError, message, caller unless !arg
|
43
|
-
|
44
34
|
end
|
45
35
|
|
46
36
|
end
|
47
37
|
end
|
48
|
-
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::ApiKey do
|
4
|
+
describe '.new' do
|
5
|
+
context 'given an id and secret' do
|
6
|
+
id = 'an_api_id'
|
7
|
+
secret = 'a_secret'
|
8
|
+
let(:apiKey) { Stormpath::ApiKey.new(id, secret) }
|
9
|
+
|
10
|
+
it 'sets the id' do
|
11
|
+
expect(apiKey.id).to eq(id)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'sets the secret' do
|
15
|
+
expect(apiKey.secret).to eq(secret)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "BasicAuthenticator" do
|
4
|
+
context "given an instance of BasicAuthenticator" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
ds = Stormpath::DataStore.new "", {}, ""
|
8
|
+
allow(test_api_client).to receive(:data_store).and_return(ds)
|
9
|
+
auth_result = Stormpath::Authentication::AuthenticationResult.new({}, test_api_client)
|
10
|
+
allow(ds).to receive(:create).and_return(auth_result)
|
11
|
+
|
12
|
+
@ba = Stormpath::Authentication::BasicAuthenticator.new ds
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when authenticating" do
|
16
|
+
before do
|
17
|
+
@response = @ba.authenticate "foo/bar", Stormpath::Authentication::UsernamePasswordRequest.new("fake-username", "fake-password")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "an AuthenticationResult is returned" do
|
21
|
+
expect(@response).to be_a Stormpath::Authentication::AuthenticationResult
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timecop'
|
3
|
+
|
4
|
+
describe Stormpath::Http::Authc::Sauthc1Signer do
|
5
|
+
let(:fake_uuid_generator) do
|
6
|
+
Proc.new { 'fake-uuid' }
|
7
|
+
end
|
8
|
+
let(:signer) do
|
9
|
+
Stormpath::Http::Authc::Sauthc1Signer.new fake_uuid_generator
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
Timecop.return
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#sign_request' do
|
17
|
+
context 'for two GET requests to the same URL' do
|
18
|
+
context 'with one request using the query_string hash' do
|
19
|
+
let(:fake_api_key) { Stormpath::ApiKey.new('foo', 'bar') }
|
20
|
+
|
21
|
+
let(:empty_query_hash_request) do
|
22
|
+
Stormpath::Http::Request.new 'get', 'http://example.com/resources/abc123?q=red blue', nil, Hash.new, nil
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:filled_query_hash_request) do
|
26
|
+
Stormpath::Http::Request.new 'get', 'http://example.com/resources/abc123', {'q' => 'red blue'}, Hash.new, nil
|
27
|
+
end
|
28
|
+
|
29
|
+
before do
|
30
|
+
Timecop.freeze(Time.now)
|
31
|
+
signer.sign_request empty_query_hash_request, fake_api_key
|
32
|
+
signer.sign_request filled_query_hash_request, fake_api_key
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'assigns identical headers to both requests' do
|
36
|
+
expect(empty_query_hash_request.http_headers['Host']).to eq(filled_query_hash_request.http_headers['Host'])
|
37
|
+
expect(empty_query_hash_request.http_headers['Authorization']).to eq(filled_query_hash_request.http_headers['Authorization'])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timecop'
|
3
|
+
|
4
|
+
describe Stormpath::Cache::CacheEntry do
|
5
|
+
after do
|
6
|
+
Timecop.return
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'by default' do
|
10
|
+
let(:cache_entry) do
|
11
|
+
Stormpath::Cache::CacheEntry.new 'foo'
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:now) { Time.now }
|
15
|
+
before { Timecop.freeze now }
|
16
|
+
|
17
|
+
it 'initializes the value' do
|
18
|
+
expect(cache_entry.value).to eq 'foo'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'initializes the creation time to now' do
|
22
|
+
expect(cache_entry.created_at).to eq now
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'initializes the last accessed time to now' do
|
26
|
+
expect(cache_entry.last_accessed_at).to eq now
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#touch' do
|
31
|
+
let(:cache_entry) do
|
32
|
+
Stormpath::Cache::CacheEntry.new 'foo'
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:now) { Time.now }
|
36
|
+
|
37
|
+
before do
|
38
|
+
Timecop.freeze now
|
39
|
+
cache_entry.touch
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'updates the last accessed at time' do
|
43
|
+
expect(cache_entry.last_accessed_at).to eq now
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#expired?=' do
|
48
|
+
let(:now) { Time.now }
|
49
|
+
|
50
|
+
let(:ttl_seconds) { 300 }
|
51
|
+
let(:tti_seconds) { 300 }
|
52
|
+
|
53
|
+
context 'has not expired' do
|
54
|
+
let(:cache_entry) do
|
55
|
+
Stormpath::Cache::CacheEntry.new 'foo'
|
56
|
+
end
|
57
|
+
|
58
|
+
let(:expired) do
|
59
|
+
cache_entry.expired? ttl_seconds, tti_seconds
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns false' do
|
63
|
+
expect(expired).to be_false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when TTL has expired' do
|
68
|
+
before do
|
69
|
+
cache_entry = Stormpath::Cache::CacheEntry.new 'foo'
|
70
|
+
Timecop.freeze now + ttl_seconds + 1
|
71
|
+
|
72
|
+
@expired = cache_entry.expired? ttl_seconds, tti_seconds
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns true' do
|
76
|
+
expect(@expired).to be_true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when TTI has expired' do
|
81
|
+
before do
|
82
|
+
cache_entry = Stormpath::Cache::CacheEntry.new 'foo'
|
83
|
+
Timecop.freeze now + tti_seconds + 1
|
84
|
+
|
85
|
+
@expired = cache_entry.expired? ttl_seconds, tti_seconds
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'returns true' do
|
89
|
+
expect(@expired).to be_true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#to_h' do
|
95
|
+
let(:cache_entry) do
|
96
|
+
Stormpath::Cache::CacheEntry.new 'foo'
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:now) { Time.now }
|
100
|
+
before { Timecop.freeze now }
|
101
|
+
|
102
|
+
it 'returns a hash of the attributes' do
|
103
|
+
expect(cache_entry.to_h).to eq({
|
104
|
+
'value' => cache_entry.value,
|
105
|
+
'created_at' => cache_entry.created_at,
|
106
|
+
'last_accessed_at' => cache_entry.last_accessed_at
|
107
|
+
})
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '.from_h=' do
|
112
|
+
let(:hash) do
|
113
|
+
{
|
114
|
+
"value" =>
|
115
|
+
{
|
116
|
+
"href" => "https://api.stormpath.com/v1/applications/app1",
|
117
|
+
"name" => "application app1",
|
118
|
+
"tenant" => {
|
119
|
+
"href" => "https://api.stormpath.com/v1/tenants/ten2"
|
120
|
+
},
|
121
|
+
"groups" =>
|
122
|
+
{"href" => "https://api.stormpath.com/v1/applications/app3/groups",
|
123
|
+
"items" =>
|
124
|
+
[{"href" => "https://api.stormpath.com/v1/groups/gro4"},
|
125
|
+
{"href" => "https://api.stormpath.com/v1/groups/gro5"}]
|
126
|
+
}
|
127
|
+
},
|
128
|
+
"created_at" => "2013-06-05T10:01:31-07:00",
|
129
|
+
"last_accessed_at" => "2013-06-05T10:01:31-07:00"
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
let(:cache_entry) do
|
134
|
+
Stormpath::Cache::CacheEntry.from_h(hash)
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:created_at) do
|
138
|
+
Time.parse(hash['created_at'])
|
139
|
+
end
|
140
|
+
|
141
|
+
let(:last_accessed_at) do
|
142
|
+
Time.parse(hash['last_accessed_at'])
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'returns a cache entry' do
|
146
|
+
expect(cache_entry).to be_kind_of Stormpath::Cache::CacheEntry
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'sets created at' do
|
150
|
+
expect(cache_entry.created_at).to eq created_at
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'sets the last accessed at' do
|
154
|
+
expect(cache_entry.last_accessed_at).to eq last_accessed_at
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timecop'
|
3
|
+
|
4
|
+
describe Stormpath::Cache::Cache do
|
5
|
+
let(:cache) { Stormpath::Cache::Cache.new ttl_seconds: 7, tti_seconds: 3 }
|
6
|
+
let(:now) { Time.now }
|
7
|
+
|
8
|
+
before do
|
9
|
+
cache.put 'foo', 'bar'
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
Timecop.return
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#put' do
|
17
|
+
it 'adds entry to the cache' do
|
18
|
+
expect(cache.size).to eq(1)
|
19
|
+
expect(cache.stats.summary).to eq [1, 0, 0, 0, 1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#get' do
|
24
|
+
context 'miss' do
|
25
|
+
before do
|
26
|
+
@foo = cache.get 'not-foo'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'gets nil' do
|
30
|
+
expect(@foo).not_to be
|
31
|
+
expect(cache.stats.summary).to eq [1, 0, 1, 0, 1]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'live before tti' do
|
36
|
+
before do
|
37
|
+
Timecop.freeze now + 2
|
38
|
+
@foo = cache.get 'foo'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'gets bar' do
|
42
|
+
expect(@foo).to eq('bar')
|
43
|
+
expect(cache.stats.summary).to eq [1, 1, 0, 0, 1]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'live after tti' do
|
48
|
+
before do
|
49
|
+
Timecop.freeze now + 2
|
50
|
+
cache.get 'foo'
|
51
|
+
Timecop.freeze now + 5
|
52
|
+
@foo = cache.get 'foo'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'gets bar' do
|
56
|
+
expect(@foo).to eq('bar')
|
57
|
+
expect(cache.stats.summary).to eq [1, 2, 0, 0, 1]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'expired by tti' do
|
62
|
+
before do
|
63
|
+
Timecop.freeze now + 4
|
64
|
+
@foo = cache.get 'foo'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'gets nil' do
|
68
|
+
expect(@foo).not_to be
|
69
|
+
expect(cache.stats.summary).to eq [1, 0, 1, 1, 1]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'expired by ttl' do
|
74
|
+
before do
|
75
|
+
Timecop.freeze now + 2
|
76
|
+
cache.get 'foo'
|
77
|
+
Timecop.freeze now + 5
|
78
|
+
cache.get 'foo'
|
79
|
+
Timecop.freeze now + 8
|
80
|
+
@foo = cache.get 'foo'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'gets nil' do
|
84
|
+
expect(@foo).not_to be
|
85
|
+
expect(cache.stats.summary).to eq [1, 2, 1, 1, 1]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::Cache::CacheStats do
|
4
|
+
let(:cache_stats) do
|
5
|
+
Stormpath::Cache::CacheStats.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'by default' do
|
9
|
+
it 'intializes counters' do
|
10
|
+
expect(cache_stats.puts).to eq 0
|
11
|
+
expect(cache_stats.hits).to eq 0
|
12
|
+
expect(cache_stats.misses).to eq 0
|
13
|
+
expect(cache_stats.expirations).to eq 0
|
14
|
+
expect(cache_stats.size).to eq 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#put' do
|
19
|
+
before { cache_stats.put }
|
20
|
+
|
21
|
+
it 'increments puts' do
|
22
|
+
expect(cache_stats.puts).to eq 1
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'increments size' do
|
26
|
+
expect(cache_stats.puts).to eq 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'updates summary' do
|
30
|
+
expect(cache_stats.summary).to eq [1, 0, 0, 0, 1]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#hit' do
|
35
|
+
before { cache_stats.hit }
|
36
|
+
|
37
|
+
it 'increments hits' do
|
38
|
+
expect(cache_stats.hits).to eq 1
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'updates summary' do
|
42
|
+
expect(cache_stats.summary).to eq [0, 1, 0, 0, 0]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#miss=' do
|
47
|
+
context 'expired is true' do
|
48
|
+
before { cache_stats.miss true }
|
49
|
+
|
50
|
+
it 'increments misses' do
|
51
|
+
expect(cache_stats.misses).to eq 1
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'increments expirations' do
|
55
|
+
expect(cache_stats.expirations).to eq 1
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'updates summary' do
|
59
|
+
expect(cache_stats.summary).to eq [0, 0, 1, 1, 0]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'expired is true' do
|
64
|
+
before { cache_stats.miss false }
|
65
|
+
|
66
|
+
it 'increments misses' do
|
67
|
+
expect(cache_stats.misses).to eq 1
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'does not increment expirations' do
|
71
|
+
expect(cache_stats.expirations).to eq 0
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'updates summary' do
|
75
|
+
expect(cache_stats.summary).to eq [0, 0, 1, 0, 0]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#delete' do
|
81
|
+
context 'when size is greater than zero' do
|
82
|
+
before do
|
83
|
+
3.times { cache_stats.put }
|
84
|
+
cache_stats.delete
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'decrements size' do
|
88
|
+
expect(cache_stats.size).to eq 2
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'updates summary' do
|
92
|
+
expect(cache_stats.summary).to eq [3, 0, 0, 0, 2]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when size is zero' do
|
97
|
+
before do
|
98
|
+
cache_stats.delete
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'does nothing' do
|
102
|
+
expect(cache_stats.size).to eq 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|