public async Task It_removes_all_stack_entries_when_it_clears()
        {
            var sut = new BlindStackNavigator();

            // Add an item to the stack.
            await sut.Navigate(CancellationToken.None, StackNavigatorRequest.GetNavigateRequest(() => new TestVM()));

            // Clear the stack.
            await sut.Clear(CancellationToken.None);

            // Stack must be empty.
            Assert.Empty(sut.State.Stack);
        }
        public async Task It_disposes_VMs_when_clearing()
        {
            var sut = new BlindStackNavigator();

            // Add 2 items to the stack.
            var vm0 = (TestVM)await sut.Navigate(CancellationToken.None, StackNavigatorRequest.GetNavigateRequest(() => new TestVM(0)));

            var vm1 = (TestVM)await sut.Navigate(CancellationToken.None, StackNavigatorRequest.GetNavigateRequest(() => new TestVM(1)));

            // Clear to remove all items.
            await sut.Clear(CancellationToken.None);

            // All entries must be disposed.
            Assert.True(vm0.IsDisposed);
            Assert.True(vm1.IsDisposed);
        }
        public async Task Interface_contract_changes_can_be_detected()
        {
            var             ct        = CancellationToken.None;
            IStackNavigator navigator = new BlindStackNavigator();

            // If the core contract changes, we get compilation errors here.
            INavigableViewModel vmAfterNavigate = await navigator.Navigate(ct, StackNavigatorRequest.GetNavigateRequest(() => new TestVM(), false, false));

            INavigableViewModel vmAfterBack = await navigator.NavigateBack(ct);

            await navigator.Clear(ct);

            // Navigate twice so that RemoveEntries works.
            await navigator.Navigate(ct, StackNavigatorRequest.GetNavigateRequest(() => new TestVM(), false, false));

            await navigator.Navigate(ct, StackNavigatorRequest.GetNavigateRequest(() => new TestVM(), false, false));

            await navigator.RemoveEntries(ct, new int[] { 0 }.AsEnumerable());
        }
        public async Task It_produces_failed_notifications_for_Clear()
        {
            var sut = new BlindStackNavigator();

            await sut.Navigate(CancellationToken.None, StackNavigatorRequest.GetNavigateRequest(() => new TestVM(throwOnDispose: true)));

            var events = new List <StackNavigatorEventArgs>();

            sut.StateChanged += Sut_StateChanged;

            void Sut_StateChanged(object sender, StackNavigatorEventArgs args)
            {
                events.Add(args);
            }

            await Assert.ThrowsAsync <InvalidOperationException>(async() => await sut.Clear(CancellationToken.None));

            sut.StateChanged -= Sut_StateChanged;

            // There must be 2 notifications: 1 Processing when the clear starts and 1 FailedToProcess when it ends.
            Assert.Equal(2, events.Count);
            Assert.Equal(NavigatorRequestState.Processing, events[0].CurrentState.LastRequestState);
            Assert.Equal(NavigatorRequestState.FailedToProcess, events[1].CurrentState.LastRequestState);
        }
        public async Task It_produces_2_notifications_for_Clear()
        {
            var sut = new BlindStackNavigator();

            await sut.Navigate(CancellationToken.None, StackNavigatorRequest.GetNavigateRequest(() => new TestVM()));

            var events = new List <StackNavigatorEventArgs>();

            sut.StateChanged += Sut_StateChanged;

            void Sut_StateChanged(object sender, StackNavigatorEventArgs args)
            {
                events.Add(args);
            }

            await sut.Clear(CancellationToken.None);

            sut.StateChanged -= Sut_StateChanged;

            // There must be 2 notifications: 1 Processing when the clear starts and 1 Processed when it ends.
            Assert.Equal(2, events.Count);
            Assert.Equal(NavigatorRequestState.Processing, events[0].CurrentState.LastRequestState);
            Assert.Equal(NavigatorRequestState.Processed, events[1].CurrentState.LastRequestState);
        }