using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using StackExchange.Redis;

using Xunit;
using Xunit.Extensions;
using Xunit.Serialization;
using Xunit.Abstractions;
using Xunit.Sdk;

using RedisStuy;

namespace RedisStudyTest
{
    /// <summary>
    /// Redis 集合学习 测试
    /// </summary>
    [Trait("RedisSortedSet", "All")]
    public class RedisSortedSetStudyTest : IDisposable
    {
        #region 初始化
        private readonly ITestOutputHelper testOutput;
        private IDatabase redisDatabase = null;
        private RedisSortedSetStudy redisSortedSetStudy = null;
        private TimeSpan defaultExpiry = TimeSpan.FromSeconds(20);
        private string defaultRedisKey = "RedisStudy:SortedSet:xUnitTest";

        /// <summary>
        /// 构造
        /// </summary>
        public RedisSortedSetStudyTest(ITestOutputHelper output)
        {
            this.testOutput = output;
            redisDatabase = RedisHelper.GetRedisDatabase();
            redisSortedSetStudy = new RedisSortedSetStudy();
        }
        #endregion

        #region SortedSetAdd

        [Fact]
        public void SortedAdd_NotKey_Test()
        {
            var addNumber = redisSortedSetStudy.SortedSetAdd(defaultRedisKey, new SortedSetEntry[] { }, CommandFlags.None);
            Assert.Equal(0, addNumber);

            var exits = redisDatabase.KeyExists(defaultRedisKey);
            Assert.False(exits);

            var result = redisSortedSetStudy.SortedSetAdd(defaultRedisKey, "first", 1, CommandFlags.None);
            Assert.True(result);

            var number = redisSortedSetStudy.SortedSetLength(defaultRedisKey);
            Assert.Equal(1, number);
        }

        [Fact]
        public void SetAdd_SortedSetEntrys_Empty_Test()
        {
            var addNumber = redisSortedSetStudy.SortedSetAdd(defaultRedisKey, new SortedSetEntry[] { }, CommandFlags.None);
            Assert.Equal(0, addNumber);
        }

        [Fact]
        public void SetAddByOneTest()
        {
            //重载方法1
            var addResult = redisSortedSetStudy.SortedSetAdd(defaultRedisKey,"first",1);
            Assert.True(addResult);

            //重载方法2
            var addResult2 = redisSortedSetStudy.SortedSetAdd(defaultRedisKey, "second", 2, CommandFlags.None);
            Assert.True(addResult2);

            //反向验证
            var members = redisSortedSetStudy.SortedSetLength(defaultRedisKey);
            Assert.Equal(2, members);
        }

        [Fact]
        public void SetAddByGroupTest()
        {
            SortedSetEntry[] sortedSetEntrys = new SortedSetEntry[] 
            {
                new SortedSetEntry("first", 1),
                new SortedSetEntry("second", 2),
                new SortedSetEntry("third", 3),
                new SortedSetEntry("four", 4),
                new SortedSetEntry("five", 5),
            };

            SortedSetEntry[] sortedSetEntrys2 = new SortedSetEntry[]
            {
                new SortedSetEntry("six", 6),
                new SortedSetEntry("seven", 7),
            };

            //重载方法1
            var memberNumber = redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntrys, CommandFlags.None);
            Assert.Equal(5, memberNumber);

            //重载方法2
            var memberNumber2 = redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntrys2, When.Always, CommandFlags.None);
            Assert.Equal(2, memberNumber2);

            //验证数据
            var totalNumber = redisSortedSetStudy.SortedSetLength(defaultRedisKey);

            Assert.Equal(7, totalNumber);
        }
        #endregion

        #region SortedSetIncrement

        [Fact]
        public void SortedSetIncrement_NotKey_Test()
        {
            var incResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", 1.0);
            Assert.Equal(1.0, incResult);
        }

        [Fact]
        public void SortedSetIncrementTest()
        {
            var incResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", 1.0);
            Assert.Equal(1.0, incResult);

            incResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", 1.5);
            double differenceValue = incResult - 2.5;
            Assert.True(differenceValue < 0.01);

            //增加负值等于减少
            incResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", -2.1);
            differenceValue =0.4 - incResult;
            Assert.True(differenceValue < 0.01);
        }
        #endregion

        #region SortedSetDecrement

        [Fact]
        public void SortedSetDecrement_NotKey_Test()
        {
            var incResult = redisSortedSetStudy.SortedSetDecrement(defaultRedisKey, "first", 1.0);
            Assert.Equal(-1.0, incResult);
        }

        [Fact]
        public void SortedSetDecrementTest()
        {
            var decResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", -1.0);
            Assert.Equal(-1.0, decResult);

            decResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", -1.5);
            double differenceValue =Math.Abs( -2.5 - decResult);
            Assert.True(differenceValue < 0.01);

            //减少负值等于增加
            decResult = redisSortedSetStudy.SortedSetIncrement(defaultRedisKey, "first", 2.1);
            differenceValue =Math.Abs(-0.4 - decResult);
            Assert.True(differenceValue < 0.01);
        }
        #endregion

        #region SortedSetLength

        [Fact]
        public void SortedSetLength_NotKey_Test()
        {
            var memberCount = redisSortedSetStudy.SortedSetLength(defaultRedisKey);
            Assert.Equal(0, memberCount);
        }

        /// <summary>
        /// 排它性参数Exclude设置 测试
        /// </summary>
        [Fact]
        public void SortedSetLength_Exclude_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:Exclude.None [Start,Stop]
            var memberCount = redisSortedSetStudy.SortedSetLength(defaultRedisKey, 2, 4, Exclude.None, CommandFlags.None);
            Assert.Equal(3, memberCount);

            //Exclude.Start (Start,Stop]
            memberCount = redisSortedSetStudy.SortedSetLength(defaultRedisKey, 2, 4, Exclude.Start, CommandFlags.None);
            Assert.Equal(2, memberCount);

            //Exclude.Stop [Start,Stop)
            memberCount = redisSortedSetStudy.SortedSetLength(defaultRedisKey, 2, 4, Exclude.Stop, CommandFlags.None);
            Assert.Equal(2, memberCount);

            //Exclude.Both (Start,Stop)
            memberCount = redisSortedSetStudy.SortedSetLength(defaultRedisKey, 2, 4, Exclude.Both, CommandFlags.None);
            Assert.Equal(1, memberCount);
        }

        [Fact]
        public void SortedSetLengthTest()
        {
            SortedSetEntry[] sortedSetEntries=new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var memberCount = redisSortedSetStudy.SortedSetLength(defaultRedisKey, 1, 5);
            Assert.Equal(sortedSetEntries.Length, memberCount);
        }

        #endregion

        #region SortedSetLengthByValue 分数相同则字典排序

        [Fact]
        public void SortedSetLengthByValue_NotKey_Test()
        {
            var memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey,1,200);
            Assert.Equal(0, memberCount);
        }

        /// <summary>
        /// 排它性参数Exclude设置 测试
        /// </summary>
        [Fact]
        public void SortedSetLengthByValue_Exclude_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",0),
                new SortedSetEntry("second",0),
                new SortedSetEntry("third",0),
                new SortedSetEntry("four",0),
                new SortedSetEntry("five",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:Exclude.None [Start,Stop]
            var memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "first", "four", Exclude.None, CommandFlags.None);
            Assert.Equal(3, memberCount);

            //Exclude.Start (Start,Stop]
            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "first", "four", Exclude.Start, CommandFlags.None);
            Assert.Equal(2, memberCount);

            //Exclude.Stop [Start,Stop)
            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "first", "four", Exclude.Stop, CommandFlags.None);
            Assert.Equal(2, memberCount);

            //Exclude.Both (Start,Stop)
            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "first", "four", Exclude.Both, CommandFlags.None);
            Assert.Equal(1, memberCount);
        }

        /// <summary>
        /// 分数相同,字典排序,逐字符比较(汉字的比较等待确认)
        /// 字典顺序(”0”<…<”9”<”A”<…<”Z”<”a”<…<”z”)
        /// </summary>
        [Fact]
        public void SortedSetLengthByValueTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",0),
                new SortedSetEntry("and",0),
                 new SortedSetEntry("And",0),
                new SortedSetEntry("Banana",0),
                new SortedSetEntry("color",0),
                new SortedSetEntry("query",0),
                new SortedSetEntry("remove",0),
                new SortedSetEntry("101",0),
                new SortedSetEntry("304",0),
                new SortedSetEntry("404",0),
                new SortedSetEntry("王高峰",0),
                new SortedSetEntry("刘山东",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //数字排序
            var memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "0", "5");
            Assert.Equal(3, memberCount);

            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "10", "4");
            Assert.Equal(2, memberCount);

            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "11", "40");
            Assert.Equal(1, memberCount);

            //字母排序
            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "And", "color");
            //And Andy Banana and color
            Assert.Equal(5, memberCount);

            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "A", "color");
            //And Andy Banana and color
            Assert.Equal(5, memberCount);

            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "A", "B");
            //And Andy 不包括Banana,因为Ba排在B后
            Assert.Equal(2, memberCount);

            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "A", "Bb");
            //And Andy Banana
            Assert.Equal(3, memberCount);

            //汉字排序(转码后比较,转码规则不清楚)
            //TODO:汉字排序规则不清楚)
            memberCount = redisSortedSetStudy.SortedSetLengthByValue(defaultRedisKey, "王", "赵");
            //王高峰
            Assert.Equal(1, memberCount);
        }

        #endregion

        #region SortedSetRank

        [Fact]
        public void SortedSetRank_NotKey_Test()
        {
            var index = redisSortedSetStudy.SortedSetRank(defaultRedisKey, "first");

            Assert.Null(index);
        }

        [Fact]
        public void SortedSetRankTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            long? memberRank = null;
            memberRank = redisSortedSetStudy.SortedSetRank(defaultRedisKey, "first");
            Assert.Equal(0, memberRank);

            memberRank = redisSortedSetStudy.SortedSetRank(defaultRedisKey, "second");
            Assert.Equal(1, memberRank);

            memberRank = redisSortedSetStudy.SortedSetRank(defaultRedisKey, "third");
            Assert.Equal(2, memberRank);

            memberRank = redisSortedSetStudy.SortedSetRank(defaultRedisKey, "four");
            Assert.Equal(3, memberRank);

            memberRank = redisSortedSetStudy.SortedSetRank(defaultRedisKey, "five");
            Assert.Equal(4, memberRank);
        }
        #endregion

        #region SortedSetScore

        [Fact]
        public void SortedSetScore_NotKey_Test()
        {
            var setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey,"first");

            Assert.False(setScore.HasValue);
        }

        [Fact]
        public void SortedSetScore_NotMember_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey, "mysix");

            Assert.False(setScore.HasValue);
        }

        [Fact]
        public void SortedSetScoreTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey, "first");
            Assert.Equal(1, setScore);

            setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey, "second");
            Assert.Equal(2, setScore);

            setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey, "third");
            Assert.Equal(3, setScore);

            setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey, "four");
            Assert.Equal(4, setScore);

            setScore = redisSortedSetStudy.SortedSetScore(defaultRedisKey, "five");
            Assert.Equal(5, setScore);
        }
        #endregion

        #region SortedSetRangeByRank

        [Fact]
        public void SortedSetRangeByRank_NotKey_Test()
        {
            var members = redisSortedSetStudy.SortedSetRangeByRank(defaultRedisKey);
            Assert.Empty(members);
        }

        [Fact]
        public void SortedSetRangeByRankTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var members = redisSortedSetStudy.SortedSetRangeByRank(defaultRedisKey);
            Assert.NotEmpty(members);
            for (var i=0; i< sortedSetEntries.Length; i++)
            {
                Assert.Equal(sortedSetEntries[0].Element, members[0]);
            }

            members = redisSortedSetStudy.SortedSetRangeByRank(defaultRedisKey, 1, -1, Order.Descending, CommandFlags.None);
            //four third second first
            Assert.Equal(sortedSetEntries[3].Element, members[0]);
            Assert.Equal(sortedSetEntries[2].Element, members[1]);
            Assert.Equal(sortedSetEntries[1].Element, members[2]);
            Assert.Equal(sortedSetEntries[0].Element, members[3]);
        }
        #endregion

        #region SortedSetRangeByRankWithScores
        [Fact]
        public void SortedSetRangeByRankWithScores_NotKey_Test()
        {
            var sortedSetEntries = redisSortedSetStudy.SortedSetRangeByRankWithScores(defaultRedisKey);
            Assert.Empty(sortedSetEntries);
        }

        [Fact]
        public void SortedSetRangeByRankWithScoresTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var queryEntries = redisSortedSetStudy.SortedSetRangeByRankWithScores(defaultRedisKey);
            Assert.NotEmpty(queryEntries);
            for (var i = 0; i < sortedSetEntries.Length; i++)
            {
                Assert.Equal(sortedSetEntries[0], queryEntries[0]);
            }

            queryEntries = redisSortedSetStudy.SortedSetRangeByRankWithScores(defaultRedisKey, 1, -1, Order.Descending, CommandFlags.None);
            //four third second first
            Assert.Equal(sortedSetEntries[3], queryEntries[0]);
            Assert.Equal(sortedSetEntries[2], queryEntries[1]);
            Assert.Equal(sortedSetEntries[1], queryEntries[2]);
            Assert.Equal(sortedSetEntries[0], queryEntries[3]);
        }
        #endregion

        #region SortedSetRangeByScore

        [Fact]
        public void SortedSetRangeByScore_NotKey_Test()
        {
            var members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey);
            Assert.Empty(members);
        }

        /// <summary>
        /// 排它性参数Exclude设置 测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByScore_Exclude_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:Exclude.None [Start,Stop]
            var members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 2, 4, Exclude.None);
            Assert.Equal(3, members.Length);
            Assert.Contains("second", members);
            Assert.Contains("third", members);
            Assert.Contains("four", members);

            //Exclude.Start (Start,Stop]
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 2, 4, Exclude.Start);
            Assert.Equal(2, members.Length);
            Assert.Contains("third", members);
            Assert.Contains("four", members);

            //Exclude.Stop [Start,Stop)
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 2, 4, Exclude.Stop);
            Assert.Equal(2, members.Length);
            Assert.Contains("second", members);
            Assert.Contains("third", members);

            //Exclude.Both (Start,Stop)
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 2, 4, Exclude.Both);
            Assert.Single(members);
            Assert.Contains("third", members);
        }

        /// <summary>
        /// 排序参数测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByScore_Sort_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:升序
            var members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 2, 4, Exclude.None, Order.Ascending);
            Assert.Equal(3, members.Length);
            Assert.Equal("second", members[0]);
            Assert.Equal("third", members[1]);
            Assert.Equal("four", members[2]);

            //降序
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 2, 4, Exclude.None, Order.Descending);
            Assert.Equal(3, members.Length);
            Assert.Equal("four", members[0]);
            Assert.Equal("third", members[1]);
            Assert.Equal("second", members[2]);
        }

        /// <summary>
        /// 分页测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByScore_Page_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",1),
                new SortedSetEntry("and",2),
                new SortedSetEntry("And",3),
                new SortedSetEntry("Banana",4),
                new SortedSetEntry("color",5),
                new SortedSetEntry("query",6),
                new SortedSetEntry("remove",7),
                new SortedSetEntry("101",8),
                new SortedSetEntry("304",9),
                new SortedSetEntry("404",10),
                new SortedSetEntry("王高峰",11),
                new SortedSetEntry("刘山东",12),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //第一页
            var members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, double.MinValue, double.MaxValue, Exclude.None, Order.Ascending, 0, 4, CommandFlags.None);
            Assert.Equal(4, members.Length);
            Assert.Contains("Andy", members);
            Assert.Contains("and", members);
            Assert.Contains("And", members);
            Assert.Contains("Banana", members);

            //第2页
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, double.NegativeInfinity, double.PositiveInfinity, Exclude.None, Order.Ascending, 4, 4, CommandFlags.None);
            Assert.Equal(4, members.Length);
            Assert.Contains("color", members);
            Assert.Contains("query", members);
            Assert.Contains("remove", members);
            Assert.Contains("101", members);

            //第3页
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, double.NegativeInfinity, double.PositiveInfinity, Exclude.None, Order.Ascending, 8, 4, CommandFlags.None);
            Assert.Equal(4, members.Length);
            Assert.Contains("304", members);
            Assert.Contains("404", members);
            Assert.Contains("王高峰", members);
            Assert.Contains("刘山东", members);
        }

        [Fact]
        public void SortedSetRangeByScoreTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",1),
                new SortedSetEntry("and",2),
                new SortedSetEntry("And",3),
                new SortedSetEntry("Banana",4),
                new SortedSetEntry("color",5),
                new SortedSetEntry("query",6),
                new SortedSetEntry("remove",7),
                new SortedSetEntry("101",8),
                new SortedSetEntry("304",9),
                new SortedSetEntry("404",10),
                new SortedSetEntry("王高峰",11),
                new SortedSetEntry("刘山东",12),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 1, 5);
            Assert.Equal(5, members.Length);
            Assert.Equal("Andy", members[0]);
            Assert.Equal("and", members[1]);
            Assert.Equal("And", members[2]);
            Assert.Equal("Banana", members[3]);
            Assert.Equal("color", members[4]);

            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 5, 7, Exclude.None, Order.Descending);
            Assert.Equal(3, members.Length);
            Assert.Equal("remove", members[0]);
            Assert.Equal("query", members[1]);
            Assert.Equal("color", members[2]);

            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, double.NegativeInfinity, double.PositiveInfinity);
            Assert.Equal(12, members.Length);
            Assert.Equal("Andy", members[0]);
            Assert.Equal("刘山东", members[11]);
        }

        #endregion

        #region SortedSetRangeByScoreWithScores
        [Fact]
        public void SortedSetRangeByScoreWithScores_NotKey_Test()
        {
            var members = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey);
            Assert.Empty(members);
        }

        /// <summary>
        /// 排它性参数Exclude设置 测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByScoreWithScores_Exclude_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:Exclude.None [Start,Stop]
            var queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 2, 4, Exclude.None);
            Assert.Equal(3, queryEntries.Length);
            Assert.Contains("second", queryEntries[0].Element);
            Assert.Contains("third", queryEntries[1].Element);
            Assert.Contains("four", queryEntries[2].Element);

            //Exclude.Start (Start,Stop]
            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 2, 4, Exclude.Start);
            Assert.Equal(2, queryEntries.Length);
            Assert.Contains("third", queryEntries[0].Element);
            Assert.Contains("four", queryEntries[1].Element);

            //Exclude.Stop [Start,Stop)
            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 2, 4, Exclude.Stop);
            Assert.Equal(2, queryEntries.Length);
            Assert.Contains("second", queryEntries[0].Element);
            Assert.Contains("third", queryEntries[1].Element);

            //Exclude.Both (Start,Stop)
            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 2, 4, Exclude.Both);
            Assert.Single(queryEntries);
            Assert.Contains("third", queryEntries[0].Element);
        }

        /// <summary>
        /// 排序参数测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByScoreWithScores_Sort_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("four",4),
                new SortedSetEntry("five",5),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:升序
            var queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 2, 4, Exclude.None, Order.Ascending);
            Assert.Equal(3, queryEntries.Length);
            Assert.Equal("second", queryEntries[0].Element);
            Assert.Equal("third", queryEntries[1].Element);
            Assert.Equal("four", queryEntries[2].Element);

            //降序
            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 2, 4, Exclude.None, Order.Descending);
            Assert.Equal(3, queryEntries.Length);
            Assert.Equal("four", queryEntries[0].Element);
            Assert.Equal("third", queryEntries[1].Element);
            Assert.Equal("second", queryEntries[2].Element);
        }

        /// <summary>
        /// 分页测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByScoreWithScores_Page_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",1),
                new SortedSetEntry("and",2),
                new SortedSetEntry("And",3),
                new SortedSetEntry("Banana",4),
                new SortedSetEntry("color",5),
                new SortedSetEntry("query",6),
                new SortedSetEntry("remove",7),
                new SortedSetEntry("101",8),
                new SortedSetEntry("304",9),
                new SortedSetEntry("404",10),
                new SortedSetEntry("王高峰",11),
                new SortedSetEntry("刘山东",12),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //第一页
            var queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, double.MinValue, double.MaxValue, Exclude.None, Order.Ascending, 0, 4, CommandFlags.None);
            Assert.Equal(4, queryEntries.Length);
            Assert.Equal(sortedSetEntries[0], queryEntries[0]);
            Assert.Equal(sortedSetEntries[1], queryEntries[1]);
            Assert.Equal(sortedSetEntries[2], queryEntries[2]);
            Assert.Equal(sortedSetEntries[3], queryEntries[3]);

            //第2页
            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, double.NegativeInfinity, double.PositiveInfinity, Exclude.None, Order.Ascending, 4, 4, CommandFlags.None);
            Assert.Equal(4, queryEntries.Length);
            Assert.Equal(sortedSetEntries[4], queryEntries[0]);
            Assert.Equal(sortedSetEntries[5], queryEntries[1]);
            Assert.Equal(sortedSetEntries[6], queryEntries[2]);
            Assert.Equal(sortedSetEntries[7], queryEntries[3]);

            //第3页
            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, double.NegativeInfinity, double.PositiveInfinity, Exclude.None, Order.Ascending, 8, 4, CommandFlags.None);
            Assert.Equal(4, queryEntries.Length);
            Assert.Equal(sortedSetEntries[8], queryEntries[0]);
            Assert.Equal(sortedSetEntries[9], queryEntries[1]);
            Assert.Equal(sortedSetEntries[10], queryEntries[2]);
            Assert.Equal(sortedSetEntries[11], queryEntries[3]);
        }

        [Fact]
        public void SortedSetRangeByScoreWithScoresTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",1),
                new SortedSetEntry("and",2),
                new SortedSetEntry("And",3),
                new SortedSetEntry("Banana",4),
                new SortedSetEntry("color",5),
                new SortedSetEntry("query",6),
                new SortedSetEntry("remove",7),
                new SortedSetEntry("101",8),
                new SortedSetEntry("304",9),
                new SortedSetEntry("404",10),
                new SortedSetEntry("王高峰",11),
                new SortedSetEntry("刘山东",12),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 1, 5);
            Assert.Equal(5, queryEntries.Length);
            Assert.Equal("Andy", queryEntries[0].Element);
            Assert.Equal("and", queryEntries[1].Element);
            Assert.Equal("And", queryEntries[2].Element);
            Assert.Equal("Banana", queryEntries[3].Element);
            Assert.Equal("color", queryEntries[4].Element);

            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, 5, 7, Exclude.None, Order.Descending);
            Assert.Equal(3, queryEntries.Length);
            Assert.Equal("remove", queryEntries[0].Element);
            Assert.Equal("query", queryEntries[1].Element);
            Assert.Equal("color", queryEntries[2].Element);

            queryEntries = redisSortedSetStudy.SortedSetRangeByScoreWithScores(defaultRedisKey, double.NegativeInfinity, double.PositiveInfinity);
            Assert.Equal(12, queryEntries.Length);
            Assert.Equal("Andy", queryEntries[0].Element);
            Assert.Equal("刘山东", queryEntries[11].Element);
        }
        #endregion

        #region SortedSetRangeByValue

        [Fact]
        public void SortedSetRangeByValue_NotKey_Test()
        {
            var mumbers = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, 0, -1);

            Assert.Empty(mumbers);
        }

        /// <summary>
        /// 排它性参数Exclude设置 测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByValue_Exclude_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",0),
                new SortedSetEntry("second",0),
                new SortedSetEntry("third",0),
                new SortedSetEntry("four",0),
                new SortedSetEntry("five",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //默认:Exclude.None [Start,Stop]
            var members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "first", "second", Exclude.None);
            //firt five four second
            Assert.Equal(4, members.Length);

            //Exclude.Start (Start,Stop]
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "first", "second", Exclude.Start);
            //five four second
            Assert.Equal(3, members.Length);

            //Exclude.Stop [Start,Stop)
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "first", "four", Exclude.Stop);
            Assert.Equal(2, members.Length);

            //Exclude.Both (Start,Stop)
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "first", "four", Exclude.Both);
            Assert.Single(members);
        }

        /// <summary>
        /// 分数相同,字典排序,逐字符比较(汉字的比较等待确认)
        /// 字典顺序(”0”<…<”9”<”A”<…<”Z”<”a”<…<”z”)
        /// </summary>
        [Fact]
        public void SortedSetRangeByValueTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",0),
                new SortedSetEntry("and",0),
                 new SortedSetEntry("And",0),
                new SortedSetEntry("Banana",0),
                new SortedSetEntry("color",0),
                new SortedSetEntry("query",0),
                new SortedSetEntry("remove",0),
                new SortedSetEntry("101",0),
                new SortedSetEntry("304",0),
                new SortedSetEntry("404",0),
                new SortedSetEntry("王高峰",0),
                new SortedSetEntry("刘山东",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //数字排序
            var members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "0", "5");
            Assert.Contains("101", members);
            Assert.Contains("304", members);
            Assert.Contains("404", members);

            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "10", "4");
            Assert.Contains("101", members);
            Assert.Contains("304", members);

            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "11", "40");
            Assert.Contains("304", members);

            //字母排序
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "And", "color");
            //And Andy Banana and color
            Assert.Contains("And", members);
            Assert.Contains("Andy", members);
            Assert.Contains("Banana", members);
            Assert.Contains("and", members);
            Assert.Contains("color", members);

            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "A", "color");
            //And Andy Banana and color
            Assert.Contains("And", members);
            Assert.Contains("Andy", members);
            Assert.Contains("Banana", members);
            Assert.Contains("and", members);
            Assert.Contains("color", members);

            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "A", "B");
            //And Andy 不包括Banana,因为Ba排在B后
            Assert.Contains("And", members);
            Assert.Contains("Andy", members);

            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "A", "Bb");
            //And Andy Banana
            Assert.Contains("And", members);
            Assert.Contains("Andy", members);
            Assert.Contains("Banana", members);

            //TODO:汉字排序规则不清楚
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "王", "赵");
            //王高峰
            Assert.Contains("王高峰", members);
        }

        /// <summary>
        /// 分页测试
        /// </summary>
        [Fact]
        public void SortedSetRangeByValue_Page_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("Andy",0),
                new SortedSetEntry("and",0),
                new SortedSetEntry("And",0),
                new SortedSetEntry("Banana",0),
                new SortedSetEntry("color",0),
                new SortedSetEntry("query",0),
                new SortedSetEntry("remove",0),
                new SortedSetEntry("101",0),
                new SortedSetEntry("304",0),
                new SortedSetEntry("404",0),
                new SortedSetEntry("王高峰",0),
                new SortedSetEntry("刘山东",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            //第一页
            var members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "101", "remove", Exclude.None, 0, 4, CommandFlags.None);
            Assert.Equal(4, members.Length);
            Assert.Contains("101", members);
            Assert.Contains("304", members);
            Assert.Contains("404", members);
            Assert.Contains("And", members);

            //第2页
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "101", "remove", Exclude.None, 4, 4, CommandFlags.None);
            Assert.Equal(4, members.Length);
            Assert.Contains("Andy", members);
            Assert.Contains("Banana", members);
            Assert.Contains("and", members);
            Assert.Contains("color", members);

            //第3页
            members = redisSortedSetStudy.SortedSetRangeByValue(defaultRedisKey, "101", "remove", Exclude.None, 8, 4, CommandFlags.None);
            Assert.Equal(2, members.Length);
            Assert.Contains("query", members);
            Assert.Contains("remove", members);
        }
        #endregion

        #region SortedSetRemove

        [Fact]
        public void SortedSetRemove_NotKey_Test()
        {
            var result =  redisSortedSetStudy.SortedSetRemove(defaultRedisKey,"first");
            Assert.False(result);
        }

        [Fact]
        public void SortedSetRemove_NotMember_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",0),
                new SortedSetEntry("second",0),
                 new SortedSetEntry("third",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var result = redisSortedSetStudy.SortedSetRemove(defaultRedisKey, "myfive");
            Assert.False(result);
        }

        [Fact]
        public void SortedSetRemove_One_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",0),
                new SortedSetEntry("second",0),
                 new SortedSetEntry("third",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var result = redisSortedSetStudy.SortedSetRemove(defaultRedisKey, "first");
            Assert.True(result);

            result = redisSortedSetStudy.SortedSetRemove(defaultRedisKey, "second");
            Assert.True(result);

            result = redisSortedSetStudy.SortedSetRemove(defaultRedisKey, "third");
            Assert.True(result);
        }

        [Fact]
        public void SortedSetRemove_Group_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",0),
                new SortedSetEntry("second",0),
                 new SortedSetEntry("third",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var removeNumber = redisSortedSetStudy.SortedSetRemove(defaultRedisKey, new RedisValue[] { "first","second"});
            Assert.Equal(2,removeNumber);

            removeNumber = redisSortedSetStudy.SortedSetRemove(defaultRedisKey, new RedisValue[] { "second", "third","myfirst" });
            Assert.Equal(1, removeNumber);
        }

        #endregion

        #region SortedSetRemoveRangeByRank

        [Fact]
        public void SortedSetRemoveRangeByRank_NotKey_Test()
        {
            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByRank(defaultRedisKey, 0, -1);
            Assert.Equal(0, removeNumber);
        }

        [Fact]
        public void SortedSetRemoveRangeByRankTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("five",4),
                new SortedSetEntry("six",5),
                new SortedSetEntry("seven",6),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByRank(defaultRedisKey, 2, 3);
            Assert.Equal(2, removeNumber);
            var members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 3, 4);
            Assert.Empty(members);

            removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByRank(defaultRedisKey, 0, 2);
            Assert.Equal(3, removeNumber);
            members = redisSortedSetStudy.SortedSetRangeByScore(defaultRedisKey, 0, 4);
            Assert.Empty(members);
        }
        #endregion

        #region SortedSetRemoveRangeByScore

        [Fact]
        public void SortedSetRemoveRangeByScore_NotKey_Test()
        {
            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByScore(defaultRedisKey,0,10000);
            Assert.Equal(0, removeNumber);
        }

        [Fact]
        public void SortedSetRemoveRangeByScore_NotScore_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("five",4),
                new SortedSetEntry("six",5),
                new SortedSetEntry("seven",6),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByScore(defaultRedisKey, 1000, 10000);
            Assert.Equal(0, removeNumber);
        }

        [Fact]
        public void SortedSetRemoveRangeByScoreTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("five",4),
                new SortedSetEntry("six",5),
                new SortedSetEntry("seven",6),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByScore(defaultRedisKey, 1, 3);
            Assert.Equal(3, removeNumber);

            removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByScore(defaultRedisKey, 4, 4);
            Assert.Equal(1, removeNumber);

            removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByScore(defaultRedisKey, 5, 6);
            Assert.Equal(2, removeNumber);
        }
        #endregion

        #region SortedSetRemoveRangeByScore

        [Fact]
        public void SortedSetRemoveRangeByValue_NotKey_Test()
        {
            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByValue(defaultRedisKey, "0", "zz");
            Assert.Equal(0, removeNumber);
        }

        [Fact]
        public void SortedSetRemoveRangeByValue_NotValue_Test()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("five",4),
                new SortedSetEntry("six",5),
                new SortedSetEntry("seven",6),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByValue(defaultRedisKey, "w", "z");
            Assert.Equal(0, removeNumber);
        }

        [Fact]
        public void SortedSetRemoveRangeByValueTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",0),
                new SortedSetEntry("second",0),
                new SortedSetEntry("third",0),
                new SortedSetEntry("five",0),
                new SortedSetEntry("six",0),
                new SortedSetEntry("seven",0),
            };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByValue(defaultRedisKey, "first", "second");
            Assert.Equal(3, removeNumber);

            removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByValue(defaultRedisKey, "seven", "seven");
            Assert.Equal(1, removeNumber);

            removeNumber = redisSortedSetStudy.SortedSetRemoveRangeByValue(defaultRedisKey, "six", "third");
            Assert.Equal(2, removeNumber);
        }
        #endregion

        #region SortedSetCombineAndStore
        [Fact]
        public void SortedSetCombineAndStore_NotKey_Test()
        {
            var memberNumber = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, "destination", "first", "second", Aggregate.Sum, CommandFlags.None);

            Assert.Equal(0, memberNumber);
        }

        /// <summary>
        /// 目标集合不存在
        /// (创建目标集成)
        /// </summary>
        [Fact]
        public void SortedSetCombineAndStore_NotDestination_Test()
        {
            //准备
            RedisKey destinationKey = "RedisStudy:SortedSet:destination";
            RedisKey firstKey = "RedisStudy:SortedSet:first";
            RedisKey secondKey = "RedisStudy:SortedSet:second";

            //删除旧数据
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);

            SortedSetEntry[] firstEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
            };

            SortedSetEntry[] secondEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("third",3),
                new SortedSetEntry("fourth",4),
            };

            redisSortedSetStudy.SortedSetAdd(firstKey, firstEntries);
            redisSortedSetStudy.SortedSetAdd(secondKey, secondEntries);

            //操作
            var combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(4, combineNum);

            var destinationLenth = redisSortedSetStudy.SortedSetLength(destinationKey);
            Assert.Equal(4, destinationLenth);

            //清理
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);
        }

        /// <summary>
        /// 目标集合存在
        /// 重写目标集合(效果等同:删除重键)
        /// </summary>
        [Fact]
        public void SortedSetCombineAndStore_HasDestination_Test()
        {
            //准备
            RedisKey destinationKey = "RedisStudy:SortedSet:destination";
            RedisKey firstKey = "RedisStudy:SortedSet:first";
            RedisKey secondKey = "RedisStudy:SortedSet:second";

            //删除旧数据
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);

            SortedSetEntry[] destinationEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("destination1",1),
                new SortedSetEntry("destination2",2),
            };

            SortedSetEntry[] firstEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
            };

            SortedSetEntry[] secondEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("third",3),
                new SortedSetEntry("fourth",4),
            };

            redisSortedSetStudy.SortedSetAdd(destinationKey, destinationEntries);
            redisSortedSetStudy.SortedSetAdd(firstKey, firstEntries);
            redisSortedSetStudy.SortedSetAdd(secondKey, secondEntries);

            //集合运算后,存储为目标集合(已存在的目标集合被覆盖)
            var combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(4, combineNum);

            var destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(2, destinationMembers.FirstOrDefault(m=>m.Element=="first").Score);
            Assert.Equal(2, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);

            //目标集合再次被覆盖
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Min, CommandFlags.None);
            Assert.Equal(4, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);

            //清理
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);
        }

        [Fact]
        public void SortedSetCombineAndStore_SetOperation_Test()
        {
            //准备
            RedisKey destinationKey = "RedisStudy:SortedSet:destination";
            RedisKey firstKey = "RedisStudy:SortedSet:first";
            RedisKey secondKey = "RedisStudy:SortedSet:second";

            //删除旧数据
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);

            SortedSetEntry[] firstEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("fourth",4),
                new SortedSetEntry("sixth",6),
                new SortedSetEntry("eighth",8),
            };

            SortedSetEntry[] secondEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("fifth",5),
                new SortedSetEntry("seventh",7),
                new SortedSetEntry("ninth",9),
            };

            redisSortedSetStudy.SortedSetAdd(firstKey, firstEntries);
            redisSortedSetStudy.SortedSetAdd(secondKey, secondEntries);

            //SetOperation.Union:并集
            var combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(9, combineNum);

            //SetOperation.Intersect:交集
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Intersect, destinationKey, firstKey, secondKey, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(3, combineNum);

            //SetOperation.Difference:差集,程序抛出异常
            Assert.Throws<ArgumentOutOfRangeException>(() => redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Difference, destinationKey, firstKey, secondKey, Aggregate.Min, CommandFlags.None));

            //清理
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);
        }

        [Fact]
        public void SortedSetCombineAndStore_Aggregate_Test()
        {
            //准备
            RedisKey destinationKey = "RedisStudy:SortedSet:destination";
            RedisKey firstKey = "RedisStudy:SortedSet:first";
            RedisKey secondKey = "RedisStudy:SortedSet:second";

            //删除旧数据
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);

            SortedSetEntry[] firstEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("fourth",4),
                new SortedSetEntry("sixth",6),
                new SortedSetEntry("eighth",8),
            };

            SortedSetEntry[] secondEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1.5),
                new SortedSetEntry("second",2.5),
                new SortedSetEntry("third",3.5),
                new SortedSetEntry("fifth",5),
                new SortedSetEntry("seventh",7),
                new SortedSetEntry("ninth",9),
            };

            redisSortedSetStudy.SortedSetAdd(firstKey, firstEntries);
            redisSortedSetStudy.SortedSetAdd(secondKey, secondEntries);

            //Aggregate.Sum 求和
            var combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(9, combineNum);

            var destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(2.5, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(4.5, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(6.5, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //Aggregate.Max 最大值
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Max, CommandFlags.None);
            Assert.Equal(9, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1.5, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2.5, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3.5, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //Aggregate.Min 最小值
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Min, CommandFlags.None);
            Assert.Equal(9, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //清理
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);
        }

        [Fact]
        public void SortedSetCombineAndStoreTest()
        {
            //准备
            RedisKey destinationKey = "RedisStudy:SortedSet:destination";
            RedisKey firstKey = "RedisStudy:SortedSet:first";
            RedisKey secondKey = "RedisStudy:SortedSet:second";

            //删除旧数据
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);

            SortedSetEntry[] firstEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("fourth",4),
                new SortedSetEntry("sixth",6),
                new SortedSetEntry("eighth",8),
            };

            SortedSetEntry[] secondEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1.5),
                new SortedSetEntry("second",2.5),
                new SortedSetEntry("third",3.5),
                new SortedSetEntry("fifth",5),
                new SortedSetEntry("seventh",7),
                new SortedSetEntry("ninth",9),
            };

            redisSortedSetStudy.SortedSetAdd(firstKey, firstEntries);
            redisSortedSetStudy.SortedSetAdd(secondKey, secondEntries);

            //1
            var combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(9, combineNum);

            var destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(2.5, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(4.5, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(6.5, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //2
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, firstKey, secondKey, Aggregate.Max, CommandFlags.None);
            Assert.Equal(9, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1.5, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2.5, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3.5, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //3
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Intersect, destinationKey, firstKey, secondKey, Aggregate.Min, CommandFlags.None);
            Assert.Equal(3, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);

            //清理
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);
        }

        [Fact]
        public void SortedSetCombineAndStore_OverLoad_Test()
        {
            //准备
            RedisKey destinationKey = "RedisStudy:SortedSet:destination";
            RedisKey firstKey = "RedisStudy:SortedSet:first";
            RedisKey secondKey = "RedisStudy:SortedSet:second";

            //删除旧数据
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);

            SortedSetEntry[] firstEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("fourth",4),
                new SortedSetEntry("sixth",6),
                new SortedSetEntry("eighth",8),
            };

            SortedSetEntry[] secondEntries = new SortedSetEntry[]
            {
                new SortedSetEntry("first",1.5),
                new SortedSetEntry("second",2.5),
                new SortedSetEntry("third",3.5),
                new SortedSetEntry("fifth",5),
                new SortedSetEntry("seventh",7),
                new SortedSetEntry("ninth",9),
            };

            redisSortedSetStudy.SortedSetAdd(firstKey, firstEntries);
            redisSortedSetStudy.SortedSetAdd(secondKey, secondEntries);

            //1
            var combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, new RedisKey[] { firstKey, secondKey }, null, Aggregate.Sum, CommandFlags.None);
            Assert.Equal(9, combineNum);

            var destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(2.5, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(4.5, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(6.5, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //2
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Union, destinationKey, new RedisKey[] { firstKey, secondKey }, null, Aggregate.Max, CommandFlags.None);
            Assert.Equal(9, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1.5, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2.5, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3.5, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);
            Assert.Equal(4, destinationMembers.FirstOrDefault(m => m.Element == "fourth").Score);
            Assert.Equal(5, destinationMembers.FirstOrDefault(m => m.Element == "fifth").Score);
            Assert.Equal(6, destinationMembers.FirstOrDefault(m => m.Element == "sixth").Score);
            Assert.Equal(7, destinationMembers.FirstOrDefault(m => m.Element == "seventh").Score);
            Assert.Equal(8, destinationMembers.FirstOrDefault(m => m.Element == "eighth").Score);
            Assert.Equal(9, destinationMembers.FirstOrDefault(m => m.Element == "ninth").Score);

            //3
            combineNum = redisSortedSetStudy.SortedSetCombineAndStore(SetOperation.Intersect, destinationKey, new RedisKey[] { firstKey, secondKey }, null, Aggregate.Min, CommandFlags.None);
            Assert.Equal(3, combineNum);

            destinationMembers = redisSortedSetStudy.SortedSetRangeByRankWithScores(destinationKey);
            Assert.Equal(1, destinationMembers.FirstOrDefault(m => m.Element == "first").Score);
            Assert.Equal(2, destinationMembers.FirstOrDefault(m => m.Element == "second").Score);
            Assert.Equal(3, destinationMembers.FirstOrDefault(m => m.Element == "third").Score);

            //清理
            redisDatabase.KeyDelete(destinationKey);
            redisDatabase.KeyDelete(firstKey);
            redisDatabase.KeyDelete(secondKey);
        }
        #endregion

        #region SortedSetScan

        [Fact]
        public void SortedSetScanTest()
        {
            SortedSetEntry[] sortedSetEntries = new SortedSetEntry[]
           {
                new SortedSetEntry("first",1),
                new SortedSetEntry("second",2),
                new SortedSetEntry("third",3),
                new SortedSetEntry("five",4),
                new SortedSetEntry("six",5),
                new SortedSetEntry("seven",6),
           };
            redisSortedSetStudy.SortedSetAdd(defaultRedisKey, sortedSetEntries);

            var members = redisSortedSetStudy.SortedSetScan(defaultRedisKey,"*", 100,CommandFlags.None);
            Assert.Equal(6, members.Count());

            members = redisSortedSetStudy.SortedSetScan(defaultRedisKey);
            Assert.Equal(6, members.Count());
        }
        #endregion

        #region 清理
        public void Dispose()
        {
            redisDatabase.KeyDelete(defaultRedisKey);
        }
        #endregion
    }
}