Skip to content

Commit

Permalink
Closes #60
Browse files Browse the repository at this point in the history
  • Loading branch information
jason-roberts committed Apr 10, 2015
1 parent 0b5843a commit 3b93eaa
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Release-Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Currently in development.
* Windows Phone 8.1 Silverlight support [#81](https://github.com/jason-roberts/FeatureToggle/issues/81)
* Windows Universal Apps 8.1 support [#21](https://github.com/jason-roberts/FeatureToggle/issues/21)
* New toggle decorator that defaults to true when a toggle (configuration) error occurs [#61](https://github.com/jason-roberts/FeatureToggle/issues/61)

* New toggle decorator that defaults to false when a toggle (configuration) error occurs [#60](https://github.com/jason-roberts/FeatureToggle/issues/60)


# Version 2.2.1
Expand Down
46 changes: 46 additions & 0 deletions src/FeatureToggle.Core/DefaultToDisabledOnErrorDecorator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;

namespace FeatureToggle.Core
{
/// <summary>
/// This decorator should be used with care or not at all. It will essentially hide any configuration errors
/// or other problems with the wrapped toggle knowing if it should enable the feature or not.
/// This feature is provided as a response to a user request.
/// </summary>
public class DefaultToDisabledOnErrorDecorator : IFeatureToggle
{
private readonly Action<Exception> _logAction;
public IFeatureToggle Toggle { get; private set; }

/// <summary>
/// Decorator constructor that allows the wrapping of another toggle
/// </summary>
/// <param name="toggle">The toggle to wrap (decorate)</param>
/// <param name="logAction">Optional action that gets called if an exception is thrown by the wrapped toggle before returning enabled = false</param>
public DefaultToDisabledOnErrorDecorator(IFeatureToggle toggle, Action<Exception> logAction = null)
{
Toggle = toggle;
_logAction = logAction;
}

public bool FeatureEnabled
{
get
{
try
{
return Toggle.FeatureEnabled;
}
catch (Exception ex)
{
if (_logAction != null)
{
_logAction(ex);
}

return false;
}
}
}
}
}
1 change: 1 addition & 0 deletions src/FeatureToggle.Core/FeatureToggle.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AlwaysOffFeatureToggle.cs" />
<Compile Include="DefaultToDisabledOnErrorDecorator.cs" />
<Compile Include="DefaultToEnabledOnErrorDecorator.cs" />
<Compile Include="ToggleConfigurationSettings.cs" />
<Compile Include="RandomFeatureToggle.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using FeatureToggle.Core;
using Xunit;

namespace FeatureToggle.Tests
{
public class DefaultToDisabledOnErrorDecoratorShould
{
[Fact]
public void ReturnFalseWhenError()
{
var sut = new DefaultToDisabledOnErrorDecorator(new FeatureToggleThatThrowsAnException());

Assert.False(sut.FeatureEnabled);
}


[Fact]
public void ReturnConfiguredValueWhenNoError()
{
var sut = new DefaultToDisabledOnErrorDecorator(new FeatureToggleThatDoesNotThrowAnException());

Assert.False(sut.FeatureEnabled);
}


[Fact]
public void AllowAccessToWrappedToggle()
{
var wrappedToggle = new FeatureToggleThatDoesNotThrowAnException();

var sut = new DefaultToDisabledOnErrorDecorator(wrappedToggle);

Assert.Same(wrappedToggle, sut.Toggle);
}


[Fact]
public void CallLoggingActionOnErrorIfSet()
{
var wrappedToggle = new FeatureToggleThatThrowsAnException();

string log = "";

var sut = new DefaultToDisabledOnErrorDecorator(wrappedToggle, ex => log += ex.Message);



try
{
var isEnabled = sut.FeatureEnabled;
}
catch
{
// ignore exception so we can assert that the specified action was called
}



Assert.Equal("Exception for testing purposes", log);
}


private class FeatureToggleThatThrowsAnException : IFeatureToggle {
public bool FeatureEnabled
{
get
{
throw new Exception("Exception for testing purposes");
}
}
}


private class FeatureToggleThatDoesNotThrowAnException : IFeatureToggle
{
public bool FeatureEnabled
{
get { return false; }
}
}

}
}
1 change: 1 addition & 0 deletions src/Tests/FeatureToggle.Tests/FeatureToggle.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<ItemGroup>
<Compile Include="DefaultToDisabledOnErrorDecoratorShould.cs" />
<Compile Include="DefaultToEnabledOnErrorDecoratorShould.cs" />
<Compile Include="RandomFeatureToggleShould.cs" />
<Compile Include="AlwaysOnFeatureToggleShould.cs" />
Expand Down

0 comments on commit 3b93eaa

Please sign in to comment.