diff --git a/mustache-sharp.test/FormatCompilerTester.cs b/mustache-sharp.test/FormatCompilerTester.cs index ad162b4..92d1085 100644 --- a/mustache-sharp.test/FormatCompilerTester.cs +++ b/mustache-sharp.test/FormatCompilerTester.cs @@ -151,6 +151,31 @@ namespace mustache.test Assert.AreEqual(expected, actual, "The wrong message was generated."); } + /// + /// If part of a key is wrong, the full details should be provided. + /// + [TestMethod] + public void TestCompile_MultipartKey_PartMissing_ProvidesFullDetail() + { + FormatCompiler compiler = new FormatCompiler(); + const string format = @"{{Customer.Name}}"; + Generator generator = compiler.Compile(format); + generator.KeyNotFound += (obj, args) => + { + args.Substitute = args.Key + "," + args.MissingMember; + args.Handled = true; + }; + string actual = generator.Render(new + { + Customer = new + { + FirstName = "Bob" + } + }); + string expected = "Customer.Name,Name"; + Assert.AreEqual(expected, actual, "The wrong message was generated."); + } + /// /// If we specify an alignment with a key, the alignment should /// be used when rending the value. diff --git a/mustache-sharp.test/Properties/AssemblyInfo.cs b/mustache-sharp.test/Properties/AssemblyInfo.cs index 276e515..a321787 100644 --- a/mustache-sharp.test/Properties/AssemblyInfo.cs +++ b/mustache-sharp.test/Properties/AssemblyInfo.cs @@ -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.0.4.0")] -[assembly: AssemblyFileVersion("0.0.4.0")] +[assembly: AssemblyVersion("0.0.5.0")] +[assembly: AssemblyFileVersion("0.0.5.0")] diff --git a/mustache-sharp/KeyScope.cs b/mustache-sharp/KeyScope.cs index ed71cc0..ec893c7 100644 --- a/mustache-sharp/KeyScope.cs +++ b/mustache-sharp/KeyScope.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using mustache.Properties; namespace mustache @@ -63,39 +64,47 @@ namespace mustache object nextLevel = _source; if (member != "this") { - nextLevel = find(member); + nextLevel = find(name, member); } for (int index = 1; index < names.Length; ++index) { IDictionary context = toLookup(nextLevel); member = names[index]; - nextLevel = context[member]; + if (!context.TryGetValue(member, out nextLevel)) + { + nextLevel = handleKeyNotFound(name, member); + } } return nextLevel; } - private object find(string name) + private object find(string fullName, string memberName) { IDictionary lookup = toLookup(_source); - if (lookup.ContainsKey(name)) + if (lookup.ContainsKey(memberName)) { - return lookup[name]; + return lookup[memberName]; } if (_parent == null) { - MissingKeyEventArgs args = new MissingKeyEventArgs(name); - if (KeyNotFound != null) - { - KeyNotFound(this, args); - } - if (args.Handled) - { - return args.Substitute; - } - string message = String.Format(CultureInfo.CurrentCulture, Resources.KeyNotFound, name); - throw new KeyNotFoundException(message); + return handleKeyNotFound(fullName, memberName); } - return _parent.find(name); + return _parent.find(fullName, memberName); + } + + private object handleKeyNotFound(string fullName, string memberName) + { + MissingKeyEventArgs args = new MissingKeyEventArgs(fullName, memberName); + if (KeyNotFound != null) + { + KeyNotFound(this, args); + } + if (args.Handled) + { + return args.Substitute; + } + string message = String.Format(CultureInfo.CurrentCulture, Resources.KeyNotFound, memberName); + throw new KeyNotFoundException(message); } private static IDictionary toLookup(object value) diff --git a/mustache-sharp/MissingKeyEventArgs.cs b/mustache-sharp/MissingKeyEventArgs.cs index 4bd759f..f2f3fd4 100644 --- a/mustache-sharp/MissingKeyEventArgs.cs +++ b/mustache-sharp/MissingKeyEventArgs.cs @@ -10,16 +10,23 @@ namespace mustache /// /// Initializes a new instance of a MissingKeyEventArgs. /// - /// The key that had no match. - internal MissingKeyEventArgs(string missingKey) + /// The fully-qualified key. + /// The part of the key that could not be found. + internal MissingKeyEventArgs(string key, string missingMember) { - MissingKey = missingKey; + Key = key; + MissingMember = missingMember; } /// - /// Gets the key that could not be found. + /// Gets the fully-qualified key. /// - public string MissingKey { get; private set; } + public string Key { get; private set; } + + /// + /// Gets the part of the key that could not be found. + /// + public string MissingMember { get; private set; } /// /// Gets or sets whether to use the substitute. diff --git a/mustache-sharp/Properties/AssemblyInfo.cs b/mustache-sharp/Properties/AssemblyInfo.cs index f4c8a32..f1d3dae 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.0.4.0")] +[assembly: AssemblyVersion("0.0.5.0")] [assembly: AssemblyFileVersion("0.0.4.0")] [assembly: InternalsVisibleTo("mustache-sharp.test")] \ No newline at end of file