Skip to content

Commit

Permalink
Expose policies in a PolicyWrap
Browse files Browse the repository at this point in the history
Implemtation for App-vNext#312 from @MartinSStewart , Polly Knowabunga Hackathon
at Tretton37
  • Loading branch information
reisenberger committed Nov 17, 2017
1 parent 10190a8 commit e350b67
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/Polly.Shared/Polly.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Utilities\TaskHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\TimedLock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\IPolicyWrap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\IPolicyWrapExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\PolicyWrapSyntax.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\PolicyWrapSyntaxAsync.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\PolicyWrap.ContextAndKeys.cs" />
Expand Down
36 changes: 36 additions & 0 deletions src/Polly.Shared/Wrap/IPolicyWrapExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Polly.Wrap
{
/// <summary>
/// Extension methods for IPolicyWrap.
/// </summary>
public static class IPolicyWrapExtension
{
/// <summary>
/// Recursively iterates through <see cref="PolicyWrap"/> nodes returning <see cref="IsPolicy"/> in Outer-Inner order.
/// </summary>
/// <param name="policyWrap"></param>
/// <returns></returns>
public static IEnumerable<IsPolicy> GetPolicies(this IPolicyWrap policyWrap)
{
var subPolicies = new[] { policyWrap.Outer, policyWrap.Inner };
foreach (var subPolicy in subPolicies)
{
if (subPolicy is IPolicyWrap outerWrap)
{
foreach (var policy in outerWrap.GetPolicies())
{
yield return policy;
}
}
else if (subPolicy != null)
{
yield return subPolicy;
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/Polly.Shared/Wrap/PolicyWrapSyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public partial class Policy
/// <exception cref="System.ArgumentException">The enumerable of policies to form the wrap must contain at least two policies.</exception>
public static PolicyWrap Wrap(params Policy[] policies)
{
switch (policies.Count())
switch (policies.Length)
{
case 0:
case 1:
Expand Down
1 change: 1 addition & 0 deletions src/Polly.SharedSpecs/Polly.SharedSpecs.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Timeout\TimeoutSpecsBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Timeout\TimeoutTResultAsyncSpecs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Timeout\TimeoutTResultSpecs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\IPolicyWrapExSpecs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\PolicyWrapSpecs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\PolicyWrapContextAndKeySpecs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Wrap\PolicyWrapContextAndKeySpecsAsync.cs" />
Expand Down
111 changes: 111 additions & 0 deletions src/Polly.SharedSpecs/Wrap/IPolicyWrapExtensionSpecs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;
using Polly.Wrap;
using System.Linq;
using FluentAssertions;

namespace Polly.Specs.Wrap
{
public class IPolicyWrapExtensionSpecs
{
[Fact]
public void Should_pass_outer_policy_and_then_inner_policy_from_PolicyWrap()
{
var outerPolicy = Policy.NoOp();
var innerPolicy = Policy.NoOp();
var policyWrap = Policy.Wrap(outerPolicy, innerPolicy);

var policies = policyWrap.GetPolicies().ToList();
policies[0].Should().Be(outerPolicy);
policies[1].Should().Be(innerPolicy);
}

[Fact]
public void Should_pass_no_policy_if_PolicyWrap_has_no_inner_or_outer_policy()
{
var policyWrap = new CustomWrap();

var policies = policyWrap.GetPolicies().ToList();
policies.Count.Should().Be(0);
}

[Fact]
public void Should_pass_only_inner_policy_if_PolicyWrap_has_no_outer_policy()
{
var innerPolicy = Policy.NoOp();
var policyWrap = new CustomWrap(null, innerPolicy);

var policies = policyWrap.GetPolicies().ToList();
policies.Count.Should().Be(1);
policies[0].Should().Be(innerPolicy);
}

[Fact]
public void Should_pass_only_outer_policy_if_PolicyWrap_has_no_inner_policy()
{
var outerPolicy = Policy.NoOp();
var policyWrap = new CustomWrap(outerPolicy, null);

var policies = policyWrap.GetPolicies().ToList();
policies.Count.Should().Be(1);
policies[0].Should().Be(outerPolicy);
}

[Fact]
public void Should_pass_all_nested_policies_from_PolicyWrap_in_same_order_they_were_added()
{
var policy0 = Policy.NoOp();
var policy1 = Policy.NoOp();
var policy2 = Policy.NoOp();
var policyWrap = Policy.Wrap(policy0, policy1, policy2);

var policies = policyWrap.GetPolicies().ToList();
policies.Count.Should().Be(3);
policies[0].Should().Be(policy0);
policies[1].Should().Be(policy1);
policies[2].Should().Be(policy2);
}

[Fact]
public void Should_pass_nested_policies_in_outer_inner_order()
{
var policy0 = Policy.NoOp();
var policy1 = Policy.NoOp();
var policy2 = Policy.NoOp();
var policy3 = Policy.NoOp();
var policyWrap =
new CustomWrap(
new CustomWrap(policy0, policy1),
new CustomWrap(
policy2,
new CustomWrap(null, policy3)));

var policies = policyWrap.GetPolicies().ToList();
policies.Count.Should().Be(4);
policies[0].Should().Be(policy0);
policies[1].Should().Be(policy1);
policies[2].Should().Be(policy2);
policies[3].Should().Be(policy3);
}

public class CustomWrap : IPolicyWrap
{
public IsPolicy Outer { get; }
public IsPolicy Inner { get; }

public string PolicyKey => throw new NotImplementedException();

public CustomWrap()
{
}

public CustomWrap(IsPolicy outer, IsPolicy inner)
{
Outer = outer;
Inner = inner;
}
}
}
}

0 comments on commit e350b67

Please sign in to comment.