public void Test()
        {
            double[] source = new double[] { 1.0, 2.0, 3.0 };
            string[] destination = new string[] { "3", "4" };

            SetComparison<double, string, int> comparison = new SetComparison<double, string, int>(
                source, delegate(double value) { return (int)value; },
                destination, delegate(string value) { return int.Parse(value); });

            Assert.AreEqual(new Set<double>(1.0, 2.0), new Set<double>(comparison.Deleted));
            Assert.AreEqual(new Set<string>("4"), new Set<string>(comparison.Created));
            Assert.AreEqual(new Set<Pair<double, string>>(new Pair<double,string>(3.0, "3")),
                new Set<Pair<double, string>>(comparison.Unmodified));
        }
        public void When_comparing_sets(IEnumerable value1, IEnumerable value2, ComparisonResult expected)
        {
            var list1 = value1.Cast<object>().ToArray();
            var list2 = value2.Cast<object>().ToArray();

            "Given a fixture"
                .Given(() =>
                    {
                        Fixture = new Fixture();
                        Fixture.Customize(new AutoMoqCustomization());
                    });

            "And an inner comparison"
                .And(() =>
                    {
                        Inner = Fixture.Freeze<Mock<IComparison>>();

                        Inner
                            .Setup(x => x.CanCompare(It.IsAny<Type>(), It.IsAny<Type>()))
                            .Returns(true);

                        Inner
                            .Setup(x => x.Compare(It.IsAny<IComparisonContext>(), It.IsAny<object>(), It.IsAny<object>()))
                            .Returns<IComparisonContext, object, object>((c, v1, v2) => v1.Equals(v2) ? ComparisonResult.Pass : ComparisonResult.Fail);
                    });

            "And a SetComparison"
                .And(() => SUT = Fixture.Create<SetComparison>());

            "And a Comparison context object"
                .And(() => Context = new ComparisonContext("Set"));

            "When comparing enumerables"
                .When(() => Result = SUT.Compare(Context, value1, value2));

            "Then it should return {2}"
                .Then(() => Result.ShouldBe(expected));

            if (list1.Length == list2.Length)
            {
                "And it should call the inner comparison Compare for each element in the set"
                    .And(() =>
                        {
                            for (var i = 0; i < list1.Length; i++)
                            {
                                var local = i;

                                Inner.Verify(x => x.Compare(
                                    It.IsAny<ComparisonContext>(),
                                    list1[local],
                                    It.IsAny<object>()), Times.AtLeastOnce());
                            }
                        });

                if (expected == ComparisonResult.Fail)
                {
                    "And it should add a SetDifference"
                        .And(() => Context.Differences[0].ShouldBeTypeOf<SetDifference>());
                }
            }
            else
            {
                var expectedDifference = new Difference
                    {
                        Breadcrumb = "Set",
                        ChildProperty = "Count",
                        Value1 = list1.Length,
                        Value2 = list2.Length
                    };

                "And it should add a Difference"
                    .And(() => Context.Differences[0].ShouldBe(expectedDifference));
            }
        }
        public void Creating_a_SetComparison()
        {
            "Given a fixture"
                .Given(() =>
                    {
                        Fixture = new Fixture();
                        Fixture.Customize(new AutoMoqCustomization());
                    });

            "When creating an SetComparison"
                .When(() => SUT = Fixture.Create<SetComparison>());

            "Then it should implement IComparison"
                .Then(() => SUT.ShouldBeTypeOf<IComparison>());
        }
        public void Can_compare_types(Type type1, Type type2, Type elementType1, Type elementType2, bool expected)
        {
            "Given a fixture"
                .Given(() =>
                    {
                        Fixture = new Fixture();
                        Fixture.Customize(new AutoMoqCustomization());
                    });

            "And an inner comparison"
                .And(() =>
                    {
                        Inner = Fixture.Freeze<Mock<IComparison>>();

                        Inner
                            .Setup(x => x.CanCompare(It.IsAny<Type>(), It.IsAny<Type>()))
                            .Returns(true);
                    });

            "And an ListComparison"
                .And(() => SUT = Fixture.Create<SetComparison>());

            "When calling CanCompare({0}, {1})"
                .When(() => CanCompareResult = SUT.CanCompare(type1, type2));

            "It should return {2}"
                .Then(() => CanCompareResult.ShouldBe(expected));

            if (expected)
            {
                "and it should call CanCompare on the inner comparer"
                    .And(() => Inner.Verify(x => x.CanCompare(elementType1, elementType2)));
            }
        }