From f848d63d9a9e1ce3516ca8ac48a043596925671f Mon Sep 17 00:00:00 2001 From: Travis Parks Date: Sat, 12 Jan 2013 20:22:20 -0500 Subject: [PATCH] Handle Unknown Tags I added code to detect unknown tags and throw an exception. I also provided a default implementation so tags are in the global scope by default. --- mustache-sharp.test/FormatCompilerTester.cs | 7 ++++--- mustache-sharp.test/Properties/AssemblyInfo.cs | 4 ++-- mustache-sharp/FormatCompiler.cs | 10 ++++++++++ mustache-sharp/InlineTagDefinition.cs | 17 +++++++++++++++-- mustache-sharp/Properties/AssemblyInfo.cs | 4 ++-- mustache-sharp/Properties/Resources.Designer.cs | 2 +- mustache-sharp/Properties/Resources.resx | 2 +- mustache-sharp/TagDefinition.cs | 5 ++++- 8 files changed, 39 insertions(+), 12 deletions(-) diff --git a/mustache-sharp.test/FormatCompilerTester.cs b/mustache-sharp.test/FormatCompilerTester.cs index 5f072d7..d9e812e 100644 --- a/mustache-sharp.test/FormatCompilerTester.cs +++ b/mustache-sharp.test/FormatCompilerTester.cs @@ -741,10 +741,11 @@ Last"; } /// - /// Second else blocks will be interpreted as just another piece of text. + /// Second else blocks will result in an exceptions being thrown. /// [TestMethod] - public void TestCompile_IfElse_TwoElses_IncludesSecondElseInElse() + [ExpectedException(typeof(FormatException))] + public void TestCompile_IfElse_TwoElses_IncludesSecondElseInElse_Throws() { FormatCompiler parser = new FormatCompiler(); const string format = "Before{{#if this}}Yay{{#else}}Nay{{#else}}Bad{{/if}}After"; @@ -910,7 +911,7 @@ Last"; return new TagParameter[] { new TagParameter("param") { IsRequired = false, DefaultValue = 123 } }; } - public override string Decorate(IFormatProvider provider, Dictionary arguments) + protected override string GetText(IFormatProvider provider, Dictionary arguments) { return arguments["param"].ToString(); } diff --git a/mustache-sharp.test/Properties/AssemblyInfo.cs b/mustache-sharp.test/Properties/AssemblyInfo.cs index 0c78dd7..8d276b2 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("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("0.0.1.0")] +[assembly: AssemblyFileVersion("0.0.1.0")] diff --git a/mustache-sharp/FormatCompiler.cs b/mustache-sharp/FormatCompiler.cs index 1f78aa9..9f22b44 100644 --- a/mustache-sharp/FormatCompiler.cs +++ b/mustache-sharp/FormatCompiler.cs @@ -106,6 +106,7 @@ namespace mustache TagDefinition childDefinition = _tagLookup[childTag]; matches.Add(getTagRegex(childDefinition)); } + matches.Add(getUnknownTagRegex()); string match = "{{(" + String.Join("|", matches) + ")}}"; regex = new Regex(match, RegexOptions.Compiled); _regexLookup.Add(definition.Name, regex); @@ -153,6 +154,11 @@ namespace mustache return regexBuilder.ToString(); } + private string getUnknownTagRegex() + { + return @"(?(#.*?))"; + } + private int buildCompoundGenerator( TagDefinition tagDefinition, CompoundGenerator generator, @@ -229,6 +235,10 @@ namespace mustache generator.AddStaticGenerators(trimmer.RecordText(leading, true, false)); formatIndex = match.Index + match.Length; } + else if (match.Groups["unknown"].Success) + { + throw new FormatException(Resources.UnknownTag); + } } return formatIndex; } diff --git a/mustache-sharp/InlineTagDefinition.cs b/mustache-sharp/InlineTagDefinition.cs index 49626b2..075dae4 100644 --- a/mustache-sharp/InlineTagDefinition.cs +++ b/mustache-sharp/InlineTagDefinition.cs @@ -36,11 +36,24 @@ namespace mustache return false; } + /// + /// Generates the text for the tag. + /// + /// The format provider to use. + /// The text to decorate. This will always be an empty string. + /// The arguments passed to the tag. + /// The generated text. public sealed override string Decorate(IFormatProvider provider, string innerText, Dictionary arguments) { - return Decorate(provider, arguments); + return GetText(provider, arguments); } - public abstract string Decorate(IFormatProvider provider, Dictionary arguments); + /// + /// Gets the text of the inline tag. + /// + /// The format provider to use. + /// The arguments passed to the tag. + /// The generated text. + protected abstract string GetText(IFormatProvider provider, Dictionary arguments); } } diff --git a/mustache-sharp/Properties/AssemblyInfo.cs b/mustache-sharp/Properties/AssemblyInfo.cs index da48055..9615c6b 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.0.0")] -[assembly: AssemblyFileVersion("0.0.0.0")] +[assembly: AssemblyVersion("0.0.1.0")] +[assembly: AssemblyFileVersion("0.0.1.0")] [assembly: InternalsVisibleTo("mustache-sharp.test")] \ No newline at end of file diff --git a/mustache-sharp/Properties/Resources.Designer.cs b/mustache-sharp/Properties/Resources.Designer.cs index db3399d..27739af 100644 --- a/mustache-sharp/Properties/Resources.Designer.cs +++ b/mustache-sharp/Properties/Resources.Designer.cs @@ -115,7 +115,7 @@ namespace mustache.Properties { } /// - /// Looks up a localized string similar to Encountered an unknown tag {0}.. + /// Looks up a localized string similar to Encountered an unknown tag. It was either not registered or exists in a different context.. /// internal static string UnknownTag { get { diff --git a/mustache-sharp/Properties/Resources.resx b/mustache-sharp/Properties/Resources.resx index 94277ae..b428e3c 100644 --- a/mustache-sharp/Properties/Resources.resx +++ b/mustache-sharp/Properties/Resources.resx @@ -136,7 +136,7 @@ Expected a matching {0} tag but none was found. - Encountered an unknown tag {0}. + Encountered an unknown tag. It was either not registered or exists in a different context. The wrong number of arguments were passed to an {0} tag. diff --git a/mustache-sharp/TagDefinition.cs b/mustache-sharp/TagDefinition.cs index aba8cd8..934b556 100644 --- a/mustache-sharp/TagDefinition.cs +++ b/mustache-sharp/TagDefinition.cs @@ -55,7 +55,10 @@ namespace mustache /// /// Gets whether a tag is limited to the parent tag's context. /// - protected abstract bool GetIsContextSensitive(); + protected virtual bool GetIsContextSensitive() + { + return false; + } /// /// Gets the parameters that are defined for the tag.