Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,46 @@ public static partial class EntityExtensions
{
/// <summary>
/// <para>
/// Returns a boolean observable that emits true when the entity opens and emits false when the entity closes.
/// The observable is distinct until changed. Other state changes are ignored.
/// Returns a boolean observable that emits <see langword="true"/> when the entity opens
/// and emits <see langword="false"/> when the entity closes or changes to any other state.
/// The observable is distinct until changed.
/// </para>
/// <para>
/// State changes other than open or closed (on or off on the entity) are ignored. This also includes a null entity state. This is typically received when an entity is removed. This will not be emitted in the observable.
/// Any state other than "on" (such as off, unknown, unavailable, or a null state when
/// the entity is removed) is treated as closed and will emit <see langword="false"/>.
/// </para>
/// </summary>
public static IObservable<bool> ToOpenClosedObservable(this Entity entity) => entity.ToBooleanObservable();

/// <summary>
/// <para>
/// Returns a boolean observable that emits true when the entity turns on and emits false when the entity turns off.
/// The observable is distinct until changed. Other state changes are ignored.
/// Returns a boolean observable that emits <see langword="true"/> when the entity turns on
/// and emits <see langword="false"/> when the entity turns off or changes to any other state.
/// The observable is distinct until changed.
/// </para>
/// <para>
/// State changes other than on or off are ignored. This also includes a null entity state. This is typically received when an entity is removed. This will not be emitted in the observable.
/// Any state other than "on" (such as off, unknown, unavailable, or a null state when
/// the entity is removed) is treated as off and will emit <see langword="false"/>.
/// </para>
/// </summary>
public static IObservable<bool> ToOnOffObservable(this Entity entity) => entity.ToBooleanObservable();

/// <summary>
/// <para>
/// Returns a boolean observable that emits true when the entity turns on and emits false when the entity turns off.
/// The observable is distinct until changed. Other state changes are ignored.
/// Returns a boolean observable that emits true when the entity turns on and emits false when the entity changes to any other state (including off, unknown, unavailable or null).
/// The observable is distinct until changed.
/// </para>
/// <para>
/// State changes other than on or off are ignored. This also includes a null entity state. This is typically received when an entity is removed. This will not be emitted in the observable.
/// A null entity state, which typically indicates the entity has been removed, will emit false.
/// </para>
/// </summary>
public static IObservable<bool> ToBooleanObservable(this Entity entity)
{
ArgumentNullException.ThrowIfNull(entity);

var statefulObservable = entity.Stateful();

var trueObservable =
statefulObservable
.Where(s => s.New?.IsOn() ?? false)
.Select(_ => true);

var falseObservable =
statefulObservable
.Where(s => s.New?.IsOff() ?? false)
.Select(_ => false);

return trueObservable.Merge(falseObservable).DistinctUntilChanged();
return entity.Stateful()
.Select(s => s.New?.IsOn() ?? false)
.DistinctUntilChanged();
}

/// <summary>
Expand Down Expand Up @@ -97,31 +91,21 @@ public static IObservable<bool>

/// <summary>
/// <para>
/// Returns a boolean observable that emits true when the entity turns on and emits false when the entity turns off.
/// Returns a boolean observable that emits true when the entity turns on and emits false when the entity changes to any other state (including off, unknown, unavailable or null).
/// Predicate will be evaluated on all state changes, including attribute changes.
/// The observable only emits changes and will not emit the initial state.
/// The observable is distinct until changed. Other state changes are ignored.
/// </para>
/// <para>
/// State changes other than on or off are ignored. This also includes a null entity state. This is typically received when an entity is removed. This will not be emitted in the observable.
/// The observable only emits subsequent changes and will not emit the initial state.
/// A null entity state, which typically indicates the entity has been removed, will emit false.
/// </para>
/// </summary>
public static IObservable<bool> ToChangesOnlyBooleanObservable(this Entity entity)
{
ArgumentNullException.ThrowIfNull(entity);

var statefulObservable = entity.StateAllChanges();
var trueObservable =
statefulObservable
.Where(s => s.New?.IsOn() ?? false)
.Select(_ => true);

var falseObservable =
statefulObservable
.Where(s => s.New?.IsOff() ?? false)
.Select(_ => false);

return trueObservable.Merge(falseObservable).DistinctUntilChanged();
return entity.StateAllChanges()
.Select(s => s.New?.IsOn() ?? false)
.DistinctUntilChanged();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void ToBooleanObservable_Distinct()
}

[TestMethod]
public void ToBooleanObservable_OtherStatesAreIgnored()
public void ToBooleanObservable_OtherStates_ReturnFalse()
{
// Arrange
var results = new List<bool>();
Expand All @@ -113,11 +113,11 @@ public void ToBooleanObservable_OtherStatesAreIgnored()
ChangeEntityState("Something else");

// Assert
CollectionAssert.AreEqual(new[] { true }, results);
CollectionAssert.AreEqual(new[] { true, false }, results);
}

[TestMethod]
public void ToBooleanObservable_NullIgnored()
public void ToBooleanObservable_NullReturnsFalse()
{
// Arrange
var results = new List<bool>();
Expand All @@ -127,7 +127,7 @@ public void ToBooleanObservable_NullIgnored()
EntityStateNull();

// Assert
CollectionAssert.AreEqual(new[] { true }, results);
CollectionAssert.AreEqual(new[] { true, false }, results);
}

[TestMethod]
Expand Down Expand Up @@ -244,7 +244,7 @@ public void ToChangesOnlyBooleanObservable_Distinct()
}

[TestMethod]
public void ToChangesOnlyBooleanObservable_OtherStatesAreIgnored()
public void ToChangesOnlyBooleanObservable_OtherStates_ReturnFalse()
{
// Arrange
var results = new List<bool>();
Expand All @@ -254,11 +254,11 @@ public void ToChangesOnlyBooleanObservable_OtherStatesAreIgnored()
ChangeEntityState("Something else");

// Assert
Assert.IsEmpty(results);
CollectionAssert.AreEqual(new[] { false }, results);
}

[TestMethod]
public void ToChangesOnlyBooleanObservable_NullIgnored()
public void ToChangesOnlyBooleanObservable_NullReturnsFalse()
{
// Arrange
var results = new List<bool>();
Expand All @@ -268,7 +268,7 @@ public void ToChangesOnlyBooleanObservable_NullIgnored()
EntityStateNull();

// Assert
Assert.IsEmpty(results);
CollectionAssert.AreEqual(new[] { false }, results);
}

[TestMethod]
Expand Down