Skip to content

Commit 18572d0

Browse files
committed
Refactor specs
1 parent 1e38d57 commit 18572d0

6 files changed

Lines changed: 234 additions & 217 deletions
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Text;
2+
3+
namespace Polly.Caching.Distributed.Specs.Integration
4+
{
5+
public class ByteArraySerializer : ICacheItemSerializer<string, byte[]>
6+
{
7+
public string Deserialize(byte[] objectToDeserialize)
8+
{
9+
return objectToDeserialize == null ? null : Encoding.UTF8.GetString(objectToDeserialize);
10+
}
11+
12+
public byte[] Serialize(string objectToSerialize)
13+
{
14+
return objectToSerialize == null ? null : Encoding.UTF8.GetBytes(objectToSerialize);
15+
}
16+
}
17+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#if !NETCOREAPP1_1
2+
3+
using System;
4+
using Microsoft.Extensions.Caching.Distributed;
5+
using Microsoft.Extensions.Caching.Memory;
6+
using Microsoft.Extensions.Options;
7+
using Newtonsoft.Json;
8+
using Polly.Caching.Serialization.Json;
9+
10+
namespace Polly.Caching.Distributed.Specs.Integration
11+
{
12+
public class CachePolicyFactory
13+
{
14+
public static (ISyncCacheProvider<TResult>, ISyncPolicy<TResult>) CreateCachePolicy<TCache, TResult>()
15+
{
16+
var memoryIDistributedCache = new MemoryDistributedCache(Options.Create(new MemoryDistributedCacheOptions()));
17+
ISyncCacheProvider<TResult> memoryIDistributedCacheProvider;
18+
if (typeof(TCache) == typeof(string))
19+
{
20+
memoryIDistributedCacheProvider = memoryIDistributedCache.AsSyncCacheProvider<string>().WithSerializer<TResult, string>(new JsonSerializer<TResult>(new JsonSerializerSettings()));
21+
}
22+
else if (typeof(TCache) == typeof(byte[]))
23+
{
24+
memoryIDistributedCacheProvider = memoryIDistributedCache.AsSyncCacheProvider<byte[]>().WithSerializer(new ByteArraySerializer()).WithSerializer<TResult, string>(new JsonSerializer<TResult>(new JsonSerializerSettings()));
25+
}
26+
else
27+
{
28+
throw new ArgumentException($"{nameof(TCache)} must be either {typeof(string).Name} or {typeof(byte).Name}[]", nameof(TCache));
29+
}
30+
31+
var policy = Policy.Cache<TResult>(memoryIDistributedCacheProvider, TimeSpan.FromHours(1));
32+
return (memoryIDistributedCacheProvider, policy);
33+
}
34+
}
35+
}
36+
37+
#endif
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using Xunit;
3+
4+
namespace Polly.Caching.Distributed.Specs.Integration
5+
{
6+
public abstract class CacheRoundTripSpecsBase
7+
{
8+
protected const string OperationKey = "SomeOperationKey";
9+
10+
public static TheoryData<SampleClass> SampleClassData =>
11+
new TheoryData<SampleClass>
12+
{
13+
new SampleClass(),
14+
new SampleClass()
15+
{
16+
StringProperty = "<html></html>",
17+
IntProperty = 1
18+
},
19+
(SampleClass)null,
20+
default(SampleClass)
21+
};
22+
23+
public static TheoryData<String> SampleStringData =>
24+
new TheoryData<String>
25+
{
26+
"some string",
27+
"",
28+
null,
29+
default(string),
30+
"null"
31+
};
32+
33+
public static TheoryData<int> SampleNumericData =>
34+
new TheoryData<int>
35+
{
36+
-1,
37+
0,
38+
1,
39+
default(int)
40+
};
41+
42+
public static TheoryData<SampleEnum> SampleEnumData =>
43+
new TheoryData<SampleEnum>
44+
{
45+
SampleEnum.FirstValue,
46+
SampleEnum.SecondValue,
47+
default(SampleEnum),
48+
};
49+
50+
public static TheoryData<bool> SampleBoolData =>
51+
new TheoryData<bool>
52+
{
53+
true,
54+
false,
55+
default(bool),
56+
};
57+
58+
public static TheoryData<bool?> SampleNullableBoolData =>
59+
new TheoryData<bool?>
60+
{
61+
true,
62+
false,
63+
null,
64+
default(bool?),
65+
};
66+
67+
public class SampleClass
68+
{
69+
public string StringProperty { get; set; }
70+
public int IntProperty { get; set; }
71+
}
72+
73+
public enum SampleEnum
74+
{
75+
FirstValue,
76+
SecondValue,
77+
}
78+
}
79+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#if !NETCOREAPP1_1
2+
3+
using System;
4+
using FluentAssertions;
5+
using Polly.Caching.Distributed.Specs.Integration;
6+
using Xunit;
7+
8+
namespace Polly.Specs.Caching.Distributed.Integration
9+
{
10+
public class CacheRoundTripSpecs_NetStandardIDistributedCacheProvider_String : CacheRoundTripSpecs_NetStandardIDistributedCacheProvider<string> { }
11+
12+
public class CacheRoundTripSpecs_NetStandardIDistributedCacheProvider_ByteArray : CacheRoundTripSpecs_NetStandardIDistributedCacheProvider<byte[]> { }
13+
14+
public abstract class CacheRoundTripSpecs_NetStandardIDistributedCacheProvider<TCache> : CacheRoundTripSpecsBase
15+
{
16+
private void Should_roundtrip_this_variant_of<TResult>(TResult testValue)
17+
{
18+
// Arrange
19+
var (memoryIDistributedCacheProvider, cache) = CachePolicyFactory.CreateCachePolicy<TCache, TResult>();
20+
21+
// Assert - should not be in cache
22+
(bool cacheHit1, TResult fromCache1) = memoryIDistributedCacheProvider.TryGet(OperationKey);
23+
cacheHit1.Should().BeFalse();
24+
fromCache1.Should().Be(default(TResult));
25+
26+
// Act - should execute underlying delegate and place in cache
27+
int underlyingDelegateExecuteCount = 0;
28+
cache.Execute(ctx =>
29+
{
30+
underlyingDelegateExecuteCount++;
31+
return testValue;
32+
}, new Context(OperationKey))
33+
.ShouldBeEquivalentTo(testValue);
34+
35+
// Assert - should have executed underlying delegate
36+
underlyingDelegateExecuteCount.Should().Be(1);
37+
38+
// Assert - should be in cache
39+
(bool cacheHit2, TResult fromCache2) = memoryIDistributedCacheProvider.TryGet(OperationKey);
40+
cacheHit2.Should().BeTrue();
41+
fromCache2.ShouldBeEquivalentTo(testValue);
42+
43+
// Act - should execute underlying delegate and place in cache
44+
cache.Execute(ctx =>
45+
{
46+
underlyingDelegateExecuteCount++;
47+
throw new Exception("Cache should be used so this should not get invoked.");
48+
}, new Context(OperationKey))
49+
.ShouldBeEquivalentTo(testValue);
50+
underlyingDelegateExecuteCount.Should().Be(1);
51+
}
52+
53+
[Theory]
54+
[MemberData(nameof(SampleClassData))]
55+
public void Should_roundtrip_all_variants_of_reference_type(SampleClass testValue)
56+
{
57+
Should_roundtrip_this_variant_of<SampleClass>(testValue);
58+
}
59+
60+
[Theory]
61+
[MemberData(nameof(SampleStringData))]
62+
public void Should_roundtrip_all_variants_of_string(String testValue)
63+
{
64+
Should_roundtrip_this_variant_of<String>(testValue);
65+
}
66+
67+
[Theory]
68+
[MemberData(nameof(SampleNumericData))]
69+
public void Should_roundtrip_all_variants_of_numeric(int testValue)
70+
{
71+
Should_roundtrip_this_variant_of<int>(testValue);
72+
}
73+
74+
[Theory]
75+
[MemberData(nameof(SampleEnumData))]
76+
public void Should_roundtrip_all_variants_of_enum(SampleEnum testValue)
77+
{
78+
Should_roundtrip_this_variant_of<SampleEnum>(testValue);
79+
}
80+
81+
[Theory]
82+
[MemberData(nameof(SampleBoolData))]
83+
public void Should_roundtrip_all_variants_of_bool(bool testValue)
84+
{
85+
Should_roundtrip_this_variant_of<bool>(testValue);
86+
}
87+
88+
[Theory]
89+
[MemberData(nameof(SampleNullableBoolData))]
90+
public void Should_roundtrip_all_variants_of_nullable_bool(bool? testValue)
91+
{
92+
Should_roundtrip_this_variant_of<bool?>(testValue);
93+
}
94+
}
95+
}
96+
97+
#endif

0 commit comments

Comments
 (0)