// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Reactive.Linq; using Microsoft.Reactive.Testing; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace ReactiveTests.Tests { [TestClass] public class DistinctUntilChangedTest : ReactiveTest { [TestMethod] public void DistinctUntilChanged_ArgumentChecking() { var someObservable = Observable.Empty(); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(null)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(null, EqualityComparer.Default)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(someObservable, null)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(null, _ => _)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(someObservable, null)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(someObservable, _ => _, null)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(null, _ => _, EqualityComparer.Default)); ReactiveAssert.Throws(() => Observable.DistinctUntilChanged(someObservable, null, EqualityComparer.Default)); } [TestMethod] public void DistinctUntilChanged_Never() { var scheduler = new TestScheduler(); var xs = Observable.Never(); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( ); } [TestMethod] public void DistinctUntilChanged_Empty() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_Return() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(220, 2), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( OnNext(220, 2), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_Throw() { var scheduler = new TestScheduler(); var ex = new Exception(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnError(250, ex) ); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( OnError(250, ex) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_AllChanges() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), OnNext(220, 3), OnNext(230, 4), OnNext(240, 5), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( OnNext(210, 2), OnNext(220, 3), OnNext(230, 4), OnNext(240, 5), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_AllSame() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), OnNext(220, 2), OnNext(230, 2), OnNext(240, 2), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( OnNext(210, 2), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_SomeChanges() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), //* OnNext(215, 3), //* OnNext(220, 3), OnNext(225, 2), //* OnNext(230, 2), OnNext(230, 1), //* OnNext(240, 2), //* OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged() ); res.Messages.AssertEqual( OnNext(210, 2), OnNext(215, 3), OnNext(225, 2), OnNext(230, 1), OnNext(240, 2), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_Comparer_AllEqual() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), OnNext(220, 3), OnNext(230, 4), OnNext(240, 5), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged(new FuncComparer((x, y) => true)) ); res.Messages.AssertEqual( OnNext(210, 2), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_Comparer_AllDifferent() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), OnNext(220, 2), OnNext(230, 2), OnNext(240, 2), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged(new FuncComparer((x, y) => false)) ); res.Messages.AssertEqual( OnNext(210, 2), OnNext(220, 2), OnNext(230, 2), OnNext(240, 2), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } [TestMethod] public void DistinctUntilChanged_KeySelector_Div2() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), //* OnNext(220, 4), OnNext(230, 3), //* OnNext(240, 5), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged(x => x % 2) ); res.Messages.AssertEqual( OnNext(210, 2), OnNext(230, 3), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } private class FuncComparer : IEqualityComparer { private readonly Func _equals; public FuncComparer(Func equals) { _equals = equals; } public bool Equals(T x, T y) { return _equals(x, y); } public int GetHashCode(T obj) { return 0; } } [TestMethod] public void DistinctUntilChanged_KeySelectorThrows() { var ex = new Exception(); var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged(new Func(x => { throw ex; })) ); res.Messages.AssertEqual( OnError(210, ex) ); } [TestMethod] public void DistinctUntilChanged_ComparerThrows() { var ex = new Exception(); var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), OnNext(220, 3), OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged(new ThrowComparer(ex)) ); res.Messages.AssertEqual( OnNext(210, 2), OnError(220, ex) ); } private class ThrowComparer : IEqualityComparer { private readonly Exception _ex; public ThrowComparer(Exception ex) { _ex = ex; } public bool Equals(T x, T y) { throw _ex; } public int GetHashCode(T obj) { return 0; } } [TestMethod] public void DistinctUntilChanged_KeySelector_Comparer() { var scheduler = new TestScheduler(); var xs = scheduler.CreateHotObservable( OnNext(150, 1), OnNext(210, 2), // * key = 1 % 3 = 1 OnNext(220, 8), // key = 4 % 3 = 1 same OnNext(230, 2), // key = 1 % 3 = 1 same OnNext(240, 5), // * key = 2 % 3 = 2 OnCompleted(250) ); var res = scheduler.Start(() => xs.DistinctUntilChanged(x => x / 2, new FuncComparer((x, y) => x % 3 == y % 3)) ); res.Messages.AssertEqual( OnNext(210, 2), OnNext(240, 5), OnCompleted(250) ); xs.Subscriptions.AssertEqual( Subscribe(200, 250) ); } } }