public void Sort_reverse()
        {
            var entityTypeA = new NamedEntityType(typeof(A));

            entityTypeA.SetKey(entityTypeA.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeB = new NamedEntityType(typeof(B));

            entityTypeB.SetKey(entityTypeB.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeC = new NamedEntityType(typeof(C));

            entityTypeC.SetKey(entityTypeC.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            // C -> B -> A
            entityTypeA.AddForeignKey(entityTypeB.GetKey(), entityTypeA.AddProperty("P", typeof(int)));
            entityTypeB.AddForeignKey(entityTypeC.GetKey(), entityTypeB.AddProperty("P", typeof(int)));

            var model = new EntityTypeGraph();

            model.Populate(entityTypeA, entityTypeB, entityTypeC);

            Assert.Equal(
                new[] { entityTypeC.Name, entityTypeB.Name, entityTypeA.Name },
                model.TopologicalSort().SelectMany(e => e).Select(e => e.Name).ToArray());
        }
        public void Sort_leafy_cycle()
        {
            var entityTypeA = new NamedEntityType(typeof(A));

            entityTypeA.SetKey(entityTypeA.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeB = new NamedEntityType(typeof(B));

            entityTypeB.SetKey(entityTypeB.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeC = new NamedEntityType(typeof(C));

            entityTypeC.SetKey(entityTypeC.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            // C -> B -> C -> A
            entityTypeB.AddForeignKey(entityTypeC.GetKey(), entityTypeB.AddProperty("P", typeof(int)));
            entityTypeC.AddForeignKey(entityTypeB.GetKey(), entityTypeC.AddProperty("P", typeof(int)));
            entityTypeA.AddForeignKey(entityTypeC.GetKey(), entityTypeA.AddProperty("P", typeof(int)));

            var model = new EntityTypeGraph();

            model.Populate(entityTypeA, entityTypeB, entityTypeC);

            Assert.Equal(
                Strings.FormatCircularDependency("C -> B -> C -> A"),
                Assert.Throws <InvalidOperationException>(() => model.TopologicalSort()).Message);
        }
        public void Sort_preserves_graph()
        {
            var entityTypeA = new NamedEntityType(typeof(A));

            entityTypeA.SetKey(entityTypeA.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeB = new NamedEntityType(typeof(B));

            entityTypeB.SetKey(entityTypeB.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeC = new NamedEntityType(typeof(C));

            entityTypeC.SetKey(entityTypeC.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            // B -> A -> C
            entityTypeC.AddForeignKey(entityTypeA.GetKey(), entityTypeC.AddProperty("P", typeof(int)));
            entityTypeA.AddForeignKey(entityTypeB.GetKey(), entityTypeA.AddProperty("P", typeof(int)));

            var model = new EntityTypeGraph();

            model.Populate(entityTypeA, entityTypeB, entityTypeC);

            Assert.Equal(
                new[] { entityTypeB.Name, entityTypeA.Name, entityTypeC.Name },
                model.TopologicalSort().SelectMany(e => e).Select(e => e.Name).ToArray());

            Assert.Equal(
                new[] { entityTypeA, entityTypeB, entityTypeC },
                model.Vertices);

            Assert.Equal(
                new[] { entityTypeC },
                model.GetOutgoingNeighbours(entityTypeA));

            Assert.Equal(
                new[] { entityTypeA },
                model.GetOutgoingNeighbours(entityTypeB));

            Assert.Equal(
                new[] { entityTypeB.Name, entityTypeA.Name, entityTypeC.Name },
                model.TopologicalSort().SelectMany(e => e).Select(e => e.Name).ToArray());
        }
        public void Sort_no_edges()
        {
            var entityTypeA = new NamedEntityType(typeof(A));

            entityTypeA.SetKey(entityTypeA.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeB = new NamedEntityType(typeof(B));

            entityTypeB.SetKey(entityTypeB.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            var entityTypeC = new NamedEntityType(typeof(C));

            entityTypeC.SetKey(entityTypeC.AddProperty("Id", typeof(int), shadowProperty: true, concurrencyToken: false));

            // A B C
            var model = new EntityTypeGraph();

            model.Populate(entityTypeC, entityTypeA, entityTypeB);

            Assert.Equal(
                new[] { entityTypeC.Name, entityTypeA.Name, entityTypeB.Name, },
                model.TopologicalSort().SelectMany(e => e).Select(e => e.Name).ToArray());
        }