redstruct 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|