From 3e064ea9c9a2533a1cf1f9e39ab1ca59277ac603 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 08:43:14 +0200 Subject: [PATCH 01/17] added an editor config file to handle spacing --- LazyCache/.editorconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 LazyCache/.editorconfig diff --git a/LazyCache/.editorconfig b/LazyCache/.editorconfig new file mode 100644 index 0000000..82e9297 --- /dev/null +++ b/LazyCache/.editorconfig @@ -0,0 +1,11 @@ +# To learn more about .editorconfig see https://aka.ms/editorconfigdocs +root = true + +# All files +[*.cs] +indent_style = space +indent_size = 4 + +# Xml files +[*.xml] +indent_size = 2 From a3d8845df257119def4ab87154739e5c956229f1 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 08:55:52 +0200 Subject: [PATCH 02/17] added the editor config to the unit test project too removed the null check for the item parameter in the CachingService.Add method --- LazyCache.UnitTests/.editorconfig | 7 +++++++ .../CachingServiceMemoryCacheProviderTests.cs | 14 ++++++++++++-- LazyCache/.editorconfig | 6 +----- LazyCache/CachingService.cs | 2 -- 4 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 LazyCache.UnitTests/.editorconfig diff --git a/LazyCache.UnitTests/.editorconfig b/LazyCache.UnitTests/.editorconfig new file mode 100644 index 0000000..8ee9848 --- /dev/null +++ b/LazyCache.UnitTests/.editorconfig @@ -0,0 +1,7 @@ +# To learn more about .editorconfig see https://aka.ms/editorconfigdocs +root = true + +# C# files +[*.cs] +indent_style = space +indent_size = 4 diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index f381820..20a3436 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -127,10 +127,20 @@ public void AddNullKeyThrowsExceptionWithSliding() } [Test] - public void AddNullThrowsException() + public void AddNullDoesNotThrowException() { Action act = () => sut.Add(TestKey, null); - act.Should().Throw(); + act.Should().NotThrow(); + } + + [Test] + public void AddNullThenGetReturnsCachedNullReference() + { + const string testValue = null; + + sut.Add(TestKey, testValue); + + Assert.IsNull(sut.Get(TestKey)); } [Test] diff --git a/LazyCache/.editorconfig b/LazyCache/.editorconfig index 82e9297..8ee9848 100644 --- a/LazyCache/.editorconfig +++ b/LazyCache/.editorconfig @@ -1,11 +1,7 @@ # To learn more about .editorconfig see https://aka.ms/editorconfigdocs root = true -# All files +# C# files [*.cs] indent_style = space indent_size = 4 - -# Xml files -[*.xml] -indent_size = 2 diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index 6becdd3..11cb8a2 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -64,8 +64,6 @@ public virtual int DefaultCacheDuration public virtual void Add(string key, T item, MemoryCacheEntryOptions policy) { - if (item == null) - throw new ArgumentNullException(nameof(item)); ValidateKey(key); CacheProvider.Set(key, item, policy); From 3cf902f8c098eabdef809916fc81fb2fe9fe163d Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 09:26:39 +0200 Subject: [PATCH 03/17] added another unit test for checking that adding null to the cache works as expected --- .../CachingServiceMemoryCacheProviderTests.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 20a3436..02a7650 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -143,6 +143,18 @@ public void AddNullThenGetReturnsCachedNullReference() Assert.IsNull(sut.Get(TestKey)); } + [Test] + public void AddNullThenTryGetReturnsTrueAndTheCachedNullReference() + { + const string testValue = null; + sut.Add(TestKey, testValue); + + var contains = sut.TryGetValue(TestKey, out var value); + + Assert.IsTrue(contains); + Assert.IsNull(value); + } + [Test] public void AddThenGetReturnsCachedObject() { From 13984b6c4263f61ba752233ad93d50347ace4831 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 09:36:55 +0200 Subject: [PATCH 04/17] Changed the signature for IAppCache so that the generic argument is actually used --- .../CachingServiceMemoryCacheProviderTests.cs | 5 +++-- LazyCache/CachingService.cs | 7 +++++-- LazyCache/IAppCache.cs | 2 +- LazyCache/Mocks/MockCachingService.cs | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 02a7650..c75d2c7 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1134,8 +1134,8 @@ public void RemovedItemCannotBeRetrievedFromCache() [Test] public void TryGetReturnsCachedValueAndTrue() { - string val = "Test Value"; - string key = "testkey"; + const string val = "Test Value"; + const string key = "testkey"; sut.Add(key, val); var contains = sut.TryGetValue(key, out var value); @@ -1146,6 +1146,7 @@ public void TryGetReturnsCachedValueAndTrue() var contains2 = sut.TryGetValue("invalidkey", out var value2); Assert.IsFalse(contains2); + Assert.IsNull(value2); } } } \ No newline at end of file diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index 11cb8a2..be6e944 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -87,11 +87,14 @@ public virtual Task GetAsync(string key) return GetValueFromAsyncLazy(item, out _); } - public virtual bool TryGetValue(string key, out object value) + public virtual bool TryGetValue(string key, out T value) { ValidateKey(key); - return CacheProvider.TryGetValue(key, out value); + var keyWasFound = CacheProvider.TryGetValue(key, out var cachedValue); + value = (T)cachedValue; + + return keyWasFound; } public virtual T GetOrAdd(string key, Func addItemFactory) diff --git a/LazyCache/IAppCache.cs b/LazyCache/IAppCache.cs index 3d9133d..1bf9737 100644 --- a/LazyCache/IAppCache.cs +++ b/LazyCache/IAppCache.cs @@ -15,7 +15,7 @@ public interface IAppCache void Add(string key, T item, MemoryCacheEntryOptions policy); T Get(string key); Task GetAsync(string key); - bool TryGetValue(string key, out object value); + bool TryGetValue(string key, out T value); T GetOrAdd(string key, Func addItemFactory); T GetOrAdd(string key, Func addItemFactory, MemoryCacheEntryOptions policy); diff --git a/LazyCache/Mocks/MockCachingService.cs b/LazyCache/Mocks/MockCachingService.cs index 9c9be86..4e9076d 100644 --- a/LazyCache/Mocks/MockCachingService.cs +++ b/LazyCache/Mocks/MockCachingService.cs @@ -52,7 +52,7 @@ public void Add(string key, T item, MemoryCacheEntryOptions policy) { } - public bool TryGetValue(string key, out object value) + public bool TryGetValue(string key, out T value) { value = default(T); return true; From 24230a9f09a7ec4452b8b05157fdc1c1541ac917 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 10:27:50 +0200 Subject: [PATCH 05/17] Reimplemented IAppCache.TryGetValue so that it works after a call to GetOrAdd --- .../CachingServiceMemoryCacheProviderTests.cs | 13 +++++++++++++ LazyCache/CachingService.cs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index c75d2c7..173ab78 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1148,5 +1148,18 @@ public void TryGetReturnsCachedValueAndTrue() Assert.IsFalse(contains2); Assert.IsNull(value2); } + + [Test] + public void GetOrAddThenTryGetReturnsCachedValueAndTrue() + { + const string value = "Test Value"; + const string key = "testkey"; + sut.GetOrAdd(key, () => value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + } } } \ No newline at end of file diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index be6e944..6e0d69f 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -92,7 +92,7 @@ public virtual bool TryGetValue(string key, out T value) ValidateKey(key); var keyWasFound = CacheProvider.TryGetValue(key, out var cachedValue); - value = (T)cachedValue; + value = GetValueFromLazy(cachedValue, out _); return keyWasFound; } From d65ee61a5b767052514d2b948703f26562227b58 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 10:34:09 +0200 Subject: [PATCH 06/17] added unit test for complex object --- .../CachingServiceMemoryCacheProviderTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 173ab78..b9ad5c3 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1160,6 +1160,27 @@ public void GetOrAddThenTryGetReturnsCachedValueAndTrue() Assert.IsTrue(contains); Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); + } + + [Test] + public void GetOrAddComplexObjectThenTryGetReturnsCachedValueAndTrue() + { + sut.GetOrAdd(TestKey, () => testObject); + + var contains = sut.TryGetValue(TestKey, out var value); + + Assert.IsTrue(contains); + Assert.AreEqual(testObject, value); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); } } } \ No newline at end of file From b891ec51e820b8d3f50f7e275e0e9a07105fe88e Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 10:47:29 +0200 Subject: [PATCH 07/17] Added some unit test to be sure that TryGet works as expected --- .../CachingServiceMemoryCacheProviderTests.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index b9ad5c3..5ae08f2 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1182,5 +1182,77 @@ public void GetOrAddComplexObjectThenTryGetReturnsCachedValueAndTrue() Assert.IsFalse(contains2); Assert.IsNull(value2); } + + [Test] + public void GetOrAddValueTypeThenTryGetReturnsCachedValueAndTrue() + { + const int value = 13; + const string key = "testkey"; + sut.GetOrAdd(key, () => value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.AreEqual(default(int), value2); + } + + [Test] + public void GetOrAddStructThenTryGetReturnsCachedValueAndTrue() + { + var value = new DateTime(2021, 6, 20, 10, 41, 13); + const string key = "testkey"; + sut.GetOrAdd(key, () => value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.AreEqual(default(DateTime), value2); + } + + [Test] + public void GetOrAddNullableStructWithValueThenTryGetReturnsCachedValueAndTrue() + { + DateTime? value = new DateTime(2021, 6, 20, 10, 41, 13); + const string key = "testkey"; + sut.GetOrAdd(key, () => value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); + } + + [Test] + public void GetOrAddNullableStructWithoutValueThenTryGetReturnsCachedValueAndTrue() + { + DateTime? value = null; + const string key = "testkey"; + sut.GetOrAdd(key, () => value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.IsNull(fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); + } } } \ No newline at end of file From 861fd40757ba84349d07d04a4c33878fa2c4388d Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 10:59:40 +0200 Subject: [PATCH 08/17] Added other unit tests for the TryGet functionality --- .../CachingServiceMemoryCacheProviderTests.cs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 5ae08f2..b008df7 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1149,6 +1149,94 @@ public void TryGetReturnsCachedValueAndTrue() Assert.IsNull(value2); } + [Test] + public void TryGetReturnsCachedComplexObjectAndTrue() + { + sut.Add(TestKey, testObject); + + var contains = sut.TryGetValue(TestKey, out var value); + + Assert.IsTrue(contains); + Assert.AreEqual(testObject, value); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); + } + + [Test] + public void TryGetReturnsCachedValueTypeAndTrue() + { + const int value = 13; + const string key = "testkey"; + sut.Add(key, value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.AreEqual(default(int), value2); + } + + [Test] + public void TryGetReturnsCachedStructAndTrue() + { + var value = new DateTime(2021, 6, 20, 10, 41, 13); + const string key = "testkey"; + sut.Add(key, value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.AreEqual(default(DateTime), value2); + } + + [Test] + public void TryGetReturnsCachedNullableStructWithValueAndTrue() + { + DateTime? value = new DateTime(2021, 6, 20, 10, 41, 13); + const string key = "testkey"; + sut.Add(key, value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); + } + + [Test] + public void TryGetReturnsCachedNullableStructWithoutValueAndTrue() + { + DateTime? value = null; + const string key = "testkey"; + sut.Add(key, value); + + var contains = sut.TryGetValue(key, out var fetchedValue); + + Assert.IsTrue(contains); + Assert.IsNull(fetchedValue); + + var contains2 = sut.TryGetValue("invalidkey", out var value2); + + Assert.IsFalse(contains2); + Assert.IsNull(value2); + } + [Test] public void GetOrAddThenTryGetReturnsCachedValueAndTrue() { From dc70a04e64acfbea86f7684c9675bf80c741a717 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 11:02:42 +0200 Subject: [PATCH 09/17] added the idea of TryGetValueAsync --- LazyCache/CachingService.cs | 5 +++++ LazyCache/IAppCache.cs | 1 + LazyCache/Mocks/MockCachingService.cs | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index 6e0d69f..f567d9c 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -97,6 +97,11 @@ public virtual bool TryGetValue(string key, out T value) return keyWasFound; } + public bool TryGetValueAsync(string key, out Task value) + { + throw new NotImplementedException(); + } + public virtual T GetOrAdd(string key, Func addItemFactory) { return GetOrAdd(key, addItemFactory, null); diff --git a/LazyCache/IAppCache.cs b/LazyCache/IAppCache.cs index 1bf9737..a1a0417 100644 --- a/LazyCache/IAppCache.cs +++ b/LazyCache/IAppCache.cs @@ -16,6 +16,7 @@ public interface IAppCache T Get(string key); Task GetAsync(string key); bool TryGetValue(string key, out T value); + bool TryGetValueAsync(string key, out Task value); T GetOrAdd(string key, Func addItemFactory); T GetOrAdd(string key, Func addItemFactory, MemoryCacheEntryOptions policy); diff --git a/LazyCache/Mocks/MockCachingService.cs b/LazyCache/Mocks/MockCachingService.cs index 4e9076d..a540444 100644 --- a/LazyCache/Mocks/MockCachingService.cs +++ b/LazyCache/Mocks/MockCachingService.cs @@ -57,5 +57,10 @@ public bool TryGetValue(string key, out T value) value = default(T); return true; } + + public bool TryGetValueAsync(string key, out Task value) + { + throw new NotImplementedException(); + } } } \ No newline at end of file From 1e8894443934bd6ddb09b8f8ee2e34e0b2008be3 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 11:12:03 +0200 Subject: [PATCH 10/17] completed the test suite for TryGet --- .../CachingServiceMemoryCacheProviderTests.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index b008df7..0aa6296 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1131,6 +1131,48 @@ public void RemovedItemCannotBeRetrievedFromCache() Assert.Null(sut.Get(TestKey)); } + [Test] + public void TryGetThrowsWhenKeyIsNull() + { + var exception = Assert.Throws(InvokeTryGetWithNullKey); + + Assert.AreEqual("key", exception.ParamName); + + void InvokeTryGetWithNullKey() + { + const string key = null; + _ = sut.TryGetValue(key, out var _); + } + } + + [Test] + public void TryGetThrowsWhenKeyIsEmptyString() + { + var exception = Assert.Throws(InvokeTryGetWithEmptyStringKey); + + Assert.AreEqual("key", exception.ParamName); + + void InvokeTryGetWithEmptyStringKey() + { + var key = string.Empty; + _ = sut.TryGetValue(key, out var _); + } + } + + [Test] + public void TryGetThrowsWhenKeyIsWhiteSpacesString() + { + var exception = Assert.Throws(InvokeTryGetWithWhiteSpacesKey); + + Assert.AreEqual("key", exception.ParamName); + + void InvokeTryGetWithWhiteSpacesKey() + { + const string key = " "; + _ = sut.TryGetValue(key, out var _); + } + } + [Test] public void TryGetReturnsCachedValueAndTrue() { From ad3f11c528baf6491547011a0d596747d3b82f68 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 11:16:14 +0200 Subject: [PATCH 11/17] implemented TryGetValueAsync still need to add unit tests --- LazyCache/CachingService.cs | 10 ++++++++-- LazyCache/Mocks/MockCachingService.cs | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index f567d9c..d1b03ce 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -97,9 +97,15 @@ public virtual bool TryGetValue(string key, out T value) return keyWasFound; } - public bool TryGetValueAsync(string key, out Task value) + // TODO EM: add unit tests + public virtual bool TryGetValueAsync(string key, out Task value) { - throw new NotImplementedException(); + ValidateKey(key); + + var keyWasFound = CacheProvider.TryGetValue(key, out var cachedValue); + value = GetValueFromAsyncLazy(cachedValue, out _); + + return keyWasFound; } public virtual T GetOrAdd(string key, Func addItemFactory) diff --git a/LazyCache/Mocks/MockCachingService.cs b/LazyCache/Mocks/MockCachingService.cs index a540444..8857eac 100644 --- a/LazyCache/Mocks/MockCachingService.cs +++ b/LazyCache/Mocks/MockCachingService.cs @@ -60,7 +60,8 @@ public bool TryGetValue(string key, out T value) public bool TryGetValueAsync(string key, out Task value) { - throw new NotImplementedException(); + value = Task.FromResult(default(T)); + return true; } } } \ No newline at end of file From aeee17b8a182e1825ab67bd0c1a62f6cb21eb72b Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 16:28:02 +0200 Subject: [PATCH 12/17] implmenting TryGetAsync --- .../CachingServiceMemoryCacheProviderTests.cs | 210 +++++++++++++++--- 1 file changed, 174 insertions(+), 36 deletions(-) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 0aa6296..08f5659 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1131,50 +1131,39 @@ public void RemovedItemCannotBeRetrievedFromCache() Assert.Null(sut.Get(TestKey)); } + [Test] - public void TryGetThrowsWhenKeyIsNull() + public void TryGetValueThrowsWhenKeyIsNull() { - var exception = Assert.Throws(InvokeTryGetWithNullKey); + TestDelegate testDelegate = () => sut.TryGetValue(null, out var _); - Assert.AreEqual("key", exception.ParamName); + var exception = Assert.Throws(testDelegate); - void InvokeTryGetWithNullKey() - { - const string key = null; - _ = sut.TryGetValue(key, out var _); - } + Assert.AreEqual("key", exception.ParamName); } [Test] - public void TryGetThrowsWhenKeyIsEmptyString() + public void TryGetValueThrowsWhenKeyIsEmptyString() { - var exception = Assert.Throws(InvokeTryGetWithEmptyStringKey); + TestDelegate testDelegate = () => sut.TryGetValue(string.Empty, out var _); - Assert.AreEqual("key", exception.ParamName); + var exception = Assert.Throws(testDelegate); - void InvokeTryGetWithEmptyStringKey() - { - var key = string.Empty; - _ = sut.TryGetValue(key, out var _); - } + Assert.AreEqual("key", exception.ParamName); } [Test] - public void TryGetThrowsWhenKeyIsWhiteSpacesString() + public void TryGetValueThrowsWhenKeyIsWhiteSpacesString() { - var exception = Assert.Throws(InvokeTryGetWithWhiteSpacesKey); + TestDelegate testDelegate = () => sut.TryGetValue(" ", out var _); - Assert.AreEqual("key", exception.ParamName); + var exception = Assert.Throws(testDelegate); - void InvokeTryGetWithWhiteSpacesKey() - { - const string key = " "; - _ = sut.TryGetValue(key, out var _); - } + Assert.AreEqual("key", exception.ParamName); } [Test] - public void TryGetReturnsCachedValueAndTrue() + public void TryGetValueReturnsCachedValueAndTrue() { const string val = "Test Value"; const string key = "testkey"; @@ -1192,7 +1181,7 @@ public void TryGetReturnsCachedValueAndTrue() } [Test] - public void TryGetReturnsCachedComplexObjectAndTrue() + public void TryGetValueReturnsCachedComplexObjectAndTrue() { sut.Add(TestKey, testObject); @@ -1208,7 +1197,7 @@ public void TryGetReturnsCachedComplexObjectAndTrue() } [Test] - public void TryGetReturnsCachedValueTypeAndTrue() + public void TryGetValueReturnsCachedValueTypeAndTrue() { const int value = 13; const string key = "testkey"; @@ -1226,7 +1215,7 @@ public void TryGetReturnsCachedValueTypeAndTrue() } [Test] - public void TryGetReturnsCachedStructAndTrue() + public void TryGetValueReturnsCachedStructAndTrue() { var value = new DateTime(2021, 6, 20, 10, 41, 13); const string key = "testkey"; @@ -1244,7 +1233,7 @@ public void TryGetReturnsCachedStructAndTrue() } [Test] - public void TryGetReturnsCachedNullableStructWithValueAndTrue() + public void TryGetValueReturnsCachedNullableStructWithValueAndTrue() { DateTime? value = new DateTime(2021, 6, 20, 10, 41, 13); const string key = "testkey"; @@ -1262,7 +1251,7 @@ public void TryGetReturnsCachedNullableStructWithValueAndTrue() } [Test] - public void TryGetReturnsCachedNullableStructWithoutValueAndTrue() + public void TryGetValueReturnsCachedNullableStructWithoutValueAndTrue() { DateTime? value = null; const string key = "testkey"; @@ -1280,7 +1269,7 @@ public void TryGetReturnsCachedNullableStructWithoutValueAndTrue() } [Test] - public void GetOrAddThenTryGetReturnsCachedValueAndTrue() + public void GetOrAddThenTryGetValueReturnsCachedValueAndTrue() { const string value = "Test Value"; const string key = "testkey"; @@ -1298,7 +1287,7 @@ public void GetOrAddThenTryGetReturnsCachedValueAndTrue() } [Test] - public void GetOrAddComplexObjectThenTryGetReturnsCachedValueAndTrue() + public void GetOrAddComplexObjectThenTryGetValueReturnsCachedValueAndTrue() { sut.GetOrAdd(TestKey, () => testObject); @@ -1314,7 +1303,7 @@ public void GetOrAddComplexObjectThenTryGetReturnsCachedValueAndTrue() } [Test] - public void GetOrAddValueTypeThenTryGetReturnsCachedValueAndTrue() + public void GetOrAddValueTypeThenTryGetValueReturnsCachedValueAndTrue() { const int value = 13; const string key = "testkey"; @@ -1332,7 +1321,7 @@ public void GetOrAddValueTypeThenTryGetReturnsCachedValueAndTrue() } [Test] - public void GetOrAddStructThenTryGetReturnsCachedValueAndTrue() + public void GetOrAddStructThenTryGetValueReturnsCachedValueAndTrue() { var value = new DateTime(2021, 6, 20, 10, 41, 13); const string key = "testkey"; @@ -1350,7 +1339,7 @@ public void GetOrAddStructThenTryGetReturnsCachedValueAndTrue() } [Test] - public void GetOrAddNullableStructWithValueThenTryGetReturnsCachedValueAndTrue() + public void GetOrAddNullableStructWithValueThenTryGetValueReturnsCachedValueAndTrue() { DateTime? value = new DateTime(2021, 6, 20, 10, 41, 13); const string key = "testkey"; @@ -1368,7 +1357,7 @@ public void GetOrAddNullableStructWithValueThenTryGetReturnsCachedValueAndTrue() } [Test] - public void GetOrAddNullableStructWithoutValueThenTryGetReturnsCachedValueAndTrue() + public void GetOrAddNullableStructWithoutValueThenTryGetValueReturnsCachedValueAndTrue() { DateTime? value = null; const string key = "testkey"; @@ -1384,5 +1373,154 @@ public void GetOrAddNullableStructWithoutValueThenTryGetReturnsCachedValueAndTru Assert.IsFalse(contains2); Assert.IsNull(value2); } + + + + [Test] + public void TryGetValueAsyncThrowsWhenKeyIsNull() + { + TestDelegate testDelegate = () => sut.TryGetValueAsync(null, out var _); + + var exception = Assert.Throws(testDelegate); + + Assert.AreEqual("key", exception.ParamName); + } + + [Test] + public void TryGetValueAsyncThrowsWhenKeyIsEmptyString() + { + TestDelegate testDelegate = () => sut.TryGetValueAsync(string.Empty, out var _); + + var exception = Assert.Throws(testDelegate); + + Assert.AreEqual("key", exception.ParamName); + } + + [Test] + public void TryGetValueAsyncThrowsWhenKeyIsWhiteSpacesString() + { + TestDelegate testDelegate = () => sut.TryGetValueAsync(" ", out var _); + + var exception = Assert.Throws(testDelegate); + + Assert.AreEqual("key", exception.ParamName); + } + + [Test] + public async Task GetOrAddAsyncThenTryGetValueAsyncReturnsCachedValueAndTrue() + { + const string value = "Test Value"; + const string key = "testkey"; + + _ = await sut.GetOrAddAsync( + key, + async () => + { + await Task.Delay(4).ConfigureAwait(false); + return value; + } + ).ConfigureAwait(false); + + var contains = sut.TryGetValueAsync(key, out var taskForValue); + + Assert.IsTrue(contains); + Assert.IsNotNull(taskForValue); + + var fetchedValue = await taskForValue.ConfigureAwait(false); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValueAsync("invalidkey", out var taskForValue2); + + Assert.IsFalse(contains2); + Assert.IsNotNull(taskForValue2); + Assert.IsNull(await taskForValue2.ConfigureAwait(false)); + } + + [Test] + public async Task GetOrAddAsyncComplexObjectThenTryGetValueAsyncReturnsCachedValueAndTrue() + { + _ = await sut.GetOrAddAsync( + TestKey, + async () => + { + await Task.Delay(4).ConfigureAwait(false); + return testObject; + } + ).ConfigureAwait(false); + + var contains = sut.TryGetValueAsync(TestKey, out var taskForValue); + + Assert.IsTrue(contains); + Assert.IsNotNull(taskForValue); + + var fetchedValue = await taskForValue.ConfigureAwait(false); + Assert.AreEqual(testObject, fetchedValue); + + var contains2 = sut.TryGetValueAsync("invalidkey", out var taskForValue2); + + Assert.IsFalse(contains2); + Assert.IsNotNull(taskForValue2); + Assert.IsNull(await taskForValue2.ConfigureAwait(false)); + } + + [Test] + public async Task GetOrAddAsyncValueTypeThenTryGetValueAsyncReturnsCachedValueAndTrue() + { + const int value = 13; + const string key = "testkey"; + + _ = await sut.GetOrAddAsync( + key, + async () => + { + await Task.Delay(4).ConfigureAwait(false); + return value; + } + ).ConfigureAwait(false); + + var contains = sut.TryGetValueAsync(key, out var taskForValue); + + Assert.IsTrue(contains); + Assert.IsNotNull(taskForValue); + + var fetchedValue = await taskForValue.ConfigureAwait(false); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValueAsync("invalidkey", out var taskForValue2); + + Assert.IsFalse(contains2); + Assert.IsNotNull(taskForValue2); + Assert.AreEqual(default(int), await taskForValue2.ConfigureAwait(false)); + } + + [Test] + public async Task GetOrAddAsyncStructThenTryGetValueAsyncReturnsCachedValueAndTrue() + { + var value = new DateTime(2021, 6, 20, 10, 41, 13); + const string key = "testkey"; + + _ = await sut.GetOrAddAsync( + key, + async () => + { + await Task.Delay(4).ConfigureAwait(false); + return value; + } + ).ConfigureAwait(false); + + var contains = sut.TryGetValueAsync(key, out var taskForValue); + + Assert.IsTrue(contains); + Assert.IsNotNull(taskForValue); + + var fetchedValue = await taskForValue.ConfigureAwait(false); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValueAsync("invalidkey", out var taskForValue2); + + Assert.IsFalse(contains2); + Assert.IsNotNull(taskForValue2); + Assert.AreEqual(default(DateTime), await taskForValue2.ConfigureAwait(false)); + } } } \ No newline at end of file From 109ee1674b64f591cad5c4fe4c30d6b558538ef8 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 18:18:17 +0200 Subject: [PATCH 13/17] Compelted the unit test suite --- .../CachingServiceMemoryCacheProviderTests.cs | 80 ++++++++++++++++++- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 08f5659..042f2c6 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1433,7 +1433,9 @@ public async Task GetOrAddAsyncThenTryGetValueAsyncReturnsCachedValueAndTrue() Assert.IsFalse(contains2); Assert.IsNotNull(taskForValue2); - Assert.IsNull(await taskForValue2.ConfigureAwait(false)); + + var fetchedValue2 = await taskForValue2.ConfigureAwait(false); + Assert.IsNull(fetchedValue2); } [Test] @@ -1460,7 +1462,9 @@ public async Task GetOrAddAsyncComplexObjectThenTryGetValueAsyncReturnsCachedVal Assert.IsFalse(contains2); Assert.IsNotNull(taskForValue2); - Assert.IsNull(await taskForValue2.ConfigureAwait(false)); + + var fetchedValue2 = await taskForValue2.ConfigureAwait(false); + Assert.IsNull(fetchedValue2); } [Test] @@ -1490,7 +1494,9 @@ public async Task GetOrAddAsyncValueTypeThenTryGetValueAsyncReturnsCachedValueAn Assert.IsFalse(contains2); Assert.IsNotNull(taskForValue2); - Assert.AreEqual(default(int), await taskForValue2.ConfigureAwait(false)); + + var fetchedValue2 = await taskForValue2.ConfigureAwait(false); + Assert.AreEqual(default(int), fetchedValue2); } [Test] @@ -1520,7 +1526,73 @@ public async Task GetOrAddAsyncStructThenTryGetValueAsyncReturnsCachedValueAndTr Assert.IsFalse(contains2); Assert.IsNotNull(taskForValue2); - Assert.AreEqual(default(DateTime), await taskForValue2.ConfigureAwait(false)); + + var fetchedValue2 = await taskForValue2.ConfigureAwait(false); + Assert.AreEqual(default(DateTime), fetchedValue2); + } + + [Test] + public async Task GetOrAddAsyncNullableStructWithValueThenTryGetValueAsyncReturnsCachedValueAndTrue() + { + DateTime? value = new DateTime(2021, 6, 20, 10, 41, 13); + const string key = "testkey"; + + _ = await sut.GetOrAddAsync( + key, + async () => + { + await Task.Delay(4).ConfigureAwait(false); + return value; + } + ).ConfigureAwait(false); + + var contains = sut.TryGetValueAsync(key, out var taskForValue); + + Assert.IsTrue(contains); + Assert.IsNotNull(taskForValue); + + var fetchedValue = await taskForValue.ConfigureAwait(false); + Assert.AreEqual(value, fetchedValue); + + var contains2 = sut.TryGetValueAsync("invalidkey", out var taskForValue2); + + Assert.IsFalse(contains2); + Assert.IsNotNull(taskForValue2); + + var fetchedValue2 = await taskForValue2.ConfigureAwait(false); + Assert.IsNull(fetchedValue2); + } + + [Test] + public async Task GetOrAddAsyncNullableStructWithoutValueThenTryGetValueAsyncReturnsCachedValueAndTrue() + { + DateTime? value = null; + const string key = "testkey"; + + _ = await sut.GetOrAddAsync( + key, + async () => + { + await Task.Delay(4).ConfigureAwait(false); + return value; + } + ).ConfigureAwait(false); + + var contains = sut.TryGetValueAsync(key, out var taskForValue); + + Assert.IsTrue(contains); + Assert.IsNotNull(taskForValue); + + var fetchedValue = await taskForValue.ConfigureAwait(false); + Assert.IsNull(fetchedValue); + + var contains2 = sut.TryGetValueAsync("invalidkey", out var taskForValue2); + + Assert.IsFalse(contains2); + Assert.IsNotNull(taskForValue2); + + var fetchedValue2 = await taskForValue2.ConfigureAwait(false); + Assert.IsNull(fetchedValue2); } } } \ No newline at end of file From 1dfb34690f17f08ac88dbaf3256687595314afe4 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 18:20:57 +0200 Subject: [PATCH 14/17] Removed space --- LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs index 042f2c6..4e8710a 100644 --- a/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs +++ b/LazyCache.UnitTests/CachingServiceMemoryCacheProviderTests.cs @@ -1375,7 +1375,6 @@ public void GetOrAddNullableStructWithoutValueThenTryGetValueReturnsCachedValueA } - [Test] public void TryGetValueAsyncThrowsWhenKeyIsNull() { From a48680943722ede9133c01463f3896b84ac8270f Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 18:23:47 +0200 Subject: [PATCH 15/17] Removed TODO --- LazyCache/AppCacheExtensions.cs | 2 -- LazyCache/CachingService.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/LazyCache/AppCacheExtensions.cs b/LazyCache/AppCacheExtensions.cs index 9d4a823..d49699a 100644 --- a/LazyCache/AppCacheExtensions.cs +++ b/LazyCache/AppCacheExtensions.cs @@ -1,8 +1,6 @@ using System; -using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Primitives; namespace LazyCache { diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index d1b03ce..8d41a33 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using LazyCache.Providers; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Primitives; namespace LazyCache { @@ -97,7 +96,6 @@ public virtual bool TryGetValue(string key, out T value) return keyWasFound; } - // TODO EM: add unit tests public virtual bool TryGetValueAsync(string key, out Task value) { ValidateKey(key); From 9d6281c0c4c7c4d4236327c548a30ea1e18031b4 Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 18:29:01 +0200 Subject: [PATCH 16/17] Suppressed warning and removed edito confg files --- LazyCache.UnitTests/.editorconfig | 7 ------- LazyCache/.editorconfig | 7 ------- LazyCache/CachingService.cs | 2 ++ 3 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 LazyCache.UnitTests/.editorconfig delete mode 100644 LazyCache/.editorconfig diff --git a/LazyCache.UnitTests/.editorconfig b/LazyCache.UnitTests/.editorconfig deleted file mode 100644 index 8ee9848..0000000 --- a/LazyCache.UnitTests/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -# To learn more about .editorconfig see https://aka.ms/editorconfigdocs -root = true - -# C# files -[*.cs] -indent_style = space -indent_size = 4 diff --git a/LazyCache/.editorconfig b/LazyCache/.editorconfig deleted file mode 100644 index 8ee9848..0000000 --- a/LazyCache/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -# To learn more about .editorconfig see https://aka.ms/editorconfigdocs -root = true - -# C# files -[*.cs] -indent_style = space -indent_size = 4 diff --git a/LazyCache/CachingService.cs b/LazyCache/CachingService.cs index 8d41a33..4a2e6a8 100644 --- a/LazyCache/CachingService.cs +++ b/LazyCache/CachingService.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using LazyCache.Providers; using Microsoft.Extensions.Caching.Memory; +using System.Diagnostics.CodeAnalysis; namespace LazyCache { @@ -96,6 +97,7 @@ public virtual bool TryGetValue(string key, out T value) return keyWasFound; } + [SuppressMessage("Naming", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "Using Async suffix here it's fine. This method name follows the same pattern used for the other methods in this class.")] public virtual bool TryGetValueAsync(string key, out Task value) { ValidateKey(key); From 5d14718560b3a7198add28403e4f583e7097810d Mon Sep 17 00:00:00 2001 From: Enrico Massone Date: Sun, 20 Jun 2021 18:33:00 +0200 Subject: [PATCH 17/17] suppressed warning --- LazyCache/IAppCache.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/LazyCache/IAppCache.cs b/LazyCache/IAppCache.cs index a1a0417..68112cb 100644 --- a/LazyCache/IAppCache.cs +++ b/LazyCache/IAppCache.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; +using System.Diagnostics.CodeAnalysis; namespace LazyCache { @@ -16,6 +17,8 @@ public interface IAppCache T Get(string key); Task GetAsync(string key); bool TryGetValue(string key, out T value); + + [SuppressMessage("Naming", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "Using Async suffix here it's fine. This method name follows the same pattern used for the other methods in this interface.")] bool TryGetValueAsync(string key, out Task value); T GetOrAdd(string key, Func addItemFactory);