Skip to content

[BUG] Sample code from Handbook is not working #533

Description

@SirRufo

Describe the bug

The given sample from Handbook/MessageBus/Ways to avoid using MessageBus is not working. Only the last added item is handled correct (removed from the list).

It worked fine on version 10.5.43 and failed after that (>=11.*).

Steps To Reproduce

using DynamicData;
using DynamicData.Binding;

using ReactiveUI;

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;

using Xunit;

namespace ReactiveUITests
{
    /// <summary>
    /// <code>https://www.reactiveui.net/docs/handbook/message-bus/#ways-to-avoid-using-messagebus</code>
    /// </summary>
    public class MessageBusWaysToAvoidUsingMessageBusTest
    {
        public class DocumentViewModel : ReactiveObject
        {
            public ReactiveCommand<Unit, Unit> Close { get; set; }

            public DocumentViewModel()
            {
                // Note that we don't actually *subscribe* to Close here or implement
                // anything in DocumentViewModel, because Closing is a responsibility
                // of the document list.
                Close = ReactiveCommand.Create(() => { });
            }
        }

        public class MainViewModel : ReactiveObject
        {
            public ObservableCollection<DocumentViewModel> OpenDocuments { get; protected set; }

            public MainViewModel()
            {
                OpenDocuments = new ObservableCollection<DocumentViewModel>();

                // Whenever the list of documents change, calculate a new Observable
                // to represent whenever any of the *current* documents have been
                // requested to close, then Switch to that. When we get something
                // to close, remove it from the list.
                OpenDocuments
                    .ToObservableChangeSet()
                    .AutoRefreshOnObservable(document => document.Close)
                    .Select(_ => WhenAnyDocumentClosed())
                    .Switch()
                    .Subscribe(x => OpenDocuments.Remove(x));
            }

            IObservable<DocumentViewModel> WhenAnyDocumentClosed()
            {
                // Select the documents into a list of Observables
                // who return the Document to close when signaled,
                // then flatten them all together.
                return OpenDocuments
                    .Select(x => x.Close.Select(_ => x))
                    .Merge();
            }
        }

        [Fact]
        public void TestWithSingleDocument()
        {
            var main = new MainViewModel();
            var doc = new DocumentViewModel();
            main.OpenDocuments.Add(doc);

            doc.Close.Execute().Subscribe();
            var actual = main.OpenDocuments.Count;

            Assert.Equal(0, actual);
        }

        [Fact]
        public void TestWithFirstFromMultipleDocuments()
        {
            var main = new MainViewModel();
            var doc = new DocumentViewModel();
            main.OpenDocuments.Add(doc);
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());

            doc.Close.Execute().Subscribe();
            var actual = main.OpenDocuments.Count;

            Assert.Equal(4, actual);
        }

        [Fact]
        public void TestWithCenterFromMultipleDocuments()
        {
            var main = new MainViewModel();
            var doc = new DocumentViewModel();
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(doc);
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());

            doc.Close.Execute().Subscribe();
            var actual = main.OpenDocuments.Count;

            Assert.Equal(4, actual);
        }

        [Fact]
        public void TestWithLastFromMultipleDocuments()
        {
            var main = new MainViewModel();
            var doc = new DocumentViewModel();
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(new DocumentViewModel());
            main.OpenDocuments.Add(doc);

            doc.Close.Execute().Subscribe();
            var actual = main.OpenDocuments.Count;

            Assert.Equal(4, actual);
        }
    }
}

Environment

  • OS: Windows
  • Version 10.0.19044.1466
  • ReactiveUI Version: 11.* -> 17.1.17

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions