using System;
using System.Collections.Generic;
using System.Text;

using System.Linq;
using Xunit;
using FluentAssertions;
using System.Collections;

namespace LinqStudy.Test.LinqToObject
{
    /// <summary>
    /// 序列相等
    /// </summary>
    public class SequenceEqualTest
    {
        /// <summary>
        ///  SequenceEqual
        ///  序列相等比较:所含项数量相同、内容相同、位置相同、引用类型则引用相同的对象,则两个序列相等。
        /// </summary>
        [Fact]
        public void SequenceEqual_Test()
        {
            List<Person> sequence = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
                new Person(){Id=1,Name="王五",Age=20},
            };
            List<Person> sequence1 = sequence;

            List<Person> sequence2 = sequence;

            Assert.True(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 引用类型相等:项数量相同、内容相同、位置相同、引用对象相同
        /// </summary>
        [Fact]
        public void SequenceEqual_Query_Test()
        {
            List<Person> sequence = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=2,Name="李四",Age=30},
                new Person(){Id=3,Name="王五",Age=40},
            };

            //查询结果相同,引用对象也相同。
            var sequence1 = sequence.Where(p => p.Id > 2);
            var sequence2 = sequence.Where(p => p.Age > 30);

            Assert.True(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 值类型相等:项数量相同、内容相同、位置相同
        /// </summary>
        [Fact]
        public void SequenceEqual_ValueType_Test()
        {

            List<int> sequence1 = new List<int>() { 1, 2, 3 };

            List<int> sequence2 = new List<int>() { 1, 2, 3 };

            Assert.True(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 引用不同
        /// </summary>
        [Fact]
        public void SequenceEqual_Reference_Test()
        {
            List<Person> sequence1 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
            };

            List<Person> sequence2 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
            };

            Assert.False(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 内容不一样
        /// </summary>
        [Fact]
        public void SequenceEqual_Content_Test()
        {
            List<Person> sequence1 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
                new Person(){Id=1,Name="王五",Age=20},
            };

            List<Person> sequence2 = new List<Person>()
            {
                new Person(){Id=1,Name="张三2",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
                new Person(){Id=1,Name="王五",Age=20},
            };

            Assert.False(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 数量不一样
        /// </summary>
        [Fact]
        public void SequenceEqual_Count_Test()
        {
            List<Person> sequence1 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
            };

            List<Person> sequence2 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
            };

            Assert.False(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 位置不同
        /// </summary>
        [Fact]
        public void SequenceEqual_Position_Test()
        {
            List<Person> sequence1 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
            };

            List<Person> sequence2 = new List<Person>()
            {
                new Person(){Id=1,Name="李四",Age=20},
                new Person(){Id=1,Name="张三",Age=20},
            };

            Assert.False(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 重载比较方法,实现自动义比较
        /// </summary>
        [Fact]
        public void SequenceEqual_OverrideEquals_Test()
        {
            List<StudentOverriteEquals> sequence1 = new List<StudentOverriteEquals>()
            {
                new StudentOverriteEquals(){Id=1,Name="张三",Age=20},
                new StudentOverriteEquals(){Id=1,Name="李四",Age=20},
            };

            List<StudentOverriteEquals> sequence2 = new List<StudentOverriteEquals>()
            {
                new StudentOverriteEquals(){Id=1,Name="李四",Age=20},
                new StudentOverriteEquals(){Id=1,Name="张三",Age=20},
            };

            Assert.True(sequence1.SequenceEqual(sequence2));
        }

        /// <summary>
        /// 提供自定义比较器
        /// </summary>
        [Fact]
        public void SequenceEqual_CustomEqual_Test()
        {
            List<Person> sequence1 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
            };

            List<Person> sequence2 = new List<Person>()
            {
                new Person(){Id=1,Name="张三",Age=20},
                new Person(){Id=1,Name="李四",Age=20},
            };

            Assert.True(sequence1.SequenceEqual(sequence2, new PersonEqualityComparer()));
        }
    }
}