using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Falcon.SugarApi.Test
{
    /// <summary>
    /// 枚举类型扩展方法
    /// </summary>
    [TestClass]
    public class IEnumerableExtendTest
    {
        [TestMethod("ToDataTable测试")]
        public void ToDataTableTest() {
            var sw = new Stopwatch();
            var list = new List<dynamic> {
                new{a=1,b="b1" },
                new{a=2,b="b2",c=1 },
            };
            sw.Start();
            var r = list.ToDataTable();
            sw.Stop();
            Console.WriteLine($"ToDataTable转换,共用时{sw.ElapsedMilliseconds}毫秒");
            //测试表
            Assert.IsNotNull(r);
            Assert.AreEqual(3,r.Columns.Count);
            Assert.AreEqual(2,r.Rows.Count);
            //测试列
            var col1 = r.Columns[0];
            Assert.IsTrue(col1.ColumnName=="a");
            Assert.IsTrue(col1.DataType==typeof(int));
            var col2 = r.Columns[1];
            Assert.IsTrue(col2.ColumnName=="b");
            Assert.IsTrue(col2.DataType==typeof(string));
            var col3 = r.Columns[2];
            Assert.IsTrue(col3.ColumnName=="c");
            Assert.IsTrue(col3.DataType==typeof(int));
            //测试行
            var row = r.Rows[0];
            Assert.IsTrue(row[0].ToString()=="1");
            Assert.IsTrue(row[1].ToString()=="b1");
            Assert.IsTrue(row[2].ToString()=="");
            row=r.Rows[1];
            Assert.IsTrue((int)row[0]==2);
            Assert.IsTrue((string)row[1]=="b2");
            Assert.IsTrue((int)row[2]==1);
            Console.WriteLine($"ToDataTable测试完成");

            var models = new List<ToDataTableTestModel> {
                new ToDataTableTestModel{ id=1, },
                new ToDataTableTestModel{id=2,Name="name2" },
            };
            sw.Reset();
            r=models.ToDataTable();
            sw.Stop();
            Console.WriteLine($"ToDataTable<>转换,共用时{sw.ElapsedMilliseconds}毫秒");
            //测试表
            Assert.IsNotNull(r);
            Assert.AreEqual(2,r.Columns.Count);
            Assert.AreEqual(2,r.Rows.Count);
            //测试列
            col1=r.Columns[0];
            Assert.IsTrue(col1.ColumnName=="id");
            Assert.IsTrue(col1.DataType==typeof(int));
            col2=r.Columns[1];
            Assert.IsTrue(col2.ColumnName=="Name");
            Assert.IsTrue(col2.DataType==typeof(string));
            //测试行
            row=r.Rows[0];
            Assert.IsTrue(row[0].ToString()=="1");
            Assert.IsTrue(row[1].ToString()=="");
            row=r.Rows[1];
            Assert.IsTrue((int)row[0]==2);
            Assert.IsTrue(row[1].ToString()=="name2");
            Console.WriteLine($"ToDataTable<>测试完成");


        }

        [TestMethod("Reduce测试")]
        public void ReduceTest() {
            var list = new List<int> { 1,2,3,4 };
            var sum = list.Reduce((a,b) => a+b,0);
            Assert.IsTrue(sum==10,"对数组求和错误");
            sum=list.Reduce(0,(a,b) => a+b);
            Assert.IsTrue(sum==10,"对数组求和错误");

            var people = new List<person> {
                new person{ IsMan=true,age=30 },
                new person{ IsMan=false,age=40 },
                new person{ IsMan=true,age=50 },
                new person{ IsMan=true,age=60 },
            };
            var sumage = people.Reduce((a,b) => a+(b.IsMan ? b.age : 0),0);
            Assert.IsTrue(sumage==30+50+60,"有条件求和错误");
            sumage=people.Reduce(0,(a,b) => b.IsMan ? a+b.age : a);
            Assert.IsTrue(sumage==30+50+60,"有条件求和错误");

            var men = people.Reduce((a,b) => {
                if(b.IsMan) {
                    a.Add(b);
                }
                return a;
            },new List<person>());
            foreach(var p in men) {
                Assert.IsTrue(p.IsMan,"缩减为男性集合错误!");
            }
            men=people.Reduce(new List<person>(),(a,b) => {
                if(b.IsMan) {
                    a.Add(b);
                }
                return a;
            });
            foreach(var p in men) {
                Assert.IsTrue(p.IsMan,"缩减为男性集合错误!");
            }

            var arr = new string[] { };
            var initVal = arr.Reduce((a,b) => throw new Exception("空集合不可以调用缩减方法"),"abc");
            Assert.IsTrue(initVal=="abc","空集合返回初始值,并且不调用缩减方法。");
        }

        [TestMethod("IsNullOrEmpty测试")]
        public void IsNullOrEmptyTest() {
            List<int> list = null;
            Assert.IsTrue(list.IsNullOrEmpty());
            Assert.IsFalse(list.IsNotNullOrEmpty());
            list=new List<int>();
            Assert.IsTrue(list.IsNullOrEmpty());
            Assert.IsFalse(list.IsNotNullOrEmpty());
            list.Add(1);
            Assert.IsFalse(list.IsNullOrEmpty());
            Assert.IsTrue(list.IsNotNullOrEmpty());
        }
    }

    internal class ToDataTableTestModel
    {
        public int id { get; set; }
        public string Name { get; set; }
    }

    internal class person
    {
        public int age { get; set; }
        public bool IsMan { get; set; }
    }

}