1100 lines
32 KiB
Zig
1100 lines
32 KiB
Zig
const std = @import("std");
|
|
const testing = std.testing;
|
|
|
|
const Renderer = @import("renderer.zig").Renderer;
|
|
const RenderError = @import("renderer.zig").RenderError;
|
|
|
|
const Context = @import("context.zig").Context;
|
|
const Value = @import("context.zig").Value;
|
|
const TemplateCache = @import("cache.zig").TemplateCache;
|
|
|
|
test "renderer: literal + variável simples" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("1 - renderer: literal + variável simples\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("nome", Value{ .string = "Fulana" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
const template =
|
|
\\Olá, {{ nome }}! Bem-vinda.
|
|
;
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings("Olá, Fulana! Bem-vinda.", buf.items);
|
|
}
|
|
|
|
test "renderer: filtros + autoescape" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("2 - renderer: filtros + autoescape\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("html", Value{ .string = "<script>alert()</script>" });
|
|
try ctx.set("texto", Value{ .string = "maiusculo e slug" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
const template =
|
|
\\Normal: {{ html }}
|
|
\\Safe: {{ html|safe }}
|
|
\\Filtrado: {{ texto|upper|slugify }}
|
|
;
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
const expected =
|
|
\\Normal: <script>alert()</script>
|
|
\\Safe: <script>alert()</script>
|
|
\\Filtrado: maiusculo-e-slug
|
|
;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "literal simples" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("3 - literal simples\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
const template = "Texto literal com acentos: Olá, mundo!";
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings("Texto literal com acentos: Olá, mundo!", buf.items);
|
|
}
|
|
|
|
test "variável com filtro encadeado e autoescape" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("4 - variável com filtro encadeado e autoescape\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("texto", Value{ .string = "Exemplo de Texto" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
const template = "Resultado: {{ texto|lower|upper }}";
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings("Resultado: EXEMPLO DE TEXTO", buf.items); // assume lower then upper
|
|
}
|
|
|
|
test "autoescape com safe" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("5 - autoescape com safe\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("html", Value{ .string = "<div>conteúdo</div>" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
const template = "Escape: {{ html }} | Safe: {{ html|safe }}";
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings("Escape: <div>conteúdo</div> | Safe: <div>conteúdo</div>", buf.items);
|
|
}
|
|
|
|
// // TODO: evaluationConditions more complex
|
|
test "renderer - if and for" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("6 - renderer - if and for\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("ativo", Value{ .bool = true });
|
|
try ctx.set("nomes", Value{ .list = &[_]Value{
|
|
Value{ .string = "Ana" },
|
|
Value{ .string = "Bia" },
|
|
Value{ .string = "Cris" },
|
|
} });
|
|
|
|
const template =
|
|
\\{% if ativo %}Sim!{% endif %}
|
|
\\{% if not ativo %}Não{% endif %}
|
|
\\Lista:
|
|
\\{% for nome in nomes %}
|
|
\\- {{ nome }}
|
|
\\{% endfor %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Sim!") != null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Não") == null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "- Ana") != null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "- Bia") != null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "- Cris") != null);
|
|
}
|
|
|
|
test "renderer - block and extends" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("7 - renderer - block and extends\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const base =
|
|
\\<html>
|
|
\\<head><title>{% block title %}Título Padrão{% endblock %}</title></head>
|
|
\\<body>
|
|
\\{% block content %}Conteúdo padrão{% endblock %}
|
|
\\</body>
|
|
\\</html>
|
|
;
|
|
|
|
const child =
|
|
\\{% extends "base.html" %}
|
|
\\{% block title %}Meu Título{% endblock %}
|
|
\\{% block content %}
|
|
\\Olá {{ nome }}!
|
|
\\{% endblock %}
|
|
;
|
|
|
|
const expected =
|
|
\\<html>
|
|
\\<head><title>Meu Título</title></head>
|
|
\\<body>
|
|
\\
|
|
\\Olá Lucas!
|
|
\\
|
|
\\</body>
|
|
\\</html>
|
|
;
|
|
|
|
// Simula arquivos (ou usa renderString com base se quiser simplificar)
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "base.html", .data = base });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "child.html", .data = child });
|
|
defer std.fs.cwd().deleteFile("base.html") catch {};
|
|
defer std.fs.cwd().deleteFile("child.html") catch {};
|
|
|
|
try ctx.set("nome", Value{ .string = "Lucas" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.render("child.html", buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{output});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "<html>") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Meu Título") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Olá Lucas!") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo padrão") == null);
|
|
try testing.expectEqualStrings(expected, output);
|
|
}
|
|
|
|
test "renderer - block and extends with super" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("8 - renderer - block and extends with super\n", .{});
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const base =
|
|
\\<html>
|
|
\\<head><title>{% block title %}Título Padrão{% endblock %}</title></head>
|
|
\\<body>
|
|
\\{% block content %}Conteúdo padrão{% endblock %}
|
|
\\</body>
|
|
\\</html>
|
|
;
|
|
|
|
const child =
|
|
\\{% extends "base.html" %}
|
|
\\{% block title %}Meu Título{% endblock %}
|
|
\\{% block content %}
|
|
\\{{ block.super }}
|
|
\\Olá {{ nome }}!
|
|
\\{% endblock %}
|
|
;
|
|
|
|
const expected =
|
|
\\<html>
|
|
\\<head><title>Meu Título</title></head>
|
|
\\<body>
|
|
\\
|
|
\\Conteúdo padrão
|
|
\\Olá Lucas!
|
|
\\
|
|
\\</body>
|
|
\\</html>
|
|
;
|
|
|
|
// Simula arquivos (ou usa renderString com base se quiser simplificar)
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "base.html", .data = base });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "child.html", .data = child });
|
|
defer std.fs.cwd().deleteFile("base.html") catch {};
|
|
defer std.fs.cwd().deleteFile("child.html") catch {};
|
|
|
|
try ctx.set("nome", Value{ .string = "Lucas" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.render("child.html", buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "<html>") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Meu Título") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Olá Lucas!") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo padrão") != null);
|
|
try testing.expectEqualStrings(expected, output);
|
|
}
|
|
|
|
test "renderer - include" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("9 - renderer - include\n", .{});
|
|
const alloc = testing.allocator;
|
|
|
|
const header =
|
|
\\<header>
|
|
\\ <h1>Bem-vindo</h1>
|
|
\\</header>
|
|
;
|
|
|
|
const main =
|
|
\\{% include "header.html" %}
|
|
\\<main>
|
|
\\ <p>Conteúdo principal</p>
|
|
\\ Olá {{ nome }}!
|
|
\\</main>
|
|
;
|
|
|
|
const expected =
|
|
\\<header>
|
|
\\ <h1>Bem-vindo</h1>
|
|
\\</header>
|
|
\\<main>
|
|
\\ <p>Conteúdo principal</p>
|
|
\\ Olá Lucas!
|
|
\\</main>
|
|
;
|
|
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "header.html", .data = header });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "main.html", .data = main });
|
|
defer std.fs.cwd().deleteFile("header.html") catch {};
|
|
defer std.fs.cwd().deleteFile("main.html") catch {};
|
|
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("nome", Value{ .string = "Lucas" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.render("main.html", buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "<h1>Bem-vindo</h1>") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Olá Lucas!") != null);
|
|
try testing.expectEqualStrings(expected, output);
|
|
}
|
|
|
|
test "renderer - comment" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("10 - renderer - comment\n", .{});
|
|
const alloc = testing.allocator;
|
|
|
|
const template =
|
|
\\Normal: Olá {{ nome }}
|
|
\\{% comment %}
|
|
\\ Isso é um comentário
|
|
\\ que não deve aparecer
|
|
\\ nem processar variáveis {{ nome }}
|
|
\\{% endcomment %}
|
|
\\Fim: {{ nome }}
|
|
;
|
|
const expected =
|
|
\\Normal: Olá Lucas
|
|
\\
|
|
\\Fim: Lucas
|
|
;
|
|
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("nome", Value{ .string = "Lucas" });
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "Olá Lucas") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Fim: Lucas") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Isso é um comentário") == null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "que não deve aparecer") == null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "nem processar variáveis") == null);
|
|
try testing.expectEqualStrings(expected, output);
|
|
}
|
|
|
|
test "renderer - full template with extends, super, include, comment" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("11 - renderer - full template with extends, super, include, comment\n", .{});
|
|
const alloc = testing.allocator;
|
|
|
|
const header = "<header>Bem-vindo</header>";
|
|
const base =
|
|
\\{% include "header.html" %}
|
|
\\<main>
|
|
\\ {% block content %}
|
|
\\ Conteúdo padrão
|
|
\\ {% endblock %}
|
|
\\</main>
|
|
;
|
|
|
|
const child =
|
|
\\{% extends "base.html" %}
|
|
\\{% block content %}
|
|
\\ {{ block.super }}
|
|
\\ Conteúdo do filho
|
|
\\ {% comment %} Isso não aparece {% endcomment %}
|
|
\\{% endblock %}
|
|
\\{% comment %} bazinga {% endcomment %}
|
|
;
|
|
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "header.html", .data = header });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "base.html", .data = base });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "child.html", .data = child });
|
|
defer std.fs.cwd().deleteFile("header.html") catch {};
|
|
defer std.fs.cwd().deleteFile("base.html") catch {};
|
|
defer std.fs.cwd().deleteFile("child.html") catch {};
|
|
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.render("child.html", buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{output});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "<header>Bem-vindo</header>") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "<main>") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo padrão") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo do filho") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Isso não aparece") == null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "bazinga") == null);
|
|
}
|
|
|
|
test "renderer - if inside block" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("12 - render - if inside block\n", .{});
|
|
const alloc = testing.allocator;
|
|
|
|
const base =
|
|
\\<main>
|
|
\\ {% block content %}
|
|
\\ Conteúdo padrão
|
|
\\ {% endblock %}
|
|
\\</main>
|
|
;
|
|
|
|
const child =
|
|
\\{% extends "base.html" %}
|
|
\\{% block content %}
|
|
\\ {{ block.super }}
|
|
\\ Conteúdo do filho
|
|
\\{% if idade > 18 %}
|
|
\\ Idade: {{ idade }}
|
|
\\{% else %}
|
|
\\ Oops
|
|
\\{% endif %}
|
|
\\{% endblock %}
|
|
;
|
|
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "base.html", .data = base });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "child.html", .data = child });
|
|
defer std.fs.cwd().deleteFile("base.html") catch {};
|
|
defer std.fs.cwd().deleteFile("child.html") catch {};
|
|
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("idade", 23);
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.render("child.html", buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{output});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo padrão") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo do filho") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Oops") == null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Idade: 23") != null);
|
|
}
|
|
|
|
test "renderer - if with operators" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("13 - render - if inside block\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("idade", Value{ .int = 20 });
|
|
try ctx.set("nome", Value{ .string = "Lucas" });
|
|
try ctx.set("ativo", Value{ .bool = true });
|
|
try ctx.set("order", 1);
|
|
|
|
const template =
|
|
\\{% if idade > 18 %}Maior{% endif %}
|
|
\\{% if idade < 18 %}Menor{% endif %}
|
|
\\{% if nome == "Lucas" %}Olá Lucas{% endif %}
|
|
\\{% if ativo %}Ativo{% endif %}
|
|
\\{% if order >= 2 %}High Order{% else %}Low Order{% endif %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Maior") != null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Olá Lucas") != null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Ativo") != null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Menor") == null);
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Low Order") != null);
|
|
}
|
|
|
|
test "renderer - widthratio inside block" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("14 - render - widthratio inside block\n", .{});
|
|
const alloc = testing.allocator;
|
|
|
|
const base =
|
|
\\<main>
|
|
\\ {% block content %}
|
|
\\ Conteúdo padrão
|
|
\\ {% endblock %}
|
|
\\</main>
|
|
;
|
|
|
|
const child =
|
|
\\{% extends "base.html" %}
|
|
\\{% block content %}
|
|
\\ Conteúdo do filho
|
|
\\<img src="bar.png" alt="Bar" height="10" width="{% widthratio value 400 %}">
|
|
\\ {{ block.super }}
|
|
\\{% endblock %}
|
|
;
|
|
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "base.html", .data = base });
|
|
try std.fs.cwd().writeFile(.{ .sub_path = "child.html", .data = child });
|
|
defer std.fs.cwd().deleteFile("base.html") catch {};
|
|
defer std.fs.cwd().deleteFile("child.html") catch {};
|
|
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
cache.default_path = ".";
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("value", 50);
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.render("child.html", buf.writer(alloc));
|
|
|
|
const output = buf.items;
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{output});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo padrão") != null);
|
|
try testing.expect(std.mem.indexOf(u8, output, "Conteúdo do filho") != null);
|
|
}
|
|
|
|
test "renderer - now" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("15 - render now\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("idade", Value{ .int = 20 });
|
|
|
|
const template =
|
|
\\{% now %}
|
|
\\{% now \"Y-m-d H:i:s\" %}
|
|
\\{% now \"Y" %}
|
|
\\{% now \"m\" %}
|
|
\\{% now \"n\" %}
|
|
\\{% now \"d\" %}
|
|
\\{% now \"j\" %}
|
|
\\{% now \"F\" %}
|
|
\\{% now \"M\" %}
|
|
\\{% now \"l\" %}
|
|
\\{% now \"D\" %}
|
|
\\{% now \"H:i:s\" %}
|
|
\\{% now \"H\" %}
|
|
\\{% now \"G\" %}
|
|
\\{% now \"i\" %}
|
|
\\{% now \"s\" %}
|
|
\\{% now \"a\" %}
|
|
\\{% now \"A\" %}
|
|
\\{% now \"P\" %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
// try testing.expect(std.mem.indexOf(u8, buf.items, "Maior") != null);
|
|
}
|
|
|
|
test "renderer - csrf_token in context" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("15 - csrf_token in context\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const token: []const u8 = "zh5fyUSICjXNsDTtJCjl9A3O2dDSHhYFlIngAEO6PXK9NX56Z1XLEy7doYuPcE0u";
|
|
|
|
try ctx.set("csrf_token", token);
|
|
const template =
|
|
\\{% csrf_token %}
|
|
;
|
|
|
|
const expected =
|
|
\\<input type="hidden" name="csrfmiddlewaretoken" value="zh5fyUSICjXNsDTtJCjl9A3O2dDSHhYFlIngAEO6PXK9NX56Z1XLEy7doYuPcE0u">
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "renderer - csrf_token not in context" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("16 - csrf_token not in context\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% csrf_token %}
|
|
;
|
|
|
|
const expected =
|
|
\\
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
// TODO: add parse filters to variables
|
|
test "renderer - firstof withtout fallback" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("17 - firstof without fallback\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("var1", "");
|
|
try ctx.set("var2", "baz");
|
|
|
|
const template =
|
|
\\{% firstof var1 var2 %}
|
|
;
|
|
|
|
const expected =
|
|
\\baz
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "renderer - firstof with fallback" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("18 - firstof with fallback\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
try ctx.set("var1", "");
|
|
try ctx.set("var2", 0);
|
|
|
|
const template =
|
|
\\{% firstof var1 var2 "Oops no value!" %}
|
|
;
|
|
|
|
const expected =
|
|
\\Oops no value!
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "renderer - firstof without value in context" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("19 - firstof without value in context\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% firstof 0 true "Oops no value!" %}
|
|
;
|
|
|
|
const expected =
|
|
\\true
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "renderer - firstof missing vars" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("20 - firstof missing vars\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% firstof %}
|
|
;
|
|
|
|
const expected =
|
|
\\
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "renderer - firstof missing vars with fallback" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("21 - firstof missing vars with fallback\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% firstof "nothing here" %}
|
|
;
|
|
|
|
const expected =
|
|
\\nothing here
|
|
;
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
// std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings(expected, buf.items);
|
|
}
|
|
|
|
test "renderer - lorem" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("22 - lorem\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% lorem %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Lorem ipsum") != null);
|
|
}
|
|
|
|
test "renderer - lorem with count and method words" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("23 - lorem with count and method words\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% lorem 3 w %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expectEqualStrings("lorem ipsum dolor", buf.items);
|
|
}
|
|
|
|
test "renderer - lorem with count and method paragraphs" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("24 - lorem with count and method paragraphs\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% lorem 5 p %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
const qty = std.mem.count(u8, buf.items, "<p>");
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "Lorem ipsum dolor") != null);
|
|
try testing.expect(qty == 5);
|
|
}
|
|
|
|
test "renderer - lorem only random" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("25 - lorem only random\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% lorem true %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(buf.items.len > 0);
|
|
}
|
|
|
|
test "renderer - lorem words random" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("26 - lorem words random\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% lorem 6 w true %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
const spaces = std.mem.count(u8, buf.items, " ");
|
|
try testing.expect(spaces == 5);
|
|
}
|
|
|
|
test "renderer - lorem paragraphs random" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("26 - lorem paragraphs random\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% lorem 3 p true %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
const spaces = std.mem.count(u8, buf.items, "<p>");
|
|
try testing.expect(spaces == 3);
|
|
}
|
|
|
|
test "renderer - svg" {
|
|
std.debug.print("____________________________________________________\n", .{});
|
|
std.debug.print("27 - svg\n", .{});
|
|
|
|
const alloc = testing.allocator;
|
|
var ctx = Context.init(alloc);
|
|
defer ctx.deinit();
|
|
|
|
var cache = TemplateCache.init(alloc);
|
|
try cache.initIcons();
|
|
defer cache.deinit();
|
|
|
|
const renderer = Renderer.init(&ctx, &cache);
|
|
|
|
const template =
|
|
\\{% svg material kangaroo %}
|
|
;
|
|
|
|
var buf = std.ArrayList(u8){};
|
|
defer buf.deinit(alloc);
|
|
|
|
try renderer.renderString(template, buf.writer(alloc));
|
|
|
|
std.debug.print("OUTPUT:\n\n{s}\n", .{buf.items});
|
|
|
|
try testing.expect(std.mem.indexOf(u8, buf.items, "<div class=\"svg-container\">") != null);
|
|
// const spaces = std.mem.count(u8, buf.items, "<p>");
|
|
// try testing.expect(spaces == 3);
|
|
}
|