using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using FluentAssertions;

using Xunit;

namespace LinqStudy.Test.LinqToObject
{
    /// <summary>
    /// 查询运算符:本质定义在下面程序集中的扩展方法,少量静态方法。
    /// System.Linq.Enumerable
    /// System.Linq.Queryable
    /// </summary>
    public class BaseTest
    {
        /// <summary>
        ///  数据源为 Null,引发异常.
        /// </summary>
        /// <exception cref="ArgumentNullException">
        ///  ArgumentNullException
        /// </exception>
        /// <remarks>
        ///  对Linq操作符而言,数据源为Null时,均引发异常。
        /// </remarks>
        [Fact]
        public void DataSource_IsNull_Test()
        {
            List<Person> person = null;

            Assert.ThrowsAny<ArgumentNullException>(() => 
            {
                //引发异常
                var query = person.Where(p => p == null);
            });
        }

        /// <summary>
        ///  数据源数据项为0时,不会引发异常.
        /// </summary>
        [Fact]
        public void DataSource_Item_0_Test()
        {
            List<Person> person = new List<Person>();

            //数据源为没有任何内容项时,即 Count=0,不会引发异常。
            Action action = () => 
            {
                //查不到任何数据,不返回null,而是返回 Count=0的对象。
                person.Where(p => p == null).ToList();
            };

            //不引发异常
            action.Should().NotThrow();
        }

        /// <summary>
        ///  数据源数据项为0时,查询等操作,不返回null,而返回“0数据项的”IEnumerable<T>对象。
        /// </summary>
        [Fact]
        public void DataSource_Item0_Return_Test()
        {
            List<Person> person = new List<Person>();

            //数据源为没有任何内容项时,即 Count=0,不会引发异常。
            Action action = () =>
            {
                //查不到任何数据,不返回null,而是返回 Count=0的对象。
                person.Where(p => p == null).ToList();
            };

            //不引发异常
            action.Should().NotThrow();
        }

        /// <summary>
        ///  查询不到数据项时,不返回null,而是返回“0数据项的”IEnumerable<T>对象
        /// </summary>
        [Fact]
        public void NoQueryItem_Return_Test()
        {
            List<Person> person = new List<Person>()
            {
                new Person(){ Id=1,Name="小屁孩",Age=87},
                new Person(){ Id=2,Name="小屁孩",Age=45},
                new Person(){ Id=3,Name="小屁孩",Age=55},
                new Person(){ Id=4,Name="小屁孩",Age=23},
            };

            //查不到数据时,返回Count=0的IEnumerable<T>对象
            var result = person.Where(p => p.Age < 10).ToList();

            Assert.Empty(result);
        }
    }
}