Permalink
Browse files

Updated TextResourceFinder

It now supports an infinate chain of dynamic properties and will
call the ITextResource with the string representation of the
chain.
  • Loading branch information...
1 parent 9e82356 commit 500a0f38aaabd737fb24aaaff5ec89e8b061962c @thecodejunkie thecodejunkie committed Dec 31, 2012
@@ -117,6 +117,7 @@
</Compile>
<Compile Include="GreetingViewBase.cs" />
<Compile Include="RazorViewEngineFixture.cs" />
+ <Compile Include="TextResourceFinderFixture.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Nancy.ViewEngines.Razor.Tests.Models\Nancy.ViewEngines.Razor.Tests.Models.csproj">
@@ -0,0 +1,83 @@
+namespace Nancy.ViewEngines.Razor.Tests
+{
+ using System;
+ using FakeItEasy;
+ using Localization;
+ using Nancy.Tests;
+ using Xunit;
+ using Xunit.Extensions;
+
+ public class TextResourceFinderFixture
+ {
+ private readonly dynamic finder;
+ private readonly ITextResource textResource;
+ private readonly NancyContext context;
+
+
+ public TextResourceFinderFixture()
+ {
+ this.context = A.Dummy<NancyContext>();
+ this.textResource = A.Fake<ITextResource>();
+ this.finder = new TextResourceFinder(textResource, context);
+ }
+
+ [Theory]
+ [InlineData("foo")]
+ [InlineData("bar")]
+ public void Should_return_result_of_text_resource(string text)
+ {
+ // Given
+ A.CallTo(() => this.textResource[A<string>._, A<NancyContext>._]).Returns(text);
+
+ // When
+ var result = (string)finder.name;
+
+ // Then
+ result.ShouldEqual(text);
+ }
+
+ [Fact]
+ public void Should_invoke_text_resource_with_context()
+ {
+ // Given
+ // When
+ var result = (string)finder.name;
+
+ // Then
+ A.CallTo(() => this.textResource[A<string>._, this.context]).MustHaveHappened();
+ }
+
+ [Fact]
+ public void Should_invoke_text_resource_with_member_name_when_not_chained()
+ {
+ // Given
+ // When
+ var result = (string)finder.foo;
+
+ // Then
+ A.CallTo(() => this.textResource["foo", A<NancyContext>._]).MustHaveHappened();
+ }
+
+ [Fact]
+ public void Should_invoke_text_resource_with_member_name_when_chained()
+ {
+ // Given
+ // When
+ var result = (string)finder.foo.bar.other;
+
+ // Then
+ A.CallTo(() => this.textResource["foo.bar.other", A<NancyContext>._]).MustHaveHappened();
+ }
+
+ [Fact]
+ public void Should_throw_invalidoperationexception_when_trying_to_cast_to_anything_but_string()
+ {
+ // Given
+ // When
+ var exception = Record.Exception(() => (decimal) finder.name);
+
+ // Then
+ exception.ShouldBeOfType<InvalidOperationException>();
+ }
+ }
+}
@@ -1,5 +1,6 @@
namespace Nancy.ViewEngines.Razor
{
+ using System;
using System.Dynamic;
using Nancy.Localization;
@@ -30,8 +31,50 @@ public TextResourceFinder(ITextResource textResource, NancyContext context)
/// <returns>Returns a value or a non existing value from the <see cref="ITextResource"/> implementation</returns>
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
- result = this.textResource[binder.Name, this.context];
+ result =
+ new DynamicMemberChainer(binder.Name, this.context, this.textResource);
+
return true;
}
+
+ public class DynamicMemberChainer : DynamicObject
+ {
+ private string memberName;
+ private readonly NancyContext context;
+ private readonly ITextResource textResource;
+
+ public DynamicMemberChainer(string memberName, NancyContext context, ITextResource resource)
+ {
+ this.memberName = memberName;
+ this.context = context;
+ this.textResource = resource;
+ }
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ this.memberName =
+ string.Concat(this.memberName, ".", binder.Name);
+
+ result = this;
+
+ return true;
+ }
+
+ public override bool TryConvert(ConvertBinder binder, out object result)
+ {
+ if (binder.ReturnType == typeof(string))
+ {
+ result = this.textResource[this.memberName, this.context];
+ return true;
+ }
+
+ throw new InvalidOperationException("Cannot cast dynamic member access to anything else than a string.");
+ }
+
+ public override string ToString()
+ {
+ return this.textResource[this.memberName, this.context]; ;
+ }
+ }
}
}

0 comments on commit 500a0f3

Please sign in to comment.