aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2021-11-15 12:51:20 +0100
committerToni Uhlig <matzeton@googlemail.com>2021-11-15 12:51:20 +0100
commit662f5a771f3807bf7ebd5a3989230d5d0a26659d (patch)
tree51cf82d5f470a0f4a9613bccbb3da3492f9eee34 /test
parent514cb71a6a3e116c229c5dc874369f8632530dc7 (diff)
Squashed 'deps/inja/' changes from 811e173..eb04bfc
eb04bfc clang-format 81cfa14 init LiteralNode with string view, code cleaning 2da715a parse_filename without json 623c267 make_result and code cleaning 1206913 rename json -> data d38c07e clang 5 minimum a067a8b make all tests C++17 098de66 inja_test C++17 173c1f5 fix C++17 2239e23 remove string view polyfill fb55f2e update minimum compiler 751d27d fix MIT license 635e1fb change readme example 5a4ac92 update single include d038c53 set .cpp in readme cf71b54 add include callback 9b9dd96 introduce INJA_DATA_TYPE 12a2c9b unify json data type 4505fd0 add tests for assignments 2d51507 set version 3.3 2ba5783 Merge branch 'master' of github.com:pantor/inja 99b85d6 remove headers in files, add central header 14f0d38 Fixed an issue with round (#207) c70fd58 Merge branch 'master' of github.com:pantor/inja 8a9aee1 add jinja python test script 91c93bf add join function (#204) 9cf7db8 add warnings for benchmark, fix for inja_throw e91a2fd #ifndef INJA_THROW 8d65633 add warnings for clang and fix them eaec58d update nlohmann/json to master 4ccadd5 update to json=3.9.1, doctest=2.4.6 83feb26 update single include 4e90947 at function for objects b473873 compactify assignments readme 798a0b9 Add support for setting subobjects via JSON pointer in set statements. (#202) 86f38f0 update single include d9ad8d1 whitespace control for comments 95af782 Add Child Inheritance Feature (#198) b4b9d8d Fix build warnings for Clang and MSVC (#197) b14f8a1 add ci for gcc 10, 11 06ff271 add no excpetion test 2491980 Fix inclusion in translation units with exceptions disabled. (#196) 4d5a7d1 fix single include eac2162 fix include of in-memory templates ca3c7a0 add test for short circuit evaluation 389c1d6 short circuit evaluation git-subtree-dir: deps/inja git-subtree-split: eb04bfc7d3cf0a5fbd0ed37a88d064230d0af377
Diffstat (limited to 'test')
-rw-r--r--test/benchmark.cpp20
-rw-r--r--test/data/html-extend/base.txt11
-rw-r--r--test/data/html-extend/data.json12
-rw-r--r--test/data/html-extend/inter.txt3
-rw-r--r--test/data/html-extend/result.txt11
-rw-r--r--test/data/html-extend/template.txt7
-rwxr-xr-xtest/data/include-both.txt1
-rw-r--r--test/jinja.py11
-rw-r--r--test/templates/example.txt1
-rw-r--r--test/test-files.cpp35
-rw-r--r--test/test-functions.cpp51
-rw-r--r--test/test-renderer.cpp79
-rw-r--r--test/test-units.cpp10
-rw-r--r--test/test.cpp2
14 files changed, 183 insertions, 71 deletions
diff --git a/test/benchmark.cpp b/test/benchmark.cpp
index 571a3ed..92c696f 100644
--- a/test/benchmark.cpp
+++ b/test/benchmark.cpp
@@ -3,22 +3,24 @@
#include "hayai/hayai.hpp"
#include <inja/inja.hpp>
-using json = nlohmann::json;
-
inja::Environment env;
const std::string test_file_directory {"../test/data/benchmark/"};
-json small_data = env.load_json(test_file_directory + "small_data.json");
-json large_data = env.load_json(test_file_directory + "large_data.json");
+auto small_data = env.load_json(test_file_directory + "small_data.json");
+auto large_data = env.load_json(test_file_directory + "large_data.json");
std::string medium_template = env.load_file(test_file_directory + "medium_template.txt");
std::string large_template = env.load_file(test_file_directory + "large_template.txt");
-
-BENCHMARK(SmallDataMediumTemplate, render, 5, 30) { env.render(medium_template, small_data); }
-BENCHMARK(LargeDataMediumTemplate, render, 5, 15) { env.render(medium_template, large_data); }
-BENCHMARK(LargeDataLargeTemplate, render, 5, 5) { env.render(large_template, large_data); }
-
+BENCHMARK(SmallDataMediumTemplate, render, 5, 30) {
+ env.render(medium_template, small_data);
+}
+BENCHMARK(LargeDataMediumTemplate, render, 5, 15) {
+ env.render(medium_template, large_data);
+}
+BENCHMARK(LargeDataLargeTemplate, render, 5, 5) {
+ env.render(large_template, large_data);
+}
int main() {
hayai::ConsoleOutputter consoleOutputter;
diff --git a/test/data/html-extend/base.txt b/test/data/html-extend/base.txt
new file mode 100644
index 0000000..e301c7a
--- /dev/null
+++ b/test/data/html-extend/base.txt
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ {% block head -%}
+ <title>{% block title %}Default - {% endblock %}</title>
+ {%- endblock -%}
+</head>
+<body>
+ {% block body %}ignored{% endblock %}
+</body>
+</html>
diff --git a/test/data/html-extend/data.json b/test/data/html-extend/data.json
new file mode 100644
index 0000000..c5726a5
--- /dev/null
+++ b/test/data/html-extend/data.json
@@ -0,0 +1,12 @@
+{
+ "author": "Pantor",
+ "date": "23/12/2018",
+ "tags": [
+ "test",
+ "templates"
+ ],
+ "views": 123,
+ "title": "Inja works.",
+ "content": "Inja is the best and fastest template engine for C++. Period.",
+ "footer-text": "This is the footer."
+}
diff --git a/test/data/html-extend/inter.txt b/test/data/html-extend/inter.txt
new file mode 100644
index 0000000..d20d97b
--- /dev/null
+++ b/test/data/html-extend/inter.txt
@@ -0,0 +1,3 @@
+{% extends "base.txt" %}
+{% block title %}Inter {{ author }}{% endblock %}
+{% block body %}<main>Intermediate Content</main>{% endblock %} \ No newline at end of file
diff --git a/test/data/html-extend/result.txt b/test/data/html-extend/result.txt
new file mode 100644
index 0000000..6d99e29
--- /dev/null
+++ b/test/data/html-extend/result.txt
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Default - Inter Pantor: Inja works.</title>
+
+ <style type="text/css">.important { color: #336699; }</style>
+</head>
+<body>
+ <main>Inja is the best and fastest template engine for C++. Period.</main>
+</body>
+</html>
diff --git a/test/data/html-extend/template.txt b/test/data/html-extend/template.txt
new file mode 100644
index 0000000..18eeb5d
--- /dev/null
+++ b/test/data/html-extend/template.txt
@@ -0,0 +1,7 @@
+{% extends "inter.txt" %}
+{% block head -%}
+ {{ super(2) }}
+ <style type="text/css">.important { color: #336699; }</style>
+{%- endblock %}
+{% block title %}{{ super(2) }}{{ super() }}: {{ title }}{% endblock %}
+{% block body %}<main>{{ content }}</main>{% endblock %}
diff --git a/test/data/include-both.txt b/test/data/include-both.txt
new file mode 100755
index 0000000..cbdc374
--- /dev/null
+++ b/test/data/include-both.txt
@@ -0,0 +1 @@
+{% include "simple.txt" %} - {% include "body" %} \ No newline at end of file
diff --git a/test/jinja.py b/test/jinja.py
new file mode 100644
index 0000000..94bc24c
--- /dev/null
+++ b/test/jinja.py
@@ -0,0 +1,11 @@
+from jinja2 import Environment, PackageLoader, select_autoescape
+
+
+if __name__ == '__main__':
+ env = Environment(
+ loader=PackageLoader("jinja"),
+ autoescape=select_autoescape()
+ )
+
+ template = env.get_template("example.txt")
+ print(template.render(name="Jeff"))
diff --git a/test/templates/example.txt b/test/templates/example.txt
new file mode 100644
index 0000000..655a3c9
--- /dev/null
+++ b/test/templates/example.txt
@@ -0,0 +1 @@
+Hello {{- name -}} ! \ No newline at end of file
diff --git a/test/test-files.cpp b/test/test-files.cpp
index 74d099a..aa01cff 100644
--- a/test/test-files.cpp
+++ b/test/test-files.cpp
@@ -2,10 +2,12 @@
TEST_CASE("loading") {
inja::Environment env;
- json data;
+ inja::json data;
data["name"] = "Jeff";
- SUBCASE("Files should be loaded") { CHECK(env.load_file(test_file_directory + "simple.txt") == "Hello {{ name }}."); }
+ SUBCASE("Files should be loaded") {
+ CHECK(env.load_file(test_file_directory + "simple.txt") == "Hello {{ name }}.");
+ }
SUBCASE("Files should be rendered") {
CHECK(env.render_file(test_file_directory + "simple.txt", data) == "Hello Jeff.");
@@ -27,10 +29,9 @@ TEST_CASE("loading") {
TEST_CASE("complete-files") {
inja::Environment env {test_file_directory};
- for (std::string test_name : {"simple-file", "nested", "nested-line", "html"}) {
+ for (std::string test_name : {"simple-file", "nested", "nested-line", "html", "html-extend"}) {
SUBCASE(test_name.c_str()) {
- CHECK(env.render_file_with_json_file(test_name + "/template.txt", test_name + "/data.json") ==
- env.load_file(test_name + "/result.txt"));
+ CHECK(env.render_file_with_json_file(test_name + "/template.txt", test_name + "/data.json") == env.load_file(test_name + "/result.txt"));
}
}
@@ -49,8 +50,7 @@ TEST_CASE("complete-files-whitespace-control") {
for (std::string test_name : {"nested-whitespace"}) {
SUBCASE(test_name.c_str()) {
- CHECK(env.render_file_with_json_file(test_name + "/template.txt", test_name + "/data.json") ==
- env.load_file(test_name + "/result.txt"));
+ CHECK(env.render_file_with_json_file(test_name + "/template.txt", test_name + "/data.json") == env.load_file(test_name + "/result.txt"));
}
}
}
@@ -58,7 +58,7 @@ TEST_CASE("complete-files-whitespace-control") {
TEST_CASE("global-path") {
inja::Environment env {test_file_directory, "./"};
inja::Environment env_result {"./"};
- json data;
+ inja::json data;
data["name"] = "Jeff";
SUBCASE("Files should be written") {
@@ -73,7 +73,20 @@ TEST_CASE("include-without-local-files") {
inja::Environment env {test_file_directory};
env.set_search_included_templates_in_files(false);
- SUBCASE("html") {
- CHECK_THROWS_WITH(env.render_file_with_json_file("html/template.txt", "html/data.json"), "[inja.exception.render_error] (at 3:14) include '../test/data/html/header.txt' not found");
- }
+ CHECK_THROWS_WITH(env.render_file_with_json_file("html/template.txt", "html/data.json"),
+ "[inja.exception.render_error] (at 3:14) include 'header.txt' not found");
+}
+
+TEST_CASE("include-in-memory-and-file-template") {
+ inja::Environment env {test_file_directory};
+
+ inja::json data;
+ data["name"] = "Jeff";
+
+ CHECK_THROWS_WITH(env.render_file("include-both.txt", data), "[inja.exception.file_error] failed accessing file at '../test/data/body'");
+
+ const auto parsed_body_template = env.parse("Bye {{ name }}.");
+ env.include_template("body", parsed_body_template);
+
+ CHECK(env.render_file("include-both.txt", data) == "Hello Jeff. - Bye Jeff.");
}
diff --git a/test/test-functions.cpp b/test/test-functions.cpp
index 4870205..667f553 100644
--- a/test/test-functions.cpp
+++ b/test/test-functions.cpp
@@ -3,7 +3,7 @@
TEST_CASE("functions") {
inja::Environment env;
- json data;
+ inja::json data;
data["name"] = "Peter";
data["city"] = "New York";
data["names"] = {"Jeff", "Seb", "Peter", "Tom"};
@@ -56,8 +56,8 @@ TEST_CASE("functions") {
SUBCASE("length") {
CHECK(env.render("{{ length(names) }}", data) == "4"); // Length of array
CHECK(env.render("{{ length(name) }}", data) == "5"); // Length of string
- // CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[inja.exception.json_error]
- // [json.exception.type_error.302] type must be array, but is number" );
+ // CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[inja.exception.json_error]
+ // [json.exception.type_error.302] type must be array, but is number" );
}
SUBCASE("sort") {
@@ -70,6 +70,8 @@ TEST_CASE("functions") {
SUBCASE("at") {
CHECK(env.render("{{ at(names, 0) }}", data) == "Jeff");
CHECK(env.render("{{ at(names, i) }}", data) == "Seb");
+ CHECK(env.render("{{ at(brother, \"name\") }}", data) == "Chris");
+ CHECK(env.render("{{ at(at(brother, \"daughters\"), 0) }}", data) == "Maria");
// CHECK(env.render("{{ at(names, 45) }}", data) == "Jeff");
}
@@ -86,7 +88,7 @@ TEST_CASE("functions") {
}
SUBCASE("round") {
- CHECK(env.render("{{ round(4, 0) }}", data) == "4.0");
+ CHECK(env.render("{{ round(4, 0) }}", data) == "4");
CHECK(env.render("{{ round(temperature, 2) }}", data) == "25.68");
// CHECK_THROWS_WITH( env.render("{{ round(name, 2) }}", data), "[inja.exception.json_error]
// [json.exception.type_error.302] type must be number, but is string" );
@@ -148,8 +150,7 @@ TEST_CASE("functions") {
CHECK(env.render("{{ default(name, \"nobody\") }}", data) == "Peter");
CHECK(env.render("{{ default(surname, \"nobody\") }}", data) == "nobody");
CHECK(env.render("{{ default(surname, \"{{ surname }}\") }}", data) == "{{ surname }}");
- CHECK_THROWS_WITH(env.render("{{ default(surname, lastname) }}", data),
- "[inja.exception.render_error] (at 1:21) variable 'lastname' not found");
+ CHECK_THROWS_WITH(env.render("{{ default(surname, lastname) }}", data), "[inja.exception.render_error] (at 1:21) variable 'lastname' not found");
}
SUBCASE("exists") {
@@ -166,10 +167,13 @@ TEST_CASE("functions") {
CHECK(env.render("{{ existsIn(brother, \"parents\") }}", data) == "false");
CHECK(env.render("{{ existsIn(brother, property) }}", data) == "true");
CHECK(env.render("{{ existsIn(brother, name) }}", data) == "false");
- CHECK_THROWS_WITH(env.render("{{ existsIn(sister, \"lastname\") }}", data),
- "[inja.exception.render_error] (at 1:13) variable 'sister' not found");
- CHECK_THROWS_WITH(env.render("{{ existsIn(brother, sister) }}", data),
- "[inja.exception.render_error] (at 1:22) variable 'sister' not found");
+ CHECK_THROWS_WITH(env.render("{{ existsIn(sister, \"lastname\") }}", data), "[inja.exception.render_error] (at 1:13) variable 'sister' not found");
+ CHECK_THROWS_WITH(env.render("{{ existsIn(brother, sister) }}", data), "[inja.exception.render_error] (at 1:22) variable 'sister' not found");
+ }
+
+ SUBCASE("join") {
+ CHECK(env.render("{{ join(names, \" | \") }}", data) == "Jeff | Seb | Peter | Tom");
+ CHECK(env.render("{{ join(vars, \", \") }}", data) == "2, 3, 4, 0, -1, -2, -3");
}
SUBCASE("isType") {
@@ -190,12 +194,22 @@ TEST_CASE("functions") {
}
}
+TEST_CASE("assignments") {
+ inja::Environment env;
+ inja::json data;
+ data["age"] = 28;
+
+ CHECK(env.render("{% set new_hour=23 %}{{ new_hour }}", data) == "23");
+ CHECK(env.render("{% set time.start=18 %}{{ time.start }}pm", data) == "18pm");
+ CHECK(env.render("{% set v1 = \"a\" %}{% set v2 = \"b\" %}{% set var = v1 + v2 %}{{ var }}", data) == "ab");
+}
+
TEST_CASE("callbacks") {
inja::Environment env;
- json data;
+ inja::json data;
data["age"] = 28;
- env.add_callback("double", 1, [](inja::Arguments &args) {
+ env.add_callback("double", 1, [](inja::Arguments& args) {
int number = args.at(0)->get<int>();
return 2 * number;
});
@@ -206,7 +220,7 @@ TEST_CASE("callbacks") {
});
std::string greet = "Hello";
- env.add_callback("double-greetings", 0, [greet](inja::Arguments args) { return greet + " " + greet + "!"; });
+ env.add_callback("double-greetings", 0, [greet](inja::Arguments) { return greet + " " + greet + "!"; });
env.add_callback("multiply", 2, [](inja::Arguments args) {
double number1 = args.at(0)->get<double>();
@@ -226,11 +240,11 @@ TEST_CASE("callbacks") {
return number1.length();
});
- env.add_void_callback("log", 1, [](inja::Arguments args) {
- int a = 2;
+ env.add_void_callback("log", 1, [](inja::Arguments) {
+
});
- env.add_callback("multiply", 0, [](inja::Arguments args) { return 1.0; });
+ env.add_callback("multiply", 0, [](inja::Arguments) { return 1.0; });
CHECK(env.render("{{ double(age) }}", data) == "56");
CHECK(env.render("{{ half(age) }}", data) == "14");
@@ -245,7 +259,7 @@ TEST_CASE("callbacks") {
SUBCASE("Variadic") {
env.add_callback("argmax", [](inja::Arguments& args) {
- auto result = std::max_element(args.begin(), args.end(), [](const json* a, const json* b) { return *a < *b;});
+ auto result = std::max_element(args.begin(), args.end(), [](const inja::json* a, const inja::json* b) { return *a < *b; });
return std::distance(args.begin(), result);
});
@@ -256,7 +270,7 @@ TEST_CASE("callbacks") {
TEST_CASE("combinations") {
inja::Environment env;
- json data;
+ inja::json data;
data["name"] = "Peter";
data["city"] = "Brunswick";
data["age"] = 29;
@@ -282,4 +296,5 @@ TEST_CASE("combinations") {
CHECK(env.render("{{ not true }}", data) == "false");
CHECK(env.render("{{ not (true) }}", data) == "false");
CHECK(env.render("{{ true or (true or true) }}", data) == "true");
+ CHECK(env.render("{{ at(list_of_objects, 1).b }}", data) == "3");
}
diff --git a/test/test-renderer.cpp b/test/test-renderer.cpp
index fe38738..2089791 100644
--- a/test/test-renderer.cpp
+++ b/test/test-renderer.cpp
@@ -2,7 +2,7 @@
TEST_CASE("types") {
inja::Environment env;
- json data;
+ inja::json data;
data["name"] = "Peter";
data["city"] = "Brunswick";
data["age"] = 29;
@@ -50,31 +50,26 @@ TEST_CASE("types") {
SUBCASE("loops") {
CHECK(env.render("{% for name in names %}a{% endfor %}", data) == "aa");
CHECK(env.render("Hello {% for name in names %}{{ name }} {% endfor %}!", data) == "Hello Jeff Seb !");
- CHECK(env.render("Hello {% for name in names %}{{ loop.index }}: {{ name }}, {% endfor %}!", data) ==
- "Hello 0: Jeff, 1: Seb, !");
+ CHECK(env.render("Hello {% for name in names %}{{ loop.index }}: {{ name }}, {% endfor %}!", data) == "Hello 0: Jeff, 1: Seb, !");
CHECK(env.render("{% for type, name in relatives %}{{ loop.index1 }}: {{ type }}: {{ name }}{% if loop.is_last == "
"false %}, {% endif %}{% endfor %}",
data) == "1: brother: Chris, 2: mother: Maria, 3: sister: Jenny");
CHECK(env.render("{% for v in vars %}{% if v > 0 %}+{% endif %}{% endfor %}", data) == "+++");
- CHECK(env.render(
- "{% for name in names %}{{ loop.index }}: {{ name }}{% if not loop.is_last %}, {% endif %}{% endfor %}!",
- data) == "0: Jeff, 1: Seb!");
+ CHECK(env.render("{% for name in names %}{{ loop.index }}: {{ name }}{% if not loop.is_last %}, {% endif %}{% endfor %}!", data) == "0: Jeff, 1: Seb!");
CHECK(env.render("{% for name in names %}{{ loop.index }}: {{ name }}{% if loop.is_last == false %}, {% endif %}{% "
"endfor %}!",
data) == "0: Jeff, 1: Seb!");
CHECK(env.render("{% for name in [] %}a{% endfor %}", data) == "");
- CHECK_THROWS_WITH(env.render("{% for name ins names %}a{% endfor %}", data),
- "[inja.exception.parser_error] (at 1:13) expected 'in', got 'ins'");
- CHECK_THROWS_WITH(env.render("{% for name in empty_loop %}a{% endfor %}", data),
- "[inja.exception.render_error] (at 1:16) variable 'empty_loop' not found");
+ CHECK_THROWS_WITH(env.render("{% for name ins names %}a{% endfor %}", data), "[inja.exception.parser_error] (at 1:13) expected 'in', got 'ins'");
+ CHECK_THROWS_WITH(env.render("{% for name in empty_loop %}a{% endfor %}", data), "[inja.exception.render_error] (at 1:16) variable 'empty_loop' not found");
// CHECK_THROWS_WITH( env.render("{% for name in relatives %}{{ name }}{% endfor %}", data),
// "[inja.exception.json_error] [json.exception.type_error.302] type must be array, but is object" );
}
SUBCASE("nested loops") {
- auto ldata = json::parse(R""""(
+ auto ldata = inja::json::parse(R""""(
{ "outer" : [
{ "inner" : [
{ "in2" : [ 1, 2 ] },
@@ -112,12 +107,10 @@ TEST_CASE("types") {
CHECK(env.render("{% if age >= 30 %}Right{% else %}Wrong{% endif %}", data) == "Wrong");
CHECK(env.render("{% if age in [28, 29, 30] %}True{% endif %}", data) == "True");
CHECK(env.render("{% if age == 28 %}28{% else if age == 29 %}29{% endif %}", data) == "29");
- CHECK(env.render("{% if age == 26 %}26{% else if age == 27 %}27{% else if age == 28 %}28{% else %}29{% endif %}",
- data) == "29");
+ CHECK(env.render("{% if age == 26 %}26{% else if age == 27 %}27{% else if age == 28 %}28{% else %}29{% endif %}", data) == "29");
CHECK(env.render("{% if age == 25 %}+{% endif %}{% if age == 29 %}+{% else %}-{% endif %}", data) == "+");
- CHECK_THROWS_WITH(env.render("{% if is_happy %}{% if is_happy %}{% endif %}", data),
- "[inja.exception.parser_error] (at 1:46) unmatched if");
+ CHECK_THROWS_WITH(env.render("{% if is_happy %}{% if is_happy %}{% endif %}", data), "[inja.exception.parser_error] (at 1:46) unmatched if");
CHECK_THROWS_WITH(env.render("{% if is_happy %}{% else if is_happy %}{% end if %}", data),
"[inja.exception.parser_error] (at 1:43) expected statement, got 'end'");
}
@@ -125,8 +118,18 @@ TEST_CASE("types") {
SUBCASE("set statements") {
CHECK(env.render("{% set predefined=true %}{% if predefined %}a{% endif %}", data) == "a");
CHECK(env.render("{% set predefined=false %}{% if predefined %}a{% endif %}", data) == "");
- CHECK_THROWS_WITH(env.render("{% if predefined %}{% endif %}", data),
- "[inja.exception.render_error] (at 1:7) variable 'predefined' not found");
+ CHECK(env.render("{% set age=30 %}{{age}}", data) == "30");
+ CHECK(env.render("{% set predefined.value=1 %}{% if existsIn(predefined, \"value\") %}{{predefined.value}}{% endif %}", data) == "1");
+ CHECK(env.render("{% set brother.name=\"Bob\" %}{{brother.name}}", data) == "Bob");
+ CHECK_THROWS_WITH(env.render("{% if predefined %}{% endif %}", data), "[inja.exception.render_error] (at 1:7) variable 'predefined' not found");
+ CHECK(env.render("{{age}}", data) == "29");
+ CHECK(env.render("{{brother.name}}", data) == "Chris");
+ }
+
+ SUBCASE("short circuit evaluation") {
+ CHECK(env.render("{% if 0 and undefined %}do{% else %}nothing{% endif %}", data) == "nothing");
+ CHECK_THROWS_WITH(env.render("{% if 1 and undefined %}do{% else %}nothing{% endif %}", data),
+ "[inja.exception.render_error] (at 1:13) variable 'undefined' not found");
}
SUBCASE("line statements") {
@@ -147,7 +150,7 @@ Yeah!
}
TEST_CASE("templates") {
- json data;
+ inja::json data;
data["name"] = "Peter";
data["city"] = "Brunswick";
data["is_happy"] = true;
@@ -170,19 +173,37 @@ TEST_CASE("templates") {
inja::Template t2 = env.parse("{% include \"greeting\" %}!");
CHECK(env.render(t2, data) == "Hello Peter!");
- CHECK_THROWS_WITH(env.parse("{% include \"does-not-exist\" %}!"),
- "[inja.exception.file_error] failed accessing file at 'does-not-exist'");
+ CHECK_THROWS_WITH(env.parse("{% include \"does-not-exist\" %}!"), "[inja.exception.file_error] failed accessing file at 'does-not-exist'");
+
+ CHECK_THROWS_WITH(env.parse("{% include does-not-exist %}!"), "[inja.exception.parser_error] (at 1:12) expected string, got 'does-not-exist'");
+ }
+
+ SUBCASE("include-callback") {
+ inja::Environment env;
+
+ CHECK_THROWS_WITH(env.parse("{% include \"does-not-exist\" %}!"), "[inja.exception.file_error] failed accessing file at 'does-not-exist'");
+
+ env.set_search_included_templates_in_files(false);
+ env.set_include_callback([&env](const std::string&, const std::string&) { return env.parse("Hello {{ name }}"); });
+
+ inja::Template t1 = env.parse("{% include \"greeting\" %}!");
+ CHECK(env.render(t1, data) == "Hello Peter!");
+
+ env.set_search_included_templates_in_files(true);
+ env.set_include_callback([&env](const std::string&, const std::string& name) { return env.parse("Bye " + name); });
+
+ inja::Template t2 = env.parse("{% include \"Jeff\" %}!");
+ CHECK(env.render(t2, data) == "Bye Jeff!");
}
SUBCASE("include-in-loop") {
- json loop_data;
- loop_data["cities"] = json::array({{{"name", "Munich"}}, {{"name", "New York"}}});
+ inja::json loop_data;
+ loop_data["cities"] = inja::json::array({{{"name", "Munich"}}, {{"name", "New York"}}});
inja::Environment env;
env.include_template("city.tpl", env.parse("{{ loop.index }}:{{ city.name }};"));
- CHECK(env.render("{% for city in cities %}{% include \"city.tpl\" %}{% endfor %}", loop_data) ==
- "0:Munich;1:New York;");
+ CHECK(env.render("{% for city in cities %}{% include \"city.tpl\" %}{% endfor %}", loop_data) == "0:Munich;1:New York;");
}
SUBCASE("count variables") {
@@ -204,32 +225,38 @@ TEST_CASE("templates") {
CHECK(env.render("Test\n {%- if is_happy %}{{ name }}{% endif %} ", data) == "Test\nPeter ");
CHECK(env.render(" {%+ if is_happy %}{{ name }}{% endif %}", data) == " Peter");
CHECK(env.render(" {%- if is_happy %}{{ name }}{% endif -%} \n ", data) == "Peter");
-
+
CHECK(env.render(" {{- name -}} \n ", data) == "Peter");
CHECK(env.render("Test\n {{- name }} ", data) == "Test\nPeter ");
CHECK(env.render(" {{ name }}\n ", data) == " Peter\n ");
+ CHECK(env.render("{{ name }}{# name -#} !", data) == "Peter!");
+ CHECK(env.render(" {#- name -#} !", data) == "!");
// Nothing will be stripped if there are other characters before the start of the block.
CHECK(env.render(". {%- if is_happy %}{{ name }}{% endif -%}\n", data) == ". Peter");
+ CHECK(env.render(". {#- comment -#}\n.", data) == ". .");
env.set_lstrip_blocks(true);
+ CHECK(env.render("Hello {{ name }}!", data) == "Hello Peter!");
CHECK(env.render(" {% if is_happy %}{{ name }}{% endif %}", data) == "Peter");
CHECK(env.render(" {% if is_happy %}{{ name }}{% endif %} ", data) == "Peter ");
CHECK(env.render(" {% if is_happy %}{{ name }}{% endif -%} ", data) == "Peter");
CHECK(env.render(" {%+ if is_happy %}{{ name }}{% endif %}", data) == " Peter");
CHECK(env.render("\n {%+ if is_happy %}{{ name }}{% endif -%} ", data) == "\n Peter");
CHECK(env.render("{% if is_happy %}{{ name }}{% endif %}\n", data) == "Peter\n");
+ CHECK(env.render(" {# comment #}", data) == "");
env.set_trim_blocks(true);
CHECK(env.render("{% if is_happy %}{{ name }}{% endif %}", data) == "Peter");
CHECK(env.render("{% if is_happy %}{{ name }}{% endif %}\n", data) == "Peter");
CHECK(env.render("{% if is_happy %}{{ name }}{% endif %} \n.", data) == "Peter.");
CHECK(env.render("{%- if is_happy %}{{ name }}{% endif -%} \n.", data) == "Peter.");
+ CHECK(env.render(" {# comment #} \n.", data) == ".");
}
}
TEST_CASE("other syntax") {
- json data;
+ inja::json data;
data["name"] = "Peter";
data["city"] = "Brunswick";
data["age"] = 29;
diff --git a/test/test-units.cpp b/test/test-units.cpp
index 95862f2..bbef190 100644
--- a/test/test-units.cpp
+++ b/test/test-units.cpp
@@ -27,7 +27,7 @@ Try this
TEST_CASE("copy environment") {
inja::Environment env;
- env.add_callback("double", 1, [](inja::Arguments &args) {
+ env.add_callback("double", 1, [](inja::Arguments& args) {
int number = args.at(0)->get<int>();
return 2 * number;
});
@@ -36,16 +36,16 @@ TEST_CASE("copy environment") {
env.include_template("tpl", t1);
std::string test_tpl = "{% include \"tpl\" %}";
- REQUIRE(env.render(test_tpl, json()) == "4");
+ REQUIRE(env.render(test_tpl, inja::json()) == "4");
inja::Environment copy(env);
- CHECK(copy.render(test_tpl, json()) == "4");
+ CHECK(copy.render(test_tpl, inja::json()) == "4");
// overwrite template in source env
inja::Template t2 = env.parse("{{ double(4) }}");
env.include_template("tpl", t2);
- REQUIRE(env.render(test_tpl, json()) == "8");
+ REQUIRE(env.render(test_tpl, inja::json()) == "8");
// template is unchanged in copy
- CHECK(copy.render(test_tpl, json()) == "4");
+ CHECK(copy.render(test_tpl, inja::json()) == "4");
}
diff --git a/test/test.cpp b/test/test.cpp
index 50161be..7645ade 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -5,8 +5,6 @@
#include "doctest/doctest.h"
#include "inja/inja.hpp"
-using json = nlohmann::json;
-
const std::string test_file_directory {"../test/data/"};
#include "test-files.cpp"