update: new tests

This commit is contained in:
Lucas F. 2026-01-11 20:39:28 -03:00
parent 3c3bd6d05f
commit c7efa6baae

View file

@ -5,16 +5,20 @@ const Renderer = @import("renderer.zig").Renderer;
const RenderError = @import("renderer.zig").RenderError;
const Context = @import("context.zig").Context;
const Value = @import("context.zig").Value; // ajuste o caminho se estiver diferente
const Value = @import("context.zig").Value;
const TemplateCache = @import("cache.zig").TemplateCache;
test "renderer: literal + variável simples" {
const alloc = testing.allocator;
var ctx = Context.init(alloc);
defer ctx.deinit();
try ctx.set("nome", Value{ .string = "Mariana" });
var cache = TemplateCache.init(alloc);
defer cache.deinit();
const renderer = Renderer.init(&ctx);
const renderer = Renderer.init(&ctx, &cache);
try ctx.set("nome", Value{ .string = "Mariana" });
var buf = std.ArrayList(u8){};
defer buf.deinit(alloc);
@ -31,14 +35,16 @@ test "renderer: literal + variável simples" {
test "renderer: filtros + autoescape" {
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" });
const renderer = Renderer.init(&ctx);
var buf = std.ArrayList(u8){};
defer buf.deinit(alloc);
@ -62,10 +68,12 @@ test "renderer: filtros + autoescape" {
test "literal simples" {
const alloc = testing.allocator;
var ctx = Context.init(alloc);
defer ctx.deinit();
const renderer = Renderer.init(&ctx);
var cache = TemplateCache.init(alloc);
defer cache.deinit();
const renderer = Renderer.init(&ctx, &cache);
var buf = std.ArrayList(u8){};
defer buf.deinit(alloc);
@ -80,14 +88,15 @@ test "literal simples" {
test "variável com filtro encadeado e autoescape" {
const alloc = testing.allocator;
var ctx = Context.init(alloc);
defer ctx.deinit();
const renderer = Renderer.init(&ctx);
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);
@ -95,20 +104,21 @@ test "variável com filtro encadeado e autoescape" {
try renderer.renderString(template, buf.writer(alloc));
try testing.expectEqualStrings("Resultado: EXEMPLO DE TEXTO", buf.items); // assume lower then upper
try testing.expectEqualStrings("Resultado: EXEMPLO DE TEXTO", buf.items); // assume lower then upper
}
test "autoescape com safe" {
const alloc = testing.allocator;
var ctx = Context.init(alloc);
defer ctx.deinit();
const renderer = Renderer.init(&ctx);
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);
@ -118,3 +128,316 @@ test "autoescape com safe" {
try testing.expectEqualStrings("Escape: &lt;div&gt;conteúdo&lt;/div&gt; | Safe: <div>conteúdo</div>", buf.items);
}
test "renderer - if and for" {
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));
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" {
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 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{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" {
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 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("{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 - include" {
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();
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;
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" {
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();
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;
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);
}
// FIX: comment inside block
//
// test "renderer - full template with extends, super, include, comment" {
// 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 %}
// ;
//
// 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();
//
// 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;
//
// try testing.expect(std.mem.indexOf(u8, output, "<header>Bem-vindo</header>") != 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);
// }