readthis 2.1.0 → 2.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 +5 -5
- data/LICENSE.txt +22 -0
- data/README.md +1 -1
- data/lib/active_support/cache/readthis_store.rb +3 -1
- data/lib/readthis.rb +2 -0
- data/lib/readthis/cache.rb +66 -26
- data/lib/readthis/entity.rb +2 -0
- data/lib/readthis/errors.rb +2 -0
- data/lib/readthis/expanders.rb +53 -4
- data/lib/readthis/passthrough.rb +19 -1
- data/lib/readthis/scripts.rb +3 -1
- data/lib/readthis/serializers.rb +44 -3
- data/lib/readthis/version.rb +3 -1
- data/readthis.gemspec +27 -0
- metadata +32 -48
- data/spec/matchers/redis_matchers.rb +0 -13
- data/spec/readthis/cache_spec.rb +0 -418
- data/spec/readthis/entity_spec.rb +0 -143
- data/spec/readthis/expanders_spec.rb +0 -40
- data/spec/readthis/passthrough_spec.rb +0 -16
- data/spec/readthis/scripts_spec.rb +0 -31
- data/spec/readthis/serializers_spec.rb +0 -96
- data/spec/readthis_spec.rb +0 -19
- data/spec/spec_helper.rb +0 -28
@@ -1,143 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
RSpec.describe Readthis::Entity do
|
4
|
-
describe '#dump' do
|
5
|
-
it 'marshals the object as a ruby string' do
|
6
|
-
string = 'some string'
|
7
|
-
entity = Readthis::Entity.new
|
8
|
-
|
9
|
-
expect(entity.dump(string)).to include(Marshal.dump(string))
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'marshals using a custom marshaller' do
|
13
|
-
string = 'some string'
|
14
|
-
entity = Readthis::Entity.new(marshal: JSON)
|
15
|
-
|
16
|
-
expect(entity.dump(string)).to include(JSON.dump(string))
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'overrides the marshaller' do
|
20
|
-
string = 'still some string'
|
21
|
-
entity = Readthis::Entity.new
|
22
|
-
|
23
|
-
expect(entity.dump(string, marshal: JSON)).to include(JSON.dump(string))
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'applies compression when enabled' do
|
27
|
-
string = 'a very large string, huge I tell you'
|
28
|
-
entity = Readthis::Entity.new(compress: true, threshold: 8)
|
29
|
-
dumped = Marshal.dump(string)
|
30
|
-
|
31
|
-
expect(entity.dump(string)).not_to eq(dumped)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'does not return compressed data when the size is below threshold' do
|
35
|
-
string = 'a' * 200
|
36
|
-
entity = Readthis::Entity.new(compress: true, threshold: 50)
|
37
|
-
|
38
|
-
expect(entity.load(entity.dump(string))).to eq(string)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'safely returns incorrectly deduced compressed data' do
|
42
|
-
string = [120, 156, 97, 98, 99].pack('CCCCC')
|
43
|
-
entity = Readthis::Entity.new(compress: true, threshold: 1)
|
44
|
-
|
45
|
-
expect(entity.load(string)).to eq(string)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'overrides the compression threshold' do
|
49
|
-
string = 'a' * 8
|
50
|
-
entity = Readthis::Entity.new(compress: true, threshold: 2)
|
51
|
-
dumped = entity.dump(string)
|
52
|
-
|
53
|
-
expect(entity.dump(string, threshold: 100)).not_to eq(dumped)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'overrides the compression option' do
|
57
|
-
string = 'a' * 8
|
58
|
-
entity = Readthis::Entity.new(compress: true, threshold: 2)
|
59
|
-
dumped = entity.dump(string)
|
60
|
-
|
61
|
-
expect(entity.dump(string, compress: false)).not_to eq(dumped)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'safely roundtrips nil values' do
|
65
|
-
entity = Readthis::Entity.new
|
66
|
-
|
67
|
-
expect(entity.load(entity.dump(nil))).to be_nil
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '#load' do
|
72
|
-
it 'unmarshals a value' do
|
73
|
-
object = { a: 1, b: '2' }
|
74
|
-
entity = Readthis::Entity.new
|
75
|
-
dumped = entity.dump(object)
|
76
|
-
|
77
|
-
expect(entity.load(dumped)).to eq(object)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'uncompresses when compression is enabled' do
|
81
|
-
string = 'another one of those huge strings'
|
82
|
-
entity = Readthis::Entity.new(compress: true, threshold: 4)
|
83
|
-
dumped = entity.dump(dumped)
|
84
|
-
|
85
|
-
expect(entity.load(dumped)).not_to eq(string)
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'uses the dumped value to define load options' do
|
89
|
-
value = [1, 2, 3]
|
90
|
-
custom = Readthis::Entity.new(marshal: JSON, compress: true)
|
91
|
-
general = Readthis::Entity.new(marshal: Marshal, compress: false)
|
92
|
-
dumped = custom.dump(value)
|
93
|
-
|
94
|
-
expect(general.load(dumped)).to eq(value)
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'passes through the value when it fails to marshal' do
|
98
|
-
entity = Readthis::Entity.new
|
99
|
-
|
100
|
-
expect { entity.load('not marshalled') }.not_to raise_error
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'passes through the value when it fails to decompress' do
|
104
|
-
entity = Readthis::Entity.new(compress: true, threshold: 0)
|
105
|
-
dumped = Marshal.dump('some sizable string')
|
106
|
-
|
107
|
-
expect { entity.load(dumped) }.not_to raise_error
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe '#compose' do
|
112
|
-
it 'prepends the string with a formatted marker' do
|
113
|
-
string = 'the quick brown fox'
|
114
|
-
marked = Readthis::Entity.new.compose(string, Marshal, true)
|
115
|
-
|
116
|
-
expect(marked[0]).not_to eq('t')
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe '#decompose' do
|
121
|
-
it 'returns extracted options and values' do
|
122
|
-
string = 'the quick brown fox'
|
123
|
-
entity = Readthis::Entity.new
|
124
|
-
marked = entity.compose(string.dup, JSON, true)
|
125
|
-
|
126
|
-
marshal, compress, value = entity.decompose(marked)
|
127
|
-
|
128
|
-
expect(marshal).to eq(JSON)
|
129
|
-
expect(compress).to eq(true)
|
130
|
-
expect(value).to eq(string)
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'returns the original string without a marker' do
|
134
|
-
string = 'the quick brown fox'
|
135
|
-
entity = Readthis::Entity.new
|
136
|
-
marshal, compress, value = entity.decompose(string)
|
137
|
-
|
138
|
-
expect(marshal).to eq(Marshal)
|
139
|
-
expect(compress).to eq(false)
|
140
|
-
expect(value).to eq(string)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
RSpec.describe Readthis::Expanders do
|
2
|
-
def expand(key, namespace = nil)
|
3
|
-
Readthis::Expanders.namespace_key(key, namespace)
|
4
|
-
end
|
5
|
-
|
6
|
-
describe '#expand' do
|
7
|
-
it 'namespaces a plain string' do
|
8
|
-
expect(expand('thing', 'space')).to eq('space:thing')
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'expands an object that has a cache_key method' do
|
12
|
-
object = double(cache_key: 'custom-key')
|
13
|
-
|
14
|
-
expect(expand(object)).to eq('custom-key')
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'expands an array of objects' do
|
18
|
-
object = double(cache_key: 'gamma')
|
19
|
-
|
20
|
-
expect(expand(%w[alpha beta])).to eq('alpha/beta')
|
21
|
-
expect(expand([object, object])).to eq('gamma/gamma')
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'expands the keys of a hash' do
|
25
|
-
keyhash = { 'beta' => 2, alpha: 1 }
|
26
|
-
|
27
|
-
expect(expand(keyhash)).to eq('alpha=1/beta=2')
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'uses the to_param method if available' do
|
31
|
-
object = double(to_param: 'thing')
|
32
|
-
|
33
|
-
expect(expand(object)).to eq('thing')
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'ensures the result is a string' do
|
37
|
-
expect(expand(123)).to eq('123')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
RSpec.describe Readthis::Passthrough do
|
2
|
-
let(:value) { 'skywalker' }
|
3
|
-
|
4
|
-
describe '.load' do
|
5
|
-
it 'passes through the provided value' do
|
6
|
-
expect(Readthis::Passthrough.load(value)).to eq(value)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
describe '.dump' do
|
11
|
-
it 'passes through the provided value' do
|
12
|
-
expect(Readthis::Passthrough.dump(value)).to eq(value)
|
13
|
-
expect(Readthis::Passthrough.dump(value)).not_to be(value)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
RSpec.describe Readthis::Scripts do
|
2
|
-
let(:scripts) { Readthis::Scripts.new }
|
3
|
-
|
4
|
-
describe '#run' do
|
5
|
-
it 'raises an error with an unknown command' do
|
6
|
-
expect do
|
7
|
-
scripts.run('unknown', nil, [])
|
8
|
-
end.to raise_error(Readthis::UnknownCommandError)
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'runs the script command with a single key' do
|
12
|
-
store = Redis.new
|
13
|
-
|
14
|
-
store.set('alpha', 'content')
|
15
|
-
scripts.run('mexpire', store, 'alpha', 1)
|
16
|
-
|
17
|
-
expect(store.ttl('alpha')).to eq(1)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'runs the script command with multiple keys' do
|
21
|
-
store = Redis.new
|
22
|
-
|
23
|
-
store.set('beta', 'content')
|
24
|
-
store.set('gamma', 'content')
|
25
|
-
scripts.run('mexpire', store, %w[beta gamma], 1)
|
26
|
-
|
27
|
-
expect(store.ttl('beta')).to eq(1)
|
28
|
-
expect(store.ttl('gamma')).to eq(1)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
RSpec.describe Readthis::Serializers do
|
2
|
-
CustomSerializer = Class.new
|
3
|
-
AnotherSerializer = Class.new
|
4
|
-
|
5
|
-
describe '#<<' do
|
6
|
-
it 'appends new serializers' do
|
7
|
-
serializers = Readthis::Serializers.new
|
8
|
-
|
9
|
-
serializers << CustomSerializer
|
10
|
-
|
11
|
-
expect(serializers.marshals).to include(CustomSerializer)
|
12
|
-
expect(serializers.flags).to eq([1, 2, 3, 4])
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'increments flags' do
|
16
|
-
serializers = Readthis::Serializers.new
|
17
|
-
serializers << CustomSerializer
|
18
|
-
serializers << AnotherSerializer
|
19
|
-
|
20
|
-
expect(serializers.flags).to eq((1..5).to_a)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'prevents more than seven serializers' do
|
24
|
-
serializers = Readthis::Serializers.new
|
25
|
-
serializers << Class.new until serializers.flags.length >= 7
|
26
|
-
expect do
|
27
|
-
serializers << Class.new
|
28
|
-
end.to raise_error(Readthis::SerializersLimitError)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe '#assoc' do
|
33
|
-
it 'looks up serializers by module' do
|
34
|
-
serializers = Readthis::Serializers.new
|
35
|
-
|
36
|
-
expect(serializers.assoc(Marshal)).to eq(0x1)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'raises a helpful error when the serializer is unknown' do
|
40
|
-
serializers = Readthis::Serializers.new
|
41
|
-
|
42
|
-
expect do
|
43
|
-
serializers.assoc(CustomSerializer)
|
44
|
-
end.to raise_error(Readthis::UnknownSerializerError)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#rassoc' do
|
49
|
-
let(:serializers) { Readthis::Serializers.new }
|
50
|
-
|
51
|
-
it 'inverts the current set of serializers' do
|
52
|
-
expect(serializers.rassoc(1)).to eq(Marshal)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'returns custom serializers' do
|
56
|
-
serializers << CustomSerializer
|
57
|
-
expect(serializers.rassoc(4)).to eq(CustomSerializer)
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'inverts default serializers after adding custom one' do
|
61
|
-
serializers << CustomSerializer
|
62
|
-
expect(serializers.rassoc(1)).to eq(Marshal)
|
63
|
-
expect(serializers.rassoc(3)).to eq(JSON)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'takes into account only first 3 bytes of passed integer' do
|
67
|
-
expect(serializers.rassoc(1)).to eq(Marshal)
|
68
|
-
expect(serializers.rassoc(11)).to eq(JSON)
|
69
|
-
serializers << CustomSerializer
|
70
|
-
expect(serializers.rassoc(12)).to eq(CustomSerializer)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '#freeze!' do
|
75
|
-
it 'does now allow appending after freeze' do
|
76
|
-
serializers = Readthis::Serializers.new
|
77
|
-
|
78
|
-
serializers.freeze!
|
79
|
-
|
80
|
-
expect do
|
81
|
-
serializers << CustomSerializer
|
82
|
-
end.to raise_error(Readthis::SerializersFrozenError)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '#reset!' do
|
87
|
-
it 'reverts back to the original set of serializers' do
|
88
|
-
serializers = Readthis::Serializers.new
|
89
|
-
|
90
|
-
serializers << Class.new
|
91
|
-
serializers.reset!
|
92
|
-
|
93
|
-
expect(serializers.serializers.length).to eq(3)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
data/spec/readthis_spec.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
RSpec.describe Readthis do
|
2
|
-
describe '#serializers' do
|
3
|
-
it 'lists currently configured serializers' do
|
4
|
-
expect(Readthis.serializers.marshals).to include(Marshal, JSON)
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
describe '#fault_tolerant?' do
|
9
|
-
it 'defaults to being false' do
|
10
|
-
expect(Readthis).not_to be_fault_tolerant
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'can be enabled' do
|
14
|
-
Readthis.fault_tolerant = true
|
15
|
-
|
16
|
-
expect(Readthis).to be_fault_tolerant
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'coveralls'
|
2
|
-
require 'readthis'
|
3
|
-
|
4
|
-
Coveralls.wear!
|
5
|
-
|
6
|
-
RSpec.configure do |config|
|
7
|
-
config.expect_with :rspec do |expectations|
|
8
|
-
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
9
|
-
end
|
10
|
-
|
11
|
-
config.mock_with :rspec do |mocks|
|
12
|
-
mocks.verify_partial_doubles = true
|
13
|
-
end
|
14
|
-
|
15
|
-
config.filter_run :focus
|
16
|
-
config.run_all_when_everything_filtered = true
|
17
|
-
|
18
|
-
config.disable_monkey_patching!
|
19
|
-
|
20
|
-
config.default_formatter = 'doc' if config.files_to_run.one?
|
21
|
-
|
22
|
-
config.order = :random
|
23
|
-
Kernel.srand config.seed
|
24
|
-
|
25
|
-
config.before do
|
26
|
-
Readthis.reset!
|
27
|
-
end
|
28
|
-
end
|