* Copyright (C) 2014 Red Hat, Inc.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "config.h"
#include "cockpittemplate.h"
#include "cockpitjson.h"
#include "testlib/cockpittest.h"
#include <string.h>
typedef struct {
GHashTable *variables;
} TestCase;
static void
setup (TestCase *tc,
gconstpointer data)
{
tc->variables = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (tc->variables, "Scruffy", "janitor");
g_hash_table_insert (tc->variables, "oh", "marmalade");
g_hash_table_insert (tc->variables, "oh_dash", "dash-marmalade");
g_hash_table_insert (tc->variables, "empty", "");
g_hash_table_insert (tc->variables, "💩", "error");
}
static void
teardown (TestCase *tc,
gconstpointer data)
{
g_hash_table_destroy (tc->variables);
}
static GBytes *
lookup_table (const char *name,
gpointer user_data)
{
GHashTable *variables = user_data;
const gchar *value;
value = g_hash_table_lookup (variables, name);
if (!value)
return NULL;
return g_bytes_new (value, strlen (value));
}
typedef struct {
const char *name;
const char *input;
const char *output[8];
} Fixture;
static const Fixture expand_fixtures[] = {
{ "empty-string", "", { NULL } },
{ "no-vars", "Test no vars", { "Test no vars", NULL } },
{ "only-var", "${oh}", { "marmalade", NULL } },
{ "only-vars", "${oh}${oh}", { "marmalade", "marmalade", NULL } },
{ "simple", "Test ${oh} suffix", { "Test ", "marmalade", " suffix", NULL } },
{ "extra-dollar", "Te$st ${oh} suffix", { "Te$st ", "marmalade", " suffix", NULL } },
{ "extra-brace", "Te{st ${oh} suffix", { "Te{st ", "marmalade", " suffix", NULL } },
{ "no-ending", "Test ${oh} su${ffix", { "Test ", "marmalade", " su${ffix", NULL } },
{ "extra-dollar-after", "Test ${oh} su${ff$ix", { "Test ", "marmalade", " su${ff$ix", NULL } },
{ "unknown", "Test ${unknown} suffix", { "Test ", "${unknown}", " suffix", NULL } },
{ "escaped", "Test \\${oh} ${oh} suffix", { "Test ", "${oh}", " ", "marmalade", " suffix", NULL } },
{ "dash", "Test ${oh_dash} suffix", { "Test ", "dash-marmalade", " suffix", NULL } },
{ "lots", "Oh ${oh} says Scruffy ${empty} the ${Scruffy}",
{ "Oh ", "marmalade", " says Scruffy ", " the ", "janitor", NULL }
},
{ "unsupported-var", "${ig.nore} ${💩} ${Kōhī}", { "${ig.nore} ${💩} ${Kōhī}" } },
{ "var-in-string", "te${oh}st", { "te", "marmalade", "st" } },
{ "var-in-var-string", "te${test${oh}st", { "te${test", "marmalade", "st" } },
};
static void
test_expand (TestCase *tc,
gconstpointer data)
{
const Fixture *fixture = data;
GBytes *input;
GList *output;
GList *l;
int i;
input = g_bytes_new_static (fixture->input, strlen (fixture->input));
output = cockpit_template_expand (input, lookup_table, tc->variables);
g_bytes_unref (input);
for (i = 0, l = output; l && fixture->output[i] != NULL; i++, l = g_list_next (l))
cockpit_assert_bytes_eq (l->data, fixture->output[i], -1);
g_assert_cmpint (g_list_length (output), ==, i);
g_list_free_full (output, (GDestroyNotify)g_bytes_unref);
}
int
main (int argc,
char *argv[])
{
gchar *name;
int i;
cockpit_test_init (&argc, &argv);
for (i = 0; i < G_N_ELEMENTS (expand_fixtures); i++)
{
name = g_strdup_printf ("/template/expand/%s", expand_fixtures[i].name);
g_test_add (name, TestCase, expand_fixtures + i, setup, test_expand, teardown);
g_free (name);
}
return g_test_run ();
}