예제 #1
0
        public void DoWorkAfter_should_execute_the_work_after_given_duration()
        {
            DateTime workStartedAt      = default(DateTime);
            DateTime workCompletedAt    = default(DateTime);
            DateTime countDownStartedAt = default(DateTime);
            TimeSpan waitDuration       = TimeSpan.FromSeconds(2);
            TimeSpan howLongWorkTakes   = TimeSpan.FromSeconds(1);
            TimeSpan timeout            = waitDuration.Add(howLongWorkTakes.Add(TimeSpan.FromMilliseconds(500)));

            DispatcherFrame frame = default(DispatcherFrame);

            "Given no parallel work running".Context(() =>
            {
                Assert.False(ParallelWork.IsAnyWorkRunning());
                frame = new DispatcherFrame();

                workStartedAt   = default(DateTime);
                workCompletedAt = default(DateTime);
            });

            "When Start.Work().RunAfter() is called".Do(() =>
            {
                Start.Work(() =>
                {
                    workStartedAt = DateTime.Now;
                    Thread.Sleep(howLongWorkTakes);
                })
                .OnComplete(() =>
                {
                    workCompletedAt = DateTime.Now;
                    frame.Continue  = false;
                })
                .RunAfter(waitDuration);

                countDownStartedAt = DateTime.Now;
            });

            "It should not start the work until the duration has elapsed".Assert(() =>
            {
                Assert.Equal(default(DateTime), workStartedAt);
                Assert.Equal(default(DateTime), workCompletedAt);

                Assert.True(WaitForWorkDoneAndFireCallback(timeout, frame));
            });

            "It should start the work after duration has elapsed".Assert(() =>
            {
                Assert.True(WaitForWorkDoneAndFireCallback(timeout, frame));

                // Work should start within 500ms of start time
                DateTime expectedStartTime = countDownStartedAt.Add(waitDuration);
                Assert.InRange(workStartedAt,
                               expectedStartTime,
                               expectedStartTime.AddMilliseconds(500));

                // Work should end within 500ms of expected end time
                DateTime expectedEndTime = countDownStartedAt.Add(waitDuration).Add(howLongWorkTakes);
                Assert.InRange(workCompletedAt,
                               expectedEndTime,
                               expectedEndTime.AddMilliseconds(500));
            });
        }
        private void SaveAndRefreshDiagram()
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return;
            }

            if (this.CurrentDiagram == default(DiagramFile))
            {
                return;
            }

            _RefreshDiagramTimerStarted = false;

            var diagramFileName      = this.CurrentDiagram.DiagramFilePath;
            var pathForContentEditor = ContentEditor.Tag as string;

            if (diagramFileName != pathForContentEditor)
            {
                MessageBox.Show(Window.GetWindow(this),
                                "Aha! This is one of those weird race condition I am getting into." + Environment.NewLine
                                + "Close the app and start again", "Weird race condition",
                                MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // Take a backup if this is the first time the diagram being modified
            // after opening
            if (_FirstSaveAfterOpen)
            {
                File.Copy(diagramFileName, diagramFileName.Replace(new FileInfo(diagramFileName).Extension, ".bak"), true);
                _FirstSaveAfterOpen = false;
            }

            var content = ContentEditor.Text;

            this.CurrentDiagram.Content = content;

            OnBeforeSave(this.CurrentDiagram);

            string plantUmlPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Thirdparty\\plantuml.exe");

            if (!File.Exists(plantUmlPath))
            {
                MessageBox.Show(Window.GetWindow(this),
                                "Cannot find file: " + Environment.NewLine
                                + plantUmlPath, "PlantUml.exe not found", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            if (ParallelWork.IsAnyWorkRunning())
            {
                return;
            }

            Start.Work(() =>
            {
                // Save the diagram content using UTF-8 encoding to support
                // various international characters, which ASCII won't support
                // and Unicode won't make it cross platform
                File.WriteAllText(diagramFileName, content, Encoding.UTF8);

                // Use plantuml to generate the graph again
                using (var process = new Process())
                {
                    var startInfo            = new ProcessStartInfo();
                    startInfo.FileName       = plantUmlPath;
                    startInfo.Arguments      = "-charset UTF-8 -graphvizdot \"" + Settings.Default.GraphVizLocation + "\" \"" + diagramFileName + "\"";
                    startInfo.WindowStyle    = ProcessWindowStyle.Hidden; // OMAR: Trick #5
                    startInfo.CreateNoWindow = true;                      // OMAR: Trick #5
                    process.StartInfo        = startInfo;
                    if (process.Start())
                    {
                        process.WaitForExit(10000);
                    }
                }
            })
            .OnComplete(() =>
            {
                BindingOperations.GetBindingExpression(DiagramImage, Image.SourceProperty).UpdateTarget();

                OnAfterSave(this.CurrentDiagram);
            })
            .OnException((exception) =>
            {
                OnAfterSave(this.CurrentDiagram);
                MessageBox.Show(Window.GetWindow(this), exception.Message, "Error running PlantUml",
                                MessageBoxButton.OK, MessageBoxImage.Error);
            })
            .Run();
        }