Skip to content

Commit

Permalink
Fix the WhenStateIsSame should not call action when completed (#1134)
Browse files Browse the repository at this point in the history
* Fix the WhenStateIsSame should not call action when completed

* better naming

* remove one where clause
  • Loading branch information
helto4real authored Jul 7, 2024
1 parent 9712288 commit 11db230
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,34 @@ public StateObservableExtensionsTest()
EntityState.Map<NumericEntityState>(e.New)));
}

[Fact]
public void TestThatWhenStateIsForDoesNotCallActionWhenCompleted()
{
bool isCalled = false;

_subject.WhenStateIsFor(n => n?.State == "off", TimeSpan.FromSeconds(10), _testScheduler).Subscribe(_ => { isCalled = true;});

_subject.OnNext(new StateChange(new Entity(new Mock<IHaContext>().Object, ""), new EntityState { State = "on" }, new EntityState { State = "off" }));

_subject.OnCompleted();

isCalled.Should().BeFalse();
}

[Fact]
public void TestNumericEntityWhenStateIsForDoesNotCallActionWhenCompleted()
{
bool isCalled = false;

_numericStateChangeObservable.WhenStateIsFor(n => n?.State > 20, TimeSpan.FromSeconds(10), _testScheduler).Subscribe(_ => { isCalled = true;});

_subject.OnNext(new StateChange(new Entity(new Mock<IHaContext>().Object, ""), new EntityState { State = "1" }, new EntityState { State = "30" }));

_subject.OnCompleted();

isCalled.Should().BeFalse();
}

[Fact]
public void WhenNumStateIsForFiresInTime()
{
Expand Down
10 changes: 8 additions & 2 deletions src/HassModel/NetDeamon.HassModel/StateObservableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ public static IObservable<StateChange> WhenStateIsFor(
ArgumentNullException.ThrowIfNull(predicate, nameof(predicate));
ArgumentNullException.ThrowIfNull(scheduler, nameof(scheduler));

var isCompleted = false;

return observable
.Do(_ => {}, () => isCompleted = true)
// Only process changes that start or stop matching the predicate
.Where(e => predicate(e.Old) != predicate(e.New))

// Both will restart the timer
.Throttle(timeSpan, scheduler)

// But only when the new state matches the predicate we emit it
.Where(e => predicate(e.New));
.Where(e => predicate(e.New) && isCompleted == false);
}

/// <summary>
Expand All @@ -68,9 +71,12 @@ public static IObservable<StateChange<TEntity, TEntityState>> WhenStateIsFor<TEn
ArgumentNullException.ThrowIfNull(predicate, nameof(predicate));
ArgumentNullException.ThrowIfNull(scheduler, nameof(scheduler));

var isCompleted = false;

return observable
.Do(_ => {}, () => isCompleted = true)
.Where(e => predicate(e.Old) != predicate(e.New))
.Throttle(timeSpan, scheduler)
.Where(e => predicate(e.New));
.Where(e => predicate(e.New) && isCompleted == false);
}
}

0 comments on commit 11db230

Please sign in to comment.