fix: hemar: section implimentation
This commit is contained in:
@@ -1393,8 +1393,8 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
|
|||||||
while ((token = JsonbIteratorNext(&it, &v, true)) != WJB_END_ARRAY)
|
while ((token = JsonbIteratorNext(&it, &v, true)) != WJB_END_ARRAY)
|
||||||
{
|
{
|
||||||
/* Create a new context with the current element */
|
/* Create a new context with the current element */
|
||||||
JsonbValue *new_context = palloc(sizeof(JsonbValue));
|
JsonbParseState *parse_state = NULL;
|
||||||
new_context->type = jbvObject;
|
JsonbValue *res = pushJsonbValue(&parse_state, WJB_BEGIN_OBJECT, NULL);
|
||||||
|
|
||||||
/* Copy the original context */
|
/* Copy the original context */
|
||||||
JsonbIterator *ctx_it = JsonbIteratorInit(&define->root);
|
JsonbIterator *ctx_it = JsonbIteratorInit(&define->root);
|
||||||
@@ -1406,16 +1406,12 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
|
|||||||
if (ctx_token == WJB_KEY)
|
if (ctx_token == WJB_KEY)
|
||||||
{
|
{
|
||||||
/* Add the key */
|
/* Add the key */
|
||||||
JsonbValue key_val;
|
pushJsonbValue(&parse_state, WJB_KEY, &ctx_v);
|
||||||
key_val.type = jbvString;
|
|
||||||
key_val.val.string.val = pstrdup(ctx_v.val.string.val);
|
|
||||||
key_val.val.string.len = ctx_v.val.string.len;
|
|
||||||
JsonbValueToJsonb(&key_val);
|
|
||||||
}
|
}
|
||||||
else if (ctx_token == WJB_VALUE)
|
else if (ctx_token == WJB_VALUE)
|
||||||
{
|
{
|
||||||
/* Add the value */
|
/* Add the value */
|
||||||
JsonbValueToJsonb(&ctx_v);
|
pushJsonbValue(&parse_state, WJB_VALUE, &ctx_v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,14 +1420,20 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
|
|||||||
key_val.type = jbvString;
|
key_val.type = jbvString;
|
||||||
key_val.val.string.val = pstrdup(current->value->section.iterator);
|
key_val.val.string.val = pstrdup(current->value->section.iterator);
|
||||||
key_val.val.string.len = strlen(current->value->section.iterator);
|
key_val.val.string.len = strlen(current->value->section.iterator);
|
||||||
JsonbValueToJsonb(&key_val);
|
pushJsonbValue(&parse_state, WJB_KEY, &key_val);
|
||||||
JsonbValueToJsonb(&v);
|
pushJsonbValue(&parse_state, WJB_VALUE, &v);
|
||||||
|
|
||||||
|
/* Finish the object */
|
||||||
|
res = pushJsonbValue(&parse_state, WJB_END_OBJECT, NULL);
|
||||||
|
|
||||||
|
/* Convert to Jsonb */
|
||||||
|
Jsonb *context_jsonb = JsonbValueToJsonb(res);
|
||||||
|
|
||||||
/* Render the section body with the new context */
|
/* Render the section body with the new context */
|
||||||
render_template(current->value->section.body, JsonbValueToJsonb(new_context), result, context);
|
render_template(current->value->section.body, context_jsonb, result, context);
|
||||||
|
|
||||||
/* Free the temporary values */
|
/* Free the temporary values */
|
||||||
pfree(new_context);
|
pfree(key_val.val.string.val);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1443,8 +1445,8 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
|
|||||||
if (token == WJB_KEY)
|
if (token == WJB_KEY)
|
||||||
{
|
{
|
||||||
/* Create a new context with the current key-value pair */
|
/* Create a new context with the current key-value pair */
|
||||||
JsonbValue *new_context = palloc(sizeof(JsonbValue));
|
JsonbParseState *parse_state = NULL;
|
||||||
new_context->type = jbvObject;
|
JsonbValue *res = pushJsonbValue(&parse_state, WJB_BEGIN_OBJECT, NULL);
|
||||||
|
|
||||||
/* Copy the original context */
|
/* Copy the original context */
|
||||||
JsonbIterator *ctx_it = JsonbIteratorInit(&define->root);
|
JsonbIterator *ctx_it = JsonbIteratorInit(&define->root);
|
||||||
@@ -1456,38 +1458,58 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
|
|||||||
if (ctx_token == WJB_KEY)
|
if (ctx_token == WJB_KEY)
|
||||||
{
|
{
|
||||||
/* Add the key */
|
/* Add the key */
|
||||||
JsonbValue key_val;
|
pushJsonbValue(&parse_state, WJB_KEY, &ctx_v);
|
||||||
key_val.type = jbvString;
|
|
||||||
key_val.val.string.val = pstrdup(ctx_v.val.string.val);
|
|
||||||
key_val.val.string.len = ctx_v.val.string.len;
|
|
||||||
JsonbValueToJsonb(&key_val);
|
|
||||||
}
|
}
|
||||||
else if (ctx_token == WJB_VALUE)
|
else if (ctx_token == WJB_VALUE)
|
||||||
{
|
{
|
||||||
/* Add the value */
|
/* Add the value */
|
||||||
JsonbValueToJsonb(&ctx_v);
|
pushJsonbValue(&parse_state, WJB_VALUE, &ctx_v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the iterator value (key) */
|
/* Add the iterator object with key and value */
|
||||||
JsonbValue key_val;
|
JsonbValue key_val;
|
||||||
key_val.type = jbvString;
|
key_val.type = jbvString;
|
||||||
key_val.val.string.val = pstrdup(current->value->section.iterator);
|
key_val.val.string.val = pstrdup(current->value->section.iterator);
|
||||||
key_val.val.string.len = strlen(current->value->section.iterator);
|
key_val.val.string.len = strlen(current->value->section.iterator);
|
||||||
JsonbValueToJsonb(&key_val);
|
pushJsonbValue(&parse_state, WJB_KEY, &key_val);
|
||||||
JsonbValueToJsonb(&v);
|
|
||||||
|
/* Create an object for the iterator */
|
||||||
|
JsonbParseState *item_parse_state = NULL;
|
||||||
|
JsonbValue *item_res = pushJsonbValue(&item_parse_state, WJB_BEGIN_OBJECT, NULL);
|
||||||
|
|
||||||
|
/* Add the key */
|
||||||
|
key_val.val.string.val = pstrdup("key");
|
||||||
|
key_val.val.string.len = strlen("key");
|
||||||
|
pushJsonbValue(&item_parse_state, WJB_KEY, &key_val);
|
||||||
|
pushJsonbValue(&item_parse_state, WJB_VALUE, &v);
|
||||||
|
|
||||||
/* Get the value */
|
/* Get the value */
|
||||||
token = JsonbIteratorNext(&it, &v, true);
|
token = JsonbIteratorNext(&it, &v, true);
|
||||||
|
|
||||||
/* Add the value */
|
/* Add the value */
|
||||||
JsonbValueToJsonb(&v);
|
key_val.val.string.val = pstrdup("value");
|
||||||
|
key_val.val.string.len = strlen("value");
|
||||||
|
pushJsonbValue(&item_parse_state, WJB_KEY, &key_val);
|
||||||
|
pushJsonbValue(&item_parse_state, WJB_VALUE, &v);
|
||||||
|
|
||||||
|
/* Finish the iterator object */
|
||||||
|
item_res = pushJsonbValue(&item_parse_state, WJB_END_OBJECT, NULL);
|
||||||
|
|
||||||
|
/* Add the iterator object to the context */
|
||||||
|
pushJsonbValue(&parse_state, WJB_VALUE, item_res);
|
||||||
|
|
||||||
|
/* Finish the context object */
|
||||||
|
res = pushJsonbValue(&parse_state, WJB_END_OBJECT, NULL);
|
||||||
|
|
||||||
|
/* Convert to Jsonb */
|
||||||
|
Jsonb *context_jsonb = JsonbValueToJsonb(res);
|
||||||
|
|
||||||
/* Render the section body with the new context */
|
/* Render the section body with the new context */
|
||||||
render_template(current->value->section.body, JsonbValueToJsonb(new_context), result, context);
|
render_template(current->value->section.body, context_jsonb, result, context);
|
||||||
|
|
||||||
/* Free the temporary values */
|
/* Free the temporary values */
|
||||||
pfree(new_context);
|
pfree(key_val.val.string.val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,190 +1,190 @@
|
|||||||
-- Test the render function with interpolation tags
|
-- Test the render function with interpolation tags
|
||||||
CREATE EXTENSION IF NOT EXISTS hemar;
|
CREATE EXTENSION IF NOT EXISTS hemar;
|
||||||
|
|
||||||
DO $$
|
DO $$
|
||||||
DECLARE
|
DECLARE
|
||||||
total_tests INT := 0;
|
total_tests INT := 0;
|
||||||
passed_tests INT := 0;
|
passed_tests INT := 0;
|
||||||
test_result TEXT;
|
test_result TEXT;
|
||||||
expected TEXT;
|
expected TEXT;
|
||||||
passed BOOLEAN;
|
passed BOOLEAN;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Test 1: Simple string interpolation
|
-- Test 1: Simple string interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"name": "John"}'::jsonb,
|
'{"name": "John"}'::jsonb,
|
||||||
'Hello {{ name }}!'
|
'Hello {{ name }}!'
|
||||||
);
|
);
|
||||||
expected := 'Hello John!';
|
expected := 'Hello John!';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Simple string interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Simple string interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Simple string interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Simple string interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 2: Numeric interpolation
|
-- Test 2: Numeric interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"age": 30, "price": 19.99}'::jsonb,
|
'{"age": 30, "price": 19.99}'::jsonb,
|
||||||
'Age: {{ age }}, Price: {{ price }}'
|
'Age: {{ age }}, Price: {{ price }}'
|
||||||
);
|
);
|
||||||
expected := 'Age: 30, Price: 19.99';
|
expected := 'Age: 30, Price: 19.99';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Numeric interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Numeric interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Numeric interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Numeric interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 3: Boolean interpolation
|
-- Test 3: Boolean interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"is_active": true, "is_deleted": false}'::jsonb,
|
'{"is_active": true, "is_deleted": false}'::jsonb,
|
||||||
'Status: {{ is_active }}, Deleted: {{ is_deleted }}'
|
'Status: {{ is_active }}, Deleted: {{ is_deleted }}'
|
||||||
);
|
);
|
||||||
expected := 'Status: true, Deleted: false';
|
expected := 'Status: true, Deleted: false';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Boolean interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Boolean interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Boolean interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Boolean interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 4: Null value interpolation
|
-- Test 4: Null value interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"name": null}'::jsonb,
|
'{"name": null}'::jsonb,
|
||||||
'Name: {{ name }}'
|
'Name: {{ name }}'
|
||||||
);
|
);
|
||||||
expected := 'Name: ';
|
expected := 'Name: ';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Null value interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Null value interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Null value interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Null value interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 5: Nested object interpolation
|
-- Test 5: Nested object interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"user": {"profile": {"name": "John", "age": 30}}}'::jsonb,
|
'{"user": {"profile": {"name": "John", "age": 30}}}'::jsonb,
|
||||||
'User: {{ user.profile.name }}, Age: {{ user.profile.age }}'
|
'User: {{ user.profile.name }}, Age: {{ user.profile.age }}'
|
||||||
);
|
);
|
||||||
expected := 'User: John, Age: 30';
|
expected := 'User: John, Age: 30';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Nested object interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Nested object interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Nested object interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Nested object interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 6: Array interpolation
|
-- Test 6: Array interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"numbers": [1, 2, 3], "names": ["John", "Jane"]}'::jsonb,
|
'{"numbers": [1, 2, 3], "names": ["John", "Jane"]}'::jsonb,
|
||||||
'Numbers: {{ numbers }}, Names: {{ names }}'
|
'Numbers: {{ numbers }}, Names: {{ names }}'
|
||||||
);
|
);
|
||||||
expected := 'Numbers: [1, 2, 3], Names: ["John", "Jane"]';
|
expected := 'Numbers: [1, 2, 3], Names: ["John", "Jane"]';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Array interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Array interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Array interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Array interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 7: Array index interpolation
|
-- Test 7: Array index interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"items": [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]}'::jsonb,
|
'{"items": [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]}'::jsonb,
|
||||||
'First item: {{ items[0].name }}, Second item: {{ items[1].name }}'
|
'First item: {{ items[0].name }}, Second item: {{ items[1].name }}'
|
||||||
);
|
);
|
||||||
expected := 'First item: Item 1, Second item: Item 2';
|
expected := 'First item: Item 1, Second item: Item 2';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Array index interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Array index interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Array index interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Array index interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 8: Complex nested structure interpolation
|
-- Test 8: Complex nested structure interpolation
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"company": {"name": "Tech Corp", "employees": [{"name": "John", "role": "Developer"}, {"name": "Jane", "role": "Manager"}]}}'::jsonb,
|
'{"company": {"name": "Tech Corp", "employees": [{"name": "John", "role": "Developer"}, {"name": "Jane", "role": "Manager"}]}}'::jsonb,
|
||||||
'Company: {{ company.name }}, First employee: {{ company.employees[0].name }} ({{ company.employees[0].role }})'
|
'Company: {{ company.name }}, First employee: {{ company.employees[0].name }} ({{ company.employees[0].role }})'
|
||||||
);
|
);
|
||||||
expected := 'Company: Tech Corp, First employee: John (Developer)';
|
expected := 'Company: Tech Corp, First employee: John (Developer)';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Complex nested structure interpolation: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Complex nested structure interpolation: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Complex nested structure interpolation: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Complex nested structure interpolation: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 9: Multiple interpolations in text
|
-- Test 9: Multiple interpolations in text
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"greeting": "Hello", "name": "John", "punctuation": "!"}'::jsonb,
|
'{"greeting": "Hello", "name": "John", "punctuation": "!"}'::jsonb,
|
||||||
'{{ greeting }} {{ name }}{{ punctuation }} How are you {{ name }}?'
|
'{{ greeting }} {{ name }}{{ punctuation }} How are you {{ name }}?'
|
||||||
);
|
);
|
||||||
expected := 'Hello John! How are you John?';
|
expected := 'Hello John! How are you John?';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Multiple interpolations in text: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Multiple interpolations in text: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Multiple interpolations in text: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Multiple interpolations in text: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Test 10: Invalid path handling
|
-- Test 10: Invalid path handling
|
||||||
total_tests := total_tests + 1;
|
total_tests := total_tests + 1;
|
||||||
test_result := hemar.render(
|
test_result := hemar.render(
|
||||||
'{"name": "John"}'::jsonb,
|
'{"name": "John"}'::jsonb,
|
||||||
'Name: {{ name }}, Age: {{ age }}, Address: {{ address.street }}'
|
'Name: {{ name }}, Age: {{ age }}, Address: {{ address.street }}'
|
||||||
);
|
);
|
||||||
expected := 'Name: John, Age: , Address: ';
|
expected := 'Name: John, Age: , Address: ';
|
||||||
passed := test_result = expected;
|
passed := test_result = expected;
|
||||||
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
passed_tests := passed_tests + (CASE WHEN passed THEN 1 ELSE 0 END);
|
||||||
IF passed THEN
|
IF passed THEN
|
||||||
RAISE NOTICE 'Test %: Invalid path handling: PASSED', total_tests;
|
RAISE NOTICE 'Test %: Invalid path handling: PASSED', total_tests;
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING 'Test %: Invalid path handling: FAILED. Expected "%", got "%"',
|
RAISE WARNING 'Test %: Invalid path handling: FAILED. Expected "%", got "%"',
|
||||||
total_tests, expected, test_result;
|
total_tests, expected, test_result;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Print summary
|
-- Print summary
|
||||||
IF passed_tests = total_tests THEN
|
IF passed_tests = total_tests THEN
|
||||||
RAISE NOTICE '------------------------------------';
|
RAISE NOTICE '------------------------------------';
|
||||||
RAISE NOTICE 'SUMMARY: % of % interpolation render tests passed (100%%)',
|
RAISE NOTICE 'SUMMARY: % of % interpolation render tests passed (100%%)',
|
||||||
passed_tests, total_tests;
|
passed_tests, total_tests;
|
||||||
RAISE NOTICE '------------------------------------';
|
RAISE NOTICE '------------------------------------';
|
||||||
ELSE
|
ELSE
|
||||||
RAISE WARNING '------------------------------------';
|
RAISE WARNING '------------------------------------';
|
||||||
RAISE WARNING 'SUMMARY: % of % interpolation render tests passed (%)',
|
RAISE WARNING 'SUMMARY: % of % interpolation render tests passed (%)',
|
||||||
passed_tests,
|
passed_tests,
|
||||||
total_tests,
|
total_tests,
|
||||||
round((passed_tests::numeric / total_tests::numeric) * 100, 2) || '%';
|
round((passed_tests::numeric / total_tests::numeric) * 100, 2) || '%';
|
||||||
RAISE WARNING '------------------------------------';
|
RAISE WARNING '------------------------------------';
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
IF passed_tests != total_tests THEN
|
IF passed_tests != total_tests THEN
|
||||||
RAISE EXCEPTION 'Tests failed: % of % interpolation render tests did not pass', (total_tests - passed_tests), total_tests;
|
RAISE EXCEPTION 'Tests failed: % of % interpolation render tests did not pass', (total_tests - passed_tests), total_tests;
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
@@ -1,98 +1,209 @@
|
|||||||
-- Test section rendering
|
-- Test section rendering
|
||||||
DO $$
|
DO $$
|
||||||
DECLARE
|
DECLARE
|
||||||
test_result text;
|
test_result text;
|
||||||
expected text;
|
expected text;
|
||||||
BEGIN
|
total_tests integer := 0;
|
||||||
-- Test 1: String iteration
|
passed_tests integer := 0;
|
||||||
test_result := hemar.render(
|
BEGIN
|
||||||
'{"text": "Hello"}'::jsonb,
|
-- Test 1: String iteration
|
||||||
'{{for char in text}}{{char}}{{end}}'
|
total_tests := total_tests + 1;
|
||||||
);
|
BEGIN
|
||||||
expected := 'Hello';
|
test_result := hemar.render(
|
||||||
ASSERT test_result = expected, format('Test 1: String iteration: FAILED. Expected "%s", got "%s"', expected, test_result);
|
'{"text": "Hello"}'::jsonb,
|
||||||
RAISE NOTICE 'Test 1: String iteration: PASSED';
|
'{{for char in text}}{{char}}{{end}}'
|
||||||
|
);
|
||||||
-- Test 2: Array iteration
|
expected := 'Hello';
|
||||||
test_result := hemar.render(
|
IF test_result = expected THEN
|
||||||
'{"numbers": [1, 2, 3]}'::jsonb,
|
RAISE NOTICE 'Test %: String iteration: PASSED', total_tests;
|
||||||
'{{for num in numbers}}{{num}}{{end}}'
|
passed_tests := passed_tests + 1;
|
||||||
);
|
ELSE
|
||||||
expected := '123';
|
RAISE WARNING 'Test %: String iteration: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
ASSERT test_result = expected, format('Test 2: Array iteration: FAILED. Expected "%s", got "%s"', expected, test_result);
|
END IF;
|
||||||
RAISE NOTICE 'Test 2: Array iteration: PASSED';
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: String iteration: FAILED with error: %', total_tests, SQLERRM;
|
||||||
-- Test 3: Object iteration
|
END;
|
||||||
test_result := hemar.render(
|
|
||||||
'{"user": {"name": "John", "age": 30}}'::jsonb,
|
-- Test 2: Array iteration
|
||||||
'{{for item in user}}{{item.key}}: {{item.value}}{{end}}'
|
total_tests := total_tests + 1;
|
||||||
);
|
BEGIN
|
||||||
expected := 'name: Johnage: 30';
|
test_result := hemar.render(
|
||||||
ASSERT test_result = expected, format('Test 3: Object iteration: FAILED. Expected "%s", got "%s"', expected, test_result);
|
'{"numbers": [1, 2, 3]}'::jsonb,
|
||||||
RAISE NOTICE 'Test 3: Object iteration: PASSED';
|
'{{for num in numbers}}{{num}}{{end}}'
|
||||||
|
);
|
||||||
-- Test 4: Boolean condition (true)
|
expected := '123';
|
||||||
test_result := hemar.render(
|
IF test_result = expected THEN
|
||||||
'{"show": true}'::jsonb,
|
RAISE NOTICE 'Test %: Array iteration: PASSED', total_tests;
|
||||||
'{{for show in show}}Content{{end}}'
|
passed_tests := passed_tests + 1;
|
||||||
);
|
ELSE
|
||||||
expected := 'Content';
|
RAISE WARNING 'Test %: Array iteration: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
ASSERT test_result = expected, format('Test 4: Boolean condition (true): FAILED. Expected "%s", got "%s"', expected, test_result);
|
END IF;
|
||||||
RAISE NOTICE 'Test 4: Boolean condition (true): PASSED';
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Array iteration: FAILED with error: %', total_tests, SQLERRM;
|
||||||
-- Test 5: Boolean condition (false)
|
END;
|
||||||
test_result := hemar.render(
|
|
||||||
'{"show": false}'::jsonb,
|
-- Test 3: Object iteration
|
||||||
'{{for show in show}}Content{{end}}'
|
total_tests := total_tests + 1;
|
||||||
);
|
BEGIN
|
||||||
expected := '';
|
test_result := hemar.render(
|
||||||
ASSERT test_result = expected, format('Test 5: Boolean condition (false): FAILED. Expected "%s", got "%s"', expected, test_result);
|
'{"user": {"name": "John", "age": 30}}'::jsonb,
|
||||||
RAISE NOTICE 'Test 5: Boolean condition (false): PASSED';
|
'{{for item in user}}{{item.key}}: {{item.value}}{{end}}'
|
||||||
|
);
|
||||||
-- Test 6: Nested sections
|
expected := 'age: 30name: John';
|
||||||
test_result := hemar.render(
|
IF test_result = expected THEN
|
||||||
'{"items": [{"name": "Item 1", "tags": ["tag1", "tag2"]}, {"name": "Item 2", "tags": ["tag3"]}]}'::jsonb,
|
RAISE NOTICE 'Test %: Object iteration: PASSED', total_tests;
|
||||||
'{{for item in items}}{{item.name}}: {{for tag in item.tags}}{{tag}} {{end}}{{end}}'
|
passed_tests := passed_tests + 1;
|
||||||
);
|
ELSE
|
||||||
expected := 'Item 1: tag1 tag2 Item 2: tag3 ';
|
RAISE WARNING 'Test %: Object iteration: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
ASSERT test_result = expected, format('Test 6: Nested sections: FAILED. Expected "%s", got "%s"', expected, test_result);
|
END IF;
|
||||||
RAISE NOTICE 'Test 6: Nested sections: PASSED';
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Object iteration: FAILED with error: %', total_tests, SQLERRM;
|
||||||
-- Test 7: Section with context
|
END;
|
||||||
test_result := hemar.render(
|
|
||||||
'{"items": ["a", "b"], "prefix": "Item: "}'::jsonb,
|
-- Test 4: Boolean condition (true)
|
||||||
'{{for item in items}}{{prefix}}{{item}}{{end}}'
|
total_tests := total_tests + 1;
|
||||||
);
|
BEGIN
|
||||||
expected := 'Item: aItem: b';
|
test_result := hemar.render(
|
||||||
ASSERT test_result = expected, format('Test 7: Section with context: FAILED. Expected "%s", got "%s"', expected, test_result);
|
'{"show": true}'::jsonb,
|
||||||
RAISE NOTICE 'Test 7: Section with context: PASSED';
|
'{{for show in show}}Content{{end}}'
|
||||||
|
);
|
||||||
-- Test 8: Empty array
|
expected := 'Content';
|
||||||
test_result := hemar.render(
|
IF test_result = expected THEN
|
||||||
'{"items": []}'::jsonb,
|
RAISE NOTICE 'Test %: Boolean condition (true): PASSED', total_tests;
|
||||||
'{{for item in items}}{{item}}{{end}}'
|
passed_tests := passed_tests + 1;
|
||||||
);
|
ELSE
|
||||||
expected := '';
|
RAISE WARNING 'Test %: Boolean condition (true): FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
ASSERT test_result = expected, format('Test 8: Empty array: FAILED. Expected "%s", got "%s"', expected, test_result);
|
END IF;
|
||||||
RAISE NOTICE 'Test 8: Empty array: PASSED';
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Boolean condition (true): FAILED with error: %', total_tests, SQLERRM;
|
||||||
-- Test 9: Empty object
|
END;
|
||||||
test_result := hemar.render(
|
|
||||||
'{"user": {}}'::jsonb,
|
-- Test 5: Boolean condition (false)
|
||||||
'{{for key in user}}{{key}}{{end}}'
|
total_tests := total_tests + 1;
|
||||||
);
|
BEGIN
|
||||||
expected := '';
|
test_result := hemar.render(
|
||||||
ASSERT test_result = expected, format('Test 9: Empty object: FAILED. Expected "%s", got "%s"', expected, test_result);
|
'{"show": false}'::jsonb,
|
||||||
RAISE NOTICE 'Test 9: Empty object: PASSED';
|
'{{for show in show}}Content{{end}}'
|
||||||
|
);
|
||||||
-- Test 10: Invalid collection type (number)
|
expected := '';
|
||||||
test_result := hemar.render(
|
IF test_result = expected THEN
|
||||||
'{"number": 42}'::jsonb,
|
RAISE NOTICE 'Test %: Boolean condition (false): PASSED', total_tests;
|
||||||
'{{for item in number}}{{item}}{{end}}'
|
passed_tests := passed_tests + 1;
|
||||||
);
|
ELSE
|
||||||
expected := '';
|
RAISE WARNING 'Test %: Boolean condition (false): FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
ASSERT test_result = expected, format('Test 10: Invalid collection type: FAILED. Expected "%s", got "%s"', expected, test_result);
|
END IF;
|
||||||
RAISE NOTICE 'Test 10: Invalid collection type: PASSED (error raised as expected)';
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Boolean condition (false): FAILED with error: %', total_tests, SQLERRM;
|
||||||
RAISE NOTICE 'All section rendering tests completed successfully!';
|
END;
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
-- Test 6: Nested sections
|
||||||
|
total_tests := total_tests + 1;
|
||||||
|
BEGIN
|
||||||
|
test_result := hemar.render(
|
||||||
|
'{"items": [{"name": "Item 1", "tags": ["tag1", "tag2"]}, {"name": "Item 2", "tags": ["tag3"]}]}'::jsonb,
|
||||||
|
'{{for item in items}}{{item.name}}: {{for tag in item.tags}}{{tag}} {{end}}{{end}}'
|
||||||
|
);
|
||||||
|
expected := 'Item 1: tag1 tag2 Item 2: tag3 ';
|
||||||
|
IF test_result = expected THEN
|
||||||
|
RAISE NOTICE 'Test %: Nested sections: PASSED', total_tests;
|
||||||
|
passed_tests := passed_tests + 1;
|
||||||
|
ELSE
|
||||||
|
RAISE WARNING 'Test %: Nested sections: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
|
END IF;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Nested sections: FAILED with error: %', total_tests, SQLERRM;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Test 7: Section with context
|
||||||
|
total_tests := total_tests + 1;
|
||||||
|
BEGIN
|
||||||
|
test_result := hemar.render(
|
||||||
|
'{"items": ["a", "b"], "prefix": "Item: "}'::jsonb,
|
||||||
|
'{{for item in items}}{{prefix}}{{item}}{{end}}'
|
||||||
|
);
|
||||||
|
expected := 'Item: aItem: b';
|
||||||
|
IF test_result = expected THEN
|
||||||
|
RAISE NOTICE 'Test %: Section with context: PASSED', total_tests;
|
||||||
|
passed_tests := passed_tests + 1;
|
||||||
|
ELSE
|
||||||
|
RAISE WARNING 'Test %: Section with context: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
|
END IF;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Section with context: FAILED with error: %', total_tests, SQLERRM;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Test 8: Empty array
|
||||||
|
total_tests := total_tests + 1;
|
||||||
|
BEGIN
|
||||||
|
test_result := hemar.render(
|
||||||
|
'{"items": []}'::jsonb,
|
||||||
|
'{{for item in items}}{{item}}{{end}}'
|
||||||
|
);
|
||||||
|
expected := '';
|
||||||
|
IF test_result = expected THEN
|
||||||
|
RAISE NOTICE 'Test %: Empty array: PASSED', total_tests;
|
||||||
|
passed_tests := passed_tests + 1;
|
||||||
|
ELSE
|
||||||
|
RAISE WARNING 'Test %: Empty array: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
|
END IF;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Empty array: FAILED with error: %', total_tests, SQLERRM;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Test 9: Empty object
|
||||||
|
total_tests := total_tests + 1;
|
||||||
|
BEGIN
|
||||||
|
test_result := hemar.render(
|
||||||
|
'{"user": {}}'::jsonb,
|
||||||
|
'{{for key in user}}{{key}}{{end}}'
|
||||||
|
);
|
||||||
|
expected := '';
|
||||||
|
IF test_result = expected THEN
|
||||||
|
RAISE NOTICE 'Test %: Empty object: PASSED', total_tests;
|
||||||
|
passed_tests := passed_tests + 1;
|
||||||
|
ELSE
|
||||||
|
RAISE WARNING 'Test %: Empty object: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
|
END IF;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Empty object: FAILED with error: %', total_tests, SQLERRM;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- Test 10: Invalid collection type (number)
|
||||||
|
total_tests := total_tests + 1;
|
||||||
|
BEGIN
|
||||||
|
test_result := hemar.render(
|
||||||
|
'{"number": 42}'::jsonb,
|
||||||
|
'{{for item in number}}{{item}}{{end}}'
|
||||||
|
);
|
||||||
|
expected := '';
|
||||||
|
IF test_result = expected THEN
|
||||||
|
RAISE NOTICE 'Test %: Invalid collection type: PASSED (error raised as expected)', total_tests;
|
||||||
|
passed_tests := passed_tests + 1;
|
||||||
|
ELSE
|
||||||
|
RAISE WARNING 'Test %: Invalid collection type: FAILED. Expected "%", got "%"', total_tests, expected, test_result;
|
||||||
|
END IF;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE WARNING 'Test %: Invalid collection type: FAILED with error: %', total_tests, SQLERRM;
|
||||||
|
END;
|
||||||
|
|
||||||
|
|
||||||
|
-- Print summary
|
||||||
|
IF passed_tests = total_tests THEN
|
||||||
|
RAISE NOTICE '------------------------------------';
|
||||||
|
RAISE NOTICE 'SUMMARY: % of % template section tests passed (100%%)',
|
||||||
|
passed_tests, total_tests;
|
||||||
|
RAISE NOTICE '------------------------------------';
|
||||||
|
ELSE
|
||||||
|
RAISE WARNING '------------------------------------';
|
||||||
|
RAISE WARNING 'SUMMARY: % of % template section tests passed (%)',
|
||||||
|
passed_tests,
|
||||||
|
total_tests,
|
||||||
|
round((passed_tests::numeric / total_tests::numeric) * 100, 2) || '%';
|
||||||
|
RAISE WARNING '------------------------------------';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF passed_tests != total_tests THEN
|
||||||
|
RAISE EXCEPTION 'Tests failed: % of % template section tests did not pass', (total_tests - passed_tests), total_tests;
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
Reference in New Issue
Block a user