diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2021-11-15 12:51:20 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2021-11-15 12:51:20 +0100 |
commit | 662f5a771f3807bf7ebd5a3989230d5d0a26659d (patch) | |
tree | 51cf82d5f470a0f4a9613bccbb3da3492f9eee34 /test | |
parent | 514cb71a6a3e116c229c5dc874369f8632530dc7 (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.cpp | 20 | ||||
-rw-r--r-- | test/data/html-extend/base.txt | 11 | ||||
-rw-r--r-- | test/data/html-extend/data.json | 12 | ||||
-rw-r--r-- | test/data/html-extend/inter.txt | 3 | ||||
-rw-r--r-- | test/data/html-extend/result.txt | 11 | ||||
-rw-r--r-- | test/data/html-extend/template.txt | 7 | ||||
-rwxr-xr-x | test/data/include-both.txt | 1 | ||||
-rw-r--r-- | test/jinja.py | 11 | ||||
-rw-r--r-- | test/templates/example.txt | 1 | ||||
-rw-r--r-- | test/test-files.cpp | 35 | ||||
-rw-r--r-- | test/test-functions.cpp | 51 | ||||
-rw-r--r-- | test/test-renderer.cpp | 79 | ||||
-rw-r--r-- | test/test-units.cpp | 10 | ||||
-rw-r--r-- | test/test.cpp | 2 |
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" |