template engine
This commit is contained in:
294
Inspectron.Epson.TemplateEngine.Tests/TemplateParserTests.cs
Normal file
294
Inspectron.Epson.TemplateEngine.Tests/TemplateParserTests.cs
Normal file
@@ -0,0 +1,294 @@
|
||||
using Inspectron.Epson.TemplateEngine.Parsing;
|
||||
|
||||
namespace Inspectron.Epson.TemplateEngine.Tests;
|
||||
|
||||
public class TemplateParserTests
|
||||
{
|
||||
private readonly TemplateParser _parser = new();
|
||||
|
||||
[Fact]
|
||||
public void Parse_EmptyReceipt()
|
||||
{
|
||||
var result = _parser.Parse("<receipt></receipt>");
|
||||
Assert.NotNull(result);
|
||||
Assert.Empty(result.Children);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_InvalidXml_Throws()
|
||||
{
|
||||
Assert.Throws<TemplateParsingException>(() => _parser.Parse("not xml"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_WrongRoot_Throws()
|
||||
{
|
||||
Assert.Throws<TemplateParsingException>(() => _parser.Parse("<div></div>"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_UnknownElement_Throws()
|
||||
{
|
||||
Assert.Throws<TemplateParsingException>(() =>
|
||||
_parser.Parse("<receipt><unknown /></receipt>"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Line_BasicText()
|
||||
{
|
||||
var result = _parser.Parse("<receipt><line>Hello</line></receipt>");
|
||||
Assert.Single(result.Children);
|
||||
var line = Assert.IsType<LineNode>(result.Children[0]);
|
||||
Assert.Equal("Hello", line.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Line_WithFormatting()
|
||||
{
|
||||
var result = _parser.Parse(
|
||||
"""<receipt><line bold="true" big="true" tall="true" red="true" align="center">Text</line></receipt>""");
|
||||
var line = Assert.IsType<LineNode>(result.Children[0]);
|
||||
Assert.True(line.Bold);
|
||||
Assert.True(line.Big);
|
||||
Assert.True(line.Tall);
|
||||
Assert.True(line.Red);
|
||||
Assert.Equal("center", line.Align);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Line_WithWrap()
|
||||
{
|
||||
var result = _parser.Parse(
|
||||
"""<receipt><line wrap="true" wrapIndent="4">Long text</line></receipt>""");
|
||||
var line = Assert.IsType<LineNode>(result.Children[0]);
|
||||
Assert.True(line.Wrap);
|
||||
Assert.Equal(4, line.WrapIndent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Line_WithLineSpacing()
|
||||
{
|
||||
var result = _parser.Parse(
|
||||
"""<receipt><line lineSpacing="50">Text</line></receipt>""");
|
||||
var line = Assert.IsType<LineNode>(result.Children[0]);
|
||||
Assert.Equal(50, line.LineSpacing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_EmptyLine()
|
||||
{
|
||||
var result = _parser.Parse("<receipt><line /></receipt>");
|
||||
var line = Assert.IsType<LineNode>(result.Children[0]);
|
||||
Assert.Equal("", line.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Columns()
|
||||
{
|
||||
var result = _parser.Parse(
|
||||
"""<receipt><columns left="Name" right="Price" bold="true" /></receipt>""");
|
||||
var col = Assert.IsType<ColumnsNode>(result.Children[0]);
|
||||
Assert.Equal("Name", col.Left);
|
||||
Assert.Equal("Price", col.Right);
|
||||
Assert.True(col.Bold);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Row_WithColumns()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<row bold="true">
|
||||
<col width="10" align="left">Name</col>
|
||||
<col width="10" align="right">Value</col>
|
||||
</row>
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
var row = Assert.IsType<RowNode>(result.Children[0]);
|
||||
Assert.True(row.Bold);
|
||||
Assert.Equal(2, row.Columns.Count);
|
||||
Assert.Equal("Name", row.Columns[0].Text);
|
||||
Assert.Equal(10, row.Columns[0].Width);
|
||||
Assert.Equal("left", row.Columns[0].Align);
|
||||
Assert.Equal("Value", row.Columns[1].Text);
|
||||
Assert.Equal(10, row.Columns[1].Width);
|
||||
Assert.Equal("right", row.Columns[1].Align);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Separator()
|
||||
{
|
||||
var result = _parser.Parse("<receipt><separator /></receipt>");
|
||||
var sep = Assert.IsType<SeparatorNode>(result.Children[0]);
|
||||
Assert.Equal('-', sep.Character);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Separator_CustomChar()
|
||||
{
|
||||
var result = _parser.Parse("""<receipt><separator char="*" /></receipt>""");
|
||||
var sep = Assert.IsType<SeparatorNode>(result.Children[0]);
|
||||
Assert.Equal('*', sep.Character);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Cut()
|
||||
{
|
||||
var result = _parser.Parse("<receipt><cut /></receipt>");
|
||||
Assert.IsType<CutNode>(result.Children[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Feed()
|
||||
{
|
||||
var result = _parser.Parse("""<receipt><feed lines="3" /></receipt>""");
|
||||
var feed = Assert.IsType<FeedNode>(result.Children[0]);
|
||||
Assert.Equal(3, feed.Lines);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Feed_Default()
|
||||
{
|
||||
var result = _parser.Parse("<receipt><feed /></receipt>");
|
||||
var feed = Assert.IsType<FeedNode>(result.Children[0]);
|
||||
Assert.Equal(1, feed.Lines);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Foreach()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<foreach items="Items" var="item">
|
||||
<line>{{item.Name}}</line>
|
||||
</foreach>
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
var fe = Assert.IsType<ForeachNode>(result.Children[0]);
|
||||
Assert.Equal("Items", fe.Items);
|
||||
Assert.Equal("item", fe.Var);
|
||||
Assert.Single(fe.Children);
|
||||
Assert.IsType<LineNode>(fe.Children[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Foreach_MissingItems_Throws()
|
||||
{
|
||||
Assert.Throws<TemplateParsingException>(() =>
|
||||
_parser.Parse("""<receipt><foreach var="item"><line /></foreach></receipt>"""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Foreach_MissingVar_Throws()
|
||||
{
|
||||
Assert.Throws<TemplateParsingException>(() =>
|
||||
_parser.Parse("""<receipt><foreach items="Items"><line /></foreach></receipt>"""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_If()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<if test="Name">
|
||||
<line>Has name</line>
|
||||
</if>
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
var ifNode = Assert.IsType<IfNode>(result.Children[0]);
|
||||
Assert.Equal("Name", ifNode.Test);
|
||||
Assert.Single(ifNode.Children);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_If_MissingTest_Throws()
|
||||
{
|
||||
Assert.Throws<TemplateParsingException>(() =>
|
||||
_parser.Parse("<receipt><if><line /></if></receipt>"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_IfElse()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<if test="Name">
|
||||
<line>Yes</line>
|
||||
</if>
|
||||
<else>
|
||||
<line>No</line>
|
||||
</else>
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
Assert.Equal(2, result.Children.Count);
|
||||
Assert.IsType<IfNode>(result.Children[0]);
|
||||
Assert.IsType<ElseNode>(result.Children[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_NestedForeach()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<foreach items="Gangs" var="gang">
|
||||
<foreach items="gang.Dishes" var="dish">
|
||||
<line>{{dish.Name}}</line>
|
||||
</foreach>
|
||||
</foreach>
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
var outer = Assert.IsType<ForeachNode>(result.Children[0]);
|
||||
Assert.Equal("Gangs", outer.Items);
|
||||
var inner = Assert.IsType<ForeachNode>(outer.Children[0]);
|
||||
Assert.Equal("gang.Dishes", inner.Items);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_Table()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<table items="Data" var="row">
|
||||
<col width="10" align="left">Header1</col>
|
||||
<col width="10" align="right">Header2</col>
|
||||
</table>
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
var table = Assert.IsType<TableNode>(result.Children[0]);
|
||||
Assert.Equal("Data", table.Items);
|
||||
Assert.Equal("row", table.Var);
|
||||
Assert.Equal(2, table.Columns.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_ComplexTemplate()
|
||||
{
|
||||
var result = _parser.Parse("""
|
||||
<receipt>
|
||||
<line align="center" big="true">Title</line>
|
||||
<separator />
|
||||
<line />
|
||||
<foreach items="Items" var="item">
|
||||
<line bold="true">{{item.Name}}</line>
|
||||
<if test="item.HasDiscount">
|
||||
<line red="true">DISCOUNT</line>
|
||||
</if>
|
||||
</foreach>
|
||||
<cut />
|
||||
</receipt>
|
||||
""");
|
||||
|
||||
Assert.Equal(5, result.Children.Count);
|
||||
Assert.IsType<LineNode>(result.Children[0]);
|
||||
Assert.IsType<SeparatorNode>(result.Children[1]);
|
||||
Assert.IsType<LineNode>(result.Children[2]);
|
||||
Assert.IsType<ForeachNode>(result.Children[3]);
|
||||
Assert.IsType<CutNode>(result.Children[4]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user