Files
Print_server/Inspectron.Epson.Templates.Tests/Integration/KitchenReceiptTests.cs
2026-01-21 15:56:37 +01:00

194 lines
6.3 KiB
C#

using Inspectron.Epson.Templates.Configuration;
using Inspectron.Epson.Templates.Interpreter;
using Inspectron.Epson.Templates.Language;
using Inspectron.Epson.Templates.Language.Nodes;
using Inspectron.Epson.Templates.Tests.Helpers;
namespace Inspectron.Epson.Templates.Tests.Integration;
public class KitchenReceiptTests
{
private readonly PrinterProfile _profile = new("tm-t30iii", "TM-T30III", 48, 24, false);
private const string KitchenReceiptJson = """
{
"Title": "Restaurant Test",
"TransactionDateTime": "2024-03-15T14:30:00",
"ReceiptNumber": "12345",
"WaiterName": "John Doe",
"WaiterId": "W001",
"TableNumber": "5",
"SpecialInstruction": "Rush Order",
"Gangs": [
{
"Id": 1,
"Name": "Starters",
"Dishes": [
{
"Number": 2,
"Name": "Caesar Salad",
"Modifications": {
"Removed": ["Croutons"],
"Added": ["Extra Dressing"]
},
"Comment": "No anchovies"
}
]
}
],
"Dishes": [
{
"Number": 1,
"Name": "Grilled Salmon",
"Modifications": {
"Removed": [],
"Added": []
},
"Comment": null
}
]
}
""";
private const string KitchenTemplate = """
#red,big,tall,center# {Title} #
---
#center# {TransactionDateTime:dd-MMM-yy HH:mm} Nr.:{ReceiptNumber} #
#center# {WaiterName} #
#center# {WaiterId} #
#big,bold,center# Tisch: {TableNumber} #
@if SpecialInstruction
#big,bold,center# {SpecialInstruction} #
@end
---
@foreach gang in Gangs
#red,big,tall,center# {gang.Id}. {gang.Name} #
@foreach dish in gang.Dishes
#tall# {dish.Number}x {dish.Name} #
@if dish.Modifications.Removed.count > 0
@foreach removed in dish.Modifications.Removed
#bold,tall# - {removed} #
@end
@end
@if dish.Modifications.Added.count > 0
@foreach added in dish.Modifications.Added
#bold,tall# + {added} #
@end
@end
@if dish.Comment
#bold,tall# Comment: {dish.Comment} #
@end
@end
@end
@if Gangs.count > 0
---
@end
@foreach dish in Dishes
#tall# {dish.Number}x {dish.Name} #
@end
""";
private TemplateNode Parse(string source)
{
var lexer = new Lexer(source);
var parser = new Parser(lexer.Tokenize().Tokens);
return parser.Parse().Template;
}
[Fact]
public void KitchenReceipt_RendersFully()
{
var template = Parse(KitchenTemplate);
var interpreter = new TemplateInterpreter(_profile);
var commands = interpreter.Interpret(template, KitchenReceiptJson);
// Verify key elements are present
Assert.Contains(commands, c => c.Text.Contains("Restaurant Test"));
Assert.Contains(commands, c => c.Text.Contains("John Doe"));
Assert.Contains(commands, c => c.Text.Contains("Tisch: 5"));
Assert.Contains(commands, c => c.Text.Contains("Rush Order"));
Assert.Contains(commands, c => c.Text.Contains("1. Starters"));
Assert.Contains(commands, c => c.Text.Contains("2x Caesar Salad"));
Assert.Contains(commands, c => c.Text.Contains("- Croutons"));
Assert.Contains(commands, c => c.Text.Contains("+ Extra Dressing"));
Assert.Contains(commands, c => c.Text.Contains("Comment: No anchovies"));
Assert.Contains(commands, c => c.Text.Contains("1x Grilled Salmon"));
}
[Fact]
public void KitchenReceipt_AppliesStyles()
{
var template = Parse(KitchenTemplate);
var interpreter = new TemplateInterpreter(_profile);
var commands = interpreter.Interpret(template, KitchenReceiptJson);
// Title should be big and tall
var titleCmd = commands.FirstOrDefault(c => c.Text.Contains("Restaurant Test"));
Assert.NotNull(titleCmd);
Assert.True(titleCmd.IsBig);
Assert.True(titleCmd.IsTall);
// Table should be bold and big
var tableCmd = commands.FirstOrDefault(c => c.Text.Contains("Tisch: 5"));
Assert.NotNull(tableCmd);
Assert.True(tableCmd.IsBold);
Assert.True(tableCmd.IsBig);
// Modifications should be bold and tall
var modCmd = commands.FirstOrDefault(c => c.Text.Contains("- Croutons"));
Assert.NotNull(modCmd);
Assert.True(modCmd.IsBold);
Assert.True(modCmd.IsTall);
}
[Fact]
public void KitchenReceipt_GeneratesSeparators()
{
var template = Parse(KitchenTemplate);
var interpreter = new TemplateInterpreter(_profile);
var commands = interpreter.Interpret(template, KitchenReceiptJson);
var separatorCount = commands.Count(c => c.Text.All(ch => ch == '-') && c.Text.Length == 48);
Assert.True(separatorCount >= 2, $"Expected at least 2 separators, found {separatorCount}");
}
[Fact]
public void KitchenReceipt_FormatsDateTime()
{
var template = Parse(KitchenTemplate);
var interpreter = new TemplateInterpreter(_profile);
var commands = interpreter.Interpret(template, KitchenReceiptJson);
Assert.Contains(commands, c => c.Text.Contains("15-Mar-24") || c.Text.Contains("15-Mär-24"));
}
[Fact]
public void KitchenReceipt_WithoutSpecialInstruction_OmitsSection()
{
var jsonWithoutInstruction = """
{
"Title": "Test",
"TransactionDateTime": "2024-03-15T14:30:00",
"ReceiptNumber": "123",
"WaiterName": "John",
"WaiterId": "W001",
"TableNumber": "1",
"SpecialInstruction": null,
"Gangs": [],
"Dishes": []
}
""";
var template = Parse(KitchenTemplate);
var interpreter = new TemplateInterpreter(_profile);
var commands = interpreter.Interpret(template, jsonWithoutInstruction);
// Should not have any content that looks like special instruction
Assert.DoesNotContain(commands, c => c.Text.Contains("Rush"));
}
}