diff --git a/Local.testsettings b/Local.testsettings index 8ff3125..6522637 100644 --- a/Local.testsettings +++ b/Local.testsettings @@ -1,26 +1,26 @@ - - - These are default test settings for a local test run. - - - - - - - - - - - - - - - - - - - - - - + + + These are default test settings for a local test run. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TraceAndTestImpact.testsettings b/TraceAndTestImpact.testsettings index 88f9753..99dbff3 100644 --- a/TraceAndTestImpact.testsettings +++ b/TraceAndTestImpact.testsettings @@ -1,21 +1,21 @@ - - - These are test settings for Trace and Test Impact. - - - - - - - - - - - - - - - - - + + + These are test settings for Trace and Test Impact. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mustache-sharp.sln b/mustache-sharp.sln index 98d40ad..b2c58b0 100644 --- a/mustache-sharp.sln +++ b/mustache-sharp.sln @@ -1,36 +1,36 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mustache-sharp", "mustache-sharp\mustache-sharp.csproj", "{D71B378F-A4BA-4263-A4F0-07A49A0C528D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mustache-sharp.test", "mustache-sharp.test\mustache-sharp.test.csproj", "{7F607362-0680-4751-B1DC-621219294AE3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{25414E49-67E6-4B8D-8AD8-78C70F8992A7}" - ProjectSection(SolutionItems) = preProject - Local.testsettings = Local.testsettings - mustache-sharp.vsmdi = mustache-sharp.vsmdi - TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings - EndProjectSection -EndProject -Global - GlobalSection(TestCaseManagementSettings) = postSolution - CategoryFile = mustache-sharp.vsmdi - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Release|Any CPU.Build.0 = Release|Any CPU - {7F607362-0680-4751-B1DC-621219294AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7F607362-0680-4751-B1DC-621219294AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7F607362-0680-4751-B1DC-621219294AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7F607362-0680-4751-B1DC-621219294AE3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mustache-sharp", "mustache-sharp\mustache-sharp.csproj", "{D71B378F-A4BA-4263-A4F0-07A49A0C528D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mustache-sharp.test", "mustache-sharp.test\mustache-sharp.test.csproj", "{7F607362-0680-4751-B1DC-621219294AE3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{25414E49-67E6-4B8D-8AD8-78C70F8992A7}" + ProjectSection(SolutionItems) = preProject + Local.testsettings = Local.testsettings + mustache-sharp.vsmdi = mustache-sharp.vsmdi + TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings + EndProjectSection +EndProject +Global + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = mustache-sharp.vsmdi + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D71B378F-A4BA-4263-A4F0-07A49A0C528D}.Release|Any CPU.Build.0 = Release|Any CPU + {7F607362-0680-4751-B1DC-621219294AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F607362-0680-4751-B1DC-621219294AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F607362-0680-4751-B1DC-621219294AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F607362-0680-4751-B1DC-621219294AE3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/mustache-sharp.test/FormatCompilerTester.cs b/mustache-sharp.test/FormatCompilerTester.cs index 9359192..dabab3c 100644 --- a/mustache-sharp.test/FormatCompilerTester.cs +++ b/mustache-sharp.test/FormatCompilerTester.cs @@ -452,6 +452,25 @@ Content"; Assert.AreEqual(String.Empty, context[0].TagName, "The top-most context had the wrong tag type."); } + /// + /// If a key refers to a public field, its value should be substituted in the output. + /// + [TestMethod] + public void TestGenerate_KeyRefersToPublicField_SubstitutesValue() + { + FormatCompiler compiler = new FormatCompiler(); + const string format = @"Hello, {{Field}}!!!"; + Generator generator = compiler.Compile(format); + ClassWithPublicField instance = new ClassWithPublicField() { Field = "Bob" }; + string result = generator.Render(instance); + Assert.AreEqual("Hello, Bob!!!", result, "The wrong text was generated."); + } + + public class ClassWithPublicField + { + public string Field; + } + #endregion #region Comment diff --git a/mustache-sharp.test/Properties/AssemblyInfo.cs b/mustache-sharp.test/Properties/AssemblyInfo.cs index 4466edd..be6af3b 100644 --- a/mustache-sharp.test/Properties/AssemblyInfo.cs +++ b/mustache-sharp.test/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyTitle("mustache-sharp.test")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] +[assembly: AssemblyCompany("Truncon")] [assembly: AssemblyProduct("mustache-sharp.test")] [assembly: AssemblyCopyright("Copyright © 2013")] [assembly: AssemblyTrademark("")] @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.2.2.0")] -[assembly: AssemblyFileVersion("0.2.2.0")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/mustache-sharp.vsmdi b/mustache-sharp.vsmdi index 881fd48..c62973b 100644 --- a/mustache-sharp.vsmdi +++ b/mustache-sharp.vsmdi @@ -1,6 +1,6 @@ - - - - - + + + + + \ No newline at end of file diff --git a/mustache-sharp/Properties/AssemblyInfo.cs b/mustache-sharp/Properties/AssemblyInfo.cs index d2415b0..e6f709e 100644 --- a/mustache-sharp/Properties/AssemblyInfo.cs +++ b/mustache-sharp/Properties/AssemblyInfo.cs @@ -34,6 +34,6 @@ using System.Runtime.CompilerServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.2.2.0")] -[assembly: AssemblyFileVersion("0.2.2.0")] +[assembly: AssemblyVersion("0.2.3.0")] +[assembly: AssemblyFileVersion("0.2.3.0")] [assembly: InternalsVisibleTo("mustache-sharp.test")] \ No newline at end of file diff --git a/mustache-sharp/PropertyDictionary.cs b/mustache-sharp/PropertyDictionary.cs index 4d4f3fa..eb6d66e 100644 --- a/mustache-sharp/PropertyDictionary.cs +++ b/mustache-sharp/PropertyDictionary.cs @@ -11,10 +11,10 @@ namespace Mustache /// internal sealed class PropertyDictionary : IDictionary { - private static readonly Dictionary> _cache = new Dictionary>(); + private static readonly Dictionary>> _cache = new Dictionary>>(); private readonly object _instance; - private readonly Dictionary _typeCache; + private readonly Dictionary> _typeCache; /// /// Initializes a new instance of a PropertyDictionary. @@ -25,7 +25,7 @@ namespace Mustache _instance = instance; if (instance == null) { - _typeCache = new Dictionary(); + _typeCache = new Dictionary>(); } else { @@ -33,21 +33,25 @@ namespace Mustache } } - private static Dictionary getCacheType(object instance) + private static Dictionary> getCacheType(object instance) { Type type = instance.GetType(); - Dictionary typeCache; + Dictionary> typeCache; if (!_cache.TryGetValue(type, out typeCache)) { - typeCache = new Dictionary(); + typeCache = new Dictionary>(); BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy; foreach (PropertyInfo propertyInfo in type.GetProperties(flags)) { if (!propertyInfo.IsSpecialName) { - typeCache.Add(propertyInfo.Name, propertyInfo); + typeCache.Add(propertyInfo.Name, i => propertyInfo.GetValue(i, null)); } } + foreach (FieldInfo fieldInfo in type.GetFields(flags)) + { + typeCache.Add(fieldInfo.Name, i => fieldInfo.GetValue(i)); + } _cache.Add(type, typeCache); } return typeCache; @@ -100,13 +104,13 @@ namespace Mustache /// The name of the property was null. public bool TryGetValue(string key, out object value) { - PropertyInfo propertyInfo; - if (!_typeCache.TryGetValue(key, out propertyInfo)) + Func getter; + if (!_typeCache.TryGetValue(key, out getter)) { value = null; return false; } - value = getValue(propertyInfo); + value = getter(_instance); return true; } @@ -117,11 +121,11 @@ namespace Mustache { get { - ICollection propertyInfos = _typeCache.Values; + ICollection> getters = _typeCache.Values; List values = new List(); - foreach (PropertyInfo propertyInfo in propertyInfos) + foreach (Func getter in getters) { - object value = getValue(propertyInfo); + object value = getter(_instance); values.Add(value); } return values.AsReadOnly(); @@ -143,8 +147,8 @@ namespace Mustache { get { - PropertyInfo propertyInfo = _typeCache[key]; - return getValue(propertyInfo); + Func getter = _typeCache[key]; + return getter(_instance); } [EditorBrowsable(EditorBrowsableState.Never)] set @@ -167,23 +171,23 @@ namespace Mustache bool ICollection>.Contains(KeyValuePair item) { - PropertyInfo propertyInfo; - if (!_typeCache.TryGetValue(item.Key, out propertyInfo)) + Func getter; + if (!_typeCache.TryGetValue(item.Key, out getter)) { return false; } - object value = getValue(propertyInfo); + object value = getter(_instance); return Equals(item.Value, value); } void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) { List> pairs = new List>(); - ICollection> collection = _typeCache; - foreach (KeyValuePair pair in collection) + ICollection>> collection = _typeCache; + foreach (KeyValuePair> pair in collection) { - PropertyInfo propertyInfo = pair.Value; - object value = getValue(propertyInfo); + Func getter = pair.Value; + object value = getter(_instance); pairs.Add(new KeyValuePair(pair.Key, value)); } pairs.CopyTo(array, arrayIndex); @@ -217,9 +221,10 @@ namespace Mustache /// public IEnumerator> GetEnumerator() { - foreach (KeyValuePair pair in _typeCache) + foreach (KeyValuePair> pair in _typeCache) { - object value = getValue(pair.Value); + Func getter = pair.Value; + object value = getter(_instance); yield return new KeyValuePair(pair.Key, value); } } @@ -228,10 +233,5 @@ namespace Mustache { return GetEnumerator(); } - - private object getValue(PropertyInfo propertyInfo) - { - return propertyInfo.GetValue(_instance, null); - } } } \ No newline at end of file