Esempio n. 1
0
        /// <summary>
        /// Creates initializes <see cref="SequentialProgressController"/>
        /// </summary>
        /// <param name="serviceProvider">Service provider instance. Required.</param>
        /// <param name="stepFactory"><see cref="IProgressStepFactory"/> to use when create steps from definitions</param>
        /// <param name="stepsDefinition">One or more instance of <see cref="IProgressStepDefinition"/></param>
        /// <returns>The initialized <see cref="SequentialProgressController"/></returns>
        public static SequentialProgressController Create(IServiceProvider serviceProvider, IProgressStepFactory stepFactory, params IProgressStepDefinition[] stepsDefinition)
        {
            SequentialProgressController controller = new SequentialProgressController(serviceProvider);

            controller.Initialize(stepFactory, stepsDefinition);
            return(controller);
        }
 public void TestCleanup()
 {
     this.errorNotifier = null;
     this.serviceProvider = null;
     this.testSubject = null;
     this.threadingService = null;
 }
 public void TestInitialize()
 {
     this.serviceProvider = new ConfigurableServiceProvider();
     this.threadingService = new SingleThreadedTaskSchedulerService();
     this.serviceProvider.RegisterService(typeof(SVsTaskSchedulerService), this.threadingService);
     this.testSubject = new SequentialProgressController(this.serviceProvider);
 }
        /// <summary>
        /// The <see cref="ProgressControllerStep"/> which are used by default will swallow the assert exceptions
        /// which means that investigating why something is failing requires more time and effort.
        /// This extension method will record the first <see cref="UnitTestAssertException"/> which was thrown during 
        /// execution and will rethrow it on a way that will allow the test to fail and see the original stack
        /// that caused the test failure (on Finished event)
        /// </summary>
        /// <param name="controller">The controller to configure</param>
        /// <returns>The notifier that was used for configuration of the assert exception</returns>
        public static ConfigurableErrorNotifier ConfigureToThrowAssertExceptions(SequentialProgressController controller)
        {
            Assert.IsNotNull(controller, "Controller argument is required");
            Assert.IsNotNull(controller.Steps, "Controller needs to be initialized");

            ConfigurableErrorNotifier errorHandler = new ConfigurableErrorNotifier();
            controller.ErrorNotificationManager.AddNotifier(errorHandler);

            UnitTestAssertException originalException = null;

            // Controller.Finished is executed out of the awaitable state machine and on the calling (UI) thread
            // which means that at this point the test runtime engine will be able to catch it and fail the test 
            EventHandler<ProgressControllerFinishedEventArgs> onFinished = null;
            onFinished = (s, e) =>
            {
                // Need to register on the UI thread
                VsThreadingHelper.RunTask(controller, Microsoft.VisualStudio.Shell.VsTaskRunContext.UIThreadNormalPriority, () =>
                {
                    controller.Finished -= onFinished;
                }).Wait();

                // Satisfy the sequential controller verification code
                e.Handled();

                if (originalException != null)
                {
                    Assert.AreEqual(ProgressControllerResult.Failed, e.Result, "Expected to be failed since the assert failed which causes an exception");
                    throw new RestoredUnitTestAssertException(originalException.Message, originalException);
                }
            };

            // Need to register on the UI thread
            VsThreadingHelper.RunTask(controller, Microsoft.VisualStudio.Shell.VsTaskRunContext.UIThreadNormalPriority, () =>
            {
                controller.Finished += onFinished;
            }).Wait();

            errorHandler.NotifyAction = (e) =>
            {
                // Only the first one
                if (originalException == null)
                {
                    originalException = e as UnitTestAssertException;
                }
            };
            return errorHandler;
        }
        public static IProgressEvents StartAsync(IServiceProvider sp, IProgressControlHost host, Func<IProgressController, ProgressStepDefinition[]> stepFactory)
        {
            if (sp == null)
            {
                throw new ArgumentNullException(nameof(sp));
            }

            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }

            if (stepFactory == null)
            {
                throw new ArgumentNullException(nameof(stepFactory));
            }

            Debug.Assert(ThreadHelper.CheckAccess(), "Expected to be called on the UI thread");

            // Initialize a controller and an observer
            var controller = new SequentialProgressController(sp);
            controller.Initialize(stepFactory(controller));

            IVsOutputWindowPane sonarLintPane = VsShellUtils.GetOrCreateSonarLintOutputPane(sp);

            bool logFullMessage;
#if DEBUG
            logFullMessage = true;
#else
            logFullMessage = false;
#endif
            var notifier = new VsOutputWindowPaneNotifier(sp,
                sonarLintPane,
                ensureOutputVisible: true,
                messageFormat: Strings.UnexpectedWorkflowError,
                logFullException: logFullMessage);
            controller.ErrorNotificationManager.AddNotifier(notifier);

            Observe(controller, host);
            controller.RunOnFinished(r => observedControllersMap.Remove(controller));
#pragma warning disable 4014 // We do want to start and forget. All the errors will be forwarded via the error notification manager
            controller.Start();
#pragma warning restore 4014

            return controller;
        }
 /// <summary>
 /// Creates initializes <see cref="SequentialProgressController"/>
 /// </summary>
 /// <param name="serviceProvider">Service provider instance. Required.</param>
 /// <param name="stepFactory"><see cref="IProgressStepFactory"/> to use when create steps from definitions</param>
 /// <param name="stepsDefinition">One or more instance of <see cref="IProgressStepDefinition"/></param>
 /// <returns>The initialized <see cref="SequentialProgressController"/></returns>
 public static SequentialProgressController Create(IServiceProvider serviceProvider, IProgressStepFactory stepFactory, params IProgressStepDefinition[] stepsDefinition)
 {
     SequentialProgressController controller = new SequentialProgressController(serviceProvider);
     controller.Initialize(stepFactory, stepsDefinition);
     return controller;
 }
 /// <summary>
 /// Initializes the specified controller with custom error handler that will allow assertions to be raised
 /// </summary>
 /// <param name="controller">Controller instance to initialize</param>
 /// <param name="definitions">The step definitions to initialize the controller with</param>
 /// <returns>The notifier that was used for test assert exceptions</returns>
 public static ConfigurableErrorNotifier InitializeWithTestErrorHandling(SequentialProgressController controller, params ProgressStepDefinition[] definitions)
 {
     controller.Initialize(definitions);
     return ConfigureToThrowAssertExceptions(controller);
 }