295 lines
8.5 KiB
C#
295 lines
8.5 KiB
C#
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]);
|
|
}
|
|
}
|