public void TriggerTransitionCondition_NotTaken_WhenMissingStartingContextParameter(string key)
        {
            Graph graph = new Graph();

            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();

            Transition transition = new Transition(waitForManualExit: false);

            transition.AddTransitionCondition(new TriggerTransitionCondition(key));
            NodeTransition nodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = transition
            };

            graph.AddOutgoingTransitionForNode(nodeA, nodeTransition);

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasTriggerParameterKey(Arg.Any <string>()).Returns(false);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool entered = false;

            nodeB.OnEnter += () => { entered = true; };

            graph.Start();
            Assert.IsFalse(entered);
        }
Ejemplo n.º 2
0
        public void Entering_TheSameNode_MultipleTimesWithCascade_Works()
        {
            Graph graph = new Graph();

            // A -> B <-> C
            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();
            Node nodeC = graph.MakeNode();

            Transition     abTransition     = new Transition(waitForManualExit: false);
            NodeTransition abNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = abTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, abNodeTransition);

            Transition bcTransition = new Transition(waitForManualExit: false);

            bcTransition.AddTransitionCondition(new TriggerTransitionCondition("BGoToC"));
            NodeTransition bcNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeC.Id }, transition = bcTransition
            };

            graph.AddOutgoingTransitionForNode(nodeB, bcNodeTransition);

            Transition cbTransition = new Transition(waitForManualExit: false);

            cbTransition.AddTransitionCondition(new TriggerTransitionCondition("CGoToB"));
            NodeTransition cbNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = cbTransition
            };

            graph.AddOutgoingTransitionForNode(nodeC, cbNodeTransition);

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasTriggerParameterKey(Arg.Is("BGoToC")).Returns(true);
            stubContext.HasTriggerParameterKey(Arg.Is("CGoToB")).Returns(true);
            // returns true then false
            stubContext.HasTrigger(Arg.Is("BGoToC")).Returns(true, false);
            // returns true then false
            stubContext.HasTrigger(Arg.Is("CGoToB")).Returns(true, false);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            int bEnteredCount = 0;

            nodeB.OnEnter += () => { bEnteredCount++; };
            int cEnteredCount = 0;

            nodeC.OnEnter += () => { cEnteredCount++; };

            graph.Start();

            Assert.AreEqual(2, bEnteredCount);
            Assert.AreEqual(1, cEnteredCount);
        }
Ejemplo n.º 3
0
        public async Task DependenciesGraphProvider_GetChildrenAsync_NodeDoesNotExistAnyMore()
        {
            // Arrange
            var projectPath  = @"c:\myproject\project.csproj";
            var nodeIdString = @"file:///[MyProvider;MyNodeItemSpec]";
            var nodeJson     = @"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}";
            var existingNode = IDependencyNodeFactory.FromJson(nodeJson);
            var inputNode    = IGraphContextFactory.CreateNode(projectPath, nodeIdString, existingNode);

            var mockGraphContext = IGraphContextFactory.Implement(CancellationToken.None,
                                                                  new HashSet <GraphNode>()
            {
                inputNode
            },
                                                                  GraphContextDirection.Contains);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();
            var mockProjectContextProvider =
                IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);

            var provider = new DependenciesGraphProvider(mockProjectContextProvider,
                                                         Mock.Of <SVsServiceProvider>(),
                                                         new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act (if something is wrong, there would be exception since we did not provide more mocks)
            await provider.BeginGetGraphDataAsync(mockGraphContext);
        }
        public void IntTransitionCondition_TakenWhenMatching_NotTakenWhenNotMatching(string key, int targetValue, bool expectedEntered)
        {
            Graph graph = new Graph();

            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();

            Transition transition = new Transition(waitForManualExit: false);

            transition.AddTransitionCondition(new IntTransitionCondition(key, targetValue));
            NodeTransition nodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = transition
            };

            graph.AddOutgoingTransitionForNode(nodeA, nodeTransition);

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasIntParameterKey(Arg.Is("Key")).Returns(true);
            stubContext.GetInt(Arg.Is("Key")).Returns(5);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool entered = false;

            nodeB.OnEnter += () => { entered = true; };

            graph.Start();
            Assert.AreEqual(expectedEntered, entered);
        }
Ejemplo n.º 5
0
        public async Task DependenciesGraphProvider_GetChildrenAsync_InvalidNodeData_NoId(
            bool canceledToken, string projectPath, string nodeJson)
        {
            // Arrange
            var nodeIdString = @"";
            var tcs          = new CancellationTokenSource();

            if (canceledToken)
            {
                tcs.Cancel();
            }

            var existingNode = IDependencyNodeFactory.FromJson(nodeJson);
            var inputNode    = IGraphContextFactory.CreateNode(projectPath, nodeIdString, existingNode);

            var mockGraphContext = IGraphContextFactory.Implement(tcs.Token,
                                                                  new HashSet <GraphNode>()
            {
                inputNode
            },
                                                                  GraphContextDirection.Contains);

            var provider = new DependenciesGraphProvider(IDependenciesGraphProjectContextProviderFactory.Create(),
                                                         Mock.Of <SVsServiceProvider>(),
                                                         new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act (if something is wrong, there would be exception since we did not provide more mocks)
            await provider.BeginGetGraphDataAsync(mockGraphContext);
        }
Ejemplo n.º 6
0
        public async Task DependenciesGraphProvider_GetChildrenAsync()
        {
            var projectPath  = @"c:\myproject\project.csproj";
            var nodeIdString = @"file:///[MyProvider;MyNodeItemSpec]";

            var nodeJson      = @"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}";
            var childNodeJson = @"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec""
    }
}";

            var existingNode      = IDependencyNodeFactory.FromJson(nodeJson);
            var existingChildNode = IDependencyNodeFactory.FromJson(childNodeJson);

            existingNode.Children.Add(existingChildNode);

            var inputNode   = IGraphContextFactory.CreateNode(projectPath, nodeIdString, existingNode);
            var outputNodes = new HashSet <GraphNode>();

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.AddTestDependencyNodes(new[] { existingNode });

            var mockProjectContextProvider = IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);
            var mockGraphContext           = IGraphContextFactory.ImplementGetChildrenAsync(inputNode,
                                                                                            trackChanges: true,
                                                                                            outputNodes: outputNodes);

            var provider = new TestableDependenciesGraphProvider(mockProjectContextProvider,
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.Equal(1, outputNodes.Count);
            var childGraphNode = outputNodes.First();

            Assert.Equal(existingChildNode, childGraphNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.False(childGraphNode.GetValue <bool>(DgmlNodeProperties.ContainsChildren));
            var childProjectPath = childGraphNode.Id.GetNestedValueByName <Uri>(CodeGraphNodeIdName.Assembly);

            Assert.Equal(projectPath.Replace('\\', '/'), childProjectPath.AbsolutePath);
            var childSubTreeProvider = childGraphNode.GetValue(DependenciesGraphSchema.ProviderProperty);

            Assert.True(childSubTreeProvider is IProjectDependenciesSubTreeProviderMock);
            Assert.Equal("MyDefaultTestProvider", ((IProjectDependenciesSubTreeProviderMock)childSubTreeProvider).ProviderTestType);
            Assert.Equal(1, childGraphNode.IncomingLinkCount);
            Assert.Equal(1, provider.GetRegisteredSubTreeProviders().Count());
        }
 public static IGraphContext MakeContext()
 {
     if (GraphContextFactoryLocator._factory == null)
     {
         GraphContextFactoryLocator._factory = new DefaultGraphContextFactory();
     }
     return(GraphContextFactoryLocator._factory.MakeContext());
 }
Ejemplo n.º 8
0
        public async Task DependenciesGraphProvider_CheckChildrenAsync_TopLevelNodeWithoutId_ShouldGetProviderFromParent()
        {
            var projectPath         = @"c:\myproject\project.csproj";
            var parentNodeIdString  = @"file:///[MyProvider;;;]";
            var nodeFilePath        = @"c:/myproject/MyNodeItemSpec";
            var mockVsHierarchyItem = IVsHierarchyItemFactory.ImplementProperties(
                text: "MyNodeItemSpec",
                parentCanonicalName: parentNodeIdString);
            var inputNode = IGraphContextFactory.CreateNode(projectPath,
                                                            nodeFilePath,
                                                            hierarchyItem: mockVsHierarchyItem);
            var rootNode          = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyRootNode""
    }
}");
            var existingNode      = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");
            var existingChildNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec""
    }   
}");

            rootNode.AddChild(existingNode);
            existingNode.Children.Add(existingChildNode);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.RootNode = rootNode;
            mockProvider.AddTestDependencyNodes(new[] { existingNode });

            var mockProjectContextProvider = IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);
            var mockGraphContext           = IGraphContextFactory.ImplementContainsChildren(inputNode);

            var provider = new DependenciesGraphProvider(mockProjectContextProvider,
                                                         Mock.Of <SVsServiceProvider>(),
                                                         new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.True(inputNode.GetValue <bool>(DgmlNodeProperties.ContainsChildren));
            Assert.NotNull(inputNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.Equal(existingNode, inputNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.True(inputNode.GetValue(DependenciesGraphSchema.ProviderProperty) is IProjectDependenciesSubTreeProviderMock);
        }
Ejemplo n.º 9
0
        public async Task DependenciesGraphProvider_CheckChildrenAsync_HasChildrenFalse()
        {
            var projectPath  = @"c:\myproject\project.csproj";
            var nodeIdString = @"file:///[MyProvider;MyNodeItemSpec]";

            var mockVsHierarchyItem = IVsHierarchyItemFactory.ImplementProperties(text: "MyNodeItemSpec");
            var inputNode           = IGraphContextFactory.CreateNode(projectPath,
                                                                      nodeIdString,
                                                                      hierarchyItem: mockVsHierarchyItem);
            var rootNode     = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyRootNode""
    }
}");
            var existingNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");

            rootNode.AddChild(existingNode);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.RootNode = rootNode;
            mockProvider.AddTestDependencyNodes(new[] { existingNode });

            var mockProjectContextProvider = IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);

            var mockGraphContext = IGraphContextFactory.Implement(CancellationToken.None,
                                                                  new HashSet <GraphNode>()
            {
                inputNode
            },
                                                                  GraphContextDirection.Self,
                                                                  new List <GraphProperty> {
                DgmlNodeProperties.ContainsChildren
            });

            var provider = new DependenciesGraphProvider(mockProjectContextProvider,
                                                         Mock.Of <SVsServiceProvider>(),
                                                         new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.False(inputNode.GetValue <bool>(DgmlNodeProperties.ContainsChildren));
            Assert.NotNull(inputNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.Equal(existingNode, inputNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.True(inputNode.GetValue(DependenciesGraphSchema.ProviderProperty) is IProjectDependenciesSubTreeProviderMock);
        }
Ejemplo n.º 10
0
        public void MultipleTransitions_HappenCorrectly()
        {
            Graph graph = new Graph();

            // A -> B -> C
            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();
            Node nodeC = graph.MakeNode();

            Transition bTransition = new Transition(waitForManualExit: false);

            bTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition bNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = bTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, bNodeTransition);

            Transition cTransition = new Transition(waitForManualExit: false);

            cTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition cNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeC.Id }, transition = cTransition
            };

            graph.AddOutgoingTransitionForNode(nodeB, cNodeTransition);

            // CLONING CODE
            graph = Graph.DeepClone(graph);

            nodeA = graph.LoadNodeById(nodeA.Id);
            nodeB = graph.LoadNodeById(nodeB.Id);
            nodeC = graph.LoadNodeById(nodeC.Id);
            // END CLONING CODE

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasIntParameterKey(Arg.Is("Key")).Returns(true);
            stubContext.GetInt(Arg.Is("Key")).Returns(5);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool bEntered = false;

            nodeB.OnEnter += () => { bEntered = true; };
            bool cEntered = false;

            nodeC.OnEnter += () => { cEntered = true; };

            graph.Start();
            Assert.IsTrue(bEntered);
            Assert.IsTrue(cEntered);
        }
Ejemplo n.º 11
0
        public async Task DependenciesGraphProvider_GetChildrenAsync_WhenPreFilledFolderNode_ShouldNotRefresh()
        {
            // Arrange
            var projectPath   = @"c:\myproject\project.csproj";
            var nodeIdString  = @"file:///[MyProvider;MyNodeItemSpec]";
            var nodeJson      = @"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}";
            var childNodeJson = @"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec""
    }
}";

            var existingNode      = IDependencyNodeFactory.FromJson(nodeJson, DependencyNode.PreFilledFolderNode);
            var existingChildNode = IDependencyNodeFactory.FromJson(childNodeJson, DependencyNode.PreFilledFolderNode);

            existingNode.Children.Add(existingChildNode);

            var inputNode   = IGraphContextFactory.CreateNode(projectPath, nodeIdString, existingNode);
            var outputNodes = new HashSet <GraphNode>();

            var mockGraphContext = IGraphContextFactory.ImplementGetChildrenAsync(inputNode,
                                                                                  trackChanges: true,
                                                                                  outputNodes: outputNodes);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();
            var mockProjectContextProvider =
                IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);

            var provider = new DependenciesGraphProvider(mockProjectContextProvider,
                                                         Mock.Of <SVsServiceProvider>(),
                                                         new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.Equal(1, outputNodes.Count);
            var childGraphNode = outputNodes.First();

            Assert.Equal(existingChildNode,
                         childGraphNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.True(childGraphNode.GetValue <bool>(DgmlNodeProperties.ContainsChildren));
            Assert.True(childGraphNode.GetValue(
                            DependenciesGraphSchema.ProviderProperty) is IProjectDependenciesSubTreeProviderMock);
            Assert.Equal(1, childGraphNode.IncomingLinkCount);
        }
        public void IntTransitionCondition_TakesCorrectTransition()
        {
            Graph graph = new Graph();

            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();
            Node nodeC = graph.MakeNode();

            Transition bTransition = new Transition(waitForManualExit: false);

            bTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition bNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = bTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, bNodeTransition);

            Transition cTransition = new Transition(waitForManualExit: false);

            cTransition.AddTransitionCondition(new IntTransitionCondition("Key", 10));
            NodeTransition cNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeC.Id }, transition = cTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, cNodeTransition);

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasIntParameterKey(Arg.Is("Key")).Returns(true);
            stubContext.GetInt(Arg.Is("Key")).Returns(10);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool bEntered = false;

            nodeB.OnEnter += () => { bEntered = true; };
            bool cEntered = false;

            nodeC.OnEnter += () => { cEntered = true; };

            graph.Start();
            Assert.IsFalse(bEntered);
            Assert.IsTrue(cEntered);
        }
Ejemplo n.º 13
0
        public async Task DependenciesGraphProvider_CheckChildrenAsync_InvalidNodeData(
            bool canceledToken, string projectPath, string nodeIdString, bool invalidProvider)
        {
            var inputNode = IGraphContextFactory.CreateNode(projectPath, nodeIdString);

            var tcs = new CancellationTokenSource();

            if (canceledToken)
            {
                tcs.Cancel();
            }

            var mockGraphContext = IGraphContextFactory.Implement(tcs.Token,
                                                                  new HashSet <GraphNode>()
            {
                inputNode
            },
                                                                  GraphContextDirection.Self,
                                                                  new List <GraphProperty> {
                DgmlNodeProperties.ContainsChildren
            });
            IProjectDependenciesSubTreeProviderMock mockProvider = invalidProvider
                    ? null
                    : new IProjectDependenciesSubTreeProviderMock();
            var mockProjectContextProvider =
                IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);

            var provider = new DependenciesGraphProvider(mockProjectContextProvider,
                                                         Mock.Of <SVsServiceProvider>(),
                                                         new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.False(inputNode.GetValue <bool>(DgmlNodeProperties.ContainsChildren));
            Assert.Null(inputNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            if (invalidProvider)
            {
                Assert.Null(inputNode.GetValue(DependenciesGraphSchema.ProviderProperty));
            }
        }
        public void PopulateStartingContextParameters_CalledWithStartingParameters()
        {
            Graph graph = new Graph();
            GraphContextParameter startingParameter = new GraphContextParameter {
                type = GraphContextParameterType.Int, key = "Key"
            };

            graph.AddStartingContextParameter(startingParameter);

            IGraphContext mockContext = Substitute.For <IGraphContext>();

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(mockContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            graph.Start();

            mockContext.Received().PopulateStartingContextParameters(Arg.Is <IList <GraphContextParameter> >(list => list.Contains(startingParameter)));
        }
Ejemplo n.º 15
0
        public void BoolTransitionCondition_MatchesOtherTests_AfterSerializingAndDeserializing(string key, bool targetValue, bool expectedEntered)
        {
            Graph graph = new Graph();

            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();

            Transition transition = new Transition(waitForManualExit: false);

            BoolTransitionCondition condition = new BoolTransitionCondition(key, targetValue);
            // NEW CODE
            string serialized = TransitionConditionSerializer.Serialize(condition);
            ITransitionCondition deserialized = TransitionConditionSerializer.Deserialize(serialized);

            transition.AddTransitionCondition(deserialized);
            // END NEW CODE

            NodeTransition nodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = transition
            };

            graph.AddOutgoingTransitionForNode(nodeA, nodeTransition);

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasBoolParameterKey(Arg.Is("Key")).Returns(true);
            stubContext.GetBool(Arg.Is("Key")).Returns(true);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool entered = false;

            nodeB.OnEnter += () => { entered = true; };

            graph.Start();
            Assert.AreEqual(expectedEntered, entered);
        }
Ejemplo n.º 16
0
 public GraphQLServerMiddleware(
     RequestDelegate next,
     IGraphContextFactory graphContextFactory,
     IGraphExecutor executor,
     IGraphSchemaFormatter schemaFormatter,
     IGraphSchemaProvider schemaProvider,
     IOptions <GraphOptions> graphOptionsAccessor,
     IOptions <GraphServerOptions> serverOptionsAccessor,
     IGraphSchemaConverter schemaConverter,
     ILogger <GraphQLServerMiddleware> logger)
 {
     _next = next ?? throw new ArgumentNullException(nameof(next));
     _graphContextFactory = graphContextFactory ?? throw new ArgumentNullException(nameof(graphContextFactory));
     _executor            = executor ?? throw new ArgumentNullException(nameof(executor));
     _schemaFormatter     = schemaFormatter ?? throw new ArgumentNullException(nameof(schemaFormatter));
     _schemaProvider      = schemaProvider ?? throw new ArgumentNullException(nameof(schemaProvider));
     _graphOptions        = (graphOptionsAccessor ?? throw new ArgumentNullException(nameof(graphOptionsAccessor))).Value;
     _serverOptions       = (serverOptionsAccessor ?? throw new ArgumentNullException(nameof(serverOptionsAccessor))).Value;
     _logger          = logger ?? throw new ArgumentNullException(nameof(logger));
     _schemaConverter = schemaConverter ?? throw new ArgumentNullException(nameof(schemaConverter));
     _log4Error       = LoggerMessage.Define <DateTimeOffset, string, string>(LogLevel.Error, 0, "[{0}]Unhandled exception. Operation: {1}. Detailed information: {2}");
 }
Ejemplo n.º 17
0
        public async Task DependenciesGraphProvider_TrackChangesAsync_WithContextProject()
        {
            var projectPath        = @"c:\myproject\project.csproj";
            var contextProjectPath = @"c:\mycontextproject\project.csproj";
            var nodeIdString       = @"file:///[MyProvider;MyNodeItemSpec]";
            var inputNode          = IGraphContextFactory.CreateNode(projectPath, nodeIdString);

            var existingNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");

            existingNode.Id.ContextProject = contextProjectPath;
            var existingChildNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpecExisting""
    }
}");

            var existingRefreshedNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");

            existingRefreshedNode.Id.ContextProject = contextProjectPath;

            var newChildNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpecNew""
    }
}");

            existingNode.Children.Add(existingChildNode);
            existingRefreshedNode.AddChild(newChildNode);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.AddTestDependencyNodes(new[] { existingRefreshedNode });

            inputNode.SetValue(DependenciesGraphSchema.DependencyNodeProperty, existingNode);
            inputNode.SetValue(DependenciesGraphSchema.ProviderProperty, mockProvider);

            var outputNodes      = new HashSet <GraphNode>();
            var mockGraphContext = IGraphContextFactory.ImplementTrackChanges(inputNode, outputNodes);

            var updatedProjectContext =
                IDependenciesGraphProjectContextProviderFactory.ImplementProjectContext(contextProjectPath);

            var provider = new TestableDependenciesGraphProvider(IDependenciesGraphProjectContextProviderFactory.Create(),
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            provider.AddExpandedGraphContext(mockGraphContext);

            // Act
            await provider.TrackChangesAsync(updatedProjectContext);

            // Assert
            Assert.Equal(1, outputNodes.Count);
            var outputNode       = outputNodes.First();
            var outputDependency = outputNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty);

            Assert.Equal(newChildNode.Id, outputDependency.Id);
            var childProjectPath = outputNode.Id.GetNestedValueByName <Uri>(CodeGraphNodeIdName.Assembly);

            Assert.Equal(contextProjectPath.Replace('\\', '/'), childProjectPath.AbsolutePath);
        }
 public static void Provide(IGraphContextFactory factory)
 {
     GraphContextFactoryLocator._factory = factory;
 }
Ejemplo n.º 19
0
        public async Task DependenciesGraphProvider_GetChildrenAsync_NoNodeAttachedToInputNode_ShouldDiscoverItAgain()
        {
            var projectPath       = @"c:\myproject\project.csproj";
            var nodeIdString      = @"file:///[MyProvider;MyNodeItemSpec]";
            var rootNode          = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyRootNode""
    }
}");
            var existingNode      = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");
            var existingChildNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec""
    }
}");

            rootNode.AddChild(existingNode);
            existingNode.Children.Add(existingChildNode);

            var mockVsHierarchyItem = IVsHierarchyItemFactory.ImplementProperties(text: "MyNodeItemSpec");
            var inputNode           = IGraphContextFactory.CreateNode(projectPath,
                                                                      nodeIdString,
                                                                      hierarchyItem: mockVsHierarchyItem);
            var outputNodes = new HashSet <GraphNode>();

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.RootNode = rootNode;
            mockProvider.AddTestDependencyNodes(new[] { existingNode });

            var mockProjectContextProvider = IDependenciesGraphProjectContextProviderFactory.Implement(projectPath, mockProvider);
            var mockGraphContext           = IGraphContextFactory.ImplementGetChildrenAsync(inputNode,
                                                                                            trackChanges: true,
                                                                                            outputNodes: outputNodes);

            var provider = new TestableDependenciesGraphProvider(mockProjectContextProvider,
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.Equal(1, outputNodes.Count);
            var childGraphNode = outputNodes.First();

            Assert.Equal(existingChildNode, childGraphNode.GetValue <IDependencyNode>(DependenciesGraphSchema.DependencyNodeProperty));
            Assert.False(childGraphNode.GetValue <bool>(DgmlNodeProperties.ContainsChildren));
            Assert.True(childGraphNode.GetValue(DependenciesGraphSchema.ProviderProperty) is IProjectDependenciesSubTreeProviderMock);
            Assert.Equal(1, childGraphNode.IncomingLinkCount);
            Assert.Equal(1, provider.GetRegisteredSubTreeProviders().Count());
        }
Ejemplo n.º 20
0
        public async Task DependenciesGraphProvider_SearchAsync()
        {
            // Arrange
            var searchString = "1.0";
            var projectPath  = @"c:\myproject\project.csproj";
            var rootNode     = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyRootNode""
    }
}");

            var topNode1 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec""
    }
}");
            var topNode2 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec/1.0.0""
    }
}");

            var topNode3 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec3/1.0.0""
    }
}");

            var childNode1 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec1.0""
    }
}");

            var childNode2 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec/1.0.0""
    }
}");

            var childNode3 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec""
    }
}");

            topNode1.Children.Add(childNode1);
            topNode2.Children.Add(childNode3);
            topNode2.Children.Add(childNode2);
            rootNode.AddChild(topNode1);
            rootNode.AddChild(topNode2);
            rootNode.AddChild(topNode3);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.RootNode = rootNode;
            mockProvider.AddTestDependencyNodes(new[] { topNode1, topNode2, topNode3 });
            mockProvider.AddSearchResults(new[] { topNode1, topNode2, topNode3 });

            var mockProjectContextProvider =
                IDependenciesGraphProjectContextProviderFactory.Implement(
                    projectPath, subTreeProviders: new[] { mockProvider });

            var outputNodes      = new HashSet <GraphNode>();
            var mockGraphContext = IGraphContextFactory.ImplementSearchAsync(searchString,
                                                                             outputNodes: outputNodes);

            var provider = new TestableDependenciesGraphProvider(mockProjectContextProvider,
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.Equal(5, outputNodes.Count);

            var outputArray = outputNodes.ToArray();

            // check if top level nodes got CodeNodeCategories.ProjectItem to make sure
            // graph matched them back with IVsHierarchy nodes
            Assert.True(outputArray[0].HasCategory(CodeNodeCategories.ProjectItem));
            Assert.Equal(1, outputArray[0].OutgoingLinkCount);
            Assert.True(outputArray[2].HasCategory(CodeNodeCategories.ProjectItem));
            Assert.Equal(2, outputArray[2].OutgoingLinkCount);

            Assert.False(outputArray[1].HasCategory(CodeNodeCategories.ProjectItem));
            Assert.False(outputArray[3].HasCategory(CodeNodeCategories.ProjectItem));
            Assert.False(outputArray[4].HasCategory(CodeNodeCategories.ProjectItem));
        }
Ejemplo n.º 21
0
        public async Task DependenciesGraphProvider_SearchAsync_TopLevel_GenericNode_WithNormalItemSpec()
        {
            // Arrange
            var searchString = "1.0";
            var projectPath  = @"c:\myproject\project.csproj";
            var rootNode     = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyRootNode""
    }
}");

            var topNode1 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec""
    }
}", DependencyNode.GenericDependencyFlags);

            ((DependencyNode)topNode1).Name = "TopNodeName";
            var childNode1 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec1.0""
    }
}");

            topNode1.Children.Add(childNode1);
            rootNode.AddChild(topNode1);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            mockProvider.RootNode = rootNode;
            mockProvider.AddTestDependencyNodes(new[] { topNode1 });
            mockProvider.AddSearchResults(new[] { topNode1 });

            var mockProjectContextProvider =
                IDependenciesGraphProjectContextProviderFactory.Implement(
                    projectPath, subTreeProviders: new[] { mockProvider });

            var outputNodes      = new HashSet <GraphNode>();
            var mockGraphContext = IGraphContextFactory.ImplementSearchAsync(searchString,
                                                                             outputNodes: outputNodes);

            var provider = new TestableDependenciesGraphProvider(mockProjectContextProvider,
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.Equal(2, outputNodes.Count);

            var outputArray = outputNodes.ToArray();

            // check if top level nodes got CodeNodeCategories.ProjectItem to make sure
            // graph matched them back with IVsHierarchy nodes
            Assert.True(outputArray[0].HasCategory(CodeNodeCategories.ProjectItem));
            Assert.Equal(1, outputArray[0].OutgoingLinkCount);
            Assert.Equal(@"c:/myproject/mytopnodeitemspec", outputArray[0].Id.GetNestedValueByName <Uri>(CodeGraphNodeIdName.File).AbsolutePath);
            Assert.False(outputArray[1].HasCategory(CodeNodeCategories.ProjectItem));
        }
Ejemplo n.º 22
0
        public async Task DependenciesGraphProvider_TrackChangesAsync_InvalidNodeData(
            string projectPath, bool existingNodeSpecified, bool updatedNodeProvided)
        {
            var nodeIdString = @"file:///[MyProvider;MyNodeItemSpec]";
            var inputNode    = IGraphContextFactory.CreateNode(projectPath, nodeIdString);

            var existingNode      = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");
            var existingChildNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpecExisting""
    }
}");

            var existingRefreshedNode = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyNodeItemSpec""
    }
}");
            var newChildNode          = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpecNew""
    }
}");

            existingNode.Children.Add(existingChildNode);
            existingRefreshedNode.AddChild(newChildNode);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock();

            if (updatedNodeProvided)
            {
                mockProvider.AddTestDependencyNodes(new[] { existingRefreshedNode });
            }

            if (existingNodeSpecified)
            {
                inputNode.SetValue(DependenciesGraphSchema.DependencyNodeProperty, existingNode);
            }

            inputNode.SetValue(DependenciesGraphSchema.ProviderProperty, mockProvider);

            var outputNodes      = new HashSet <GraphNode>();
            var mockGraphContext = IGraphContextFactory.ImplementTrackChanges(inputNode, outputNodes);

            var updatedProjectContext =
                IDependenciesGraphProjectContextProviderFactory.ImplementProjectContext(projectPath);

            var provider = new TestableDependenciesGraphProvider(IDependenciesGraphProjectContextProviderFactory.Create(),
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            provider.AddExpandedGraphContext(mockGraphContext);

            // Act
            await provider.TrackChangesAsync(updatedProjectContext);

            // Assert
            Assert.Equal(0, outputNodes.Count);
        }
Ejemplo n.º 23
0
        public void MoreComplexGraph_RunsCorrectly()
        {
            Graph graph = new Graph();

            // A --- B --
            //  \--- C --\- D
            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();
            Node nodeC = graph.MakeNode();
            Node nodeD = graph.MakeNode();

            Transition bTransition = new Transition(waitForManualExit: false);

            bTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition bNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = bTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, bNodeTransition);

            Transition cTransition = new Transition(waitForManualExit: false);

            cTransition.AddTransitionCondition(new IntTransitionCondition("Key", 3));
            NodeTransition cNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeC.Id }, transition = cTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, cNodeTransition);

            Transition cdTransition = new Transition(waitForManualExit: false);

            cdTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition cdNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeD.Id }, transition = cdTransition
            };

            graph.AddOutgoingTransitionForNode(nodeC, cdNodeTransition);

            Transition bdTransition = new Transition(waitForManualExit: true);

            bdTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition bdNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeD.Id }, transition = bdTransition
            };

            graph.AddOutgoingTransitionForNode(nodeB, bdNodeTransition);

            // CLONING CODE
            Graph clonedGraph = Graph.DeepClone(graph);

            Node clonedNodeA = clonedGraph.LoadNodeById(nodeA.Id);
            Node clonedNodeB = clonedGraph.LoadNodeById(nodeB.Id);
            Node clonedNodeC = clonedGraph.LoadNodeById(nodeC.Id);
            Node clonedNodeD = clonedGraph.LoadNodeById(nodeD.Id);
            // END CLONING CODE

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasIntParameterKey(Arg.Is("Key")).Returns(true);
            stubContext.GetInt(Arg.Is("Key")).Returns(5);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool aEntered = false;

            nodeA.OnEnter += () => { aEntered = true; };
            bool bEntered = false;

            nodeB.OnEnter += () => { bEntered = true; };

            bool clonedAEntered = false;

            clonedNodeA.OnEnter += () => { clonedAEntered = true; };
            bool clonedBEntered = false;

            clonedNodeB.OnEnter += () => { clonedBEntered = true; };
            bool clonedCEntered = false;

            clonedNodeC.OnEnter += () => { clonedCEntered = true; };
            bool clonedDEntered = false;

            clonedNodeD.OnEnter += () => { clonedDEntered = true; };

            clonedGraph.Start();
            Assert.IsTrue(clonedAEntered);
            Assert.IsTrue(clonedBEntered);
            Assert.IsFalse(clonedCEntered);
            Assert.IsFalse(clonedDEntered);

            // check to make sure the original nodes are not entered
            Assert.IsFalse(aEntered);
            Assert.IsFalse(bEntered);

            clonedAEntered = false;
            clonedBEntered = false;
            clonedCEntered = false;
            clonedDEntered = false;

            clonedNodeB.TriggerManualExit();
            Assert.IsFalse(clonedAEntered);
            Assert.IsFalse(clonedBEntered);
            Assert.IsFalse(clonedCEntered);
            Assert.IsTrue(clonedDEntered);
        }
Ejemplo n.º 24
0
        public void MoreComplexGraph_RunsCorrectly()
        {
            Graph graph = new Graph();

            // A --- B --
            //  \--- C --\- D
            Node nodeA = graph.MakeNode();
            Node nodeB = graph.MakeNode();
            Node nodeC = graph.MakeNode();
            Node nodeD = graph.MakeNode();

            Transition bTransition = new Transition(waitForManualExit: false);

            bTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition bNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeB.Id }, transition = bTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, bNodeTransition);

            Transition cTransition = new Transition(waitForManualExit: false);

            cTransition.AddTransitionCondition(new IntTransitionCondition("Key", 3));
            NodeTransition cNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeC.Id }, transition = cTransition
            };

            graph.AddOutgoingTransitionForNode(nodeA, cNodeTransition);

            Transition cdTransition = new Transition(waitForManualExit: false);

            cdTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition cdNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeD.Id }, transition = cdTransition
            };

            graph.AddOutgoingTransitionForNode(nodeC, cdNodeTransition);

            Transition bdTransition = new Transition(waitForManualExit: true);

            bdTransition.AddTransitionCondition(new IntTransitionCondition("Key", 5));
            NodeTransition bdNodeTransition = new NodeTransition {
                targets = new NodeId[] { nodeD.Id }, transition = bdTransition
            };

            graph.AddOutgoingTransitionForNode(nodeB, bdNodeTransition);

            IGraphContext stubContext = Substitute.For <IGraphContext>();

            stubContext.HasIntParameterKey(Arg.Is("Key")).Returns(true);
            stubContext.GetInt(Arg.Is("Key")).Returns(5);

            IGraphContextFactory stubFactory = Substitute.For <IGraphContextFactory>();

            stubFactory.MakeContext().Returns(stubContext);
            GraphContextFactoryLocator.Provide(stubFactory);

            bool aEntered = false;

            nodeA.OnEnter += () => { aEntered = true; };
            bool bEntered = false;

            nodeB.OnEnter += () => { bEntered = true; };
            bool cEntered = false;

            nodeC.OnEnter += () => { cEntered = true; };
            bool dEntered = false;

            nodeD.OnEnter += () => { dEntered = true; };

            graph.Start();
            Assert.IsTrue(aEntered);
            Assert.IsTrue(bEntered);
            Assert.IsFalse(cEntered);
            Assert.IsFalse(dEntered);

            aEntered = false;
            bEntered = false;
            cEntered = false;
            dEntered = false;

            nodeB.TriggerManualExit();
            Assert.IsFalse(aEntered);
            Assert.IsFalse(bEntered);
            Assert.IsFalse(cEntered);
            Assert.IsTrue(dEntered);
        }
Ejemplo n.º 25
0
        public async Task DependenciesGraphProvider_SearchAsync()
        {
            // Arrange
            var searchString = "1.0";
            var projectPath  = @"c:\myproject\project.csproj";
            var rootNode     = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyRootNode""
    }
}");

            var topNode1 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec""
    }
}");
            var topNode2 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec/1.0.0""
    }
}");

            var topNode3 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyTopNodeItemSpec3/1.0.0""
    }
}");

            var childNode1 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec1.0""
    }
}");

            var childNode2 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec/1.0.0""
    }
}");

            var childNode3 = IDependencyNodeFactory.FromJson(@"
{
    ""Id"": {
        ""ProviderType"": ""MyProvider"",
        ""ItemSpec"": ""MyChildNodeItemSpec""
    }
}");

            topNode1.AddChild(childNode1);
            topNode2.AddChild(childNode3);
            topNode2.AddChild(childNode2);
            rootNode.AddChild(topNode1);
            rootNode.AddChild(topNode2);
            rootNode.AddChild(topNode3);

            var mockProvider = new IProjectDependenciesSubTreeProviderMock
            {
                RootNode = rootNode
            };

            mockProvider.AddTestDependencyNodes(new[] { topNode1, topNode2, topNode3 });
            mockProvider.AddSearchResults(new[] { topNode1, topNode2, topNode3 });

            var mockProjectContextProvider =
                IDependenciesGraphProjectContextProviderFactory.Implement(
                    projectPath, subTreeProviders: new[] { mockProvider });

            var outputNodes      = new HashSet <GraphNode>();
            var mockGraphContext = IGraphContextFactory.ImplementSearchAsync(searchString,
                                                                             outputNodes: outputNodes);

            var provider = new TestableDependenciesGraphProvider(mockProjectContextProvider,
                                                                 Mock.Of <SVsServiceProvider>(),
                                                                 new IProjectThreadingServiceMock().JoinableTaskContext);

            // Act
            await provider.BeginGetGraphDataAsync(mockGraphContext);

            // Assert
            Assert.Equal(4, outputNodes.Count);

            var topNode1Result = GetNodeById(projectPath, outputNodes, topNode1.Id);

            Assert.True(topNode1Result.HasCategory(CodeNodeCategories.ProjectItem));
            Assert.Equal(1, topNode1Result.OutgoingLinkCount);

            var topNode2Result = GetNodeById(projectPath, outputNodes, topNode2.Id);

            Assert.Equal(1, topNode2Result.OutgoingLinkCount);
            Assert.True(topNode2Result.HasCategory(CodeNodeCategories.ProjectItem));

            var childNode1Result = GetNodeById(projectPath, outputNodes, childNode1.Id);

            Assert.Equal(0, childNode1Result.OutgoingLinkCount);
            Assert.False(childNode1Result.HasCategory(CodeNodeCategories.ProjectItem));

            var childNode2Result = GetNodeById(projectPath, outputNodes, childNode2.Id);

            Assert.Equal(0, childNode2Result.OutgoingLinkCount);
            Assert.False(childNode2Result.HasCategory(CodeNodeCategories.ProjectItem));
        }