diff --git a/CHANGELOG.md b/CHANGELOG.md index 145f09c..e6175e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # MockRedis Changelog +### 0.38.0 + +* Add support for `EXAT` AND `PXAT` arguments to `SET` command + ### 0.37.0 * Require Ruby 2.7 or newer, since Ruby 2.6 and older are EOL diff --git a/lib/mock_redis/string_methods.rb b/lib/mock_redis/string_methods.rb index 1501c77..4daee18 100644 --- a/lib/mock_redis/string_methods.rb +++ b/lib/mock_redis/string_methods.rb @@ -210,9 +210,9 @@ def mapped_msetnx(hash) msetnx(*hash.to_a.flatten) end - # Parameer list required to ensure the ArgumentError is returned correctly + # Parameter list required to ensure the ArgumentError is returned correctly # rubocop:disable Metrics/ParameterLists - def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil, get: nil) + def set(key, value, ex: nil, px: nil, exat: nil, pxat: nil, nx: nil, xx: nil, keepttl: nil, get: nil) key = key.to_s retval = self.get(key) if get @@ -248,6 +248,20 @@ def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil, get: nil) pexpire(key, px) end + if exat + if exat == 0 + raise Redis::CommandError, 'ERR invalid expire time in set' + end + expireat(key, exat) + end + + if pxat + if pxat == 0 + raise Redis::CommandError, 'ERR invalid expire time in set' + end + pexpireat(key, pxat) + end + if get retval else diff --git a/lib/mock_redis/version.rb b/lib/mock_redis/version.rb index 0e051fe..86e98a5 100644 --- a/lib/mock_redis/version.rb +++ b/lib/mock_redis/version.rb @@ -2,5 +2,5 @@ # Defines the gem version. class MockRedis - VERSION = '0.37.0' + VERSION = '0.38.0' end diff --git a/spec/commands/set_spec.rb b/spec/commands/set_spec.rb index 6cdb177..9f5fb6f 100644 --- a/spec/commands/set_spec.rb +++ b/spec/commands/set_spec.rb @@ -20,6 +20,18 @@ end.to raise_error(Redis::CommandError, 'ERR invalid expire time in set') end + it 'raises an error for EXAT seconds = 0' do + expect do + @redises.set('mock-redis-test', 1, exat: 0) + end.to raise_error(Redis::CommandError, 'ERR invalid expire time in set') + end + + it 'raises an error for PXAT seconds = 0' do + expect do + @redises.set('mock-redis-test', 1, pxat: 0) + end.to raise_error(Redis::CommandError, 'ERR invalid expire time in set') + end + it 'accepts NX' do @redises.del(key) expect(@redises.set(key, 1, nx: true)).to eq(true) @@ -33,6 +45,16 @@ expect(@redises.set(key, 1, xx: true)).to eq(true) end + it 'accepts EXAT' do + @redises.del(key) + expect(@redises.set(key, 1, exat: 1697197606)).to eq('OK') + end + + it 'accepts PXAT' do + @redises.del(key) + expect(@redises.set(key, 1, exat: 1697197589362)).to eq('OK') + end + it 'accepts GET on a string' do expect(@redises.set(key, '1')).to eq('OK') expect(@redises.set(key, '2', get: true)).to eq('1') @@ -129,6 +151,22 @@ allow(Time).to receive(:now).and_return(@now + 600 / 1000.to_f) expect(@mock.get(key)).to be_nil end + + it 'accepts EXAT seconds' do + expect(@mock.set(key, 1, exat: (@now + 1).to_i)).to eq('OK') + expect(@mock.get(key)).not_to be_nil + allow(Time).to receive(:now).and_return(@now + 2) + expect(@mock.get(key)).to be_nil + end + + it 'accepts PXAT milliseconds' do + expect(@mock.set(key, 1, pxat: ((@now + 500).to_f * 1000).to_i)).to eq('OK') + expect(@mock.get(key)).not_to be_nil + allow(Time).to receive(:now).and_return(@now + 300) + expect(@mock.get(key)).not_to be_nil + allow(Time).to receive(:now).and_return(@now + 600) + expect(@mock.get(key)).to be_nil + end end end end