Skip to content

Commit 7380202

Browse files
committed
Updated extensions to account for nulls
Also added unit tests for these scenarios
1 parent 92efc36 commit 7380202

3 files changed

Lines changed: 82 additions & 4 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using NSubstitute;
4+
using SystemsRx.Extensions;
5+
using Xunit;
6+
7+
namespace SystemsRx.Tests.SystemsRx.Extensions
8+
{
9+
public class IDictionaryExtensionTests
10+
{
11+
[Fact]
12+
public void should_work_with_nulls_and_disposables_individually()
13+
{
14+
var mockDisposable1 = Substitute.For<IDisposable>();
15+
var mockDisposable2 = Substitute.For<IDisposable>();
16+
17+
var dictionary = new Dictionary<int, IDisposable>
18+
{
19+
{ 1, null },
20+
{ 2, mockDisposable1 },
21+
{ 3, null },
22+
{ 4, mockDisposable2 }
23+
};
24+
25+
dictionary.RemoveAndDispose(1);
26+
dictionary.RemoveAndDispose(2);
27+
dictionary.RemoveAndDispose(3);
28+
dictionary.RemoveAndDispose(4);
29+
30+
Assert.Empty(dictionary);
31+
mockDisposable1.Received(1).Dispose();
32+
mockDisposable2.Received(1).Dispose();
33+
}
34+
35+
[Fact]
36+
public void should_work_with_nulls_and_disposables()
37+
{
38+
var mockDisposable1 = Substitute.For<IDisposable>();
39+
var mockDisposable2 = Substitute.For<IDisposable>();
40+
41+
var dictionary = new Dictionary<int, IDisposable>
42+
{
43+
{ 1, null },
44+
{ 2, mockDisposable1 },
45+
{ 3, null },
46+
{ 4, mockDisposable2 }
47+
};
48+
49+
dictionary.RemoveAndDisposeAll();
50+
51+
Assert.Empty(dictionary);
52+
mockDisposable1.Received(1).Dispose();
53+
mockDisposable2.Received(1).Dispose();
54+
}
55+
56+
[Fact]
57+
public void should_work_with_nulls_and_disposables_in_enumerable()
58+
{
59+
var mockDisposable1 = Substitute.For<IDisposable>();
60+
var mockDisposable2 = Substitute.For<IDisposable>();
61+
62+
var collection = new[]
63+
{
64+
null,
65+
mockDisposable1,
66+
null,
67+
mockDisposable2
68+
};
69+
70+
collection.DisposeAll();
71+
72+
Assert.Equal(4, collection.Length);
73+
mockDisposable1.Received(1).Dispose();
74+
mockDisposable2.Received(1).Dispose();
75+
}
76+
}
77+
}

src/SystemsRx/Extensions/IDictionaryExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ public static class IDictionaryExtensions
77
{
88
public static void RemoveAndDispose<T>(this IDictionary<T, IDisposable> disposables, T key)
99
{
10-
disposables[key].Dispose();
10+
var disposable = disposables[key];
1111
disposables.Remove(key);
12+
disposable?.Dispose();
1213
}
1314

1415
public static void RemoveAndDisposeAll<T>(this IDictionary<T, IDisposable> disposables)
1516
{
16-
disposables.ForEachRun(x => x.Value.Dispose());
17+
disposables.ForEachRun(x => x.Value?.Dispose());
1718
disposables.Clear();
1819
}
1920
}

src/SystemsRx/Extensions/IDisposableExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ public static class IDisposableExtensions
88
public static void DisposeAll(this IEnumerable<IDisposable> disposables)
99
{
1010
foreach(var disposable in disposables)
11-
{ disposable.Dispose(); }
11+
{ disposable?.Dispose(); }
1212
}
1313

1414
public static void DisposeAll<T>(this IDictionary<T, IDisposable> disposables)
1515
{
1616
foreach(var disposable in disposables.Values)
17-
{ disposable.Dispose(); }
17+
{ disposable?.Dispose(); }
1818
}
1919

2020
public static IDisposable AddTo(this IDisposable currentDisposable, ICollection<IDisposable> disposables)

0 commit comments

Comments
 (0)