Pop Context When Exiting Tag
I was not removing context when I was leaving a tag. This caused the context to grow indefinitely, which is not a valid representation of where the placeholder was located in the template.
This commit is contained in:
parent
42463a888f
commit
11b73b696e
|
@ -362,10 +362,34 @@ Content";
|
|||
|
||||
Assert.IsNotNull(context, "The context was not set.");
|
||||
Assert.AreEqual(2, context.Length, "The context did not contain the right number of items.");
|
||||
Assert.AreEqual(String.Empty, context[0].Tag.Name, "The top-most context had the wrong tag type.");
|
||||
Assert.AreEqual("this", context[0].Argument, "The top-level argument should always be 'this'.");
|
||||
Assert.AreEqual("with", context[1].Tag.Name, "The inner context should have been a 'with' tag.");
|
||||
Assert.AreEqual("Address", context[1].Argument, "The inner context argument was wrong.");
|
||||
|
||||
Assert.AreEqual(String.Empty, context[0].TagName, "The top-most context had the wrong tag type.");
|
||||
Assert.AreEqual("with", context[1].TagName, "The bottom context had the wrong tag type.");
|
||||
|
||||
Assert.AreEqual(0, context[0].Parameters.Length, "The top-most context had the wrong number of parameters.");
|
||||
Assert.AreEqual(1, context[1].Parameters.Length, "The bottom context had the wrong number of parameters.");
|
||||
Assert.AreEqual("Address", context[1].Parameters[0].Argument, "The bottom context had the wrong argument.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// I was leaving behind context even after reaching a closing tag. We need to make sure
|
||||
/// that context is like a call stack and that it is cleaned up after leaving the context.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void TestCompile_ExitContext_RemoveContext()
|
||||
{
|
||||
FormatCompiler compiler = new FormatCompiler();
|
||||
Context[] context = null;
|
||||
compiler.PlaceholderFound += (o, e) =>
|
||||
{
|
||||
context = e.Context;
|
||||
};
|
||||
compiler.Compile(@"{{#with Address}}{{/with}}{{FirstName}}");
|
||||
|
||||
Assert.IsNotNull(context, "The context was not set.");
|
||||
Assert.AreEqual(1, context.Length, "The context did not contain the right number of items.");
|
||||
|
||||
Assert.AreEqual(String.Empty, context[0].TagName, "The top-most context had the wrong tag type.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -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.7.0")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.0")]
|
||||
[assembly: AssemblyVersion("0.0.7.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.1")]
|
||||
|
|
|
@ -26,20 +26,6 @@ namespace mustache
|
|||
_primaryGenerators = new LinkedList<IGenerator>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the argument that will act as the context for the content.
|
||||
/// </summary>
|
||||
/// <returns>The argument that will act as the context for the content.</returns>
|
||||
public string GetContextArgument()
|
||||
{
|
||||
TagParameter parameter = _definition.GetChildContextParameter();
|
||||
if (parameter == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _arguments.GetKey(parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the given generator.
|
||||
/// </summary>
|
||||
|
|
|
@ -90,12 +90,12 @@ namespace mustache
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a new child context.
|
||||
/// Gets the parameters that are used to create a new child context.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that is used to create a new child context.</returns>
|
||||
public override TagParameter GetChildContextParameter()
|
||||
/// <returns>The parameters that are used to create a new child context.</returns>
|
||||
public override IEnumerable<TagParameter> GetChildContextParameters()
|
||||
{
|
||||
return null;
|
||||
return new TagParameter[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,22 +10,22 @@ namespace mustache
|
|||
/// <summary>
|
||||
/// Initializes a new instance of a Context.
|
||||
/// </summary>
|
||||
/// <param name="definition">The definition of tag that created the context.</param>
|
||||
/// <param name="tagName">The name of the tag that created the context.</param>
|
||||
/// <param name="argument">The argument used to create the context.</param>
|
||||
internal Context(TagDefinition definition, string argument)
|
||||
internal Context(string tagName, ContextParameter[] parameters)
|
||||
{
|
||||
Tag = definition;
|
||||
Argument = argument;
|
||||
TagName = tagName;
|
||||
Parameters = parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag that created the context.
|
||||
/// </summary>
|
||||
public TagDefinition Tag { get; private set; }
|
||||
public string TagName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the argument used to create the context.
|
||||
/// </summary>
|
||||
public string Argument { get; private set; }
|
||||
public ContextParameter[] Parameters { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
|
||||
namespace mustache
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information describing a parameter that creates a new context.
|
||||
/// </summary>
|
||||
public sealed class ContextParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of a ContextParameter.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The parameter that is used to create a new context.</param>
|
||||
/// <param name="argument">The key whose corresponding value will be used to create the context.</param>
|
||||
internal ContextParameter(string parameter, string argument)
|
||||
{
|
||||
Parameter = parameter;
|
||||
Argument = argument;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a new context.
|
||||
/// </summary>
|
||||
public string Parameter { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key whose corresponding value will be used to create the context.
|
||||
/// </summary>
|
||||
public string Argument { get; private set; }
|
||||
}
|
||||
}
|
|
@ -70,12 +70,12 @@ namespace mustache
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a new child context.
|
||||
/// Gets the parameters that are used to create a new child context.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that is used to create a new child context.</returns>
|
||||
public override TagParameter GetChildContextParameter()
|
||||
/// <returns>The parameters that are used to create a new child context.</returns>
|
||||
public override IEnumerable<TagParameter> GetChildContextParameters()
|
||||
{
|
||||
return collection;
|
||||
return new TagParameter[] { collection };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,12 +33,12 @@ namespace mustache
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a new child context.
|
||||
/// Gets the parameters that are used to create a new child context.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that is used to create a new child context.</returns>
|
||||
public override TagParameter GetChildContextParameter()
|
||||
/// <returns>The parameters that are used to create a new child context.</returns>
|
||||
public override IEnumerable<TagParameter> GetChildContextParameters()
|
||||
{
|
||||
return null;
|
||||
return new TagParameter[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace mustache
|
|||
}
|
||||
CompoundGenerator generator = new CompoundGenerator(_masterDefinition, new ArgumentCollection());
|
||||
Trimmer trimmer = new Trimmer();
|
||||
List<Context> context = new List<Context>() { new Context(_masterDefinition, "this") };
|
||||
List<Context> context = new List<Context>() { new Context(_masterDefinition.Name, new ContextParameter[0]) };
|
||||
int formatIndex = buildCompoundGenerator(_masterDefinition, context, generator, trimmer, format, 0);
|
||||
string trailing = format.Substring(formatIndex);
|
||||
generator.AddStaticGenerators(trimmer.RecordText(trailing, false, false));
|
||||
|
@ -218,13 +218,19 @@ namespace mustache
|
|||
generator.AddStaticGenerators(trimmer.RecordText(leading, true, false));
|
||||
ArgumentCollection arguments = getArguments(nextDefinition, match);
|
||||
CompoundGenerator compoundGenerator = new CompoundGenerator(nextDefinition, arguments);
|
||||
string newContext = compoundGenerator.GetContextArgument();
|
||||
if (newContext != null)
|
||||
IEnumerable<TagParameter> contextParameters = nextDefinition.GetChildContextParameters();
|
||||
bool hasContext = contextParameters.Any();
|
||||
if (hasContext)
|
||||
{
|
||||
context.Add(new Context(nextDefinition, newContext));
|
||||
ContextParameter[] parameters = contextParameters.Select(p => new ContextParameter(p.Name, arguments.GetKey(p))).ToArray();
|
||||
context.Add(new Context(nextDefinition.Name, parameters));
|
||||
}
|
||||
formatIndex = buildCompoundGenerator(nextDefinition, context, compoundGenerator, trimmer, format, formatIndex);
|
||||
generator.AddGenerator(nextDefinition, compoundGenerator);
|
||||
if (hasContext)
|
||||
{
|
||||
context.RemoveAt(context.Count - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -38,12 +38,12 @@ namespace mustache
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a child context.
|
||||
/// Gets the parameters that are used to create a child context.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that is used to create a child context.</returns>
|
||||
public override TagParameter GetChildContextParameter()
|
||||
/// <returns>The parameters that are used to create a child context.</returns>
|
||||
public override IEnumerable<TagParameter> GetChildContextParameters()
|
||||
{
|
||||
return null;
|
||||
return new TagParameter[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ namespace mustache
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a new child context.
|
||||
/// Gets the parameters that are used to create a new child context.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that is used to create a new child context.</returns>
|
||||
public override TagParameter GetChildContextParameter()
|
||||
/// <returns>The parameters that are used to create a new child context.</returns>
|
||||
public override IEnumerable<TagParameter> GetChildContextParameters()
|
||||
{
|
||||
return null;
|
||||
return new TagParameter[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.7.0")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.0")]
|
||||
[assembly: AssemblyVersion("0.0.7.1")]
|
||||
[assembly: AssemblyFileVersion("0.0.7.1")]
|
||||
[assembly: InternalsVisibleTo("mustache-sharp.test")]
|
|
@ -133,7 +133,7 @@ namespace mustache
|
|||
/// Gets the parameter that will be used to create a new child scope.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that will be used to create a new child scope -or- null if no new scope is created.</returns>
|
||||
public abstract TagParameter GetChildContextParameter();
|
||||
public abstract IEnumerable<TagParameter> GetChildContextParameters();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the context to use when building the inner text of the tag.
|
||||
|
|
|
@ -38,12 +38,12 @@ namespace mustache
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter that is used to create a new child context.
|
||||
/// Gets the parameters that are used to create a new child context.
|
||||
/// </summary>
|
||||
/// <returns>The parameter that is used to create a new child context.</returns>
|
||||
public override TagParameter GetChildContextParameter()
|
||||
/// <returns>The parameters that are used to create a new child context.</returns>
|
||||
public override IEnumerable<TagParameter> GetChildContextParameters()
|
||||
{
|
||||
return context;
|
||||
return new TagParameter[] { context };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<Compile Include="ConditionTagDefinition.cs" />
|
||||
<Compile Include="ContentTagDefinition.cs" />
|
||||
<Compile Include="Context.cs" />
|
||||
<Compile Include="ContextParameter.cs" />
|
||||
<Compile Include="KeyFoundEventArgs.cs" />
|
||||
<Compile Include="InlineTagDefinition.cs" />
|
||||
<Compile Include="EachTagDefinition.cs" />
|
||||
|
|
Loading…
Reference in New Issue