Example #1
0
        /// <summary>
        /// Gets the top level feature graphs, that is the graphs
        /// for features that do not have a parent feature.
        /// </summary>
        /// <returns>
        /// A collection of <see cref="FeatureGraph"/> instances representing
        /// the dependency graphs for the unparented features.
        /// </returns>
        public async Task <IEnumerable <FeatureGraph> > GetTopLevelFeatureGraphsAsync()
        {
            var features    = (await _featureManager.GetAllDbFeatures()).ToList();
            var invocations = (await _analysisReportManager.GetAllDbInvocations()).ToList();

            _logger.LogInformation("Calculating top level feature graphs for {FeatureCount} features and {InvocationCount} invocations.",
                                   features.Count, invocations.Count);

            var invocationFeatures = (from invocation in invocations
                                      select new
            {
                Invocation = invocation,
                Features = features.Where(f => f.DirectInvocationSignatures != null && f.DirectInvocationSignatures.Intersect(invocation.InvokedSignatures).Any()).ToList()
            }).ToList();

            var featuresInvocations = (from feature in features
                                       select new
            {
                Feature = feature,
                Invocations = invocationFeatures.Where(i => feature.DirectInvocationSignatures != null && feature.DirectInvocationSignatures.Contains(i.Invocation.Signature))
            }).ToList();

            var featureGraphs = new Dictionary <DbFeature, FeatureGraph>();

            foreach (var feature in featuresInvocations)
            {
                var featureGraph = new FeatureGraph
                {
                    FeatureName = feature.Feature.Title,
                    ProductName = feature.Feature.Product,
                    GroupName   = feature.Feature.Group,
                    Tags        = feature.Feature.Tags,
                    Version     = feature.Feature.Version,
                    DependsOn   = new List <FeatureGraph>()
                };

                featureGraphs.Add(feature.Feature, featureGraph);
            }

            var unparentedGraphs = new List <FeatureGraph>(featureGraphs.Values);

            foreach (var feature in featuresInvocations)
            {
                var featureGraph = featureGraphs[feature.Feature];
                var dependencies = feature.Invocations.SelectMany(i => i.Features).Select(f => featureGraphs[f]).ToList();
                dependencies.ForEach(f => unparentedGraphs.Remove(f));
                featureGraph.DependsOn.AddRange(dependencies.Distinct());
            }

            return(unparentedGraphs);
        }
        public async Task VerifyFeatureGraphsCanBeDiscovered()
        {
            // Arrange
            var callingFeature = CreateDbFeature("CallingFeature", "SomeClass.Foo()");
            var calledFeature  = CreateDbFeature("CalledFeature", "SomeOtherClass.Bar()");

            _featureManager.GetAllDbFeatures().Returns(new[] { callingFeature, calledFeature });
            _analysisReportManager.GetAllDbInvocations().Returns(new DbInvocation[]
            {
                new DbInvocation()
                {
                    Signature         = "SomeClass.Foo()",
                    InvokedSignatures = new []
                    {
                        "SomeClass.Foo(System.String)",
                        "SomeOtherClass.Bar()"
                    }
                },
                new DbInvocation()
                {
                    Signature         = "SomeOtherClass.Bar()",
                    InvokedSignatures = new []
                    {
                        "SomeOtherClass.JuiceBar()"
                    }
                }
            });

            // Act
            var target = new DependencyManager(_featureManager, _analysisReportManager, _logger);
            var graphs = (await target.GetTopLevelFeatureGraphsAsync()).ToList();

            // Assert
            graphs.Count.ShouldBe(1);
            graphs[0].FeatureName.ShouldBe("CallingFeature");
            graphs[0].DependsOn.Count.ShouldBe(1);
            graphs[0].DependsOn[0].FeatureName.ShouldBe("CalledFeature");
        }