bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen#include "test-lib.h"
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen#include "str.h"
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen#include "env-util.h"
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen#include "hostpid.h"
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen#include "var-expand.h"
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi#include "var-expand-private.h"
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainenstruct var_expand_test {
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen const char *in;
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen const char *out;
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen int ret;
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen};
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainenstruct var_get_key_range_test {
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen const char *in;
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen unsigned int idx, size;
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen};
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainenstatic void test_var_expand_ranges(void)
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_expand_test tests[] = {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%v", "value1234", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%3v", "val", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%3.2v", "ue", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%3.-2v", "ue12", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%-3.2v", "23", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%0.-1v", "value123", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%-4.-1v", "123", 1 }
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen };
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_expand_table table[] = {
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen { 'v', "value1234", NULL },
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen { '\0', NULL, NULL }
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen };
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen string_t *str = t_str_new(128);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen unsigned int i;
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen
260faead609f10c5820e2006cdfc4852fc1cf1a9Phil Carmody test_begin("var_expand - ranges");
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen str_truncate(str, 0);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen test_assert(var_expand(str, tests[i].in, table, &error) == tests[i].ret);
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen test_assert(strcmp(tests[i].out, str_c(str)) == 0);
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen }
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen test_end();
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen}
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainenstatic void test_var_expand_builtin(void)
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen{
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen static struct var_expand_test tests[] = {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{hostname}", NULL, 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{pid}", NULL, 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "a%{env:FOO}b", "abaRb", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%50Hv", "1f", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%50Hw", "2e", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%50Nv", "25", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%50Nw", "e", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{nonexistent}", "UNSUPPORTED_VARIABLE_nonexistent", 0 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{nonexistent:default}", "UNSUPPORTED_VARIABLE_nonexistent", 0 },
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen };
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_expand_table table[] = {
2e01cfaa0acc57a7f44478ecf82be8b8521a3fcfTimo Sirainen { 'v', "value", NULL },
2e01cfaa0acc57a7f44478ecf82be8b8521a3fcfTimo Sirainen { 'w', "value2", NULL },
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen { '\0', NULL, NULL }
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen };
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen string_t *str = t_str_new(128);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen unsigned int i;
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen tests[0].out = my_hostname;
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen tests[1].out = my_pid;
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen env_put("FOO=baR");
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen
260faead609f10c5820e2006cdfc4852fc1cf1a9Phil Carmody test_begin("var_expand - builtin");
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen str_truncate(str, 0);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen test_assert_idx(var_expand(str, tests[i].in, table, &error) == tests[i].ret, i);
552a9b01e99cb9201de5ea5591df293d3b7495e0Phil Carmody test_assert_idx(strcmp(tests[i].out, str_c(str)) == 0, i);
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen }
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen test_end();
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen}
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainenstatic void test_var_get_key_range(void)
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_get_key_range_test tests[] = {
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen { "", 0, 0 },
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen { "{", 1, 0 },
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen { "k", 0, 1 },
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen { "{key}", 1, 3 },
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen { "5.5Rk", 4, 1 },
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen { "5.5R{key}", 5, 3 },
66bdf53dbb272c55bd2c5c4d3980f34296f1a95fAki Tuomi { "{key", 1, 3 },
66bdf53dbb272c55bd2c5c4d3980f34296f1a95fAki Tuomi { "{if;%{if;%{value};eq;value;t;f};eq;t;t;f}", 1, 39 },
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen };
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen unsigned int i, idx, size;
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen test_begin("var_get_key_range");
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen var_get_key_range(tests[i].in, &idx, &size);
552a9b01e99cb9201de5ea5591df293d3b7495e0Phil Carmody test_assert_idx(tests[i].idx == idx, i);
552a9b01e99cb9201de5ea5591df293d3b7495e0Phil Carmody test_assert_idx(tests[i].size == size, i);
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen if (tests[i].size == 1)
552a9b01e99cb9201de5ea5591df293d3b7495e0Phil Carmody test_assert_idx(tests[i].in[idx] == var_get_key(tests[i].in), i);
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen }
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen test_end();
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen}
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int test_var_expand_func1(const char *data, void *context,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r ATTR_UNUSED)
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen{
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen test_assert(*(int *)context == 0xabcdef);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *value_r = t_strdup_printf("<%s>", data);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 1;
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen}
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int test_var_expand_func2(const char *data ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen void *context ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r ATTR_UNUSED)
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen{
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *value_r = "";
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 1;
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen}
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int test_var_expand_func3(const char *data ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen void *context ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r ATTR_UNUSED)
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen{
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *value_r = NULL;
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 1;
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen}
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int test_var_expand_func4(const char *data,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen void *context ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r)
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen{
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *error_r = t_strdup_printf("Unknown data %s", data == NULL ? "" : data);
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return 0;
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen}
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainenstatic int test_var_expand_func5(const char *data ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen void *context ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **value_r ATTR_UNUSED,
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen const char **error_r)
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen{
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen *error_r = "Internal error";
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen return -1;
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen}
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainenstatic void test_var_expand_with_funcs(void)
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_expand_test tests[] = {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{func1}", "<>", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{func1:foo}", "<foo>", 1 },
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen { "%{func2}", "", 1 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "%{func3}", "", 1 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "%{func4}", "", 0 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "%{func5}", "", -1 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "%{func4}%{func5}", "", -1 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "%{func5}%{func4}%{func3}", "", -1 },
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen };
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_expand_table table[] = {
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen { '\0', NULL, NULL }
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen };
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen static const struct var_expand_func_table func_table[] = {
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen { "func1", test_var_expand_func1 },
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen { "func2", test_var_expand_func2 },
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen { "func3", test_var_expand_func3 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "func4", test_var_expand_func4 },
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen { "func5", test_var_expand_func5 },
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen { NULL, NULL }
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen };
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen string_t *str = t_str_new(128);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen const char *error;
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen unsigned int i;
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen int ctx = 0xabcdef;
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen test_begin("var_expand_with_funcs");
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen str_truncate(str, 0);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen test_assert_idx(var_expand_with_funcs(str, tests[i].in, table, func_table, &ctx, &error) == tests[i].ret, i);
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen test_assert_idx(strcmp(tests[i].out, str_c(str)) == 0, i);
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen }
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen test_end();
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen}
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainenstatic void test_var_get_key(void)
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct {
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen const char *str;
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen char key;
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen } tests[] = {
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen { "x", 'x' },
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen { "2.5Mx", 'x' },
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen { "200MDx", 'x' },
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen { "200MD{foo}", '{' },
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen { "{foo}", '{' },
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen { "", '\0' },
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen };
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen test_begin("var_get_key");
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen for (unsigned int i = 0; i < N_ELEMENTS(tests); i++)
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen test_assert_idx(var_get_key(tests[i].str) == tests[i].key, i);
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen test_end();
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen}
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainenstatic void test_var_has_key(void)
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen{
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct {
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen const char *str;
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen char key;
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen const char *long_key;
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen bool result;
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen } tests[] = {
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%x%y", 'x', NULL, TRUE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%x%y", 'y', NULL, TRUE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%x%y", 'z', NULL, FALSE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%{foo}", 'f', NULL, FALSE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%{foo}", 'o', NULL, FALSE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%{foo}", '\0', "foo", TRUE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%{foo}", 'o', "foo", TRUE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%2.5Mx%y", 'x', NULL, TRUE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen { "%2.5M{foo}", '\0', "foo", TRUE },
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen };
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen test_begin("var_has_key");
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen for (unsigned int i = 0; i < N_ELEMENTS(tests); i++)
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen test_assert_idx(var_has_key(tests[i].str, tests[i].key, tests[i].long_key) == tests[i].result, i);
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen test_end();
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen}
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomistatic int test_var_expand_hashing_func1(const char *data,
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi void *context ATTR_UNUSED,
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi const char **value_r,
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi const char **error_r ATTR_UNUSED)
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi{
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi *value_r = data;
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi return 1;
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi}
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomistatic int test_var_expand_bad_func(struct var_expand_context *ctx ATTR_UNUSED,
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi const char *key,
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi const char *field ATTR_UNUSED,
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi const char **result_r ATTR_UNUSED,
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi const char **error_r)
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi{
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi if (strcmp(key, "notfound") == 0) return 0;
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi *error_r = "Bad parameters";
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi return -1;
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi}
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomistatic const struct var_expand_extension_func_table test_extension_funcs[] = {
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi { "notfound", test_var_expand_bad_func },
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi { "badparam", test_var_expand_bad_func },
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi { NULL, NULL }
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi};
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomistatic void test_var_expand_extensions(void)
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi{
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi const char *error;
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi test_begin("var_expand_extensions");
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi var_expand_register_func_array(test_extension_funcs);
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct var_expand_table table[] = {
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi {'\0', "example", "value" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi {'\0', "other-example", "other-value" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi {'\0', NULL, NULL}
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi };
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainen static const struct {
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi const char *in;
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi const char *out;
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi } tests[] = {
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "md5: %M{value} %{md5:value}", "md5: 1a79a4d60de6718e8e5b326e338ae533 1a79a4d60de6718e8e5b326e338ae533" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "sha1: %{sha1:value}", "sha1: c3499c2729730a7f807efb8676a92dcb6f8a3f8f" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "sha1: %{sha1:func1:example}", "sha1: c3499c2729730a7f807efb8676a92dcb6f8a3f8f" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "truncate: %{sha1;truncate=12:value}", "truncate: 0c34" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "truncate: %{sha1;truncate=16:value}", "truncate: c349" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "rounds,salt: %{sha1;rounds=1000,salt=seawater:value}", "rounds,salt: b515c85884f6b82dc7588279f3643a73e55d2289" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "rounds,salt,expand: %{sha1;rounds=1000,salt=%{other-value}:value} %{other-value}", "rounds,salt,expand: 49a598ee110af615e175f2e4511cc5d7ccff96ab other-example" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "format: %4.8{sha1:value}", "format: 9c272973" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "base64: %{sha1;format=base64:value}", "base64: w0mcJylzCn+AfvuGdqkty2+KP48=" },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi };
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi static const struct var_expand_func_table func_table[] = {
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { "func1", test_var_expand_hashing_func1 },
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi { NULL, NULL }
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi };
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi string_t *str = t_str_new(128);
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) {
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi str_truncate(str, 0);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi error = NULL;
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi test_assert(var_expand_with_funcs(str, tests[i].in, table,
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi func_table, NULL, &error) == 1);
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi test_assert_idx(strcmp(str_c(str), tests[i].out) == 0, i);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi if (error != NULL) {
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi i_debug("Error: %s", error);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi }
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi }
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi test_assert(var_expand_with_funcs(str, "notfound: %{notfound:field}",
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi table, func_table, NULL, &error) == 0);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi error = NULL;
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi test_assert(var_expand_with_funcs(str, "notfound: %{badparam:field}",
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi table, func_table, NULL, &error) == -1);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi test_assert(error != NULL);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi var_expand_unregister_func_array(test_extension_funcs);
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi test_end();
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi}
14c903cfef0227c750e66298df56c3bf8ef258a1Aki Tuomi
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomistatic void test_var_expand_if(void)
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi{
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi static const struct var_expand_table table[] = {
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { 'a', "alpha", "alpha" },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { 'b', "beta", "beta" },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { 'o', "1", "one" },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { 't', "2", "two" },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { '\0', ";:", "evil1" },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { '\0', ";test;", "evil2" },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { '\0', NULL, NULL }
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi };
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi const char *error;
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi string_t *dest = t_str_new(64);
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi test_begin("var_expand_if");
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi static const struct var_expand_test tests[] = {
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* basic numeric operand test */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;==;1;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;==;2;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;<;1;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;<;2;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;<=;1;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;<=;2;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;>;1;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;>;2;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;>=;1;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;>=;2;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;!=;1;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;!=;2;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* basic string operand test */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;eq;a;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;eq;b;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;lt;a;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;lt;b;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;le;a;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;le;b;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;gt;a;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;gt;b;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;ge;a;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;ge;b;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;ne;a;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;ne;b;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;*;a;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;*;b;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;*;*a*;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;*;*b*;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;*;*;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!*;a;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!*;b;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!*;*a*;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!*;*b*;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!*;*;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;~;a;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;~;b;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;~;.*a.*;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;~;.*b.*;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;~;.*;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!~;a;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!~;b;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!~;.*a.*;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!~;.*b.*;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;a;!~;.*;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;this is test;~;^test;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;this is test;~;.*test;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* variable expansion */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%a;eq;%a;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%a;eq;%b;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{alpha};eq;%{alpha};yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{alpha};eq;%{beta};yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%o;eq;%o;yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%o;eq;%t;yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{one};eq;%{one};yes;no}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{one};eq;%{two};yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{one};eq;%{one};%{one};%{two}}", "1", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{one};gt;%{two};%{one};%{two}}", "2", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{evil1};eq;\\;\\:;%{evil2};no}", ";test;", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* inner if */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{if;%{one};eq;1;1;0};eq;%{if;%{two};eq;2;2;3};yes;no}", "no", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* no false */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;==;1;yes}", "yes", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;==;2;yes}", "", 1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* invalid input */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;}", "", -1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;}", "", -1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;==;}", "", -1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;==;2;}", "", -1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;1;fu;2;yes;no}", "", -1 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi /* missing variables */
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi { "%{if;%{missing1};==;%{missing2};yes;no}", "", 0 },
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi };
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi for(size_t i = 0; i < N_ELEMENTS(tests); i++) {
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi int ret;
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi error = NULL;
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi str_truncate(dest, 0);
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi ret = var_expand(dest, tests[i].in, table, &error);
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi test_assert_idx(tests[i].ret == ret, i);
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi test_assert_idx(strcmp(tests[i].out, str_c(dest)) == 0, i);
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi }
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi test_end();
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi}
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomistatic void test_var_expand_merge_tables(void)
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi{
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi const struct var_expand_table one[] = {
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi { 'a', "1", "alpha" },
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi { '\0', "2", "beta" },
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi { '\0', NULL, NULL }
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi },
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi two[] = {
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi { 't', "3", "theta" },
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi { '\0', "4", "phi" },
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi { '\0', NULL, NULL }
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi },
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi *merged = NULL;
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_begin("var_expand_merge_tables");
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi merged = t_var_expand_merge_tables(one, two);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert(var_expand_table_size(merged) == 4);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi for(unsigned int i = 0; i < var_expand_table_size(merged); i++) {
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi if (i < 2) {
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert_idx(merged[i].key == one[i].key, i);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert_idx(merged[i].value == one[i].value || strcmp(merged[i].value, one[i].value) == 0, i);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert_idx(merged[i].long_key == one[i].long_key || strcmp(merged[i].long_key, one[i].long_key) == 0, i);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi } else if (i < 4) {
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert_idx(merged[i].key == two[i-2].key, i);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert_idx(merged[i].value == two[i-2].value || strcmp(merged[i].value, two[i-2].value) == 0, i);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_assert_idx(merged[i].long_key == two[i-2].long_key || strcmp(merged[i].long_key, two[i-2].long_key) == 0, i);
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi } else {
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi break;
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi }
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi }
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_end();
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi}
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainenvoid test_var_expand(void)
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen{
1bc529e36d36f9a525c6af023ae014ebc6cdb440Timo Sirainen test_var_expand_ranges();
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen test_var_expand_builtin();
b58cb4b59ccd78ee1c3e0df0bc13c300d1bec380Timo Sirainen test_var_get_key_range();
654b46078129456bda90c5eb18014fb2858c302eTimo Sirainen test_var_expand_with_funcs();
7a556ac46f1f51ee29bc8aa92b5ffe05b004a8b8Timo Sirainen test_var_get_key();
e539ff946adcbc68793adb6d9d84621dce3bf46bTimo Sirainen test_var_has_key();
b8596c89dd8b6628e0fa52e52f2a95e869968706Aki Tuomi test_var_expand_extensions();
57479bd6600f51e0c4850969f6587cae40f56782Aki Tuomi test_var_expand_if();
857a9e1f1cf3a2241403bfb201421bb1a66038b1Aki Tuomi test_var_expand_merge_tables();
927d3977d5598f12ae18d4fa3f22b9e913f7dd46Timo Sirainen}