为什么合并的可观察序列不会以与其组成序列之一相同的方式发出信号?

时间:2014-07-15 15:38:38

标签: c# system.reactive reactiveui

请参阅下面的两个单元测试(ReactiveObject来自ReactiveUI)。唯一的区别是第一个单元测试监视合并的序列,第二个单元测试监视合并的序列之一。第一个单元测试失败,而第二个单元测试通过。

UPDATE:具体来说,第一次单元测试在最后一次断言时失败,因为hitCount为零而不是1.第二次单元测试成功。

为什么第一个单元测试失败

[TestFixture]
public class ReactiveListTests : ReactiveObject
{
    private bool _showAll;

    private IReactiveDerivedList<Node> _nodes;

    public bool ShowAll
    {
        get { return _showAll; }
        set { this.RaiseAndSetIfChanged(ref _showAll, value); }
    }

    public class Node : ReactiveObject
    {
        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set { this.RaiseAndSetIfChanged(ref _isSelected, value); }
        }

        private bool _isHidden;
        public bool IsHidden
        {
            get { return _isHidden; }
            set { this.RaiseAndSetIfChanged(ref _isHidden, value); }
        }

        public ReactiveList<Node> Nodes { get; private set; }

        public Node()
        {
            Nodes = new ReactiveList<Node>(scheduler: Scheduler.Immediate) { ChangeTrackingEnabled = true };
        }
    }


    [Test]
    public void WhenInnerReactiveListItemIsChanged_ThenObservableShouldBeSignaled()
    {
        var inner = new[] { new Node() { Nodes = { new Node() } } };
        var nodes = new ReactiveList<Node>(inner, scheduler: Scheduler.Immediate);

        // set up combined signal
        var nodeChanged = nodes.Select(node => node.Nodes.ItemChanged).Merge().Select(_ =>
            {
                return Unit.Default;
            });
        var showAllToggled = this.WhenAnyValue(vm => vm.ShowAll).Select(_ => 
            {
                return Unit.Default;
            });
        var signal = nodeChanged.Merge(showAllToggled);

        _nodes = nodes.CreateDerivedCollection(node => node,
                                               node => ShowAll || node.Nodes.Any(innerNode => !innerNode.IsHidden),
                                               null,
                                               signal);

        // whenever inner node item changes, increment
        int hitCount = 0;
        signal.Subscribe(_ =>
            {
                hitCount++;
            });

        Assert.AreEqual(0, hitCount);

        _nodes[0].Nodes[0].IsSelected = true;

        Assert.AreEqual(1, hitCount);
    }


    [Test]
    public void WhenInnerReactiveListItemIsChanged_ThenObservableShouldBeSignaled2()
    {
        var inner = new[] { new Node() { Nodes = { new Node() } } };
        var nodes = new ReactiveList<Node>(inner, scheduler: Scheduler.Immediate);

        // set up combined signal
        var nodeChanged = nodes.Select(node => node.Nodes.ItemChanged).Merge().Select(_ =>
            {
                return Unit.Default;
            });
        var showAllToggled = this.WhenAnyValue(vm => vm.ShowAll).Select(_ => 
            {
                return Unit.Default;
            });
        var signal = nodeChanged.Merge(showAllToggled);

        _nodes = nodes.CreateDerivedCollection(node => node,
                                               node => ShowAll || node.Nodes.Any(innerNode => !innerNode.IsHidden),
                                               null,
                                               signal);

        // whenever inner node item changes, increment
        int hitCount = 0;
        nodeChanged.Subscribe(_ =>
            {
                hitCount++;
            });

        Assert.AreEqual(0, hitCount);

        _nodes[0].Nodes[0].IsSelected = true;

        Assert.AreEqual(1, hitCount);
    }

0 个答案:

没有答案