public void SortingCircular()
        {
            // Circular dependencies are not supported in Rhetos,
            // but this test verifies robustness of the algorithm implementation
            // and error detection.

            var cA = new C1 {
                Name = "A"
            };
            var cB = new C1 {
                Name = "B"
            };

            cA.Ref1 = cB;
            cB.Ref1 = cA;
            var cInit = new InitializationConcept {
                RhetosVersion = "init"
            };
            var cDependant = new C2 {
                Name = "dep", Ref1 = cA, Ref2 = cB
            };

            var testData = new List <IConceptInfo> {
                cDependant, cA, cB, cInit
            };
            var dslContainer = new DslContainerAccessor {
                ResolvedConcepts = testData
            };

            TestUtility.ShouldFail <FrameworkException>(
                () => dslContainer.SortReferencesBeforeUsingConcept(InitialConceptsSort.None),
                "C1 A");
        }
Exemplo n.º 2
0
        public void UnresolvedReferences()
        {
            var dslContainer = new DslContainerAccessor();

            var missing = new C0 {
                Name = "X"
            };

            var a = new C0 {
                Name = "A"
            };                             // should be resolved
            var b = new C1 {
                Name = "B", Ref1 = a
            };                                       // should be resolved
            var c = new C1 {
                Name = "C", Ref1 = b
            };                                       // should be resolved
            var d = new C2 {
                Name = "D", Ref1 = c, Ref2 = missing
            };                                                       // unresolved
            var i = new C1 {
                Name = "I", Ref1 = d
            };                                       // resolved, but references unresolved
            var j = new C1 {
                Name = "J", Ref1 = i
            };                                       // resolved, but indirectly references unresolved

            var g = new C2 {
                Name = "G", Ref2 = missing
            };                                             // unresolved
            var h = new C1 {
                Name = "H"
            };                             // resolved, but references unresolved

            g.Ref1 = h;
            h.Ref1 = g;

            var newConcepts = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { a }).NewUniqueConcepts;

            Assert.AreEqual("A", TestUtility.DumpSorted(newConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            newConcepts = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { i, d, c, b, g, h, i, j, a }).NewUniqueConcepts;
            Assert.AreEqual("B, C, D, G, H, I, J", TestUtility.DumpSorted(newConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A, B, C", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            newConcepts = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { i, d, c, b, g, h, i, j, a }).NewUniqueConcepts;
            Assert.AreEqual("", TestUtility.DumpSorted(newConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A, B, C", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            var ex = TestUtility.ShouldFail <DslSyntaxException>(
                () => dslContainer.ReportErrorForUnresolvedConcepts(),
                "Referenced concept is not defined in DSL scripts",
                missing.GetUserDescription());

            Assert.IsTrue(new IConceptInfo[] { d, i, j, g, h }
                          .Any(conceptInfo => ex.Message.Contains(conceptInfo.GetUserDescription())));
        }
        public void SortEmpty()
        {
            var testData     = new List <IConceptInfo> {
            };
            var dslContainer = new DslContainerAccessor {
                ResolvedConcepts = testData
            };

            dslContainer.SortReferencesBeforeUsingConcept(InitialConceptsSort.None);
            Assert.AreEqual(
                TestUtility.Dump(testData, c => c.GetKey()),
                TestUtility.Dump(dslContainer.ResolvedConcepts, c => c.GetKey()));
        }
Exemplo n.º 4
0
        private void TestDifferentConceptSameKey(ListOfTuples <IConceptInfo[], string, string, string[]> newConceptsSets)
        {
            var dslContainer = new DslContainerAccessor();

            foreach (var newConceptsSet in newConceptsSets)
            {
                if (newConceptsSet.Item4 == null)
                {
                    var report = dslContainer.AddNewConceptsAndReplaceReferences(newConceptsSet.Item1);
                    Assert.AreEqual(newConceptsSet.Item2, TestUtility.DumpSorted(report.NewUniqueConcepts, item => item.GetShortDescription()));
                    Assert.AreEqual(newConceptsSet.Item3, TestUtility.DumpSorted(dslContainer.Concepts, item => item.GetShortDescription()));
                }
                else
                {
                    TestUtility.ShouldFail(() => dslContainer.AddNewConceptsAndReplaceReferences(newConceptsSet.Item1), newConceptsSet.Item4);
                }
            }
        }
        public void SortInitOnly()
        {
            var cInit = new InitializationConcept {
                RhetosVersion = "init"
            };

            var testData = new List <IConceptInfo> {
                cInit
            };
            var dslContainer = new DslContainerAccessor {
                ResolvedConcepts = testData
            };

            dslContainer.SortReferencesBeforeUsingConcept(InitialConceptsSort.None);
            Assert.AreEqual(
                TestUtility.Dump(testData, c => c.GetKey()),
                TestUtility.Dump(dslContainer.ResolvedConcepts, c => c.GetKey()));
        }
Exemplo n.º 6
0
        public void UnresolvedReferences()
        {
            var dslContainer = new DslContainerAccessor();

            var missing = new C0 { Name = "X" };

            var a = new C0 { Name = "A" }; // should be resolved
            var b = new C1 { Name = "B", Ref1 = a }; // should be resolved
            var c = new C1 { Name = "C", Ref1 = b }; // should be resolved
            var d = new C2 { Name = "D", Ref1 = c, Ref2 = missing }; // unresolved
            var i = new C1 { Name = "I", Ref1 = d }; // resolved, but references unresolved
            var j = new C1 { Name = "J", Ref1 = i }; // resolved, but indirectly references unresolved

            var e = new C1 { Name = "E" }; // should be resolved, circular reference should not be a problem
            var f = new C1 { Name = "F" }; // should be resolved, circular reference should not be a problem
            e.Ref1 = f;
            f.Ref1 = e;

            var g = new C2 { Name = "G", Ref2 = missing }; // unresolved
            var h = new C1 { Name = "H" }; // resolved, but references unresolved
            g.Ref1 = h;
            h.Ref1 = g;

            var newConcepts = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { a }).NewUniqueConcepts;
            Assert.AreEqual("A", TestUtility.DumpSorted(newConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            newConcepts = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { i, d, c, b, e, f, g, h, i, j, a }).NewUniqueConcepts;
            Assert.AreEqual("B, C, D, E, F, G, H, I, J", TestUtility.DumpSorted(newConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A, B, C, E, F", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            newConcepts = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { i, d, c, b, e, f, g, h, i, j, a }).NewUniqueConcepts;
            Assert.AreEqual("", TestUtility.DumpSorted(newConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A, B, C, E, F", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            var ex = TestUtility.ShouldFail<DslSyntaxException>(
                () => dslContainer.ReportErrorForUnresolvedConcepts(),
                "Referenced concept is not defined in DSL scripts",
                missing.GetUserDescription());

            Assert.IsTrue(new IConceptInfo[] { d, i, j, g, h }
                .Any(conceptInfo => ex.Message.Contains(conceptInfo.GetUserDescription())));
        }
Exemplo n.º 7
0
        public void CircularReferences()
        {
            var dslContainer = new DslContainerAccessor();

            var a = new C0 {
                Name = "A"
            };                             // should be resolved
            var b = new C1 {
                Name = "B"
            };                             // referencing circular dependency
            var c = new C1 {
                Name = "C"
            };                             // circular dependency
            var d = new C1 {
                Name = "D"
            };                             // circular dependency
            var e = new C1 {
                Name = "E"
            };                             // referencing circular dependency

            b.Ref1 = c;
            c.Ref1 = d;
            d.Ref1 = c;
            e.Ref1 = d;

            var report = dslContainer.AddNewConceptsAndReplaceReferences(new IConceptInfo[] { a, b, c, d, e });

            Assert.AreEqual("A, B, C, D, E", TestUtility.DumpSorted(report.NewUniqueConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A", TestUtility.DumpSorted(report.NewlyResolvedConcepts, item => ((dynamic)item).Name));
            Assert.AreEqual("A", TestUtility.DumpSorted(dslContainer.Concepts, item => ((dynamic)item).Name));

            var ex = TestUtility.ShouldFail <DslSyntaxException>(
                () => dslContainer.ReportErrorForUnresolvedConcepts(),
                "circular dependency");

            // Circular dependency error message should contain only the circle, not external references to it.
            Assert.IsTrue(new IConceptInfo[] { c, d }.All(conceptInfo => ex.Message.Contains(conceptInfo.GetUserDescription())));
            Assert.IsFalse(new IConceptInfo[] { b, e }.Any(conceptInfo => ex.Message.Contains(conceptInfo.GetUserDescription())));
        }
Exemplo n.º 8
0
        public void Sorting()
        {
            var cInit = new InitializationConcept {
                RhetosVersion = "init"
            };
            var c01 = new C0 {
                Name = "1"
            };
            var c02 = new C0 {
                Name = "2"
            };
            var c03 = new C0 {
                Name = "3"
            };
            var cB1 = new CBase {
                Name = "1"
            };
            var cB2 = new CBase {
                Name = "2"
            };
            var c2Dependant = new C2 {
                Name = "dep", Ref1 = c01, Ref2 = cB2
            };

            var testData = new List <IConceptInfo> {
                c02, c01, cB2, c2Dependant, cInit, c03, cB1
            };

            // The expected positions may somewhat change if the sorting algorithm internals change.
            var tests = new List <(string SortMethod, List <IConceptInfo> ExpectedResult)>
            {
                // cInit always goes first. cDependant does not need to move because it is after referenced c1 and c5.
                ("None", new List <IConceptInfo> {
                    cInit, c02, c01, cB2, c2Dependant, c03, cB1
                }),

                // cB2 is pushed before c2Dependant, to respect dependency precedence.
                ("Key", new List <IConceptInfo> {
                    cInit, c01, c02, c03, cB2, c2Dependant, cB1
                }),

                // c01 is pushed before c2Dependant, to respect dependency precedence.
                ("KeyDescending", new List <IConceptInfo> {
                    cInit, cB2, cB1, c01, c2Dependant, c03, c02
                }),
            };

            foreach (var test in tests)
            {
                var configuration = new MockConfiguration {
                    { "CommonConcepts.Debug.SortConcepts", test.SortMethod }
                };
                var dslContainer = new DslContainerAccessor(configuration);
                dslContainer.ResolvedConcepts = testData;
                dslContainer.SortReferencesBeforeUsingConcept();
                Assert.AreEqual(
                    TestUtility.Dump(test.ExpectedResult, c => c.GetKey()),
                    TestUtility.Dump(dslContainer.ResolvedConcepts, c => c.GetKey()),
                    test.SortMethod);
            }
        }
Exemplo n.º 9
0
 private void TestDifferentConceptSameKey(ListOfTuples<IConceptInfo[], string, string, string[]> newConceptsSets)
 {
     var dslContainer = new DslContainerAccessor();
     foreach (var newConceptsSet in newConceptsSets)
     {
         if (newConceptsSet.Item4 == null)
         {
             var report = dslContainer.AddNewConceptsAndReplaceReferences(newConceptsSet.Item1);
             Assert.AreEqual(newConceptsSet.Item2, TestUtility.DumpSorted(report.NewUniqueConcepts, item => item.GetShortDescription()));
             Assert.AreEqual(newConceptsSet.Item3, TestUtility.DumpSorted(dslContainer.Concepts, item => item.GetShortDescription()));
         }
         else
         {
             TestUtility.ShouldFail(() => dslContainer.AddNewConceptsAndReplaceReferences(newConceptsSet.Item1), newConceptsSet.Item4);
         }
     }
 }
Exemplo n.º 10
0
        public void Sorting()
        {
            var cInit = new InitializationConcept {
                RhetosVersion = "init"
            };
            var c01 = new C0 {
                Name = "1"
            };
            var c02 = new C0 {
                Name = "2"
            };
            var c03 = new C0 {
                Name = "3"
            };
            var cB1 = new CBase {
                Name = "1"
            };
            var cB2 = new CBase {
                Name = "2"
            };
            var c2Dependant = new C2 {
                Name = "dep", Ref1 = c01, Ref2 = cB2
            };

            var testData = new List <IConceptInfo> {
                c02, c01, cB2, c2Dependant, cInit, c03, cB1
            };

            // The expected positions may somewhat change if the sorting algorithm internals change.
            var tests = new List <(InitialConceptsSort SortMethod, List <IConceptInfo> ExpectedResult)>
            {
                // cInit always goes first. cDependant is moved to the end, even though it does not need to be moved
                // because it is after referenced c01 and cB2. Putting all level 2 concept after level 1,
                // instead of keeping the initial sort based on dynamic evaluation, should result with
                // less changes in the final generated code.
                (InitialConceptsSort.None, new List <IConceptInfo> {
                    cInit, c02, c01, cB2, c03, cB1, c2Dependant
                }),

                // Keeping the InitialConceptsSort ordering between the concepts of the same level.
                (InitialConceptsSort.Key, new List <IConceptInfo> {
                    cInit, c01, c02, c03, cB1, cB2, c2Dependant
                }),

                // Keeping the InitialConceptsSort ordering between the concepts of the same level.
                (InitialConceptsSort.KeyDescending, new List <IConceptInfo> {
                    cInit, cB2, cB1, c03, c02, c01, c2Dependant
                }),
            };

            foreach (var test in tests)
            {
                var dslContainer = new DslContainerAccessor {
                    ResolvedConcepts = testData
                };
                dslContainer.SortReferencesBeforeUsingConcept(test.SortMethod);
                Assert.AreEqual(
                    TestUtility.Dump(test.ExpectedResult, c => c.GetKey()),
                    TestUtility.Dump(dslContainer.ResolvedConcepts, c => c.GetKey()),
                    $"SortConceptsMethod: {test.SortMethod}");
            }
        }