コード例 #1
0
        public void Test_AsyncRelayCommand_WithCanExecuteFunctionFalse()
        {
            int ticks = 0;

            var command = new AsyncRelayCommand(
                () =>
            {
                ticks++;
                return(Task.CompletedTask);
            }, () => false);

            Assert.IsFalse(command.CanExecute(null));
            Assert.IsFalse(command.CanExecute(new object()));

            Assert.IsFalse(command.CanBeCanceled);
            Assert.IsFalse(command.IsCancellationRequested);

            command.Execute(null);

            Assert.AreEqual(ticks, 0);

            command.Execute(new object());

            Assert.AreEqual(ticks, 0);
        }
コード例 #2
0
        public async Task CanExecuteChanged_RemoveHandler_HandlerIsNotCalled()
        {
            var commandExecuted = false;

            _canExecuteChangedRaised = false;

            var command = new AsyncRelayCommand(_ =>
            {
                // ReSharper disable once AccessToModifiedClosure
                Assert.False(commandExecuted);
                commandExecuted = true;
                return(Task.CompletedTask);
            });

            command.CanExecuteChanged += CommandOnCanExecuteChanged;

            command.Execute(null);

            await Task.Delay(100);

            Assert.True(commandExecuted);
            Assert.True(_canExecuteChangedRaised);

            _canExecuteChangedRaised = false;
            commandExecuted          = false;

            command.CanExecuteChanged -= CommandOnCanExecuteChanged;

            command.Execute(null);

            await Task.Delay(100);

            Assert.True(commandExecuted);
            Assert.False(_canExecuteChangedRaised);
        }
コード例 #3
0
        public async Task Execute_Wait_ActionIsExecuted()
        {
            var commandExecuted         = false;
            var canExecuteChangedRaised = false;

            var command = new AsyncRelayCommand(_ =>
            {
                Assert.False(commandExecuted);
                commandExecuted = true;
                return(Task.CompletedTask);
            });

            command.CanExecuteChanged += (_, _) =>
            {
                Assert.False(canExecuteChangedRaised);
                canExecuteChangedRaised = true;
            };

            command.Execute(null);

            await Task.Delay(100);

            Assert.True(commandExecuted);
            Assert.True(canExecuteChangedRaised);
        }
コード例 #4
0
        public async Task Test_AsyncRelayCommand_WithCancellation()
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            var command = new AsyncRelayCommand(token => tcs.Task);

            Assert.IsTrue(command.CanExecute(null));
            Assert.IsTrue(command.CanExecute(new object()));

            Assert.IsTrue(command.CanBeCanceled);
            Assert.IsFalse(command.IsCancellationRequested);

            command.Execute(null);

            Assert.IsFalse(command.IsCancellationRequested);

            command.Cancel();

            Assert.IsTrue(command.IsCancellationRequested);

            tcs.SetResult(null);

            await command.ExecutionTask !;

            Assert.IsTrue(command.IsCancellationRequested);
        }
コード例 #5
0
        public void ActionPredicateInvocation()
        {
            IAsyncExecutionContext context = new AsyncExecutionContext();
            var invoked           = false;
            var canExecuteInvoked = false;

            ICommand rc = new AsyncRelayCommand(context,
                                                async(t) => invoked = true,
                                                () =>
            {
                canExecuteInvoked = true;
                return(true);
            });

            Assert.IsFalse(invoked);
            Assert.IsFalse(canExecuteInvoked);

            Assert.IsTrue(rc.CanExecute(null));

            Assert.IsFalse(invoked);
            Assert.IsTrue(canExecuteInvoked);

            canExecuteInvoked = false;

            rc.Execute(null);

            Assert.IsTrue(invoked);
            Assert.IsTrue(canExecuteInvoked);
        }
コード例 #6
0
        public async Task ExecuteAsync_ExceptionInExecute_ErrorHandlerIsCalled()
        {
            Exception handledException = null;

            var errorHandler = A.Fake <IErrorHandler>();

            A
            .CallTo(() => errorHandler.HandleException(A <Exception> .Ignored))
            .Invokes(call => handledException = call.Arguments.Get <Exception>(0));

            var command = new AsyncRelayCommand <string>(parameter =>
            {
                if (parameter == null)
                {
                    throw new ArgumentNullException(nameof(parameter));
                }
                return(Task.CompletedTask);
            }, errorHandler);

            command.Execute(null);

            await Task.Delay(100);

            Assert.IsType <ArgumentNullException>(handledException);
        }
コード例 #7
0
        public void TestExecutionSetOnExecute()
        {
            var cmd = new AsyncRelayCommand(() => Task.CompletedTask);

            cmd.Execute();

            Assert.IsNotNull(cmd.Execution);
        }
コード例 #8
0
        public async Task Test_AsyncRelayCommandOfT_AlwaysEnabled()
        {
            int ticks = 0;

            var command = new AsyncRelayCommand <string>(async s =>
            {
                await Task.Delay(1000);
                ticks = int.Parse(s);
                await Task.Delay(1000);
            });

            Assert.IsTrue(command.CanExecute(null));
            Assert.IsTrue(command.CanExecute("1"));

            (object, EventArgs)args = default;

            command.CanExecuteChanged += (s, e) => args = (s, e);

            command.NotifyCanExecuteChanged();

            Assert.AreSame(args.Item1, command);
            Assert.AreSame(args.Item2, EventArgs.Empty);

            Assert.IsNull(command.ExecutionTask);
            Assert.IsFalse(command.IsRunning);

            Task task = command.ExecuteAsync((object)"42");

            Assert.IsNotNull(command.ExecutionTask);
            Assert.AreSame(command.ExecutionTask, task);
            Assert.IsTrue(command.IsRunning);

            await task;

            Assert.IsFalse(command.IsRunning);

            Assert.AreEqual(ticks, 42);

            command.Execute("2");

            await command.ExecutionTask !;

            Assert.AreEqual(ticks, 2);

            Assert.ThrowsException <InvalidCastException>(() => command.Execute(new object()));
        }
コード例 #9
0
        public async Task Test_AsyncRelayCommand_WithCancellation()
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            // We need to test the cancellation support here, so we use the overload with an input
            // parameter, which is a cancellation token. The token is the one that is internally managed
            // by the AsyncRelayCommand instance, and canceled when using IAsyncRelayCommand.Cancel().
            var command = new AsyncRelayCommand(token => tcs.Task);

            List <PropertyChangedEventArgs> args = new List <PropertyChangedEventArgs>();

            command.PropertyChanged += (s, e) => args.Add(e);

            // We have no canExecute parameter, so the command can always be invoked
            Assert.IsTrue(command.CanExecute(null));
            Assert.IsTrue(command.CanExecute(new object()));

            // The command isn't running, so it can't be canceled yet
            Assert.IsFalse(command.CanBeCanceled);
            Assert.IsFalse(command.IsCancellationRequested);

            // Start the command, which will return the token from our task completion source.
            // We can use that to easily keep the command running while we do our tests, and then
            // stop the processing by completing the source when we need (see below).
            command.Execute(null);

            // The command is running, so it can be canceled, as we used the token overload
            Assert.IsTrue(command.CanBeCanceled);
            Assert.IsFalse(command.IsCancellationRequested);

            // Validate the various event args for all the properties that were updated when executing the command
            Assert.AreEqual(args.Count, 4);
            Assert.AreEqual(args[0].PropertyName, nameof(IAsyncRelayCommand.IsCancellationRequested));
            Assert.AreEqual(args[1].PropertyName, nameof(IAsyncRelayCommand.ExecutionTask));
            Assert.AreEqual(args[2].PropertyName, nameof(IAsyncRelayCommand.IsRunning));
            Assert.AreEqual(args[3].PropertyName, nameof(IAsyncRelayCommand.CanBeCanceled));

            command.Cancel();

            // Verify that these two properties raised notifications correctly when canceling the command too.
            // We need to ensure all command properties support notifications so that users can bind to them.
            Assert.AreEqual(args.Count, 6);
            Assert.AreEqual(args[4].PropertyName, nameof(IAsyncRelayCommand.IsCancellationRequested));
            Assert.AreEqual(args[5].PropertyName, nameof(IAsyncRelayCommand.CanBeCanceled));

            Assert.IsTrue(command.IsCancellationRequested);

            // Complete the source, which will mark the command as completed too (as it returned the same task)
            tcs.SetResult(null);

            await command.ExecutionTask !;

            // Verify that the command can no longer be canceled, and that the cancellation is
            // instead still true, as that's reset when executing a command and not on completion.
            Assert.IsFalse(command.CanBeCanceled);
            Assert.IsTrue(command.IsCancellationRequested);
        }
コード例 #10
0
        public void ParameterTransferTest()
        {
            IAsyncExecutionContext context = new AsyncExecutionContext();
            var param = 12356;

            var rc = new AsyncRelayCommand <int>(
                context,
                async(i, t) => Assert.AreEqual(param, i),
                i => i == param);

            rc.Execute(param);
        }
コード例 #11
0
        public void Test_WithoutParameter_Execute()
        {
            // Arrange.
            var command = new AsyncRelayCommand(DelayAndSet);

            // Act.
            command.Execute(true);

            // Assert.
            resetEvent.Wait();
            Assert.True(resetEvent.IsSet);
        }
コード例 #12
0
        public void Test_AsyncRelayCommand_WithCanExecuteFunctionTrue()
        {
            int ticks = 0;

            var command = new AsyncRelayCommand(
                () =>
            {
                ticks++;
                return(Task.CompletedTask);
            }, () => true);

            Assert.IsTrue(command.CanExecute(null));
            Assert.IsTrue(command.CanExecute(new object()));

            command.Execute(null);

            Assert.AreEqual(ticks, 1);

            command.Execute(new object());

            Assert.AreEqual(ticks, 2);
        }
コード例 #13
0
        public void ActionInvokation()
        {
            IAsyncExecutionContext context = new AsyncExecutionContext();
            var invoked = false;

            var rc = new AsyncRelayCommand <int>(context, async(i, t) => invoked = true);

            Assert.IsFalse(invoked);

            rc.Execute(0);

            Assert.IsTrue(invoked);
        }
コード例 #14
0
        public void Test_AsyncRelayCommandOfT_WithCanExecuteFunctionFalse()
        {
            int ticks = 0;

            var command = new AsyncRelayCommand <string>(
                s =>
            {
                ticks = int.Parse(s);
                return(Task.CompletedTask);
            }, s => false);

            Assert.IsFalse(command.CanExecute(null));
            Assert.IsFalse(command.CanExecute("1"));

            command.Execute("2");

            Assert.AreEqual(ticks, 0);

            command.Execute("42");

            Assert.AreEqual(ticks, 0);
        }
コード例 #15
0
        public void NonGenericAsyncRelayCommandExecuteShouldInvokeExecuteActionException()
        {
            var executed = false;
            var command  = new AsyncRelayCommand(
                async() =>
            {
                await Task.Yield();
                throw new Exception("Test Exception");
            }) as ICommand;

            command.Execute(new object());

            Assert.False(executed);
        }
コード例 #16
0
        public void TestPropertyChangedRaisedOnExecuteForExecution()
        {
            var cmd = new AsyncRelayCommand(() => Task.CompletedTask);

            var changes = new List <string>();

            cmd.PropertyChanged += (sender, e) =>
            {
                changes.Add(e.PropertyName);
            };

            cmd.Execute();

            CollectionAssert.AreEqual(new[] { nameof(AsyncRelayCommand.Execution) }, changes);
        }
コード例 #17
0
        public void TestExplicitExecute()
        {
            int executeRunCount = 0;

            Func <Task> execute = () =>
            {
                executeRunCount++;
                return(Task.CompletedTask);
            };

            ICommand cmd = new AsyncRelayCommand(execute);

            cmd.Execute(null);

            Assert.AreEqual(1, executeRunCount);
        }
コード例 #18
0
        public async Task Test_AsyncRelayCommand_AlwaysEnabled()
        {
            int ticks = 0;

            var command = new AsyncRelayCommand(async() =>
            {
                await Task.Delay(1000);
                ticks++;
                await Task.Delay(1000);
            });

            Assert.IsTrue(command.CanExecute(null));
            Assert.IsTrue(command.CanExecute(new object()));

            Assert.IsFalse(command.CanBeCanceled);
            Assert.IsFalse(command.IsCancellationRequested);

            (object, EventArgs)args = default;

            command.CanExecuteChanged += (s, e) => args = (s, e);

            command.NotifyCanExecuteChanged();

            Assert.AreSame(args.Item1, command);
            Assert.AreSame(args.Item2, EventArgs.Empty);

            Assert.IsNull(command.ExecutionTask);
            Assert.IsFalse(command.IsRunning);

            Task task = command.ExecuteAsync(null);

            Assert.IsNotNull(command.ExecutionTask);
            Assert.AreSame(command.ExecutionTask, task);
            Assert.IsTrue(command.IsRunning);

            await task;

            Assert.IsFalse(command.IsRunning);

            Assert.AreEqual(ticks, 1);

            command.Execute(new object());

            await command.ExecutionTask !;

            Assert.AreEqual(ticks, 2);
        }
コード例 #19
0
        public async Task NonGenericAsyncRelayCommandExecuteShouldInvokeExecuteAction()
        {
            var executed = false;
            var command  = new AsyncRelayCommand(
                async() =>
            {
                await Task.Delay(50);
                executed = true;
            }) as ICommand;

            command.Execute(new object());

            Assert.False(executed);
            await Task.Delay(100);

            Assert.True(executed);
        }
コード例 #20
0
        public void IsBusyTest()
        {
            var mock = new Mock <IAsyncExecutionContext>();

            mock.SetupGet(o => o.IsBusy).Returns(true);
            var invoked = false;

            var rc = new AsyncRelayCommand <int>(
                mock.Object,
                async(i, t) => invoked = true);

            Assert.IsFalse(invoked);

            rc.Execute(10);

            Assert.IsFalse(invoked);
        }
コード例 #21
0
        public void ExecuteCallsPassedInExecuteDelegate()
        {
            var handlers = new AsyncDelegateObjectHandlers();

            using var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

            var command = new AsyncRelayCommand <object>(async o =>
            {
                await handlers.Execute(o);
                waitHandle.Set();
            }) as ICommand;
            var parameter = new object();

            command.Execute(parameter);
            waitHandle.WaitOne();
            Assert.AreSame(parameter, handlers.ExecuteParameter);
        }
コード例 #22
0
        public void ActionPredicateInvocationOnExecute()
        {
            IAsyncExecutionContext context = new AsyncExecutionContext();
            var invoked           = false;
            var canExecuteInvoked = false;

            var rc = new AsyncRelayCommand <int>(context, async(i, t) => invoked = true,
                                                 i => { canExecuteInvoked = true; return(true); });

            Assert.IsFalse(invoked);
            Assert.IsFalse(canExecuteInvoked);

            rc.Execute(0);

            Assert.IsTrue(invoked);
            Assert.IsTrue(canExecuteInvoked);
        }
コード例 #23
0
        public void TestExecuteRunsDelegate()
        {
            int executeRunCount = 0;

            // note: this needs to be 100% synchronous so we don't end up with a race condition
            Func <Task> execute = () =>
            {
                executeRunCount++;
                return(Task.CompletedTask);
            };

            var cmd = new AsyncRelayCommand(execute);

            cmd.Execute();

            Assert.AreEqual(1, executeRunCount);
        }
コード例 #24
0
        public async Task NonGenericAsyncRelayCommandExecuteShouldInvokeExecuteActionException2()
        {
            Exception exception = null;
            var       command   = new AsyncRelayCommand(
                async() =>
            {
                await Task.Delay(50);
                throw new Exception("Test Exception");
            },
                ex => exception = ex) as ICommand;

            command.Execute(new object());

            Assert.Null(exception);
            await Task.Delay(100);

            Assert.NotNull(exception);
            Assert.AreEqual("Test Exception", exception.Message);
        }
コード例 #25
0
        public void TestExplicitExecuteWrongType()
        {
            int executeRunCount = 0;

            Func <int, Task> execute = (x) =>
            {
                executeRunCount++;
                return(Task.CompletedTask);
            };

            ICommand cmd = new AsyncRelayCommand <int>(execute);

            // exact exception will depend on the conversion
            Assert.ThrowsException <InvalidCastException>(
                () => cmd.Execute(new IncompatibleType())
                );

            Assert.AreEqual(0, executeRunCount);
        }
コード例 #26
0
        public void NonGenericAsyncRelayCommandExecuteShouldInvokeExecuteActionErrorHandler()
        {
            var executed = false;
            var hasError = false;

            using  var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

            var command = new AsyncRelayCommand(
                async() =>
            {
                await Task.Yield();
                executed = true;
                waitHandle.Set();
            },
                ex => hasError = true) as ICommand;

            command.Execute(new object());

            waitHandle.WaitOne();
            Task.Delay(50);
            Assert.False(hasError);
            Assert.True(executed);
        }
コード例 #27
0
        public void Test_AsyncRelayCommandOfT_NullWithValueType()
        {
            int n = 0;

            var command = new AsyncRelayCommand <int>(i =>
            {
                n = i;
                return(Task.CompletedTask);
            });

            Assert.IsFalse(command.CanExecute(null));
            Assert.ThrowsException <NullReferenceException>(() => command.Execute(null));

            command = new AsyncRelayCommand <int>(
                i =>
            {
                n = i;
                return(Task.CompletedTask);
            }, i => i > 0);

            Assert.IsFalse(command.CanExecute(null));
            Assert.ThrowsException <NullReferenceException>(() => command.Execute(null));
        }
コード例 #28
0
        public void WhenConstructedWithGenericTypeIsNonNullableValueType_Throws()
        {
            ICommand command = new AsyncRelayCommand <int>(async o => await Task.Yield(), exception => { });

            Assert.Throws <InvalidCastException>(() => { command.Execute(new object()); });
        }