Lt, Lte, Gt, Gte (less than etc.) tags added

This commit is contained in:
Paul Grimshaw 2014-02-04 13:07:28 +00:00
parent 7c3df01029
commit 6c902dff3b
9 changed files with 419 additions and 3 deletions

View File

@ -1158,6 +1158,7 @@ Item Number: foo<br />
#endregion #endregion
#region eq
/// <summary> /// <summary>
/// If the two values don't match, the content of an eq statement should not be printed. /// If the two values don't match, the content of an eq statement should not be printed.
@ -1167,7 +1168,7 @@ Item Number: foo<br />
FormatCompiler parser = new FormatCompiler(); FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#eq OneValue OtherValue}}Content{{/eq}}After"; const string format = "Before{{#eq OneValue OtherValue}}Content{{/eq}}After";
Generator generator = parser.Compile(format); Generator generator = parser.Compile(format);
string result = generator.Render(new {OneValue = "Foo", OtherValue = "Bar"} ); string result = generator.Render(new { OneValue = "Foo", OtherValue = "Bar" });
Assert.AreEqual("BeforeAfter", result, "The wrong text was generated."); Assert.AreEqual("BeforeAfter", result, "The wrong text was generated.");
} }
@ -1184,6 +1185,113 @@ Item Number: foo<br />
} }
#endregion
#region gt
/// <summary>
/// If first value is not greater than the second, the content of the gt statement should not be printed.
/// </summary>
[TestMethod]
public void TestCompile_Gt_EvaluatesToFalse_SkipsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#gt OneValue OtherValue}}Content{{/gt}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 10, OtherValue = 11 });
Assert.AreEqual("BeforeAfter", result, "The wrong text was generated.");
}
/// <summary>
/// If first value is greater than the second, the content of the gt statement should be printed.
/// </summary>
[TestMethod]
public void TestCompile_Gt_EvaluatesToTrue_PrintsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#gt OneValue OtherValue}}Content{{/gt}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 11.11, OtherValue = 11.1 });
Assert.AreEqual("BeforeContentAfter", result, "The wrong text was generated.");
}
#endregion
#region lt
/// <summary>
/// If first value is not greater than the second, the content of the gt statement should not be printed.
/// </summary>
[TestMethod]
public void TestCompile_Lt_EvaluatesToFalse_SkipsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#lt OneValue OtherValue}}Content{{/lt}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 11, OtherValue = 10.5 });
Assert.AreEqual("BeforeAfter", result, "The wrong text was generated.");
}
/// <summary>
/// If first value is greater than the second, the content of the gt statement should be printed.
/// </summary>
[TestMethod]
public void TestCompile_Lt_EvaluatesToTrue_PrintsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#lt OneValue OtherValue}}Content{{/lt}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 11.1, OtherValue = 11.11 });
Assert.AreEqual("BeforeContentAfter", result, "The wrong text was generated.");
}
#endregion
#region gte
/// <summary>
/// If first value is not greater than or equal to the second, the content of the gt statement should not be printed.
/// </summary>
[TestMethod]
public void TestCompile_Gte_EvaluatesToFalse_SkipsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#gte OneValue OtherValue}}Content{{/gte}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 9, OtherValue = 10 });
Assert.AreEqual("BeforeAfter", result, "The wrong text was generated.");
}
/// <summary>
/// If first value is greater than or equal to the second, the content of the gt statement should be printed.
/// </summary>
[TestMethod]
public void TestCompile_Gte_EvaluatesToTrue_PrintsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#gte OneValue OtherValue}}Content{{/gte}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 11.11, OtherValue = 11.11 });
Assert.AreEqual("BeforeContentAfter", result, "The wrong text was generated.");
}
#endregion
#region lte
/// <summary>
/// If first value is not greater than the second, the content of the gt statement should not be printed.
/// </summary>
[TestMethod]
public void TestCompile_Lte_EvaluatesToFalse_SkipsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#lte OneValue OtherValue}}Content{{/lte}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 11, OtherValue = 10.5 });
Assert.AreEqual("BeforeAfter", result, "The wrong text was generated.");
}
/// <summary>
/// If first value is greater than the second, the content of the gt statement should be printed.
/// </summary>
[TestMethod]
public void TestCompile_Lte_EvaluatesToTrue_PrintsContent() {
FormatCompiler parser = new FormatCompiler();
const string format = "Before{{#lte OneValue OtherValue}}Content{{/lte}}After";
Generator generator = parser.Compile(format);
string result = generator.Render(new { OneValue = 11.11, OtherValue = 11.11 });
Assert.AreEqual("BeforeContentAfter", result, "The wrong text was generated.");
}
#endregion
#region Compound Tags #region Compound Tags
/// <summary> /// <summary>

View File

@ -29,7 +29,7 @@ namespace Mustache
/// </summary> /// </summary>
protected override IEnumerable<string> GetClosingTags() protected override IEnumerable<string> GetClosingTags()
{ {
return new string[] { "if","eq" }; return new string[] { "if","eq","gt","gte","lt","lte" };
} }
/// <summary> /// <summary>

View File

@ -59,7 +59,7 @@ namespace Mustache {
if ((condition is double || condition is int) && (targetValue is double || targetValue is int) ) { if ((condition is double || condition is int) && (targetValue is double || targetValue is int) ) {
return Math.Abs((double) condition - (double) targetValue) < 0.0; return Convert.ToDouble(condition) == Convert.ToDouble(targetValue);
} }
if (condition is string && targetValue is string) { if (condition is string && targetValue is string) {

View File

@ -41,8 +41,17 @@ namespace Mustache
_tagLookup.Add(newlineDefinition.Name, newlineDefinition); _tagLookup.Add(newlineDefinition.Name, newlineDefinition);
SetTagDefinition setDefinition = new SetTagDefinition(); SetTagDefinition setDefinition = new SetTagDefinition();
_tagLookup.Add(setDefinition.Name, setDefinition); _tagLookup.Add(setDefinition.Name, setDefinition);
EqTagDefinition eqTagDefinition = new EqTagDefinition(); EqTagDefinition eqTagDefinition = new EqTagDefinition();
_tagLookup.Add(eqTagDefinition.Name,eqTagDefinition); _tagLookup.Add(eqTagDefinition.Name,eqTagDefinition);
GtTagDefinition gtTagDefinition = new GtTagDefinition();
_tagLookup.Add(gtTagDefinition.Name,gtTagDefinition);
LtTagDefinition ltTagDefinition = new LtTagDefinition();
_tagLookup.Add(ltTagDefinition.Name, ltTagDefinition);
GteTagDefinition gteTagDefinition = new GteTagDefinition();
_tagLookup.Add(gteTagDefinition.Name, gteTagDefinition);
LteTagDefinition lteTagDefinition = new LteTagDefinition();
_tagLookup.Add(lteTagDefinition.Name, lteTagDefinition);
} }

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mustache {
/// <summary>
/// Defines a tag that conditionally prints its content, based on whether the passed in values are equal
/// </summary>
internal sealed class GtTagDefinition : ConditionTagDefinition {
private const string ConditionParameter = "condition";
private const string TargetValueParameter = "targetValue";
/// <summary>
/// Initializes a new instance of a IfTagDefinition.
/// </summary>
public GtTagDefinition()
: base("gt") {}
/// <summary>
/// Gets whether the tag only exists within the scope of its parent.
/// </summary>
protected override bool GetIsContextSensitive() {
return false;
}
/// <summary>
/// Gets the parameters that can be passed to the tag.
/// </summary>
/// <returns>The parameters.</returns>
protected override IEnumerable<TagParameter> GetParameters() {
return new[] {
new TagParameter(ConditionParameter) {IsRequired = true},
new TagParameter(TargetValueParameter) {IsRequired = true}
};
}
/// <summary>
/// Gets whether the primary generator group should be used to render the tag.
/// </summary>
/// <param name="arguments">The arguments passed to the tag.</param>
/// <returns>
/// True if the primary generator group should be used to render the tag;
/// otherwise, false to use the secondary group.
/// </returns>
public override bool ShouldGeneratePrimaryGroup(Dictionary<string, object> arguments) {
object condition = arguments[ConditionParameter];
object targetValue = arguments[TargetValueParameter];
return isConditionSatisfied(condition, targetValue);
}
private bool isConditionSatisfied(object condition, object targetValue) {
if (condition == null || targetValue == null) {
return false;
}
if ((condition is double || condition is int) && (targetValue is double || targetValue is int)) {
return Convert.ToDouble(condition) > Convert.ToDouble(targetValue);
}
return false;
}
/// <summary>
/// Gets the parameters that are used to create a new child context.
/// </summary>
/// <returns>The parameters that are used to create a new child context.</returns>
public override IEnumerable<TagParameter> GetChildContextParameters() {
return new TagParameter[0];
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mustache {
/// <summary>
/// Defines a tag that conditionally prints its content, based on whether the passed in values are equal
/// </summary>
internal sealed class GteTagDefinition : ConditionTagDefinition {
private const string ConditionParameter = "condition";
private const string TargetValueParameter = "targetValue";
/// <summary>
/// Initializes a new instance of a IfTagDefinition.
/// </summary>
public GteTagDefinition()
: base("gte") {}
/// <summary>
/// Gets whether the tag only exists within the scope of its parent.
/// </summary>
protected override bool GetIsContextSensitive() {
return false;
}
/// <summary>
/// Gets the parameters that can be passed to the tag.
/// </summary>
/// <returns>The parameters.</returns>
protected override IEnumerable<TagParameter> GetParameters() {
return new[] {
new TagParameter(ConditionParameter) {IsRequired = true},
new TagParameter(TargetValueParameter) {IsRequired = true}
};
}
/// <summary>
/// Gets whether the primary generator group should be used to render the tag.
/// </summary>
/// <param name="arguments">The arguments passed to the tag.</param>
/// <returns>
/// True if the primary generator group should be used to render the tag;
/// otherwise, false to use the secondary group.
/// </returns>
public override bool ShouldGeneratePrimaryGroup(Dictionary<string, object> arguments) {
object condition = arguments[ConditionParameter];
object targetValue = arguments[TargetValueParameter];
return isConditionSatisfied(condition, targetValue);
}
private bool isConditionSatisfied(object condition, object targetValue) {
if (condition == null || targetValue == null) {
return false;
}
if ((condition is double || condition is int) && (targetValue is double || targetValue is int)) {
return Convert.ToDouble(condition) >= Convert.ToDouble(targetValue);
}
return false;
}
/// <summary>
/// Gets the parameters that are used to create a new child context.
/// </summary>
/// <returns>The parameters that are used to create a new child context.</returns>
public override IEnumerable<TagParameter> GetChildContextParameters() {
return new TagParameter[0];
}
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mustache {
/// <summary>
/// Defines a tag that conditionally prints its content, based on whether the passed in values are equal
/// </summary>
internal sealed class LtTagDefinition : ConditionTagDefinition {
private const string ConditionParameter = "condition";
private const string TargetValueParameter = "targetValue";
/// <summary>
/// Initializes a new instance of a IfTagDefinition.
/// </summary>
public LtTagDefinition()
: base("lt") {}
/// <summary>
/// Gets whether the tag only exists within the scope of its parent.
/// </summary>
protected override bool GetIsContextSensitive() {
return false;
}
/// <summary>
/// Gets the parameters that can be passed to the tag.
/// </summary>
/// <returns>The parameters.</returns>
protected override IEnumerable<TagParameter> GetParameters() {
return new[] {
new TagParameter(ConditionParameter) {IsRequired = true},
new TagParameter(TargetValueParameter) {IsRequired = true}
};
}
/// <summary>
/// Gets whether the primary generator group should be used to render the tag.
/// </summary>
/// <param name="arguments">The arguments passed to the tag.</param>
/// <returns>
/// True if the primary generator group should be used to render the tag;
/// otherwise, false to use the secondary group.
/// </returns>
public override bool ShouldGeneratePrimaryGroup(Dictionary<string, object> arguments) {
object condition = arguments[ConditionParameter];
object targetValue = arguments[TargetValueParameter];
return isConditionSatisfied(condition, targetValue);
}
private bool isConditionSatisfied(object condition, object targetValue) {
if (condition == null || targetValue == null) {
return false;
}
if ((condition is double || condition is int) && (targetValue is double || targetValue is int)) {
return Convert.ToDouble(condition) < Convert.ToDouble(targetValue);
}
return false;
}
/// <summary>
/// Gets the parameters that are used to create a new child context.
/// </summary>
/// <returns>The parameters that are used to create a new child context.</returns>
public override IEnumerable<TagParameter> GetChildContextParameters() {
return new TagParameter[0];
}
}
}

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mustache {
/// <summary>
/// Defines a tag that conditionally prints its content, based on whether the passed in values are equal
/// </summary>
internal sealed class LteTagDefinition : ConditionTagDefinition {
private const string ConditionParameter = "condition";
private const string TargetValueParameter = "targetValue";
/// <summary>
/// Initializes a new instance of a IfTagDefinition.
/// </summary>
public LteTagDefinition()
: base("lte") {}
/// <summary>
/// Gets whether the tag only exists within the scope of its parent.
/// </summary>
protected override bool GetIsContextSensitive() {
return false;
}
/// <summary>
/// Gets the parameters that can be passed to the tag.
/// </summary>
/// <returns>The parameters.</returns>
protected override IEnumerable<TagParameter> GetParameters() {
return new[] {
new TagParameter(ConditionParameter) {IsRequired = true},
new TagParameter(TargetValueParameter) {IsRequired = true}
};
}
/// <summary>
/// Gets whether the primary generator group should be used to render the tag.
/// </summary>
/// <param name="arguments">The arguments passed to the tag.</param>
/// <returns>
/// True if the primary generator group should be used to render the tag;
/// otherwise, false to use the secondary group.
/// </returns>
public override bool ShouldGeneratePrimaryGroup(Dictionary<string, object> arguments) {
object condition = arguments[ConditionParameter];
object targetValue = arguments[TargetValueParameter];
return isConditionSatisfied(condition, targetValue);
}
private bool isConditionSatisfied(object condition, object targetValue) {
if (condition == null || targetValue == null) {
return false;
}
if ((condition is double || condition is int) && (targetValue is double || targetValue is int)) {
return Convert.ToDouble(condition) <= Convert.ToDouble(targetValue);
}
return false;
}
/// <summary>
/// Gets the parameters that are used to create a new child context.
/// </summary>
/// <returns>The parameters that are used to create a new child context.</returns>
public override IEnumerable<TagParameter> GetChildContextParameters() {
return new TagParameter[0];
}
}
}

View File

@ -40,7 +40,11 @@
<Compile Include="ContentTagDefinition.cs" /> <Compile Include="ContentTagDefinition.cs" />
<Compile Include="Context.cs" /> <Compile Include="Context.cs" />
<Compile Include="ContextParameter.cs" /> <Compile Include="ContextParameter.cs" />
<Compile Include="LteTagDefinition.cs" />
<Compile Include="GteTagDefinition.cs" />
<Compile Include="LtTagDefinition.cs" />
<Compile Include="EqTagDefinition.cs" /> <Compile Include="EqTagDefinition.cs" />
<Compile Include="GtTagDefinition.cs" />
<Compile Include="VariableFoundEventArgs.cs" /> <Compile Include="VariableFoundEventArgs.cs" />
<Compile Include="SetTagDefinition.cs" /> <Compile Include="SetTagDefinition.cs" />
<Compile Include="NewlineTagDefinition.cs" /> <Compile Include="NewlineTagDefinition.cs" />