Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 26 additions & 64 deletions Liquid.NET.Tests/Constants/MissingValueTests.cs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,117 +5,79 @@

namespace Liquid.NET.Tests.Constants
{

public class MissingValueTests
{
[Theory]
[InlineData("x", "x")]
[InlineData("d.x", "x")]
[InlineData("d[x]", "x")]
[InlineData("a.b.c", "a")]
public void It_Should_Display_An_Error_When_Dereferencing_Missing_Value(String varname, String missingVar)
public void It_Should_Display_An_Error_When_Value_Is_Undefined(String varname, String missingVar)
{
// Arrange

ITemplateContext ctx = new TemplateContext()
ITemplateContext ctx = new TemplateContext()
.ErrorWhenValueMissing();
ctx.DefineLocalVariable("d", new LiquidHash());

ctx.DefineLocalVariable("x", LiquidValue.None);
ctx.DefineLocalVariable("d", new LiquidHash()
{
{
"x", LiquidValue.None
}
});

// Act
var template = LiquidTemplate.Create("Result : {{ " + varname + " }}");
var result = template.LiquidTemplate.Render(ctx);
//Console.WriteLine(result);

// Assert
Assert.Equal("Result : ERROR: " + missingVar + " is undefined", result.Result);

}

[Theory]
[InlineData("e[1]")]
[InlineData("e.first")]
[InlineData("e.last")]
public void It_Should_Display_An_Error_When_Dereferencing_Empty_Array(String varname)
[InlineData("e[1]", "1")]
[InlineData("e.first", "first")]
[InlineData("e.last", "last")]
public void It_Should_Display_An_Error_When_Array_Value_Is_Undefined(String varname, String missingVar)
{
// Arrange
ITemplateContext ctx = new TemplateContext()
.ErrorWhenValueMissing();
ctx.DefineLocalVariable("e", new LiquidCollection());
ctx.DefineLocalVariable("e", new LiquidCollection(new[] { LiquidValue.None, LiquidValue.None, LiquidValue.None }));

// Act
//var result = RenderingHelper.RenderTemplate("Result : {{ " + varname + " }}", ctx);
var template = LiquidTemplate.Create("Result : {{ " + varname + " }}");
var result = template.LiquidTemplate.Render(ctx);

// Assert
Assert.Equal("Result : ERROR: cannot dereference empty array", result.Result);

}



[Fact]
public void It_Should_Display_Error_When_Dereferencing_Array_With_Non_Int()
{
// Arrange
ITemplateContext ctx = new TemplateContext()
.ErrorWhenValueMissing();
ctx.DefineLocalVariable("e", new LiquidCollection());

// Act
var template = LiquidTemplate.Create("Result : {{ e.x }}");
var result = template.LiquidTemplate.Render(ctx);
//var result = RenderingHelper.RenderTemplate("Result : {{ e.x }}", ctx);

// Assert
Assert.Contains("invalid index: 'x'", result.Result);

}

[Fact]
public void It_Should_Display_Error_When_Dereferencing_Primitive_With_Index()
{
// Arrange
ITemplateContext ctx = new TemplateContext()
.ErrorWhenValueMissing();
ctx.DefineLocalVariable("e", LiquidString.Create("Hello"));

// Act
var template = LiquidTemplate.Create("Result : {{ e.x }}");
var result = template.LiquidTemplate.Render(ctx);

Assert.True(result.HasRenderingErrors);
var errorMessage = String.Join(",", result.RenderingErrors.Select(x => x.Message));
// Assert
Assert.Contains("invalid string index: 'x'", errorMessage);

Assert.Equal("Result : ERROR: " + missingVar + " is undefined", result.Result);
}


[Theory]
[InlineData("x")]
[InlineData("e.first")]
[InlineData("e[1]")]
[InlineData("e.x")]
[InlineData("d.x")]
[InlineData("d[x]")]
[InlineData("a.b.c")]
public void It_Should_Not_Display_An_Error_When_Dereferencing_Missing_Value(String varname)
public void It_Should_Not_Display_An_Error_When_Values_Are_Missing(String varname)
{
// Arrange
//Console.WriteLine(varname);
TemplateContext ctx = new TemplateContext();
ctx.DefineLocalVariable("e", new LiquidCollection());
ctx.DefineLocalVariable("d", new LiquidHash());
ITemplateContext ctx = new TemplateContext()
.ErrorWhenVariableMissing();
ctx.DefineLocalVariable("e", new LiquidCollection(new[] { LiquidValue.None, LiquidValue.None, LiquidValue.None }));
ctx.DefineLocalVariable("d", new LiquidHash()
{
{ "x", LiquidValue.None }
});
ctx.DefineLocalVariable("x", LiquidValue.None);

// Act
var result = RenderingHelper.RenderTemplate("Result : {{ " + varname + " }}", ctx);

// Assert
Assert.Equal("Result : ", result);

}



}
}
121 changes: 121 additions & 0 deletions Liquid.NET.Tests/Constants/MissingVariableTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System;
using System.Linq;
using Liquid.NET.Constants;
using Xunit;

namespace Liquid.NET.Tests.Constants
{
public class MissingVariableTests
{
[Theory]
[InlineData("x", "x")]
[InlineData("d.x", "x")]
[InlineData("d[x]", "x")]
[InlineData("a.b.c", "a")]
public void It_Should_Display_An_Error_When_Dereferencing_Missing_Variable(String varname, String missingVar)
{
// Arrange

ITemplateContext ctx = new TemplateContext()
.ErrorWhenVariableMissing();
ctx.DefineLocalVariable("d", new LiquidHash());

// Act
var template = LiquidTemplate.Create("Result : {{ " + varname + " }}");
var result = template.LiquidTemplate.Render(ctx);
Console.WriteLine(result);

// Assert
Assert.Equal("Result : ERROR: " + missingVar + " is undefined", result.Result);

}

[Theory]
[InlineData("e[1]")]
[InlineData("e.first")]
[InlineData("e.last")]
public void It_Should_Display_An_Error_When_Dereferencing_Empty_Array(String varname)
{
// Arrange
ITemplateContext ctx = new TemplateContext()
.ErrorWhenVariableMissing();
ctx.DefineLocalVariable("e", new LiquidCollection());

// Act
//var result = RenderingHelper.RenderTemplate("Result : {{ " + varname + " }}", ctx);
var template = LiquidTemplate.Create("Result : {{ " + varname + " }}");
var result = template.LiquidTemplate.Render(ctx);

// Assert
Assert.Equal("Result : ERROR: cannot dereference empty array", result.Result);

}



[Fact]
public void It_Should_Display_Error_When_Dereferencing_Array_With_Non_Int()
{
// Arrange
ITemplateContext ctx = new TemplateContext()
.ErrorWhenVariableMissing();
ctx.DefineLocalVariable("e", new LiquidCollection());

// Act
var template = LiquidTemplate.Create("Result : {{ e.x }}");
var result = template.LiquidTemplate.Render(ctx);
//var result = RenderingHelper.RenderTemplate("Result : {{ e.x }}", ctx);

// Assert
Assert.Contains("invalid index: 'x'", result.Result);

}

[Fact]
public void It_Should_Display_Error_When_Dereferencing_Primitive_With_Index()
{
// Arrange
ITemplateContext ctx = new TemplateContext()
.ErrorWhenVariableMissing();
ctx.DefineLocalVariable("e", LiquidString.Create("Hello"));

// Act
var template = LiquidTemplate.Create("Result : {{ e.x }}");
var result = template.LiquidTemplate.Render(ctx);

Assert.True(result.HasRenderingErrors);
var errorMessage = String.Join(",", result.RenderingErrors.Select(x => x.Message));
// Assert
Assert.Contains("invalid string index: 'x'", errorMessage);

}


[Theory]
[InlineData("x")]
[InlineData("e[1]")]
[InlineData("e.x")]
[InlineData("d.x")]
[InlineData("d[x]")]
[InlineData("a.b.c")]
public void It_Should_Not_Display_An_Error_When_Dereferencing_Missing_Variable(String varname)
{
// Arrange
Console.WriteLine(varname);
ITemplateContext ctx = new TemplateContext()
.ErrorWhenValueMissing();
ctx.DefineLocalVariable("e", new LiquidCollection());
ctx.DefineLocalVariable("d", new LiquidHash());

// Act
var result = RenderingHelper.RenderTemplate("Result : {{ " + varname + " }}", ctx);

// Assert
Assert.Equal("Result : ", result);

}



}
}
37 changes: 28 additions & 9 deletions Liquid.NET/src/Constants/IndexDereferencer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public LiquidExpressionResult Lookup(

private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidCollection liquidCollection, ILiquidValue indexProperty)
{
bool errorOnEmpty = ctx.Options.ErrorWhenValueMissing && liquidCollection.Count == 0;
bool errorOnEmpty = ctx.Options.ErrorWhenVariableMissing && liquidCollection.Count == 0;



Expand Down Expand Up @@ -75,7 +75,7 @@ private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidCollection l

if (!success)
{
if (ctx.Options.ErrorWhenValueMissing)
if (ctx.Options.ErrorWhenVariableMissing)
{
return LiquidExpressionResult.Error("invalid index: '" + propertyNameString + "'");
}
Expand Down Expand Up @@ -103,6 +103,11 @@ private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidCollection l
}
var result = liquidCollection.ValueAt(index);

if (!result.HasValue)
{
return LiquidExpressionResult.ErrorOrNone(ctx, propertyNameString);
}

return LiquidExpressionResult.Success(result);
}

Expand All @@ -115,15 +120,22 @@ private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidHash liquidH
return LiquidExpressionResult.Success(LiquidNumeric.Create(liquidHash.Keys.Count));
}

var valueAt = liquidHash.ValueAt(indexProperty.Value.ToString());
if (valueAt.HasValue)
var key = indexProperty.Value.ToString();
if (liquidHash.ContainsKey(key))
{
return LiquidExpressionResult.Success(valueAt);
var value = liquidHash[key];
if (value.HasValue)
{
return LiquidExpressionResult.Success(value);
}
else
{
return LiquidExpressionResult.ErrorOrNone(ctx, indexProperty.ToString());
}
}
else
{
return LiquidExpressionResult.ErrorOrNone(ctx, indexProperty.ToString());

return LiquidExpressionResult.MissingOrNone(ctx, indexProperty.ToString());
}
}

Expand Down Expand Up @@ -152,7 +164,7 @@ private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidString str,

if (numericIndexProperty == null)
{
return ctx.Options.ErrorWhenValueMissing ?
return ctx.Options.ErrorWhenVariableMissing ?
LiquidExpressionResult.Error("invalid string index: '" + propertyNameString + "'") :
LiquidExpressionResult.Success(new None<ILiquidValue>());
}
Expand All @@ -167,7 +179,14 @@ private LiquidExpressionResult DoLookup(ITemplateContext ctx, LiquidString str,
//return LiquidExpressionResult.Error("Empty string: " + propertyNameString);
return LiquidExpressionResult.Success(new None<ILiquidValue>()); // not an error in Ruby liquid.
}
return LiquidExpressionResult.Success(CollectionIndexer.ValueAt(strValues, index));

var result = CollectionIndexer.ValueAt(strValues, index);
if (!result.HasValue)
{
return LiquidExpressionResult.ErrorOrNone(ctx, propertyNameString);
}

return LiquidExpressionResult.Success(result);

}

Expand Down
18 changes: 3 additions & 15 deletions Liquid.NET/src/Expressions/VariableReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,9 @@ public VariableReference(String name)
public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable<Option<ILiquidValue>> childresults)
{
var lookupResult= templateContext.SymbolTableStack.Reference(Name);
return lookupResult.IsSuccess ?
lookupResult :
ErrorOrNone(templateContext, lookupResult);
}

private LiquidExpressionResult ErrorOrNone(ITemplateContext templateContext, LiquidExpressionResult failureResult)
{
if (templateContext.Options.ErrorWhenValueMissing)
{
return failureResult;
}
else
{
return LiquidExpressionResult.Success(new None<ILiquidValue>());
}
return lookupResult.IsSuccess
? (lookupResult.SuccessResult.HasValue ? lookupResult : LiquidExpressionResult.ErrorOrNone(templateContext, Name))
: LiquidExpressionResult.MissingOrNone(templateContext, Name);
}
}
}
2 changes: 2 additions & 0 deletions Liquid.NET/src/ITemplateContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public interface ITemplateContext
ITemplateContext WithNoForLimit();
ITemplateContext WithASTGenerator(Func<string, Action<LiquidError>, LiquidAST> astGeneratorFunc);

ITemplateContext ErrorWhenValueMissing();
ITemplateContext ErrorWhenVariableMissing();

IFileSystem FileSystem { get; }
IDictionary<String, Object> Registers { get; }
Expand Down
Loading