public void TestObservePropertyChanged_Fail()
        {
            // 被観測者, 観測者を生成します
            var model    = new ObservableModel();
            var observer = new Observer <PropertyChangedEventArgs>();

            // イベント購読が失敗することを確認します
            Assert.Throws <ArgumentException>(() => { model.ObservePropertyChanged(o => "notPropertyName"); });
            Assert.Throws <ArgumentException>(() => { model.ObservePropertyChanged(o => o.GetType()); });
        }
        public void TestSubscribeWeakly_AutoUnsubscribe()
        {
            // 被観測者, 観測者を生成します
            var model    = new ObservableModel();
            var observer = new Observer <PropertyChangedEventArgs>();
            var observerWeakReference = new WeakReference(observer);

            // イベントを購読します
            var subscription =
                model
                .ObservePropertyChanged()
                .SubscribeWeakly(observer.OnObservedEvent);
            var subscriptionWeakReference = new WeakReference(subscription);

            // サブスクリプションを観測者に持たせておき, 観測者が破棄されるとき自動的に購読解除されるようにします
            observer.Subscriptions.Add(subscription);

            // サブスクリプションへの参照を破棄します
            subscription = null;

            // 観測者を破棄します
            observer = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();

            // 被観測者, サブスクリプションが回収されたことで, 自動での購読解除を確認します
            Assert.That(observerWeakReference.IsAlive, Is.False);
            Assert.That(subscriptionWeakReference.IsAlive, Is.False);

            // オブジェクトを延命します
            Console.WriteLine(model);
        }
        public void TestSubscribeWeakly_ReferenceStrongness()
        {
            // 被観測者, 観測者を生成します
            var model = new ObservableModel();
            var modelWeakReference = new WeakReference(model);
            var observer           = new Observer <PropertyChangedEventArgs>();

            // イベントを購読します
            var subscription =
                model
                .ObservePropertyChanged()
                .SubscribeWeakly(observer.OnObservedEvent);

            // 被観測者, 観測者への参照を破棄し, GCを実行します
            model    = null;
            observer = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();

            // 被観測者が破棄されないことを確認します
            Assert.That(modelWeakReference.IsAlive, Is.True);

            // イベントを購読解除します
            subscription.Dispose();

            // 被観測者が破棄されることで, Subscriptionから被観測者への参照が強参照でることを確認します
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Assert.That(modelWeakReference.IsAlive, Is.False);

            // オブジェクトを延命します
            Console.WriteLine(subscription);
        }
        public void TestSubscribeWeakly_ReferenceWeakness()
        {
            // 被観測者, 観測者を生成します
            var model    = new ObservableModel();
            var observer = new Observer <PropertyChangedEventArgs>();
            var observerWeakReference = new WeakReference(observer);

            // イベントを購読します
            var subscription =
                model
                .ObservePropertyChanged()
                .SubscribeWeakly(observer.OnObservedEvent);

            // 観測者を破棄. 回収します
            observer = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();

            // 観測者が回収されたことで, ハンドラへの弱参照性を確認する
            Assert.That(observerWeakReference.IsAlive, Is.False);

            // オブジェクトを延命します
            Console.WriteLine(model);
            Console.WriteLine(subscription);
        }
        public void TestSubscribeWeakly()
        {
            // 被観測者, 観測者を生成します
            var model    = new ObservableModel();
            var observer = new Observer <PropertyChangedEventArgs>();

            // イベントを購読します
            var subscription =
                model
                .ObservePropertyChanged()
                .SubscribeWeakly(observer.OnObservedEvent);

            observer.Subscriptions.Add(subscription);

            // イベントを送受信することで, 以上の動作を確認します
            model.Qty = 8;
            Assert.That(observer.LastEventArgs.PropertyName, Is.EqualTo(nameof(model.Qty)));

            // イベント購読を解除します
            observer.Subscriptions.Dispose();

            // イベントを受信できないことで, 以上の動作を確認します
            observer.LastEventArgs = null;
            model.Qty = 16;
            Assert.That(observer.LastEventArgs, Is.Null);
        }