redstruct 0.2.2 → 0.2.3
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/lib/redstruct/list.rb +1 -1
- data/lib/redstruct/script.rb +2 -2
- data/lib/redstruct/struct.rb +9 -4
- data/lib/redstruct/version.rb +1 -1
- data/test/helpers/test_case.rb +35 -0
- data/test/redstruct/configuration_test.rb +1 -1
- data/test/redstruct/connection_proxy_test.rb +1 -1
- data/test/redstruct/counter_test.rb +1 -1
- data/test/redstruct/factory/object_test.rb +1 -1
- data/test/redstruct/factory_test.rb +1 -1
- data/test/redstruct/hash_test.rb +1 -1
- data/test/redstruct/list_test.rb +1 -4
- data/test/redstruct/lock_test.rb +1 -1
- data/test/redstruct/script_test.rb +1 -1
- data/test/redstruct/set_test.rb +1 -1
- data/test/redstruct/sorted_set/slice_test.rb +1 -1
- data/test/redstruct/sorted_set_test.rb +1 -1
- data/test/redstruct/string_test.rb +1 -1
- data/test/redstruct/struct_test.rb +33 -4
- data/test/redstruct/utils/coercion_test.rb +1 -1
- data/test/redstruct/utils/inspectable_test.rb +1 -1
- data/test/redstruct/utils/iterable_test.rb +1 -1
- data/test/redstruct/utils/scriptable_test.rb +1 -5
- data/test/redstruct_test.rb +1 -1
- data/test/test_helper.rb +12 -37
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba26d3bd5b2d46e3f499125f7e6ec6166afade9d
|
4
|
+
data.tar.gz: 6616843bccefb369e2a9d3b1a4e40c7b8f48b6d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f01736c5c824bf2e5e7c3cf5487c8886cfcfefba0c6cfcb258c499427d933ad382292f330931ce5d54ad03fef34262fa3039ce69055fe61cf7bf0b696dcec584
|
7
|
+
data.tar.gz: ae8f90b885b9f7ce20fc4b7fb2e7fec7744d9783fb75a22ed398c08ebcba9be959a42f6be6b6afe2adc9f827efd11cbc23de3a37968ea4cc6c569ca7f8ff34d5
|
data/lib/redstruct/list.rb
CHANGED
data/lib/redstruct/script.rb
CHANGED
@@ -11,7 +11,7 @@ module Redstruct
|
|
11
11
|
# are not used anymore.
|
12
12
|
class Script
|
13
13
|
# Redis returns an error starting with NOSCRIPT when we try to evaluate am unknown script using its sha1.
|
14
|
-
|
14
|
+
ERROR_MESSAGE_PATTERN = /^NOSCRIPT.*$/
|
15
15
|
|
16
16
|
# @return [String] the Lua script to evaluate
|
17
17
|
attr_reader :script
|
@@ -80,7 +80,7 @@ module Redstruct
|
|
80
80
|
|
81
81
|
@connection.evalsha(self.sha1, keys, argv)
|
82
82
|
rescue Redis::CommandError => err
|
83
|
-
raise unless err.message
|
83
|
+
raise unless ERROR_MESSAGE_PATTERN.match(err.message)
|
84
84
|
@connection.eval(@script, keys, argv)
|
85
85
|
end
|
86
86
|
|
data/lib/redstruct/struct.rb
CHANGED
@@ -51,13 +51,18 @@ module Redstruct
|
|
51
51
|
|
52
52
|
# @return [String] the underlying redis type
|
53
53
|
def type
|
54
|
-
self.connection.type(@key)
|
54
|
+
name = self.connection.type(@key)
|
55
|
+
return nil if name == 'none'
|
56
|
+
return name
|
55
57
|
end
|
56
58
|
|
57
59
|
# Returns the time to live of the key
|
58
|
-
# @return [Float
|
60
|
+
# @return [Float, nil time nil if the key does not exist or has no expiry, or the time to live in seconds
|
59
61
|
def ttl
|
60
|
-
|
62
|
+
value = self.connection.pttl(@key)
|
63
|
+
|
64
|
+
return nil if [-1, -2].include?(value)
|
65
|
+
return value.to_f / 1000
|
61
66
|
end
|
62
67
|
|
63
68
|
# Returns a serialized representation of the key, which can be used to store a value externally, and restored to
|
@@ -71,7 +76,7 @@ module Redstruct
|
|
71
76
|
|
72
77
|
# Restores the struct to its serialized value as given
|
73
78
|
# @param [String] serialized serialized representation of the value
|
74
|
-
# @param [#to_f] ttl the time to live for the struct; defaults to 0 (meaning no expiry)
|
79
|
+
# @param [#to_f] ttl the time to live (in seconds) for the struct; defaults to 0 (meaning no expiry)
|
75
80
|
# @raise [Redis::CommandError] raised if the serialized value is incompatible or the key already exists
|
76
81
|
# @return [Boolean] true if restored, false otherwise
|
77
82
|
def restore(serialized, ttl: 0)
|
data/lib/redstruct/version.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'redstruct/utils/atomic_counter'
|
4
|
+
|
5
|
+
module Redstruct
|
6
|
+
# Base class for all Redstruct tests. Configures the gem, provides a default factory, and makes sure to clean it up
|
7
|
+
# at the end
|
8
|
+
class TestCase < Minitest::Test
|
9
|
+
# rubocop: disable Style/ClassVars
|
10
|
+
@@counter = Redstruct::Utils::AtomicCounter.new
|
11
|
+
@@factory = Redstruct::Factory.new
|
12
|
+
|
13
|
+
parallelize_me!
|
14
|
+
make_my_diffs_pretty!
|
15
|
+
|
16
|
+
# Use this helper to create a factory that the test class will keep track of and remove at the end
|
17
|
+
def create_factory(namespace = nil)
|
18
|
+
namespace ||= @@counter.increment.to_s
|
19
|
+
return @@factory.factory(namespace)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Helper when trying to ensure a particular redis-rb command was called
|
23
|
+
# while still calling it. This allows for testing things outside of our
|
24
|
+
# control (e.g. srandmember returning random items)
|
25
|
+
# The reason we don't simply just mock the return value is to ensure
|
26
|
+
# that tests will break if a command (e.g. srandmember) changes its return
|
27
|
+
# value
|
28
|
+
def ensure_command_called(object, command, *args, allow: true)
|
29
|
+
mock = flexmock(object.connection).should_receive(command).with(object.key, *args)
|
30
|
+
mock = mock.pass_thru if allow
|
31
|
+
|
32
|
+
return mock
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
module Redstruct
|
6
|
-
class ConfigurationTest < Redstruct::
|
6
|
+
class ConfigurationTest < Redstruct::TestCase
|
7
7
|
def test_initialize
|
8
8
|
@config = Redstruct::Configuration.new
|
9
9
|
assert_nil @config.default_connection, 'Should have no default connection initially'
|
@@ -4,7 +4,7 @@ require 'test_helper'
|
|
4
4
|
|
5
5
|
module Redstruct
|
6
6
|
# TODO: not quite sure if this test suite is good enough
|
7
|
-
class ConnectionProxyTest < Redstruct::
|
7
|
+
class ConnectionProxyTest < Redstruct::TestCase
|
8
8
|
def test_initialize
|
9
9
|
assert_raises(ArgumentError, 'should fail to initialize without a proxy object') { Redstruct::ConnectionProxy.new }
|
10
10
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
module Redstruct
|
6
|
-
class FactoryTest < Redstruct::
|
6
|
+
class FactoryTest < Redstruct::TestCase
|
7
7
|
def test_initialize_default
|
8
8
|
flexmock(Redstruct::ConnectionProxy).should_receive(:new).with(Redstruct.config.default_connection).once.pass_thru
|
9
9
|
factory = Redstruct::Factory.new
|
data/test/redstruct/hash_test.rb
CHANGED
data/test/redstruct/list_test.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
module Redstruct
|
6
|
-
class ListTest < Redstruct::
|
6
|
+
class ListTest < Redstruct::TestCase
|
7
7
|
def setup
|
8
8
|
super
|
9
9
|
@factory = create_factory
|
@@ -34,9 +34,6 @@ module Redstruct
|
|
34
34
|
|
35
35
|
def test_insert_single
|
36
36
|
initial = SecureRandom.hex(4)
|
37
|
-
assert_raises(Redis::CommandError, 'should fail (out of bounds)') do
|
38
|
-
@list.insert(initial, 1)
|
39
|
-
end
|
40
37
|
|
41
38
|
assert @list.insert(initial, 0), 'should insert correctly first element'
|
42
39
|
assert_equal initial, @list[0]
|
data/test/redstruct/lock_test.rb
CHANGED
data/test/redstruct/set_test.rb
CHANGED
@@ -4,7 +4,7 @@ require 'securerandom'
|
|
4
4
|
require 'test_helper'
|
5
5
|
|
6
6
|
module Redstruct
|
7
|
-
class StructTest < Redstruct::
|
7
|
+
class StructTest < Redstruct::TestCase
|
8
8
|
def setup
|
9
9
|
super
|
10
10
|
@factory = create_factory
|
@@ -42,11 +42,40 @@ module Redstruct
|
|
42
42
|
refute @struct.exists?, 'should not exist since it was marked to be expired 1 second after 1970-01-01'
|
43
43
|
end
|
44
44
|
|
45
|
-
def test_persist
|
45
|
+
def test_persist
|
46
|
+
refute @struct.persist, 'should not be able to persist non existent keys'
|
47
|
+
write_struct
|
48
|
+
refute @struct.persist, 'should not be able to persist keys with no expiry'
|
49
|
+
|
50
|
+
@struct.expire(1)
|
51
|
+
assert @struct.ttl.positive?, 'should now have a ttl'
|
52
|
+
assert @struct.persist, 'should be able to persist keys with expiry'
|
53
|
+
assert_nil @struct.ttl, 'should not have a ttl anymore'
|
54
|
+
end
|
46
55
|
|
47
|
-
def test_type
|
56
|
+
def test_type
|
57
|
+
assert_nil @struct.type, 'should have no type when it does not exist'
|
58
|
+
|
59
|
+
# to avoid writing tests for each possible type, we simply ensure we return
|
60
|
+
# whatever redis returned
|
61
|
+
type = SecureRandom.hex(8)
|
62
|
+
write_struct
|
63
|
+
ensure_command_called(@struct, :type, allow: false).once.and_return(type)
|
64
|
+
assert_equal type, @struct.type, 'should return whatever redis returns'
|
65
|
+
end
|
48
66
|
|
49
|
-
def test_ttl
|
67
|
+
def test_ttl
|
68
|
+
assert_nil @struct.ttl, 'should have no ttl initially'
|
69
|
+
|
70
|
+
write_struct
|
71
|
+
assert_nil @struct.ttl, 'should still have no ttl even if it exists'
|
72
|
+
|
73
|
+
@struct.expire(1)
|
74
|
+
assert @struct.ttl.positive?, 'should have a ttl > 0'
|
75
|
+
|
76
|
+
@struct.persist
|
77
|
+
assert_nil @struct.ttl, 'should now have no ttl again'
|
78
|
+
end
|
50
79
|
|
51
80
|
def test_dump; end
|
52
81
|
|
@@ -4,7 +4,7 @@ require 'test_helper'
|
|
4
4
|
|
5
5
|
module Redstruct
|
6
6
|
module Utils
|
7
|
-
class CoercionTest < Redstruct::
|
7
|
+
class CoercionTest < Redstruct::TestCase
|
8
8
|
def test_coerce_bool
|
9
9
|
refute Redstruct::Utils::Coercion.coerce_bool(nil), 'nil should be coerced to false'
|
10
10
|
refute Redstruct::Utils::Coercion.coerce_bool(false), 'false should be coerced to false'
|
@@ -4,7 +4,7 @@ require 'test_helper'
|
|
4
4
|
|
5
5
|
module Redstruct
|
6
6
|
module Utils
|
7
|
-
class IterableTest < Redstruct::
|
7
|
+
class IterableTest < Redstruct::TestCase
|
8
8
|
def test_to_enum_bad_impl
|
9
9
|
assert_raises(NotImplementedError, 'should fail and raise not implemented on missing implementations') do
|
10
10
|
BadIterator.new.to_enum
|
@@ -6,7 +6,7 @@ require 'test_helper'
|
|
6
6
|
|
7
7
|
module Redstruct
|
8
8
|
module Utils
|
9
|
-
class ScriptableTest < Redstruct::
|
9
|
+
class ScriptableTest < Redstruct::TestCase
|
10
10
|
def test_defscript
|
11
11
|
script = <<~LUA
|
12
12
|
local sum = 0
|
@@ -42,8 +42,6 @@ module Redstruct
|
|
42
42
|
klass = Class.new { include Redstruct::Utils::Scriptable }
|
43
43
|
klass.const_set('SCRIPT_TEST', true)
|
44
44
|
|
45
|
-
stdout, = capture_subprocess_io { klass.defscript('test', 'return 0') }
|
46
|
-
assert_match(/WARN/, stdout, 'should produce a warning if the constant is already defined')
|
47
45
|
refute klass.method_defined?('test')
|
48
46
|
assert_equal true, klass::SCRIPT_TEST, 'should still be the old value'
|
49
47
|
end
|
@@ -57,8 +55,6 @@ module Redstruct
|
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
60
|
-
stdout, = capture_subprocess_io { klass.defscript('test', 'return 0') }
|
61
|
-
assert_match(/WARN/, stdout, 'should produce a warning if the method is already defined')
|
62
58
|
refute klass.const_defined?('SCRIPT_TEST')
|
63
59
|
assert_equal true, klass.new.test, 'should still be the old value'
|
64
60
|
end
|
data/test/redstruct_test.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'securerandom'
|
5
|
-
require 'bundler/setup'
|
6
|
-
require 'minitest/autorun'
|
7
|
-
require 'flexmock/minitest'
|
8
|
-
require 'redstruct/utils/atomic_counter'
|
9
|
-
|
3
|
+
# Environment
|
10
4
|
ci_build = ENV['CI_BUILD'].to_i.positive?
|
5
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
11
6
|
|
7
|
+
# Bundler setup
|
8
|
+
require 'bundler/setup'
|
12
9
|
bundler_groups = %i[default test]
|
13
10
|
bundler_groups << (ci_build ? :ci : :debug)
|
14
11
|
Bundler.require(*bundler_groups)
|
@@ -23,7 +20,11 @@ Redstruct.config.default_connection = ConnectionPool.new(size: 5, timeout: 2) do
|
|
23
20
|
Redis.new(host: ENV.fetch('REDIS_HOST', '127.0.0.1'), port: ENV.fetch('REDIS_PORT', 6379).to_i, db: ENV.fetch('REDIS_DB', 0).to_i)
|
24
21
|
end
|
25
22
|
|
26
|
-
# Setup
|
23
|
+
# Setup Minitest
|
24
|
+
require 'minitest/autorun'
|
25
|
+
require 'flexmock/minitest'
|
26
|
+
require 'minitest/reporters'
|
27
|
+
Minitest::Reporters.use!([Minitest::Reporters::SpecReporter.new])
|
27
28
|
Minitest.after_run do
|
28
29
|
Redstruct.config.default_connection.with do |conn|
|
29
30
|
conn.flushdb
|
@@ -31,32 +32,6 @@ Minitest.after_run do
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
class Test < Minitest::Test
|
38
|
-
@@counter = Redstruct::Utils::AtomicCounter.new # rubocop: disable Style/ClassVars
|
39
|
-
|
40
|
-
parallelize_me!
|
41
|
-
make_my_diffs_pretty!
|
42
|
-
|
43
|
-
# Use this helper to create a factory that the test class will keep track of and remove at the end
|
44
|
-
def create_factory(namespace = nil)
|
45
|
-
namespace ||= "#{Redstruct.config.default_namespace}:#{@@counter.increment}"
|
46
|
-
return Redstruct::Factory.new(namespace: namespace)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Helper when trying to ensure a particular redis-rb command was called
|
50
|
-
# while still calling it. This allows for testing things outside of our
|
51
|
-
# control (e.g. srandmember returning random items)
|
52
|
-
# The reason we don't simply just mock the return value is to ensure
|
53
|
-
# that tests will break if a command (e.g. srandmember) changes its return
|
54
|
-
# value
|
55
|
-
def ensure_command_called(object, command, *args, allow: true)
|
56
|
-
mock = flexmock(object.connection).should_receive(command).with(object.key, *args)
|
57
|
-
mock = mock.pass_thru if allow
|
58
|
-
|
59
|
-
return mock
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
35
|
+
# Require everything else
|
36
|
+
require 'securerandom'
|
37
|
+
require 'helpers/test_case'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redstruct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Pepin-Perreault
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- lib/redstruct/utils/scriptable.rb
|
121
121
|
- lib/redstruct/version.rb
|
122
122
|
- lib/yard/defscript_handler.rb
|
123
|
+
- test/helpers/test_case.rb
|
123
124
|
- test/redstruct/configuration_test.rb
|
124
125
|
- test/redstruct/connection_proxy_test.rb
|
125
126
|
- test/redstruct/counter_test.rb
|
@@ -165,6 +166,7 @@ signing_key:
|
|
165
166
|
specification_version: 4
|
166
167
|
summary: Higher level data structures for Redis.
|
167
168
|
test_files:
|
169
|
+
- test/helpers/test_case.rb
|
168
170
|
- test/redstruct/configuration_test.rb
|
169
171
|
- test/redstruct/connection_proxy_test.rb
|
170
172
|
- test/redstruct/counter_test.rb
|