diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md
index 4b7a77c9e..56c31a1a1 100644
--- a/docs/ReleaseNotes.md
+++ b/docs/ReleaseNotes.md
@@ -7,7 +7,8 @@
- Fixes a few internal edge cases that will now throw proper errors (rather than a downstream null reference)
- Fixes inconsistencies with `null` vs. empty array returns (preferring an not-null empty array in those edge cases)
- Note: does *not* increment a major version (as these are warnings to consumers), because: they're warnings (errors are opt-in), removing obsolete types with a 3.0 rev _would_ be binary breaking (this isn't), and reving to 3.0 would cause binding redirect pain for consumers. Bumping from 2.5 to 2.6 only for this change.
-- Adds: Support for `COPY` ([#2064 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2064))
+- Adds: Support for `COPY` with `.KeyCopy()`/`.KeyCopyAsync()` ([#2064 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2064))
+- Adds: Support for `LMOVE` with `.ListMove()`/`.ListMoveAsync()` ([#2065 by Avital-Fine](https://github.com/StackExchange/StackExchange.Redis/pull/2065))
## 2.5.61
diff --git a/src/StackExchange.Redis/Enums/ListSide.cs b/src/StackExchange.Redis/Enums/ListSide.cs
new file mode 100644
index 000000000..0e71f91e8
--- /dev/null
+++ b/src/StackExchange.Redis/Enums/ListSide.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace StackExchange.Redis
+{
+ ///
+ /// Specifies what side of the list to refer to.
+ ///
+ public enum ListSide
+ {
+ ///
+ /// The head of the list.
+ ///
+ Left,
+ ///
+ /// The tail of the list.
+ ///
+ Right,
+ }
+
+ internal static class ListSideExtensions
+ {
+ public static RedisValue ToLiteral(this ListSide side) => side switch
+ {
+ ListSide.Left => RedisLiterals.LEFT,
+ ListSide.Right => RedisLiterals.RIGHT,
+ _ => throw new ArgumentOutOfRangeException(nameof(side))
+ };
+ }
+}
diff --git a/src/StackExchange.Redis/Enums/RedisCommand.cs b/src/StackExchange.Redis/Enums/RedisCommand.cs
index 09d067184..5e7de00c1 100644
--- a/src/StackExchange.Redis/Enums/RedisCommand.cs
+++ b/src/StackExchange.Redis/Enums/RedisCommand.cs
@@ -83,6 +83,7 @@ internal enum RedisCommand
LINDEX,
LINSERT,
LLEN,
+ LMOVE,
LPOP,
LPUSH,
LPUSHX,
diff --git a/src/StackExchange.Redis/Interfaces/IDatabase.cs b/src/StackExchange.Redis/Interfaces/IDatabase.cs
index 0c4c4acce..92853a20c 100644
--- a/src/StackExchange.Redis/Interfaces/IDatabase.cs
+++ b/src/StackExchange.Redis/Interfaces/IDatabase.cs
@@ -769,6 +769,19 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// https://redis.io/commands/llen
long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None);
+ ///
+ /// Returns and removes the first or last element of the list stored at , and pushes the element
+ /// as the first or last element of the list stored at .
+ ///
+ /// The key of the list to remove from.
+ /// The key of the list to move to.
+ /// What side of the list to remove from.
+ /// What side of the list to move to.
+ /// The flags to use for this operation.
+ /// The element being popped and pushed or if there is no element to move.
+ /// https://redis.io/commands/lmove
+ RedisValue ListMove(RedisKey sourceKey, RedisKey destinationKey, ListSide sourceSide, ListSide destinationSide, CommandFlags flags = CommandFlags.None);
+
///
/// Returns the specified elements of the list stored at key.
/// The offsets start and stop are zero-based indexes, with 0 being the first element of the list (the head of the list), 1 being the next element and so on.
diff --git a/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs b/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs
index 81d4d55af..7bb26ed1b 100644
--- a/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs
+++ b/src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs
@@ -745,6 +745,19 @@ public interface IDatabaseAsync : IRedisAsync
/// https://redis.io/commands/llen
Task ListLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None);
+ ///
+ /// Returns and removes the first or last element of the list stored at , and pushes the element
+ /// as the first or last element of the list stored at .
+ ///
+ /// The key of the list to remove from.
+ /// The key of the list to move to.
+ /// What side of the list to remove from.
+ /// What side of the list to move to.
+ /// The flags to use for this operation.
+ /// The element being popped and pushed or if there is no element to move.
+ /// https://redis.io/commands/lmove
+ Task ListMoveAsync(RedisKey sourceKey, RedisKey destinationKey, ListSide sourceSide, ListSide destinationSide, CommandFlags flags = CommandFlags.None);
+
///
/// Returns the specified elements of the list stored at key.
/// The offsets start and stop are zero-based indexes, with 0 being the first element of the list (the head of the list), 1 being the next element and so on.
diff --git a/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs b/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs
index e755c2d34..a669cee57 100644
--- a/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs
+++ b/src/StackExchange.Redis/KeyspaceIsolation/DatabaseWrapper.cs
@@ -203,6 +203,9 @@ public long ListLeftPush(RedisKey key, RedisValue value, When when = When.Always
public long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None) =>
Inner.ListLength(ToInner(key), flags);
+ public RedisValue ListMove(RedisKey sourceKey, RedisKey destinationKey, ListSide sourceSide, ListSide destinationSide, CommandFlags flags = CommandFlags.None) =>
+ Inner.ListMove(ToInner(sourceKey), ToInner(destinationKey), sourceSide, destinationSide);
+
public RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) =>
Inner.ListRange(ToInner(key), start, stop, flags);
diff --git a/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs b/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs
index 2da36d504..694087e75 100644
--- a/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs
+++ b/src/StackExchange.Redis/KeyspaceIsolation/WrapperBase.cs
@@ -213,6 +213,9 @@ public Task ListLeftPushAsync(RedisKey key, RedisValue value, When when =
public Task ListLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) =>
Inner.ListLengthAsync(ToInner(key), flags);
+ public Task ListMoveAsync(RedisKey sourceKey, RedisKey destinationKey, ListSide sourceSide, ListSide destinationSide, CommandFlags flags = CommandFlags.None) =>
+ Inner.ListMoveAsync(ToInner(sourceKey), ToInner(destinationKey), sourceSide, destinationSide);
+
public Task ListRangeAsync(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None) =>
Inner.ListRangeAsync(ToInner(key), start, stop, flags);
@@ -532,7 +535,7 @@ public Task StringGetAsync(RedisKey[] keys, CommandFlags flags = C
public Task StringGetAsync(RedisKey key, CommandFlags flags = CommandFlags.None) =>
Inner.StringGetAsync(ToInner(key), flags);
-
+
public Task StringGetSetExpiryAsync(RedisKey key, TimeSpan? expiry, CommandFlags flags = CommandFlags.None) =>
Inner.StringGetSetExpiryAsync(ToInner(key), expiry, flags);
diff --git a/src/StackExchange.Redis/PublicAPI.Shipped.txt b/src/StackExchange.Redis/PublicAPI.Shipped.txt
index 008027d61..da09e4044 100644
--- a/src/StackExchange.Redis/PublicAPI.Shipped.txt
+++ b/src/StackExchange.Redis/PublicAPI.Shipped.txt
@@ -411,6 +411,9 @@ StackExchange.Redis.GeoUnit.Feet = 3 -> StackExchange.Redis.GeoUnit
StackExchange.Redis.GeoUnit.Kilometers = 1 -> StackExchange.Redis.GeoUnit
StackExchange.Redis.GeoUnit.Meters = 0 -> StackExchange.Redis.GeoUnit
StackExchange.Redis.GeoUnit.Miles = 2 -> StackExchange.Redis.GeoUnit
+StackExchange.Redis.ListSide
+StackExchange.Redis.ListSide.Left = 0 -> StackExchange.Redis.ListSide
+StackExchange.Redis.ListSide.Right = 1 -> StackExchange.Redis.ListSide
StackExchange.Redis.HashEntry
StackExchange.Redis.HashEntry.Equals(StackExchange.Redis.HashEntry other) -> bool
StackExchange.Redis.HashEntry.HashEntry() -> void
@@ -537,6 +540,7 @@ StackExchange.Redis.IDatabase.KeyType(StackExchange.Redis.RedisKey key, StackExc
StackExchange.Redis.IDatabase.ListGetByIndex(StackExchange.Redis.RedisKey key, long index, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue
StackExchange.Redis.IDatabase.ListInsertAfter(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue pivot, StackExchange.Redis.RedisValue value, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> long
StackExchange.Redis.IDatabase.ListInsertBefore(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue pivot, StackExchange.Redis.RedisValue value, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> long
+StackExchange.Redis.IDatabase.ListMove(StackExchange.Redis.RedisKey sourceKey, StackExchange.Redis.RedisKey destinationKey, StackExchange.Redis.ListSide sourceSide, StackExchange.Redis.ListSide destinationSide, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue
StackExchange.Redis.IDatabase.ListLeftPop(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue[]!
StackExchange.Redis.IDatabase.ListLeftPop(StackExchange.Redis.RedisKey key, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> StackExchange.Redis.RedisValue
StackExchange.Redis.IDatabase.ListLeftPush(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue value, StackExchange.Redis.When when = StackExchange.Redis.When.Always, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> long
@@ -726,6 +730,7 @@ StackExchange.Redis.IDatabaseAsync.KeyTypeAsync(StackExchange.Redis.RedisKey key
StackExchange.Redis.IDatabaseAsync.ListGetByIndexAsync(StackExchange.Redis.RedisKey key, long index, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
StackExchange.Redis.IDatabaseAsync.ListInsertAfterAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue pivot, StackExchange.Redis.RedisValue value, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
StackExchange.Redis.IDatabaseAsync.ListInsertBeforeAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue pivot, StackExchange.Redis.RedisValue value, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
+StackExchange.Redis.IDatabaseAsync.ListMoveAsync(StackExchange.Redis.RedisKey sourceKey, StackExchange.Redis.RedisKey destinationKey, StackExchange.Redis.ListSide sourceSide, StackExchange.Redis.ListSide destinationSide, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
StackExchange.Redis.IDatabaseAsync.ListLeftPopAsync(StackExchange.Redis.RedisKey key, long count, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
StackExchange.Redis.IDatabaseAsync.ListLeftPopAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
StackExchange.Redis.IDatabaseAsync.ListLeftPushAsync(StackExchange.Redis.RedisKey key, StackExchange.Redis.RedisValue value, StackExchange.Redis.When when = StackExchange.Redis.When.Always, StackExchange.Redis.CommandFlags flags = StackExchange.Redis.CommandFlags.None) -> System.Threading.Tasks.Task!
diff --git a/src/StackExchange.Redis/RedisDatabase.cs b/src/StackExchange.Redis/RedisDatabase.cs
index 6eb4ed0bf..cc8fa6acd 100644
--- a/src/StackExchange.Redis/RedisDatabase.cs
+++ b/src/StackExchange.Redis/RedisDatabase.cs
@@ -1009,6 +1009,18 @@ public Task ListLengthAsync(RedisKey key, CommandFlags flags = CommandFlag
return ExecuteAsync(msg, ResultProcessor.Int64);
}
+ public RedisValue ListMove(RedisKey sourceKey, RedisKey destinationKey, ListSide sourceSide, ListSide destinationSide, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.LMOVE, sourceKey, destinationKey, sourceSide.ToLiteral(), destinationSide.ToLiteral());
+ return ExecuteSync(msg, ResultProcessor.RedisValue);
+ }
+
+ public Task ListMoveAsync(RedisKey sourceKey, RedisKey destinationKey, ListSide sourceSide, ListSide destinationSide, CommandFlags flags = CommandFlags.None)
+ {
+ var msg = Message.Create(Database, flags, RedisCommand.LMOVE, sourceKey, destinationKey, sourceSide.ToLiteral(), destinationSide.ToLiteral());
+ return ExecuteAsync(msg, ResultProcessor.RedisValue);
+ }
+
public RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None)
{
var msg = Message.Create(Database, flags, RedisCommand.LRANGE, key, start, stop);
diff --git a/src/StackExchange.Redis/RedisLiterals.cs b/src/StackExchange.Redis/RedisLiterals.cs
index a31fbdf25..ca3a79357 100644
--- a/src/StackExchange.Redis/RedisLiterals.cs
+++ b/src/StackExchange.Redis/RedisLiterals.cs
@@ -68,6 +68,7 @@ public static readonly RedisValue
KEEPTTL = "KEEPTTL",
KILL = "KILL",
LATEST = "LATEST",
+ LEFT = "LEFT",
LIMIT = "LIMIT",
LIST = "LIST",
LOAD = "LOAD",
@@ -89,6 +90,7 @@ public static readonly RedisValue
PURGE = "PURGE",
PX = "PX",
PXAT = "PXAT",
+ RIGHT = "RIGHT",
REPLACE = "REPLACE",
RESET = "RESET",
RESETSTAT = "RESETSTAT",
diff --git a/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs b/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs
index 0ddd9981b..53a7437f6 100644
--- a/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs
+++ b/tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs
@@ -412,6 +412,13 @@ public void ListLength()
mock.Verify(_ => _.ListLength("prefix:key", CommandFlags.None));
}
+ [Fact]
+ public void ListMove()
+ {
+ wrapper.ListMove("key", "destination", ListSide.Left, ListSide.Right, CommandFlags.None);
+ mock.Verify(_ => _.ListMove("prefix:key", "prefix:destination", ListSide.Left, ListSide.Right, CommandFlags.None));
+ }
+
[Fact]
public void ListRange()
{
diff --git a/tests/StackExchange.Redis.Tests/Lists.cs b/tests/StackExchange.Redis.Tests/Lists.cs
index 0667b6266..a3daeb9a5 100644
--- a/tests/StackExchange.Redis.Tests/Lists.cs
+++ b/tests/StackExchange.Redis.Tests/Lists.cs
@@ -40,7 +40,7 @@ public void ListLeftPushEmptyValues()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = db.ListLeftPush(key, Array.Empty(), When.Always, CommandFlags.None);
Assert.Equal(0, result);
@@ -53,7 +53,7 @@ public void ListLeftPushKeyDoesNotExists()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = db.ListLeftPush(key, new RedisValue[] { "testvalue" }, When.Exists, CommandFlags.None);
Assert.Equal(0, result);
@@ -66,7 +66,7 @@ public void ListLeftPushToExisitingKey()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = db.ListLeftPush(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -88,7 +88,7 @@ public void ListLeftPushMultipleToExisitingKey()
{
Skip.IfBelow(conn, RedisFeatures.v4_0_0);
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = db.ListLeftPush(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -110,7 +110,7 @@ public async Task ListLeftPushAsyncEmptyValues()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = await db.ListLeftPushAsync(key, Array.Empty(), When.Always, CommandFlags.None);
Assert.Equal(0, result);
@@ -123,7 +123,7 @@ public async Task ListLeftPushAsyncKeyDoesNotExists()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = await db.ListLeftPushAsync(key, new RedisValue[] { "testvalue" }, When.Exists, CommandFlags.None);
Assert.Equal(0, result);
@@ -136,7 +136,7 @@ public async Task ListLeftPushAsyncToExisitingKey()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = await db.ListLeftPushAsync(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -158,7 +158,7 @@ public async Task ListLeftPushAsyncMultipleToExisitingKey()
{
Skip.IfBelow(conn, RedisFeatures.v4_0_0);
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = await db.ListLeftPushAsync(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -180,7 +180,7 @@ public void ListRightPushEmptyValues()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = db.ListRightPush(key, Array.Empty(), When.Always, CommandFlags.None);
Assert.Equal(0, result);
@@ -193,7 +193,7 @@ public void ListRightPushKeyDoesNotExists()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = db.ListRightPush(key, new RedisValue[] { "testvalue" }, When.Exists, CommandFlags.None);
Assert.Equal(0, result);
@@ -206,7 +206,7 @@ public void ListRightPushToExisitingKey()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = db.ListRightPush(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -228,7 +228,7 @@ public void ListRightPushMultipleToExisitingKey()
{
Skip.IfBelow(conn, RedisFeatures.v4_0_0);
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = db.ListRightPush(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -250,7 +250,7 @@ public async Task ListRightPushAsyncEmptyValues()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = await db.ListRightPushAsync(key, Array.Empty(), When.Always, CommandFlags.None);
Assert.Equal(0, result);
@@ -263,7 +263,7 @@ public async Task ListRightPushAsyncKeyDoesNotExists()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var result = await db.ListRightPushAsync(key, new RedisValue[] { "testvalue" }, When.Exists, CommandFlags.None);
Assert.Equal(0, result);
@@ -276,7 +276,7 @@ public async Task ListRightPushAsyncToExisitingKey()
using (var conn = Create())
{
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = await db.ListRightPushAsync(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -298,7 +298,7 @@ public async Task ListRightPushAsyncMultipleToExisitingKey()
{
Skip.IfBelow(conn, RedisFeatures.v4_0_0);
var db = conn.GetDatabase();
- RedisKey key = "testlist";
+ RedisKey key = Me();
db.KeyDelete(key, CommandFlags.FireAndForget);
var pushResult = await db.ListRightPushAsync(key, new RedisValue[] { "testvalue1" }, CommandFlags.None);
@@ -313,5 +313,44 @@ public async Task ListRightPushAsyncMultipleToExisitingKey()
Assert.Equal("testvalue3", rangeResult[2]);
}
}
+
+ [Fact]
+ public async Task ListMove()
+ {
+ using var conn = Create();
+ Skip.IfBelow(conn, RedisFeatures.v6_2_0);
+
+ var db = conn.GetDatabase();
+ RedisKey src = Me();
+ RedisKey dest = Me() + "dest";
+ db.KeyDelete(src, CommandFlags.FireAndForget);
+
+ var pushResult = await db.ListRightPushAsync(src, new RedisValue[] { "testvalue1", "testvalue2" });
+ Assert.Equal(2, pushResult);
+
+ var rangeResult1 = db.ListMove(src, dest, ListSide.Left, ListSide.Right);
+ var rangeResult2 = db.ListMove(src, dest, ListSide.Left, ListSide.Left);
+ var rangeResult3 = db.ListMove(dest, src, ListSide.Right, ListSide.Right);
+ var rangeResult4 = db.ListMove(dest, src, ListSide.Right, ListSide.Left);
+ Assert.Equal("testvalue1", rangeResult1);
+ Assert.Equal("testvalue2", rangeResult2);
+ Assert.Equal("testvalue1", rangeResult3);
+ Assert.Equal("testvalue2", rangeResult4);
+ }
+
+ [Fact]
+ public void ListMoveKeyDoesNotExist()
+ {
+ using var conn = Create();
+ Skip.IfBelow(conn, RedisFeatures.v6_2_0);
+
+ var db = conn.GetDatabase();
+ RedisKey src = Me();
+ RedisKey dest = Me() + "dest";
+ db.KeyDelete(src, CommandFlags.FireAndForget);
+
+ var rangeResult1 = db.ListMove(src, dest, ListSide.Left, ListSide.Right);
+ Assert.True(rangeResult1.IsNull);
+ }
}
}
diff --git a/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs b/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs
index 13b5fd8cd..1197a636d 100644
--- a/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs
+++ b/tests/StackExchange.Redis.Tests/WrapperBaseTests.cs
@@ -372,6 +372,13 @@ public void ListLengthAsync()
mock.Verify(_ => _.ListLengthAsync("prefix:key", CommandFlags.None));
}
+ [Fact]
+ public void ListMoveAsync()
+ {
+ wrapper.ListMoveAsync("key", "destination", ListSide.Left, ListSide.Right, CommandFlags.None);
+ mock.Verify(_ => _.ListMoveAsync("prefix:key", "prefix:destination", ListSide.Left, ListSide.Right, CommandFlags.None));
+ }
+
[Fact]
public void ListRangeAsync()
{