• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

net-daemon / netdaemon / 16665318319

01 Aug 2025 03:13AM UTC coverage: 83.619% (-0.5%) from 84.091%
16665318319

Pull #1323

github

web-flow
Merge 6bcfe26ea into 8be16906a
Pull Request #1323: Added Equal(object) to ServiceTarget so FluentAssertions of equality work correctly

875 of 1179 branches covered (74.22%)

Branch coverage included in aggregate %.

13 of 29 new or added lines in 1 file covered. (44.83%)

3372 of 3900 relevant lines covered (86.46%)

1890.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.05
/src/HassModel/NetDaemon.HassModel/ServiceTarget.cs
1
namespace NetDaemon.HassModel.Entities;
2

3
/// <summary>
4
/// Target for a service call
5
/// </summary>
6
public class ServiceTarget
7
{
8
    /// <summary>
9
    /// Creates a new ServiceTarget from an EntityId
10
    /// </summary>
11
    /// <param name="entityId">The Id of the entity</param>
12
    /// <returns>A new ServiceTarget</returns>
13
    public static ServiceTarget FromEntity(string entityId) =>
14
        new() { EntityIds = new[] { entityId } };
29✔
15

16
    /// <summary>
17
    /// Creates a new ServiceTarget from a list of EntityIds
18
    /// </summary>
19
    /// <param name="entityIds">The Ids of entities</param>
20
    /// <returns>A new ServiceTarget</returns>
21
    public static ServiceTarget FromEntities(IEnumerable<string> entityIds) =>
22
        new() { EntityIds = entityIds.ToArray() };
×
23

24
    /// <summary>
25
    /// Creates a new ServiceTarget from EntityIds
26
    /// </summary>
27
    /// <param name="entityIds">The Ids of entities</param>
28
    /// <returns>A new ServiceTarget</returns>
29
    public static ServiceTarget FromEntities(params string[] entityIds) =>
30
        new() { EntityIds = [.. entityIds] };
18✔
31

32
    /// <summary>
33
    /// Override low level object Equals.  This is used by fluent assertions and other libraries to compare objects 
34
    /// </summary>
35
    /// <param name="obj">The object that we are comparing to</param>
36
    /// <returns>true if the two objects are the same (Reference equal), or if the two objects are ServiceTargets and passes the Equal test</returns>
37
    public override bool Equals(object? obj)
38
    {
39
        if (ReferenceEquals(this, obj))
6!
40
        {
NEW
41
            return true;
×
42
        }
43

44
        if (obj is null)
6!
45
        {
NEW
46
            return false;
×
47
        }
48

49
        if (obj.GetType() != GetType())
6!
50
        {
NEW
51
            return false;
×
52
        }
53

54
        ServiceTarget other = (ServiceTarget)obj;
6✔
55
        //return Equals((ServiceTarget)obj);
56
        return AreCollectionsEqual(EntityIds, other.EntityIds)
6✔
57
            && AreCollectionsEqual(DeviceIds, other.DeviceIds)
6✔
58
            && AreCollectionsEqual(AreaIds, other.AreaIds)
6✔
59
            && AreCollectionsEqual(FloorIds, other.FloorIds)
6✔
60
            && AreCollectionsEqual(LabelIds, other.LabelIds);
6✔
61

62
    }
63

64
    private static bool AreCollectionsEqual(IReadOnlyCollection<string>? a, IReadOnlyCollection<string>? b)
65
    {
66
        if (ReferenceEquals(a, b))
18✔
67
            return true;
12✔
68
        if (a is null || b is null)
6!
NEW
69
            return false;
×
70
        bool bReturn = a.Count == b.Count && !a.Except(b).Any();
6!
NEW
71
        return bReturn;
×
72
    }
73

74
    /// <summary>
75
    /// Override the GetHashCode for completeness for equality checking
76
    /// </summary>
77
    /// <returns>integer hash code for this ServiceTarget</returns>
78
    public override int GetHashCode()
79
    {
NEW
80
        int hash = 17;
×
NEW
81
        hash = hash * 23 + (EntityIds is null ? 0 : GetCollectionHashCode(EntityIds));
×
NEW
82
        hash = hash * 23 + (DeviceIds is null ? 0 : GetCollectionHashCode(DeviceIds));
×
NEW
83
        hash = hash * 23 + (AreaIds is null ? 0 : GetCollectionHashCode(AreaIds));
×
NEW
84
        hash = hash * 23 + (FloorIds is null ? 0 : GetCollectionHashCode(FloorIds));
×
NEW
85
        hash = hash * 23 + (LabelIds is null ? 0 : GetCollectionHashCode(LabelIds));
×
NEW
86
        return hash;
×
87
    }
88

89
    private static int GetCollectionHashCode(IReadOnlyCollection<string> collection)
90
    {
91
        unchecked
92
        {
NEW
93
            int hash = 19;
×
NEW
94
            foreach (var item in collection.OrderBy(x => x))
×
95
            {
NEW
96
                hash = hash * 31 + item.GetHashCode(StringComparison.Ordinal);
×
97
            }
NEW
98
            return hash;
×
99
        }
100
    }
101

102

103
    /// <summary>
104
    /// Creates a new empty ServiceTarget
105
    /// </summary>
106
    public ServiceTarget()
51✔
107
    { }
51✔
108

109
    /// <summary>
110
    /// IDs of entities to invoke a service on
111
    /// </summary>
112
    public IReadOnlyCollection<string>? EntityIds { get; init; }
91✔
113

114
    /// <summary>
115
    /// Ids of Devices to invoke a service on
116
    /// </summary>
117
    public IReadOnlyCollection<string>? DeviceIds { get; init; }
29✔
118

119
    /// <summary>
120
    /// Ids of Areas to invoke a service on
121
    /// </summary>
122
    public IReadOnlyCollection<string>? AreaIds { get; init; }
29✔
123

124
    /// <summary>
125
    /// Ids of floors to invoke a service on
126
    /// </summary>
127
    public IReadOnlyCollection<string>? FloorIds { get; init; }
31✔
128

129
    /// <summary>
130
    /// Ids of labels to invoke a service on
131
    /// </summary>
132
    public IReadOnlyCollection<string>? LabelIds { get; init; }
31✔
133

134
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc