コード例 #1
0
        public void ExecuteCommand(DynamoModel.RecordableCommand command, string uniqueId, string extensionName)
        {
            // log that the command is being executed
            if (dynamoModel.DebugSettings.VerboseLogging)
            {
                dynamoModel.Logger.Log("Command: " + command);
            }

            var extnDetails = string.Format(
                "ExtensionCommandExecutive ( UniqueId: {0}, Name: {1}, commandTypeName: {2} )",
                uniqueId, extensionName, command.GetType().Name);

            Log(LogMessage.Info(extnDetails));

            try
            {
                // run the command
                dynamoModel.ExecuteCommand(command);
            }
            catch (Exception e)
            {
                // clean up or show failure messages
                Log(LogMessage.Error(string.Format("{0}, from {1}", e.Message, extnDetails)));
            }
        }
コード例 #2
0
ファイル: CommandLineRunner.cs プロジェクト: zjloscar/Dynamo
        private static XmlDocument RunCommandLineArgs(DynamoModel model, StartupUtils.CommandLineArguments cmdLineArgs)
        {
            var evalComplete = false;

            if (string.IsNullOrEmpty(cmdLineArgs.OpenFilePath))
            {
                return(null);
            }
            if (!(string.IsNullOrEmpty(cmdLineArgs.CommandFilePath)))
            {
                Console.WriteLine("commandFilePath option is only available when running DynamoSandbox, not DynamoCLI");
            }

            if (!(string.IsNullOrEmpty(cmdLineArgs.GeometryFilePath)))
            {
                Console.WriteLine("geometryFilePath option is only available when running DynamoWPFCLI, not DynamoCLI");
            }

            cmdLineArgs.ImportedPaths.ToList().ForEach(path =>
            {
                ImportAssembly(model, path);
            });

            model.OpenFileFromPath(cmdLineArgs.OpenFilePath, true);
            Console.WriteLine("loaded file");
            model.EvaluationCompleted += (o, args) => { evalComplete = true; };

            // Build a list of states, by default there is only a single state `default`
            // If the desire is to have additional states you can add logic here to build
            // up a list and iterate through each state in the list using the loop below.
            // This must be done after potentially loading states from an external file.
            var stateNames = new List <String>();

            stateNames.Add("default");

            XmlDocument doc = null;

            foreach (var stateName in stateNames)
            {
                // Graph execution
                model.ExecuteCommand(new DynamoModel.RunCancelCommand(false, false));

                while (evalComplete == false)
                {
                    Thread.Sleep(250);
                }

                //if verbose was true, then print all nodes to the console
                if (!String.IsNullOrEmpty(cmdLineArgs.Verbose))
                {
                    doc = CreateXMLDoc(model);
                }

                evalComplete = false;
            }

            return(doc);
        }
コード例 #3
0
        public void CollapsedGroupDisplaysWarningIfNodeInWarningState()
        {
            // Adding a dummy node to the workspace
            var         dummyNode = new DummyNode();
            DynamoModel model     = GetModel();

            model.ExecuteCommand(new DynamoModel.CreateNodeCommand(dummyNode, 0, 0, true, true));

            NodeViewModel dummyNodeViewModel = ViewModel.CurrentSpaceViewModel.Nodes
                                               .FirstOrDefault(x => x.NodeModel.GUID == dummyNode.GUID);

            ViewModel.Model.CurrentWorkspace.AddAndRegisterNode(dummyNode, false);

            //verify the node was created
            Assert.AreEqual(1, ViewModel.Model.CurrentWorkspace.Nodes.Count());

            //Select the node for group
            DynamoSelection.Instance.Selection.Add(dummyNode);

            //Create a Group around that node
            ViewModel.AddAnnotationCommand.Execute(null);
            var annotation          = ViewModel.Model.CurrentWorkspace.Annotations.FirstOrDefault();
            var annotationViewModel = ViewModel.CurrentSpaceViewModel.Annotations.FirstOrDefault();

            //Check if the group is created
            Assert.IsNotNull(annotation);

            //Clear the selection
            DynamoSelection.Instance.ClearSelection();

            // Collapses the group
            annotationViewModel.IsExpanded = false;

            NodeModel dummyNodeModel = dummyNodeViewModel.NodeModel;

            var topLeft  = new Point(dummyNodeViewModel.X, dummyNodeViewModel.Y);
            var botRight = new Point(dummyNodeViewModel.X + dummyNodeModel.Width, dummyNodeViewModel.Y + dummyNodeModel.Height);

            if (dummyNodeViewModel.ErrorBubble == null)
            {
                dummyNodeViewModel.ErrorBubble = new InfoBubbleViewModel(ViewModel);
            }

            InfoBubbleViewModel infoBubbleViewModel = dummyNodeViewModel.ErrorBubble;

            // The collection of messages the node receives
            ObservableCollection <InfoBubbleDataPacket> nodeMessages = infoBubbleViewModel.NodeMessages;

            nodeMessages.Add(new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Warning, topLeft, botRight, "Warning", InfoBubbleViewModel.Direction.Top));

            Assert.AreEqual(ElementState.Warning, annotationViewModel.AnnotationModel.GroupState);
        }
コード例 #4
0
ファイル: InfoBubbleTests.cs プロジェクト: reddyashish/Dynamo
        public void IteratorsDisplayWhenMoreThanOneMessage()
        {
            // Arrange
            OpenModel(@"core\Home.dyn");

            var info1 = "Info 1";
            var info2 = "Info 2";

            var         dummyNode = new DummyNode();
            DynamoModel model     = GetModel();

            model.ExecuteCommand(new DynamoModel.CreateNodeCommand(dummyNode, 0, 0, true, true));

            NodeViewModel dummyNodeViewModel = ViewModel.CurrentSpaceViewModel.Nodes
                                               .FirstOrDefault(x => x.NodeModel.GUID == dummyNode.GUID);

            if (dummyNodeViewModel.ErrorBubble == null)
            {
                dummyNodeViewModel.ErrorBubble = new InfoBubbleViewModel(ViewModel);
            }

            NodeModel dummyNodeModel = dummyNodeViewModel.NodeModel;

            var topLeft  = new Point(dummyNodeModel.X, dummyNodeModel.Y);
            var botRight = new Point(dummyNodeModel.X + dummyNodeModel.Width, dummyNodeModel.Y + dummyNodeModel.Height);

            InfoBubbleViewModel infoBubbleViewModel = dummyNodeViewModel.ErrorBubble;

            // The collection of messages the node receives
            ObservableCollection <InfoBubbleDataPacket> nodeMessages = infoBubbleViewModel.NodeMessages;

            // Act
            Assert.IsFalse(infoBubbleViewModel.NodeInfoIteratorVisible);

            InfoBubbleDataPacket infoBubbleDataPacket1 =
                new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Info, topLeft, botRight, info1, InfoBubbleViewModel.Direction.Top);

            nodeMessages.Add(infoBubbleDataPacket1);

            Assert.IsFalse(infoBubbleViewModel.NodeInfoIteratorVisible);

            InfoBubbleDataPacket infoBubbleDataPacket2 =
                new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Info, topLeft, botRight, info2, InfoBubbleViewModel.Direction.Top);

            nodeMessages.Add(infoBubbleDataPacket2);

            Assert.IsTrue(infoBubbleViewModel.NodeInfoIteratorVisible);

            infoBubbleViewModel.DismissMessageCommand.Execute(infoBubbleDataPacket1);

            Assert.IsFalse(infoBubbleViewModel.NodeInfoIteratorVisible);
        }
コード例 #5
0
        /// <summary>
        /// Rewires nodes and newly placed watch node between them.
        /// </summary>
        /// <param name="dynamoModel"></param>
        /// <param name="startNode"></param>
        /// <param name="endNode"></param>
        /// <param name="watchNodeModel"></param>
        private void WireNewNode(
            DynamoModel dynamoModel,
            NodeModel startNode,
            NodeModel endNode,
            NodeModel watchNodeModel,
            ConnectorModel connector,
            IEnumerable <Point> connectorPinLocations,
            List <ModelBase> allCreatedModels,
            List <ModelBase> allDeletedModels)
        {
            (int startIndex, int endIndex) = GetPortIndex(connector);

            // Connect startNode and watch node
            dynamoModel.ExecuteCommand(new DynamoModel.MakeConnectionCommand(startNode.GUID, startIndex, PortType.Output, DynamoModel.MakeConnectionCommand.Mode.Begin));
            dynamoModel.ExecuteCommand(new DynamoModel.MakeConnectionCommand(watchNodeModel.GUID, 0, PortType.Input, DynamoModel.MakeConnectionCommand.Mode.End));

            // Connect watch node and endNode
            dynamoModel.ExecuteCommand(new DynamoModel.MakeConnectionCommand(watchNodeModel.GUID, 0, PortType.Output, DynamoModel.MakeConnectionCommand.Mode.Begin));
            dynamoModel.ExecuteCommand(new DynamoModel.MakeConnectionCommand(endNode.GUID, endIndex, PortType.Input, DynamoModel.MakeConnectionCommand.Mode.End));

            PlacePinsOnWires(startNode, watchNodeModel, connector, connectorPinLocations, allCreatedModels, allDeletedModels);
        }
コード例 #6
0
        public void LinterManagerStoresRuleEvaluationResults()
        {
            // Arrange
            var evaluationResultsBefore = model.LinterManager.RuleEvaluationResults.ToList();

            SetupNodeNameChangedRule(mockRule);

            mockExtension.Object.AddLinterRule(mockRule.Object);

            // Act
            var failureNode = new DummyNode();

            model.ExecuteCommand(new DynamoModel.CreateNodeCommand(failureNode, 0, 0, false, false));

            // When setting a linter as the active linter, that linters Activate() gets called
            // which will initialize the rules using the init function. As we only have one mock rule
            // that checks if the node name is "NewNodeName" no failed evaluation results should be created here.
            model.LinterManager.ActiveLinter = model.LinterManager.AvailableLinters
                                               .Where(x => x.Id == MOCK_GUID)
                                               .FirstOrDefault();

            // Update graph nodes name to trigger the node rule evaluation
            failureNode.Name = "NewNodeName";

            // Assert
            CollectionAssert.IsEmpty(evaluationResultsBefore);
            Assert.That(model.LinterManager.RuleEvaluationResults.Count == 1);
            Assert.That(model.LinterManager.RuleEvaluationResults.
                        Any(x => x.RuleId == MOCK_RULE_ID));

            Assert.That(model.LinterManager.RuleEvaluationResults.
                        Any(x => x is NodeRuleEvaluationResult));

            Assert.That(model.LinterManager.RuleEvaluationResults.
                        Where(x => x is NodeRuleEvaluationResult).
                        Cast <NodeRuleEvaluationResult>().
                        Any(x => x.NodeId == failureNode.GUID.ToString()));
        }
コード例 #7
0
ファイル: InfoBubbleTests.cs プロジェクト: reddyashish/Dynamo
        public void NodeWarningBarVisibility()
        {
            OpenModel(@"core\Home.dyn");

            var info = "Information";

            // Arrange
            var         dummyNode = new DummyNode();
            DynamoModel model     = GetModel();

            model.ExecuteCommand(new DynamoModel.CreateNodeCommand(dummyNode, 0, 0, true, true));

            NodeViewModel dummyNodeViewModel = ViewModel.CurrentSpaceViewModel.Nodes
                                               .FirstOrDefault(x => x.NodeModel.GUID == dummyNode.GUID);

            NodeModel dummyNodeModel = dummyNodeViewModel.NodeModel;

            if (dummyNodeViewModel.ErrorBubble == null)
            {
                dummyNodeViewModel.ErrorBubble = new InfoBubbleViewModel(ViewModel);
            }

            InfoBubbleViewModel infoBubbleViewModel = dummyNodeViewModel.ErrorBubble;

            ObservableCollection <InfoBubbleDataPacket> nodeMessages = infoBubbleViewModel.NodeMessages;

            // Assert
            Assert.IsFalse(dummyNodeViewModel.NodeWarningBarVisible);

            // Act
            InfoBubbleDataPacket infoBubbleDataPacket = new InfoBubbleDataPacket
                                                        (
                InfoBubbleViewModel.Style.Info,
                new Point(dummyNodeModel.X, dummyNodeModel.Y),
                new Point(dummyNodeModel.X + dummyNodeModel.Width, dummyNodeModel.Y + dummyNodeModel.Height),
                info,
                InfoBubbleViewModel.Direction.Top
                                                        );

            nodeMessages.Add(infoBubbleDataPacket);

            Assert.IsTrue(infoBubbleViewModel.NodeInfoVisible);

            infoBubbleViewModel.DismissMessageCommand.Execute(infoBubbleDataPacket);

            Assert.IsFalse(dummyNodeViewModel.NodeWarningBarVisible);
        }
コード例 #8
0
ファイル: InfoBubbleTests.cs プロジェクト: reddyashish/Dynamo
        public void CanDismissUserFacingMessages()
        {
            OpenModel(@"core\Home.dyn");

            var info1 = "Dismissed Info 1";

            // Arrange
            var         dummyNode = new DummyNode();
            DynamoModel model     = GetModel();

            model.ExecuteCommand(new DynamoModel.CreateNodeCommand(dummyNode, 0, 0, true, true));

            NodeViewModel dummyNodeViewModel = ViewModel.CurrentSpaceViewModel.Nodes
                                               .FirstOrDefault(x => x.NodeModel.GUID == dummyNode.GUID);

            NodeModel dummyNodeModel = dummyNodeViewModel.NodeModel;

            var topLeft  = new Point(dummyNodeModel.X, dummyNodeModel.Y);
            var botRight = new Point(dummyNodeModel.X + dummyNodeModel.Width, dummyNodeModel.Y + dummyNodeModel.Height);

            if (dummyNodeViewModel.ErrorBubble == null)
            {
                dummyNodeViewModel.ErrorBubble = new InfoBubbleViewModel(ViewModel);
            }

            InfoBubbleViewModel infoBubbleViewModel = dummyNodeViewModel.ErrorBubble;

            // The collection of messages the node receives
            ObservableCollection <InfoBubbleDataPacket> nodeMessages = infoBubbleViewModel.NodeMessages;

            // Act
            InfoBubbleDataPacket infoBubbleDataPacket = new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Info, topLeft, botRight, info1, InfoBubbleViewModel.Direction.Top);

            nodeMessages.Add(infoBubbleDataPacket);

            Assert.AreEqual(1, infoBubbleViewModel.NodeInfoToDisplay.Count);
            Assert.AreEqual(0, infoBubbleViewModel.DismissedMessages.Count);
            Assert.IsTrue(infoBubbleViewModel.NodeInfoVisible);

            infoBubbleViewModel.DismissMessageCommand.Execute(infoBubbleDataPacket);

            // Assert
            Assert.AreEqual(0, infoBubbleViewModel.NodeInfoToDisplay.Count);
            Assert.AreEqual(1, infoBubbleViewModel.DismissedMessages.Count);
            Assert.AreEqual(info1, infoBubbleViewModel.DismissedMessages.First().Message);
        }
コード例 #9
0
        /// <summary>
        /// Places watch node at the midpoint of the connector
        /// </summary>
        internal List <ModelBase> PlaceWatchNode(ConnectorModel connector, IEnumerable <Point> connectorPinLocations, List <ModelBase> allDeletedModels)
        {
            var createdModels = new List <ModelBase>();

            NodeModel startNode = ViewModel.ConnectorModel.Start.Owner;
            NodeModel endNode   = ViewModel.ConnectorModel.End.Owner;

            this.Dispatcher.Invoke(() =>
            {
                var watchNode = new Watch();
                var nodeX     = CurrentPosition.X - (watchNode.Width / 2);
                var nodeY     = CurrentPosition.Y - (watchNode.Height / 2);
                DynamoModel.ExecuteCommand(new DynamoModel.CreateNodeCommand(watchNode, nodeX, nodeY, false, false));
                createdModels.Add(watchNode);
                WireNewNode(DynamoModel, startNode, endNode, watchNode, connector, connectorPinLocations, createdModels, allDeletedModels);
            });

            return(createdModels);
        }
コード例 #10
0
        private void OnPlaybackTimerTick(object sender, EventArgs e)
        {
            var timer = (DispatcherTimer)sender;

            timer.Stop();                  // Stop the timer before command completes.

            if (loadedCommands.Count <= 0) // There's nothing else for playback.
            {
                if (ExitAfterPlayback == false)
                {
                    // The playback is done, but the command file indicates that
                    // Dynamo should not be shutdown after the playback, so here
                    // we simply invalidate the timer.
                    //
                    playbackTimer = null;
                    ChangeStateInternal(State.Stopped);
                }
                else
                {
                    // The command file requires Dynamo be shutdown after all
                    // commands has been played back. If that's the case, we'll
                    // reconfigure the callback to a shutdown timer, and then
                    // change its interval to the duration specified earlier.
                    //
                    playbackTimer.Tick -= OnPlaybackTimerTick;
                    playbackTimer.Tick += OnShutdownTimerTick;

                    var interval = TimeSpan.FromMilliseconds(PauseAfterPlayback);
                    playbackTimer.Interval = interval;
                    playbackTimer.Start(); // Start shutdown timer.
                    ChangeStateInternal(State.ShuttingDown);
                }

                return;
            }

            // Remove the first command from the loaded commands.
            DynamoModel.RecordableCommand nextCommand = loadedCommands[0];
            loadedCommands.RemoveAt(0);

            // Update the cached command references.
            PreviousCommand = CurrentCommand;
            CurrentCommand  = nextCommand;

            if (nextCommand is DynamoModel.PausePlaybackCommand)
            {
                var command = nextCommand as DynamoModel.PausePlaybackCommand;
                PauseCommandPlayback(command.PauseDurationInMs);
                return;
            }

            try
            {
                // Execute the command, this may take a while longer than the timer
                // inverval (usually very short), that's why the timer was stopped
                // before the command execution starts. After the command is done,
                // the timer is then resumed for the next command in queue.
                //
                owningDynamoModel.ExecuteCommand(nextCommand);
            }
            catch (Exception exception)
            {
                // An exception is thrown while playing back a command. Remove any
                // pending commands and allow the "playbackTimer" to continue with
                // its next tick. Proper shutdown sequence will be initialized
                // when the "playbackTimer" tries to pick up the next command and
                // realized that there is no more commands waiting.
                //
                loadedCommands.Clear();
                PlaybackException = exception;
            }

            timer.Start();
        }
コード例 #11
0
ファイル: CommandLineRunner.cs プロジェクト: ipud2/Dynamo
        private static XmlDocument RunCommandLineArgs(DynamoModel model, StartupUtils.CommandLineArguments cmdLineArgs)
        {
            var evalComplete = false;

            if (string.IsNullOrEmpty(cmdLineArgs.OpenFilePath))
            {
                return(null);
            }
            if (!(string.IsNullOrEmpty(cmdLineArgs.CommandFilePath)))
            {
                Console.WriteLine("commandFilePath option is only available when running DynamoSandbox, not DynamoCLI");
            }

            model.OpenFileFromPath(cmdLineArgs.OpenFilePath, true);
            Console.WriteLine("loaded file");
            model.EvaluationCompleted += (o, args) => { evalComplete = true; };

            // Build a list of states, by default there is only a single state `default`
            // If the desire is to have additional states you can add logic here to build
            // up a list and iterate through each state in the list using the loop below.
            // This must be done after potentially loading states from an external file.
            var stateNames = new List <String>();

            stateNames.Add("default");

            var         outputresults = new List <Dictionary <Guid, List <object> > >();
            XmlDocument doc           = null;

            foreach (var stateName in stateNames)
            {
                // Graph execution
                model.ExecuteCommand(new DynamoModel.RunCancelCommand(false, false));

                while (evalComplete == false)
                {
                    Thread.Sleep(250);
                }

                //if verbose was true, then print all nodes to the console
                if (!String.IsNullOrEmpty(cmdLineArgs.Verbose))
                {
                    doc = new XmlDocument();
                    var resultsdict = new Dictionary <Guid, List <object> >();
                    foreach (var node in model.CurrentWorkspace.Nodes)
                    {
                        var portvalues = new List <object>();
                        foreach (var port in node.OutPorts)
                        {
                            var value = node.GetValue(port.Index, model.EngineController);
                            if (value.IsCollection)
                            {
                                portvalues.Add(GetStringRepOfCollection(value));
                            }
                            else
                            {
                                portvalues.Add(value.StringData);
                            }
                        }
                        resultsdict.Add(node.GUID, portvalues);
                    }
                    outputresults.Add(resultsdict);
                    populateXmlDocWithResults(doc, outputresults);
                }
                evalComplete = false;
            }

            return(doc);
        }
コード例 #12
0
ファイル: CommandLineRunner.cs プロジェクト: wynged/Dynamo
        private static XmlDocument RunCommandLineArgs(DynamoModel model, StartupUtils.CommandLineArguments cmdLineArgs)
        {
            var evalComplete = false;

            if (string.IsNullOrEmpty(cmdLineArgs.OpenFilePath))
            {
                return(null);
            }
            if (!(string.IsNullOrEmpty(cmdLineArgs.CommandFilePath)))
            {
                Console.WriteLine("commandFilePath option is only available when running DynamoSandbox, not DynamoCLI");
            }

            model.OpenFileFromPath(cmdLineArgs.OpenFilePath, true);
            Console.WriteLine("loaded file");
            model.EvaluationCompleted += (o, args) => { evalComplete = true; };

            if (!string.IsNullOrEmpty(cmdLineArgs.PresetFilePath))
            {
                //first load the openfile nodegraph
                var originalGraphdoc = XmlHelper.CreateDocument("tempworkspace");
                originalGraphdoc.Load(cmdLineArgs.OpenFilePath);
                var graph = NodeGraph.LoadGraphFromXml(originalGraphdoc, model.NodeFactory);

                //then load the presetsfile nodegraph (this should only contain presets),
                var presetsDoc = XmlHelper.CreateDocument("presetstempworkspace");
                presetsDoc.Load(cmdLineArgs.PresetFilePath);
                //when we load the presets we need to pass in the nodeModels from the original graph
                var presets = NodeGraph.LoadPresetsFromXml(presetsDoc, graph.Nodes);

                //load the presets contained in the presetsfile into the workspace,
                model.CurrentWorkspace.ImportPresets(presets);
            }

            //build a list of states, for now, none, a single state, or all of them
            //this must be done after potentially loading states from external file
            var stateNames = new List <String>();

            if (!string.IsNullOrEmpty(cmdLineArgs.PresetStateID))
            {
                if (cmdLineArgs.PresetStateID == "all")
                {
                    foreach (var state in model.CurrentWorkspace.Presets)
                    {
                        stateNames.Add(state.Name);
                    }
                }
                else
                {
                    stateNames.Add(cmdLineArgs.PresetStateID);
                }
            }
            else
            {
                stateNames.Add("default");
            }

            var         outputresults = new List <Dictionary <Guid, List <object> > >();
            XmlDocument doc           = null;

            foreach (var stateName in stateNames)
            {
                Guid stateGuid = Guid.Empty;
                var  state     = model.CurrentWorkspace.Presets.Where(x => x.Name == stateName).FirstOrDefault();
                if (state != null)
                {
                    stateGuid = state.GUID;
                }

                model.ExecuteCommand(new DynamoModel.ApplyPresetCommand(model.CurrentWorkspace.Guid, stateGuid));
                model.ExecuteCommand(new DynamoModel.RunCancelCommand(false, false));

                while (evalComplete == false)
                {
                    Thread.Sleep(250);
                }

                //if verbose was true, then print all nodes to the console
                if (!String.IsNullOrEmpty(cmdLineArgs.Verbose))
                {
                    doc = new XmlDocument();
                    var resultsdict = new Dictionary <Guid, List <object> >();
                    foreach (var node in model.CurrentWorkspace.Nodes)
                    {
                        var portvalues = new List <object>();
                        foreach (var port in node.OutPorts)
                        {
                            var value = node.GetValue(port.Index, model.EngineController);
                            if (value.IsCollection)
                            {
                                portvalues.Add(GetStringRepOfCollection(value));
                            }
                            else
                            {
                                portvalues.Add(value.StringData);
                            }
                        }
                        resultsdict.Add(node.GUID, portvalues);
                    }
                    outputresults.Add(resultsdict);
                    populateXmlDocWithResults(doc, outputresults);
                }
                evalComplete = false;
            }


            return(doc);
        }
コード例 #13
0
ファイル: InfoBubbleTests.cs プロジェクト: reddyashish/Dynamo
        public void CanAddUserFacingMessagesToNode()
        {
            // Arrange
            OpenModel(@"core\Home.dyn");

            var info1    = "Info 1";
            var warning1 = "Warning 1";
            var error1   = "Error 1";

            var         dummyNode = new DummyNode();
            DynamoModel model     = GetModel();

            model.ExecuteCommand(new DynamoModel.CreateNodeCommand(dummyNode, 0, 0, true, true));

            NodeViewModel dummyNodeViewModel = ViewModel.CurrentSpaceViewModel.Nodes
                                               .FirstOrDefault(x => x.NodeModel.GUID == dummyNode.GUID);

            NodeModel dummyNodeModel = dummyNodeViewModel.NodeModel;

            var topLeft  = new Point(dummyNodeModel.X, dummyNodeModel.Y);
            var botRight = new Point(dummyNodeModel.X + dummyNodeModel.Width, dummyNodeModel.Y + dummyNodeModel.Height);

            if (dummyNodeViewModel.ErrorBubble == null)
            {
                dummyNodeViewModel.ErrorBubble = new InfoBubbleViewModel(ViewModel);
            }

            InfoBubbleViewModel infoBubbleViewModel = dummyNodeViewModel.ErrorBubble;

            // The collection of messages the node receives
            ObservableCollection <InfoBubbleDataPacket> nodeMessages = infoBubbleViewModel.NodeMessages;

            // The collections of messages the node displays to the user
            ObservableCollection <InfoBubbleDataPacket> userFacingInfo     = infoBubbleViewModel.NodeInfoToDisplay;
            ObservableCollection <InfoBubbleDataPacket> userFacingWarnings = infoBubbleViewModel.NodeWarningsToDisplay;
            ObservableCollection <InfoBubbleDataPacket> userFacingErrors   = infoBubbleViewModel.NodeErrorsToDisplay;

            // Act
            Assert.AreEqual(0, userFacingInfo.Count);
            Assert.AreEqual(0, userFacingWarnings.Count);
            Assert.AreEqual(0, userFacingErrors.Count);

            Assert.IsFalse(infoBubbleViewModel.NodeInfoVisible);
            Assert.IsFalse(infoBubbleViewModel.NodeWarningsVisible);
            Assert.IsFalse(infoBubbleViewModel.NodeErrorsVisible);

            nodeMessages.Add(new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Info, topLeft, botRight, info1, InfoBubbleViewModel.Direction.Top));
            nodeMessages.Add(new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Warning, topLeft, botRight, warning1, InfoBubbleViewModel.Direction.Top));
            nodeMessages.Add(new InfoBubbleDataPacket(InfoBubbleViewModel.Style.Error, topLeft, botRight, error1, InfoBubbleViewModel.Direction.Top));

            // Assert
            Assert.AreEqual(1, userFacingInfo.Count);
            Assert.AreEqual(1, userFacingWarnings.Count);
            Assert.AreEqual(1, userFacingErrors.Count);

            Assert.IsTrue(infoBubbleViewModel.NodeInfoVisible);
            Assert.IsTrue(infoBubbleViewModel.NodeWarningsVisible);
            Assert.IsTrue(infoBubbleViewModel.NodeErrorsVisible);

            Assert.IsFalse(infoBubbleViewModel.NodeInfoIteratorVisible);
            Assert.IsFalse(infoBubbleViewModel.NodeWarningsIteratorVisible);
            Assert.IsFalse(infoBubbleViewModel.NodeErrorsIteratorVisible);

            Assert.IsFalse(infoBubbleViewModel.NodeInfoShowMoreButtonVisible);
            Assert.IsFalse(infoBubbleViewModel.NodeWarningsShowMoreButtonVisible);
            Assert.IsFalse(infoBubbleViewModel.NodeErrorsShowMoreButtonVisible);

            Assert.AreEqual(info1, userFacingInfo.First().Message);
            Assert.AreEqual(warning1, userFacingWarnings.First().Message);
            Assert.AreEqual(error1, userFacingErrors.First().Message);
        }