Skip to content

Commit 11db230

Browse files
authored
Fix the WhenStateIsSame should not call action when completed (#1134)
* Fix the WhenStateIsSame should not call action when completed * better naming * remove one where clause
1 parent 9712288 commit 11db230

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

src/HassModel/NetDaemon.HassModel.Tests/StateObservableExtensionsTest.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,34 @@ public StateObservableExtensionsTest()
2020
EntityState.Map<NumericEntityState>(e.New)));
2121
}
2222

23+
[Fact]
24+
public void TestThatWhenStateIsForDoesNotCallActionWhenCompleted()
25+
{
26+
bool isCalled = false;
27+
28+
_subject.WhenStateIsFor(n => n?.State == "off", TimeSpan.FromSeconds(10), _testScheduler).Subscribe(_ => { isCalled = true;});
29+
30+
_subject.OnNext(new StateChange(new Entity(new Mock<IHaContext>().Object, ""), new EntityState { State = "on" }, new EntityState { State = "off" }));
31+
32+
_subject.OnCompleted();
33+
34+
isCalled.Should().BeFalse();
35+
}
36+
37+
[Fact]
38+
public void TestNumericEntityWhenStateIsForDoesNotCallActionWhenCompleted()
39+
{
40+
bool isCalled = false;
41+
42+
_numericStateChangeObservable.WhenStateIsFor(n => n?.State > 20, TimeSpan.FromSeconds(10), _testScheduler).Subscribe(_ => { isCalled = true;});
43+
44+
_subject.OnNext(new StateChange(new Entity(new Mock<IHaContext>().Object, ""), new EntityState { State = "1" }, new EntityState { State = "30" }));
45+
46+
_subject.OnCompleted();
47+
48+
isCalled.Should().BeFalse();
49+
}
50+
2351
[Fact]
2452
public void WhenNumStateIsForFiresInTime()
2553
{

src/HassModel/NetDeamon.HassModel/StateObservableExtensions.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,18 @@ public static IObservable<StateChange> WhenStateIsFor(
4242
ArgumentNullException.ThrowIfNull(predicate, nameof(predicate));
4343
ArgumentNullException.ThrowIfNull(scheduler, nameof(scheduler));
4444

45+
var isCompleted = false;
46+
4547
return observable
48+
.Do(_ => {}, () => isCompleted = true)
4649
// Only process changes that start or stop matching the predicate
4750
.Where(e => predicate(e.Old) != predicate(e.New))
4851

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

5255
// But only when the new state matches the predicate we emit it
53-
.Where(e => predicate(e.New));
56+
.Where(e => predicate(e.New) && isCompleted == false);
5457
}
5558

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

74+
var isCompleted = false;
75+
7176
return observable
77+
.Do(_ => {}, () => isCompleted = true)
7278
.Where(e => predicate(e.Old) != predicate(e.New))
7379
.Throttle(timeSpan, scheduler)
74-
.Where(e => predicate(e.New));
80+
.Where(e => predicate(e.New) && isCompleted == false);
7581
}
7682
}

0 commit comments

Comments
 (0)