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.
This commit is contained in:
Travis Parks 2013-01-12 20:22:20 -05:00
parent a0bacd250d
commit f848d63d9a
8 changed files with 39 additions and 12 deletions

View File

@ -741,10 +741,11 @@ Last";
} }
/// <summary> /// <summary>
/// Second else blocks will be interpreted as just another piece of text. /// Second else blocks will result in an exceptions being thrown.
/// </summary> /// </summary>
[TestMethod] [TestMethod]
public void TestCompile_IfElse_TwoElses_IncludesSecondElseInElse() [ExpectedException(typeof(FormatException))]
public void TestCompile_IfElse_TwoElses_IncludesSecondElseInElse_Throws()
{ {
FormatCompiler parser = new FormatCompiler(); FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#if this}}Yay{{#else}}Nay{{#else}}Bad{{/if}}After"; 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 } }; return new TagParameter[] { new TagParameter("param") { IsRequired = false, DefaultValue = 123 } };
} }
public override string Decorate(IFormatProvider provider, Dictionary<string, object> arguments) protected override string GetText(IFormatProvider provider, Dictionary<string, object> arguments)
{ {
return arguments["param"].ToString(); return arguments["param"].ToString();
} }

View File

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("0.0.1.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("0.0.1.0")]

View File

@ -106,6 +106,7 @@ namespace mustache
TagDefinition childDefinition = _tagLookup[childTag]; TagDefinition childDefinition = _tagLookup[childTag];
matches.Add(getTagRegex(childDefinition)); matches.Add(getTagRegex(childDefinition));
} }
matches.Add(getUnknownTagRegex());
string match = "{{(" + String.Join("|", matches) + ")}}"; string match = "{{(" + String.Join("|", matches) + ")}}";
regex = new Regex(match, RegexOptions.Compiled); regex = new Regex(match, RegexOptions.Compiled);
_regexLookup.Add(definition.Name, regex); _regexLookup.Add(definition.Name, regex);
@ -153,6 +154,11 @@ namespace mustache
return regexBuilder.ToString(); return regexBuilder.ToString();
} }
private string getUnknownTagRegex()
{
return @"(?<unknown>(#.*?))";
}
private int buildCompoundGenerator( private int buildCompoundGenerator(
TagDefinition tagDefinition, TagDefinition tagDefinition,
CompoundGenerator generator, CompoundGenerator generator,
@ -229,6 +235,10 @@ namespace mustache
generator.AddStaticGenerators(trimmer.RecordText(leading, true, false)); generator.AddStaticGenerators(trimmer.RecordText(leading, true, false));
formatIndex = match.Index + match.Length; formatIndex = match.Index + match.Length;
} }
else if (match.Groups["unknown"].Success)
{
throw new FormatException(Resources.UnknownTag);
}
} }
return formatIndex; return formatIndex;
} }

View File

@ -36,11 +36,24 @@ namespace mustache
return false; return false;
} }
/// <summary>
/// Generates the text for the tag.
/// </summary>
/// <param name="provider">The format provider to use.</param>
/// <param name="innerText">The text to decorate. This will always be an empty string.</param>
/// <param name="arguments">The arguments passed to the tag.</param>
/// <returns>The generated text.</returns>
public sealed override string Decorate(IFormatProvider provider, string innerText, Dictionary<string, object> arguments) public sealed override string Decorate(IFormatProvider provider, string innerText, Dictionary<string, object> arguments)
{ {
return Decorate(provider, arguments); return GetText(provider, arguments);
} }
public abstract string Decorate(IFormatProvider provider, Dictionary<string, object> arguments); /// <summary>
/// Gets the text of the inline tag.
/// </summary>
/// <param name="provider">The format provider to use.</param>
/// <param name="arguments">The arguments passed to the tag.</param>
/// <returns>The generated text.</returns>
protected abstract string GetText(IFormatProvider provider, Dictionary<string, object> arguments);
} }
} }

View File

@ -34,6 +34,6 @@ using System.Runtime.CompilerServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.0.0.0")] [assembly: AssemblyVersion("0.0.1.0")]
[assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: InternalsVisibleTo("mustache-sharp.test")] [assembly: InternalsVisibleTo("mustache-sharp.test")]

View File

@ -115,7 +115,7 @@ namespace mustache.Properties {
} }
/// <summary> /// <summary>
/// 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..
/// </summary> /// </summary>
internal static string UnknownTag { internal static string UnknownTag {
get { get {

View File

@ -136,7 +136,7 @@
<value>Expected a matching {0} tag but none was found.</value> <value>Expected a matching {0} tag but none was found.</value>
</data> </data>
<data name="UnknownTag" xml:space="preserve"> <data name="UnknownTag" xml:space="preserve">
<value>Encountered an unknown tag {0}.</value> <value>Encountered an unknown tag. It was either not registered or exists in a different context.</value>
</data> </data>
<data name="WrongNumberOfArguments" xml:space="preserve"> <data name="WrongNumberOfArguments" xml:space="preserve">
<value>The wrong number of arguments were passed to an {0} tag.</value> <value>The wrong number of arguments were passed to an {0} tag.</value>

View File

@ -55,7 +55,10 @@ namespace mustache
/// <summary> /// <summary>
/// Gets whether a tag is limited to the parent tag's context. /// Gets whether a tag is limited to the parent tag's context.
/// </summary> /// </summary>
protected abstract bool GetIsContextSensitive(); protected virtual bool GetIsContextSensitive()
{
return false;
}
/// <summary> /// <summary>
/// Gets the parameters that are defined for the tag. /// Gets the parameters that are defined for the tag.