const std = @import("std"); const testing = std.testing; const parser = @import("parser.zig"); test "parse simple text" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("1 - parse simple text\n", .{}); const allocator = testing.allocator; const template = "Olá mundo!"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| { node.deinit(allocator); } allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Olá mundo!", nodes[0].text.?.content); } test "parse simple var" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("2 - parse simple var\n", .{}); const allocator = testing.allocator; const template = "Olá {{ nome }}!"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| { node.deinit(allocator); } allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Olá ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .variable); try testing.expectEqualStrings("nome", nodes[1].variable.?.expr); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings("!", nodes[2].text.?.content); } test "parse var with spaces" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("3 - parse var with spaces\n", .{}); const allocator = testing.allocator; const template = "{{ espacos }}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| { node.deinit(allocator); } allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .variable); try testing.expectEqualStrings("espacos", nodes[0].variable.?.expr); } test "parse autoescape on" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("4 - parse autoescape on\n", .{}); const allocator = testing.allocator; const template = "{% autoescape on %}Texto negrito{% endautoescape %}"; const expected = "Texto negrito"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); if (nodes[0].tag) |tag| { try testing.expect(tag.body.autoescape.enabled == true); try testing.expectEqual(@as(usize, 1), tag.body.autoescape.body.len); try testing.expectEqualStrings(expected, tag.body.autoescape.body[0].text.?.content); } } test "parse autoescape off" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("5 - parse autoescape off\n", .{}); const allocator = testing.allocator; const template = "{% autoescape off %}Texto negrito{% endautoescape %}"; const expected = "Texto negrito"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); if (nodes[0].tag) |tag| { try testing.expect(tag.body.autoescape.enabled == false); try testing.expectEqual(@as(usize, 1), tag.body.autoescape.body.len); try testing.expectEqualStrings(expected, tag.body.autoescape.body[0].text.?.content); } } test "parse simple block" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("6 - parse simple block\n", .{}); const allocator = testing.allocator; const template = "{% block titulo %}Meu Título{% endblock %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expectEqual(nodes[0].tag.?.kind, .block); try testing.expectEqualStrings("titulo", nodes[0].tag.?.body.block.name); const b = nodes[0].tag.?.body.block.body; try testing.expectEqual(@as(usize, 1), b.len); try testing.expectEqual(b[0].type, .text); try testing.expectEqualStrings("Meu Título", b[0].text.?.content); } test "parse block with super" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("7 - parse block with super\n", .{}); const allocator = testing.allocator; const template = "{% block conteudo %}{{ block.super }} Conteúdo filho{% endblock %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expectEqualStrings("conteudo", nodes[0].tag.?.body.block.name); const b = nodes[0].tag.?.body.block.body; try testing.expectEqual(@as(usize, 2), b.len); try testing.expect(b[0].type == .tag); try testing.expect(b[0].tag.?.kind == .super); try testing.expect(b[1].type == .text); try testing.expectEqualStrings(" Conteúdo filho", b[1].text.?.content); } // TODO: check it test "parse block with block inside" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("8 - parse block with block inside\n", .{}); const allocator = testing.allocator; const template = "{% block conteudo %}{% block inner %}Conteúdo filho{% endblock %}{% endblock %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expectEqualStrings("conteudo", nodes[0].tag.?.body.block.name); const b = nodes[0].tag.?.body.block.body; try testing.expectEqual(@as(usize, 3), b.len); try testing.expect(b[0].type == .tag); try testing.expect(b[0].tag.?.kind == .block); try testing.expect(b[1].type == .text); try testing.expectEqualStrings("Conteúdo filho", b[1].text.?.content); try testing.expect(b[2].type == .tag); // std.debug.print("block:\n {any}",.{nodes[0].tag.?.body.block}); // for(b) |node| std.debug.print("block:\n {any}\n",.{node}); // try testing.expectEqualStrings("inner",b[0].tag.?.body.block.name); // try testing.expect(b[1].type == .text); // try testing.expectEqualStrings(" Conteúdo filho",b[1].text.?.content); } test "parse simple csrf_token" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("9 - parse simple csrf_token\n", .{}); const allocator = testing.allocator; const template = "
{% csrf_token %}
"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("
", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .csrf_token); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings("
", nodes[2].text.?.content); } test "parse just csrf_token" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("10 - parse just csrf_token\n", .{}); const allocator = testing.allocator; const template = "{% csrf_token %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .csrf_token); } test "parse comment" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("11 - parse comment\n", .{}); const allocator = testing.allocator; const template = "Bazinga! {% comment %}{% for item in lista %}Tem{% empty %}Vazio{% endfor %}{% endcomment %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Bazinga! ", nodes[0].text.?.content); } test "parse comment inside block" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("12 - parse comment\n", .{}); const allocator = testing.allocator; const template = "{% block conteudo %}Bazinga!{% comment %}{% for item in lista %}Tem{% empty %}Vazio{% endfor %}{% endcomment %} haha{% endblock %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const child_nodes = nodes[0].tag.?.body.block.body; try testing.expectEqual(@as(usize, 2), child_nodes.len); try testing.expect(child_nodes[0].type == .text); try testing.expect(child_nodes[1].type == .text); try testing.expectEqualStrings("Bazinga!", child_nodes[0].text.?.content); try testing.expectEqualStrings(" haha", child_nodes[1].text.?.content); } test "parse simple cycle" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("13 - parse simple cycle\n", .{}); const allocator = testing.allocator; const template = "{% cycle 'row1' 'row2' %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const args = nodes[0].tag.?.body.cycle.values; try testing.expectEqual(@as(usize, 2), args.len); try testing.expectEqualStrings("row1", args[0]); try testing.expectEqualStrings("row2", args[1]); } test "parse cycle values without quotes" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("14 - parse cycle values without quotes\n", .{}); const allocator = testing.allocator; const template = "{% cycle row1 row2 row3 %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const args = nodes[0].tag.?.body.cycle.values; try testing.expectEqual(@as(usize, 3), args.len); try testing.expectEqualStrings("row1", args[0]); try testing.expectEqualStrings("row2", args[1]); try testing.expectEqualStrings("row3", args[2]); } test "parse simple debug" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("15 - parse simple debug\n", .{}); const allocator = testing.allocator; const template = "Antes {% debug %} Depois"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Antes ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .debug); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" Depois", nodes[2].text.?.content); } test "parse extends" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("16 - parse extends\n", .{}); const allocator = testing.allocator; const template = "{% extends \"base.html\" %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .extends); try testing.expectEqualStrings("base.html", nodes[0].tag.?.body.extends.parent_name); } test "parse simple filter block" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("17 - parse simple filter block\n", .{}); const allocator = testing.allocator; const template = "{% filter upper %}olá mundo{% endfilter %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const fb = nodes[0].tag.?.body.filter_block; try testing.expectEqualStrings("upper", fb.filters); try testing.expectEqual(@as(usize, 1), fb.body.len); try testing.expectEqualStrings("olá mundo", fb.body[0].text.?.content); } test "parse filter block multiple filters" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("18 - parse filter block multiple filters\n", .{}); const allocator = testing.allocator; const template = "{% filter upper|escape %}Conteúdo negrito{% endfilter %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .filter_block); const fb = nodes[0].tag.?.body.filter_block; try testing.expectEqualStrings("upper|escape", fb.filters); try testing.expectEqual(@as(usize, 1), fb.body.len); try testing.expectEqualStrings("Conteúdo negrito", fb.body[0].text.?.content); } test "parse variable with filters" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("19 - parse variable with filters\n", .{}); const allocator = testing.allocator; const template = "{{ nome|upper|default:\"Visitante\" }}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .variable); const v = nodes[0].variable.?; try testing.expectEqualStrings("nome", v.expr); try testing.expectEqual(@as(usize, 2), v.filters.len); try testing.expectEqualStrings("upper", v.filters[0].name); try testing.expect(v.filters[0].arg == null); try testing.expectEqualStrings("default", v.filters[1].name); try testing.expectEqualStrings("Visitante", v.filters[1].arg.?); } test "parse simple firstof" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("20 - parse simple firstof\n", .{}); const allocator = testing.allocator; const template = "Valor: {% firstof var1 var2 var3 %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 2), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Valor: ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); const fo = nodes[1].tag.?.body.firstof.values; try testing.expectEqual(@as(usize, 3), fo.len); try testing.expectEqualStrings("var1", fo[0]); try testing.expectEqualStrings("var2", fo[1]); try testing.expectEqualStrings("var3", fo[2]); } test "parse firstof with fallback" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("21 - parse firstof with fallback\n", .{}); const allocator = testing.allocator; const template = "{% firstof var1 var2 \"Nenhum valor\" %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const fo = nodes[0].tag.?.body.firstof.values; try testing.expectEqual(@as(usize, 3), fo.len); try testing.expectEqualStrings("var1", fo[0]); try testing.expectEqualStrings("var2", fo[1]); try testing.expectEqualStrings("Nenhum valor", fo[2]); } test "parse for block whithout empty" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("22 - parse for block whithout empty\n", .{}); const allocator = testing.allocator; const template = "{% for item in lista %}Item: {{ item }}{% endfor %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const fb = nodes[0].tag.?.body.@"for"; try testing.expectEqualStrings("item", fb.loop_var); try testing.expectEqualStrings("lista", fb.iterable); try testing.expectEqual(@as(usize, 2), fb.body.len); try testing.expectEqual(@as(usize, 0), fb.empty_body.len); try testing.expect(fb.body[0].type == .text); try testing.expectEqualStrings("Item: ", fb.body[0].text.?.content); try testing.expect(fb.body[1].type == .variable); try testing.expectEqualStrings("item", fb.body[1].variable.?.expr); } test "parse for block with empty" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("23 - parse for block with empty\n", .{}); const allocator = testing.allocator; const template = "{% for item in lista %}Tem{% empty %}Vazio{% endfor %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const fb = nodes[0].tag.?.body.@"for"; try testing.expectEqual(@as(usize, 1), fb.body.len); try testing.expectEqualStrings("Tem", fb.body[0].text.?.content); try testing.expectEqual(@as(usize, 1), fb.empty_body.len); try testing.expectEqualStrings("Vazio", fb.empty_body[0].text.?.content); } test "parse basic if block" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("24 - parse basic if block\n", .{}); const allocator = testing.allocator; const template = "{% if user.logged %}Welcome!{% endif %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| { node.deinit(allocator); } allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const ib = nodes[0].tag.?.body.@"if"; try testing.expectEqualStrings("user.logged", ib.condition); try testing.expectEqual(@as(usize, 1), ib.true_body.len); try testing.expect(ib.true_body[0].type == .text); try testing.expectEqualStrings("Welcome!", ib.true_body[0].text.?.content); try testing.expectEqual(@as(usize, 0), ib.false_body.len); } test "parse if block whithout else" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("25 - parse if block whithout else\n", .{}); const allocator = testing.allocator; const template = "{% if cond %}Verdadeiro{% endif %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| { node.deinit(allocator); } allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); const ib = nodes[0].tag.?.body.@"if"; try testing.expectEqualStrings("cond", ib.condition); try testing.expectEqual(@as(usize, 1), ib.true_body.len); try testing.expectEqualStrings("Verdadeiro", ib.true_body[0].text.?.content); try testing.expectEqual(@as(usize, 0), ib.false_body.len); } test "parse if block with else" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("26 - parse if block with else\n", .{}); const allocator = testing.allocator; const template = "{% if cond %}Verdadeiro{% else %}Falso{% endif %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| { node.deinit(allocator); } allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .if_block); const ib = nodes[0].tag.?.body.@"if"; try testing.expectEqualStrings("cond", ib.condition); try testing.expectEqual(@as(usize, 1), ib.true_body.len); try testing.expectEqualStrings("Verdadeiro", ib.true_body[0].text.?.content); try testing.expectEqual(@as(usize, 1), ib.false_body.len); try testing.expectEqualStrings("Falso", ib.false_body[0].text.?.content); } test "parse simple include" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("27 - parse simple include\n", .{}); const allocator = testing.allocator; const template = "Cabeçalho {% include \"header.html\" %} Conteúdo {% include \"footer.html\" %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 4), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Cabeçalho ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .include); try testing.expectEqualStrings("header.html", nodes[1].tag.?.body.include.template_path); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" Conteúdo ", nodes[2].text.?.content); try testing.expect(nodes[3].type == .tag); try testing.expectEqualStrings("footer.html", nodes[3].tag.?.body.include.template_path); } test "parse include without quotes (it is ok for now)" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("28 - parse include without quotes (it is ok for now)\n", .{}); const allocator = testing.allocator; const template = "{% include header.html %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .include); try testing.expectEqualStrings("header.html", nodes[0].tag.?.body.include.template_path); } test "parse simple load" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("29 - parse simple load\n", .{}); const allocator = testing.allocator; const template = "{% load i18n %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .load); const l = nodes[0].tag.?.body.load; try testing.expectEqual(@as(usize, 1), l.libraries.len); try testing.expectEqualStrings("i18n", l.libraries[0]); } test "parse load with multiple libraries" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("30 - parse load with multiple libraries\n", .{}); const allocator = testing.allocator; const template = "{% load admin_urls static %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .load); const l = nodes[0].tag.?.body.load; try testing.expectEqual(@as(usize, 2), l.libraries.len); try testing.expectEqualStrings("admin_urls", l.libraries[0]); try testing.expectEqualStrings("static", l.libraries[1]); } test "parse simple lorem" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("31 - parse simple lorem\n", .{}); const allocator = testing.allocator; const template = "{% lorem %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .lorem); const l = nodes[0].tag.?.body.lorem; try testing.expect(l.count == null); try testing.expect(l.method == null); try testing.expect(l.format == null); } test "parse lorem with arguments" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("32 - parse lorem with arguments\n", .{}); const allocator = testing.allocator; const template = "{% lorem 5 p html %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .lorem); const l = nodes[0].tag.?.body.lorem; try testing.expectEqualStrings("5", l.count.?); try testing.expectEqualStrings("p", l.method.?); try testing.expectEqualStrings("html", l.format.?); } test "parse simple now" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("33 - parse simple now\n", .{}); const allocator = testing.allocator; const template = "Data atual: {% now \"Y-m-d\" %} às {% now \"H:i\" %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 4), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Data atual: ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .now); try testing.expectEqualStrings("Y-m-d", nodes[1].tag.?.body.now.format); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" às ", nodes[2].text.?.content); try testing.expect(nodes[3].type == .tag); try testing.expect(nodes[3].tag.?.kind == .now); try testing.expectEqualStrings("H:i", nodes[3].tag.?.body.now.format); } test "parse now whithout quotes" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("34 - parse now whithout quotes\n", .{}); const allocator = testing.allocator; const template = "{% now Y-m-d %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .now); try testing.expectEqualStrings("Y-m-d", nodes[0].tag.?.body.now.format); } test "parse simple partial" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("35 - parse simple partial\n", .{}); const allocator = testing.allocator; const template = "Início {% partial \"cabecalho\" %} Fim"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Início ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .partial); try testing.expectEqualStrings("cabecalho", nodes[1].tag.?.body.partial.name); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" Fim", nodes[2].text.?.content); } test "parse partial whithout quotes" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("36 - parse partial whithout quotes\n", .{}); const allocator = testing.allocator; const template = "Início {% partial cabecalho %} Fim"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Início ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .partial); try testing.expectEqualStrings("cabecalho", nodes[1].tag.?.body.partial.name); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" Fim", nodes[2].text.?.content); } test "parse simple partialdef" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("37 - parse simple partialdef\n", .{}); const allocator = testing.allocator; const template = "{% partialdef cabecalho %}Cabeçalho{% endpartialdef %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .partialdef); const pd = nodes[0].tag.?.body.partialdef; try testing.expectEqualStrings("cabecalho", pd.name); try testing.expectEqual(@as(usize, 1), pd.body.len); try testing.expectEqualStrings("Cabeçalho", pd.body[0].text.?.content); } test "parse simple querystring" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("38 - parse simple querystring\n", .{}); const allocator = testing.allocator; const template = "Link: {% querystring \"page=2\" %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 2), nodes.len); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .querystring); const qs = nodes[1].tag.?.body.querystring; try testing.expectEqual(@as(usize, 1), qs.modifications.len); try testing.expectEqualStrings("page=2", qs.modifications[0]); } test "parse querystring with multiple modifications" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("39 - parse querystring with multiple modifications\n", .{}); const allocator = testing.allocator; const template = "{% querystring \"ordenar=-nome\" \"pagina\" None %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .querystring); const qs = nodes[0].tag.?.body.querystring; try testing.expectEqual(@as(usize, 3), qs.modifications.len); try testing.expectEqualStrings("ordenar=-nome", qs.modifications[0]); try testing.expectEqualStrings("pagina", qs.modifications[1]); try testing.expectEqualStrings("None", qs.modifications[2]); } test "parse simple regroup" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("40 - parse simple regroup\n", .{}); const allocator = testing.allocator; const template = "{% regroup pessoas by cidade as grupos_cidade %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .regroup); const r = nodes[0].tag.?.body.regroup; try testing.expectEqualStrings("pessoas", r.source); try testing.expectEqualStrings("cidade", r.by); try testing.expectEqualStrings("grupos_cidade", r.as_var); } test "parse simple resetcycle" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("41 - parse simple resetcycle\n", .{}); const allocator = testing.allocator; const template = "{% resetcycle %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .resetcycle); const rc = nodes[0].tag.?.body.resetcycle; try testing.expect(rc.cycle_name == null); } test "parse resetcycle with name" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("42 - parse resetcycle with name\n", .{}); const allocator = testing.allocator; const template = "{% resetcycle rowclass %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .resetcycle); const rc = nodes[0].tag.?.body.resetcycle; try testing.expect(rc.cycle_name != null); try testing.expectEqualStrings("rowclass", rc.cycle_name.?); } test "parse simple spaceless" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("43 - parse simple spaceless\n", .{}); const allocator = testing.allocator; const template = "{% spaceless %}

Foo

{% endspaceless %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .spaceless); const sl = nodes[0].tag.?.body.spaceless; try testing.expectEqual(@as(usize, 1), sl.body.len); try testing.expectEqualStrings("

Foo

", sl.body[0].text.?.content); } // TODO: check nested spaceless test "parse spaceless nested" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("44 - parse spaceless nested\n", .{}); const allocator = testing.allocator; const template = "{% spaceless %}Outer {% spaceless %}Inner{% endspaceless %} Outer{% endspaceless %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .spaceless); const sl = nodes[0].tag.?.body.spaceless; try testing.expectEqual(@as(usize, 4), sl.body.len); } test "parse templatetag openblock" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("45 - parse templatetag openblock\n", .{}); const allocator = testing.allocator; const template = "{% templatetag openblock %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .templatetag); try testing.expect(nodes[0].tag.?.body.templatetag.kind == .openblock); } test "parse templatetag closevariable" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("46 - parse templatetag closevariable\n", .{}); const allocator = testing.allocator; const template = "{% templatetag closevariable %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .templatetag); try testing.expect(nodes[0].tag.?.body.templatetag.kind == .closevariable); } test "parse simple url" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("47 - parse simple url\n", .{}); const allocator = testing.allocator; const template = "Link: {% url 'home' %} Fim"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Link: ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .url); const u = nodes[1].tag.?.body.url; try testing.expectEqualStrings("home", u.name); try testing.expectEqual(@as(usize, 0), u.args.len); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" Fim", nodes[2].text.?.content); } test "parse url with arguments" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("48 - parse url with arguments\n", .{}); const allocator = testing.allocator; const template = "{% url 'post_detail' post.id \"comentario\" %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .url); const u = nodes[0].tag.?.body.url; try testing.expectEqualStrings("post_detail", u.name); try testing.expectEqual(@as(usize, 2), u.args.len); try testing.expectEqualStrings("post.id", u.args[0]); try testing.expectEqualStrings("\"comentario\"", u.args[1]); } test "parse simple widthratio" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("49 - parse simple widthratio\n", .{}); const allocator = testing.allocator; const template = "Progresso: {% widthratio progresso 0 100 %}%"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Progresso: ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .widthratio); const wr = nodes[1].tag.?.body.widthratio; try testing.expectEqualStrings("progresso", wr.value); try testing.expectEqualStrings("0", wr.max_value); try testing.expectEqualStrings("100", wr.divisor.?); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings("%", nodes[2].text.?.content); } test "parse simple widthratio without divisor" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("50 - parse simple widthratio without divisor\n", .{}); const allocator = testing.allocator; const template = "Progresso: {% widthratio progresso 0 %}%"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Progresso: ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .widthratio); const wr = nodes[1].tag.?.body.widthratio; try testing.expectEqualStrings("progresso", wr.value); try testing.expectEqualStrings("0", wr.max_value); try testing.expect(wr.divisor == null); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings("%", nodes[2].text.?.content); } test "parse simple verbatim" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("51 - parse simple verbatim\n", .{}); const allocator = testing.allocator; const template = "Texto {% verbatim %}{{ variável }}{% endblock %}{% endverbatim %} Texto"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 3), nodes.len); try testing.expect(nodes[0].type == .text); try testing.expectEqualStrings("Texto ", nodes[0].text.?.content); try testing.expect(nodes[1].type == .tag); try testing.expect(nodes[1].tag.?.kind == .verbatim); const vb = nodes[1].tag.?.body.verbatim; try testing.expectEqualStrings("{{ variável }}{% endblock %}", vb.content); try testing.expect(std.mem.eql(u8, vb.name.?, "")); try testing.expect(nodes[2].type == .text); try testing.expectEqualStrings(" Texto", nodes[2].text.?.content); } test "parse verbatim nested" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("52 - parse verbatim nested\n", .{}); const allocator = testing.allocator; const template = "{% verbatim baz %}Outer {% verbatim %}Inner{% endverbatim %} Outer{% endverbatim baz %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .verbatim); const vb = nodes[0].tag.?.body.verbatim; try testing.expectEqualStrings("Outer {% verbatim %}Inner{% endverbatim %} Outer", vb.content); try testing.expect(std.mem.eql(u8, vb.name.?, "baz")); } test "parse simple with block" { std.debug.print("____________________________________________________\n", .{}); std.debug.print("53 - parse with block\n", .{}); const allocator = testing.allocator; const template = "{% with nome=\"Lucas\" idade=30 %}Olá {{ nome }}, você tem {{ idade }} anos.{% endwith %}"; var p = parser.Parser.init(template); const nodes = try p.parse(allocator); defer { for (nodes) |node| node.deinit(allocator); allocator.free(nodes); } try testing.expectEqual(@as(usize, 1), nodes.len); try testing.expect(nodes[0].type == .tag); try testing.expect(nodes[0].tag.?.kind == .with_block); const w = nodes[0].tag.?.body.with; try testing.expectEqual(@as(usize, 2), w.assignments.len); try testing.expectEqual(@as(usize, 5), w.body.len); try testing.expect(w.body[0].type == .text); } // test "parse simple tag" { // std.debug.print("____________________________________________________\n", .{}); // std.debug.print("54 - parse simple tag\n", .{}); // // const allocator = testing.allocator; // const template = "Antes {% minha_tag %} Depois"; // var p = parser.Parser.init(template); // const nodes = try p.parse(allocator); // defer { // for (nodes) |node| { // node.deinit(allocator); // } // allocator.free(nodes); // } // // try testing.expectEqual(@as(usize, 3), nodes.len); // // try testing.expect(nodes[0].type == .text); // try testing.expectEqualStrings("Antes ", nodes[0].text.?.content); // // try testing.expect(nodes[1].type == .tag); // try testing.expectEqualStrings("minha_tag", nodes[1].tag.?.name); // try testing.expectEqualStrings("", nodes[1].tag.?.args); // // try testing.expect(nodes[2].type == .text); // try testing.expectEqualStrings(" Depois", nodes[2].text.?.content); // }