mirror of
https://github.com/pantor/inja.git
synced 2026-10-30 14:25:44 +00:00
Inja v2 (#67)
* inja2 * header only * reduce dependencies * code cleaning * c++17 * use stdc++ * code cleaning * infrastructure * header only * add infrastructure * fix tests * use minimum clang 6 * code cleaning, polyfill for c++11 * fix some file tests * fix readme * update appveyor * fix polyfill and ci * fix polyfill * fix ci? * test msvc __cplusplus * add doxygen * activate all tests * code cleaning * add coveralls, set default to dot notation * add html test * add doxygen comments * test single_include file * change build folder in appveyor * correct make arguments in appveyor * fix appveyor arguments
This commit is contained in:
1 parent
d90f93fda0
commit
699c207c8c
77 files changed
+7420
-3522
No files matched your search
@@ -1,92 +0,0 @@
|
||||
##
|
||||
## HUNTER
|
||||
##
|
||||
option(HUNTER_ENABLED "Use hunter to manage dependencies" OFF)
|
||||
if(HUNTER_ENABLED)
|
||||
include("../cmake/HunterGate.cmake")
|
||||
HunterGate(
|
||||
URL "https://github.com/ruslo/hunter/archive/v0.19.156.tar.gz"
|
||||
SHA1 "8d5e4635b137365e0d1ade4d60accf4e2bb41f0d"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
##
|
||||
## TESTS
|
||||
##
|
||||
add_executable(inja_test
|
||||
src/unit-files.cpp
|
||||
src/unit-renderer.cpp
|
||||
src/unit-string-helper.cpp
|
||||
src/unit.cpp
|
||||
)
|
||||
|
||||
add_executable(inja_single_test
|
||||
src/unit-files.cpp
|
||||
src/unit-renderer.cpp
|
||||
src/unit-string-helper.cpp
|
||||
src/unit.cpp
|
||||
)
|
||||
|
||||
|
||||
if(HUNTER_ENABLED) # Use Hunter to manage dependencies
|
||||
# Add Catch framework
|
||||
hunter_add_package(Catch)
|
||||
find_package(Catch CONFIG REQUIRED)
|
||||
|
||||
# Add JSON package
|
||||
hunter_add_package(nlohmann_json)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
|
||||
# Add dependencies to target
|
||||
target_link_libraries(inja_test Catch::Catch nlohmann_json inja)
|
||||
else() # Manage dependencies manually
|
||||
# Prepare "Catch" library for other executables
|
||||
add_library(Catch INTERFACE)
|
||||
target_include_directories(Catch INTERFACE "src/catch")
|
||||
|
||||
# Prepare "hayai" library for other executables
|
||||
add_library(hayai INTERFACE)
|
||||
target_include_directories(hayai INTERFACE "src/hayai")
|
||||
|
||||
# Add dependencies to targets
|
||||
target_link_libraries(inja_test Catch inja)
|
||||
target_link_libraries(inja_single_test Catch inja_single)
|
||||
endif()
|
||||
|
||||
|
||||
##
|
||||
## BENCHMARK
|
||||
##
|
||||
if(BUILD_BENCHMARK)
|
||||
add_executable(inja_benchmark
|
||||
src/benchmark.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(inja_benchmark hayai inja)
|
||||
endif()
|
||||
|
||||
|
||||
##
|
||||
## Copy test files to build directory
|
||||
##
|
||||
add_custom_command(
|
||||
TARGET inja_test POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/data
|
||||
${CMAKE_CURRENT_BINARY_DIR}/data
|
||||
)
|
||||
|
||||
|
||||
##
|
||||
## Add tests to make
|
||||
##
|
||||
add_test(NAME inja_test
|
||||
COMMAND inja_test
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_test(NAME inja_single_test
|
||||
COMMAND inja_single_test
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "hayai/hayai.hpp"
|
||||
#include "inja.hpp"
|
||||
#include <inja/inja.hpp>
|
||||
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
|
||||
json data = {{"name", "Peter"}};
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"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."
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Inja works.</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Inja works.</h1>
|
||||
<small>Written by Pantor</small>
|
||||
|
||||
<p>Inja is the best and fastest template engine for C++. Period.</p>
|
||||
<small>123 views</small>
|
||||
|
||||
<h5>Tags</h5>
|
||||
<ul>
|
||||
<li>test</li>
|
||||
<li>templates</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<small>Written by {{ author }}</small>
|
||||
|
||||
<p>{{ content }}</p>
|
||||
<small>{{ views }} views</small>
|
||||
|
||||
<h5>Tags</h5>
|
||||
<ul>
|
||||
## for tag in tags
|
||||
<li>{{ tag }}</li>
|
||||
## endfor
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
-1
@@ -1,6 +1,5 @@
|
||||
## for x in xarray
|
||||
## for y in yarray
|
||||
{{x}}-{{y}}
|
||||
|
||||
## endfor
|
||||
## endfor
|
||||
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
Regular → Executable
File mode changed.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -256,7 +256,7 @@ namespace hayai
|
||||
# elif defined(CLOCK_REALTIME)
|
||||
clock_gettime(CLOCK_REALTIME, &result);
|
||||
# else
|
||||
clock_gettime((clockid_t)-1, &result);
|
||||
clock_gettime((clocId_t)-1, &result);
|
||||
# endif
|
||||
return result;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,26 +0,0 @@
|
||||
unit_test = executable(
|
||||
'inja-test',
|
||||
'src/unit.cpp',
|
||||
'src/unit-files.cpp',
|
||||
'src/unit-renderer.cpp',
|
||||
'src/unit-string-helper.cpp',
|
||||
dependencies: inja_dep
|
||||
)
|
||||
|
||||
unit_single_test = executable(
|
||||
'inja-single-test',
|
||||
'src/unit.cpp',
|
||||
'src/unit-files.cpp',
|
||||
'src/unit-renderer.cpp',
|
||||
'src/unit-string-helper.cpp',
|
||||
dependencies: inja_single_dep
|
||||
)
|
||||
|
||||
inja_benchmark = executable(
|
||||
'inja_benchmark',
|
||||
'src/benchmark.cpp',
|
||||
dependencies: inja_dep
|
||||
)
|
||||
|
||||
test('Inja unit test', unit_test)
|
||||
test('Inja single unit test', unit_single_test)
|
||||
@@ -1,164 +0,0 @@
|
||||
#include "catch/catch.hpp"
|
||||
#include "inja.hpp"
|
||||
|
||||
|
||||
TEST_CASE("dot to pointer") {
|
||||
CHECK( inja::Parser::dot_to_json_pointer_notation("person.names.surname") == "/person/names/surname" );
|
||||
CHECK( inja::Parser::dot_to_json_pointer_notation("guests.2") == "/guests/2" );
|
||||
}
|
||||
|
||||
TEST_CASE("basic-search") {
|
||||
std::string input = "lorem ipsum dolor it";
|
||||
inja::Regex regex("i(.*)m");
|
||||
|
||||
SECTION("from start") {
|
||||
inja::Match match = inja::search(input, regex, 0);
|
||||
CHECK( match.found() == true );
|
||||
CHECK( match.position() == 6 );
|
||||
CHECK( match.length() == 5 );
|
||||
CHECK( match.end_position() == 11 );
|
||||
CHECK( match.str() == "ipsum" );
|
||||
CHECK( match.str(1) == "psu" );
|
||||
}
|
||||
|
||||
SECTION("from position") {
|
||||
inja::Match match = inja::search(input, regex, 8);
|
||||
CHECK( match.found() == false );
|
||||
CHECK( match.length() == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("search-multiple-regexes") {
|
||||
std::string input = "lorem ipsum dolor amit estas tronum.";
|
||||
|
||||
SECTION("basic 1") {
|
||||
std::map<int, inja::Regex> regex_patterns = {
|
||||
{0, inja::Regex("tras")},
|
||||
{1, inja::Regex("do(\\w*)or")},
|
||||
{2, inja::Regex("es(\\w*)as")},
|
||||
{3, inja::Regex("ip(\\w*)um")}
|
||||
};
|
||||
inja::MatchType<int> match = inja::search(input, regex_patterns, 0);
|
||||
CHECK( match.type() == 3 );
|
||||
CHECK( match.str() == "ipsum" );
|
||||
CHECK( match.str(1) == "s" );
|
||||
}
|
||||
|
||||
SECTION("basic 2") {
|
||||
std::map<int, inja::Regex> regex_patterns = {
|
||||
{11, inja::Regex("tras")},
|
||||
{21, inja::Regex("ip(\\w*)um")},
|
||||
{31, inja::Regex("do(\\w*)or")},
|
||||
{41, inja::Regex("es(\\w*)as")}
|
||||
};
|
||||
inja::MatchType<int> match = inja::search(input, regex_patterns, 0);
|
||||
CHECK( match.type() == 21 );
|
||||
CHECK( match.str() == "ipsum" );
|
||||
CHECK( match.str(1) == "s" );
|
||||
}
|
||||
|
||||
SECTION("basic 3") {
|
||||
auto map_functions = inja::Parser().regex_map_functions;
|
||||
std::map<int, inja::Regex> regex_patterns = {
|
||||
{0, map_functions.at(inja::Parsed::Function::Upper)},
|
||||
{1, map_functions.at(inja::Parsed::Function::Lower)},
|
||||
{2, map_functions.at(inja::Parsed::Function::ReadJson)}
|
||||
};
|
||||
|
||||
const std::string input_1 = "upper(name)";
|
||||
inja::MatchType<int> match = inja::search(input_1, regex_patterns, 0);
|
||||
CHECK( match.type() == 0 );
|
||||
CHECK( match.str(0) == "upper(name)" );
|
||||
CHECK( match.str(1) == "name" );
|
||||
|
||||
const std::string input_2 = "upper(lower(name))";
|
||||
inja::MatchType<int> match2 = inja::search(input_2, regex_patterns, 0);
|
||||
CHECK( match2.type() == 0 );
|
||||
CHECK( match2.str(0) == "upper(lower(name))" );
|
||||
CHECK( match2.str(1) == "lower(name)" );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("match-multiple-regexes") {
|
||||
std::string input = "ipsum";
|
||||
|
||||
SECTION("basic 1") {
|
||||
std::map<int, inja::Regex> regex_patterns = {
|
||||
{1, inja::Regex("tras")},
|
||||
{2, inja::Regex("ip(\\w*)um")},
|
||||
{3, inja::Regex("do(\\w*)or")},
|
||||
{4, inja::Regex("es(\\w*)as")}
|
||||
};
|
||||
inja::MatchType<int> match = inja::match(input, regex_patterns);
|
||||
CHECK( match.type() == 2 );
|
||||
CHECK( match.str() == "ipsum" );
|
||||
CHECK( match.str(1) == "s" );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("search-on-level") {
|
||||
std::string input = "(% up %)(% up %)Test(% N1 %)(% down %)...(% up %)(% N2 %)(% up %)(% N3 %)(% down %)(% N4 %)(% down %)(% N5 %)(% down %)";
|
||||
|
||||
inja::Regex regex_statement("\\(\\% (.*?) \\%\\)");
|
||||
inja::Regex regex_level_up("up");
|
||||
inja::Regex regex_level_down("down");
|
||||
inja::Regex regex_search("N(\\d+)");
|
||||
|
||||
SECTION("first instance") {
|
||||
inja::Match open_match = inja::search(input, regex_statement, 0);
|
||||
CHECK( open_match.position() == 0 );
|
||||
CHECK( open_match.end_position() == 8 );
|
||||
CHECK( open_match.str(1) == "up" );
|
||||
|
||||
inja::MatchClosed match = inja::search_closed_on_level(input, regex_statement, regex_level_up, regex_level_down, regex_search, open_match);
|
||||
CHECK( match.position() == 0 );
|
||||
CHECK( match.end_position() == 109 );
|
||||
}
|
||||
|
||||
SECTION("second instance") {
|
||||
inja::Match open_match = inja::search(input, regex_statement, 4);
|
||||
|
||||
CHECK( open_match.position() == 8 );
|
||||
CHECK( open_match.end_position() == 16 );
|
||||
CHECK( open_match.str(1) == "up" );
|
||||
|
||||
inja::MatchClosed match = inja::search_closed_on_level(input, regex_statement, regex_level_up, regex_level_down, regex_search, open_match);
|
||||
|
||||
CHECK( match.open_match.position() == 8 );
|
||||
CHECK( match.open_match.end_position() == 16 );
|
||||
CHECK( match.close_match.position() == 20 );
|
||||
CHECK( match.close_match.end_position() == 28 );
|
||||
CHECK( match.position() == 8 );
|
||||
CHECK( match.end_position() == 28 );
|
||||
CHECK( match.outer() == "(% up %)Test(% N1 %)" );
|
||||
CHECK( match.inner() == "Test" );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("match-functions") {
|
||||
auto map_regex = inja::Parser().regex_map_functions;
|
||||
|
||||
CHECK( inja::match("not test", map_regex).type() == inja::Parsed::Function::Not );
|
||||
CHECK( inja::match("not test", map_regex).type() != inja::Parsed::Function::And );
|
||||
CHECK( inja::match("2 == 3", map_regex).type() == inja::Parsed::Function::Equal );
|
||||
CHECK( inja::match("test and test", map_regex).type() == inja::Parsed::Function::And );
|
||||
CHECK( inja::match("test and test", map_regex).type() != inja::Parsed::Function::ReadJson );
|
||||
CHECK( inja::match("test", map_regex).type() == inja::Parsed::Function::ReadJson );
|
||||
CHECK( inja::match("upper", map_regex).type() == inja::Parsed::Function::ReadJson );
|
||||
CHECK( inja::match("upper()", map_regex).type() == inja::Parsed::Function::Upper );
|
||||
CHECK( inja::match("upper(var)", map_regex).type() == inja::Parsed::Function::Upper );
|
||||
CHECK( inja::match("upper( var )", map_regex).type() == inja::Parsed::Function::Upper );
|
||||
CHECK( inja::match("upper(lower())", map_regex).type() == inja::Parsed::Function::Upper );
|
||||
CHECK( inja::match("upper( lower() )", map_regex).type() == inja::Parsed::Function::Upper );
|
||||
CHECK( inja::match(" upper(lower()) ", map_regex).type() == inja::Parsed::Function::Upper );
|
||||
CHECK( inja::match("lower(upper(test))", map_regex).type() == inja::Parsed::Function::Lower );
|
||||
CHECK( inja::match("round(2, 3)", map_regex).type() == inja::Parsed::Function::Round );
|
||||
CHECK( inja::match("exists(\"var\")", map_regex).type() == inja::Parsed::Function::Exists );
|
||||
CHECK( inja::match("existsIn(var, \"othervar\")", map_regex).type() == inja::Parsed::Function::ExistsInObject );
|
||||
}
|
||||
|
||||
TEST_CASE("create-regex-functions") {
|
||||
CHECK( inja::Parser::function_regex("upper", 1).pattern() == "\\s*upper(?:\\((.*)\\))\\s*" );
|
||||
CHECK( inja::Parser::function_regex("upper", 0).pattern() == "\\s*upper(?:\\(\\))?\\s*" );
|
||||
CHECK( inja::Parser::function_regex("lower", 2).pattern() == "\\s*lower(?:\\((.*),(.*)\\))\\s*" );
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "catch/catch.hpp"
|
||||
#include "inja.hpp"
|
||||
#include "inja/inja.hpp"
|
||||
|
||||
|
||||
using json = nlohmann::json;
|
||||
@@ -11,7 +11,7 @@ TEST_CASE("loading") {
|
||||
data["name"] = "Jeff";
|
||||
|
||||
SECTION("Files should be loaded") {
|
||||
CHECK( env.load_global_file("../test/data/simple.txt") == "Hello {{ name }}." );
|
||||
CHECK( env.load_file("../test/data/simple.txt") == "Hello {{ name }}." );
|
||||
}
|
||||
|
||||
SECTION("Files should be rendered") {
|
||||
@@ -26,9 +26,9 @@ TEST_CASE("loading") {
|
||||
TEST_CASE("complete-files") {
|
||||
inja::Environment env = inja::Environment("../test/data/");
|
||||
|
||||
for (std::string test_name : {"simple-file", "nested", "nested-line"}) {
|
||||
for (std::string test_name : {"simple-file", "nested", "nested-line", "html"}) {
|
||||
SECTION(test_name) {
|
||||
CHECK( env.render_file_with_json_file(test_name + "/template.txt", test_name + "/data.json") == env.load_global_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") );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,6 @@ TEST_CASE("global-path") {
|
||||
|
||||
SECTION("Files should be written") {
|
||||
env.write("simple.txt", data, "global-path-result.txt");
|
||||
CHECK( env_result.load_global_file("global-path-result.txt") == "Hello Jeff." );
|
||||
CHECK( env_result.load_file("global-path-result.txt") == "Hello Jeff." );
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,18 @@
|
||||
#include "catch/catch.hpp"
|
||||
#include "inja.hpp"
|
||||
#include "inja/inja.hpp"
|
||||
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
TEST_CASE("dot-to-pointer") {
|
||||
std::string buffer;
|
||||
CHECK( inja::convert_dot_to_json_pointer("person.names.surname", buffer) == "/person/names/surname" );
|
||||
CHECK( inja::convert_dot_to_json_pointer("guests.2", buffer) == "/guests/2" );
|
||||
}
|
||||
|
||||
TEST_CASE("types") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
json data;
|
||||
data["name"] = "Peter";
|
||||
data["city"] = "Brunswick";
|
||||
@@ -34,11 +40,11 @@ TEST_CASE("types") {
|
||||
CHECK( env.render("{{name}}", data) == "Peter" );
|
||||
CHECK( env.render("{{ name }} is {{ age }} years old.", data) == "Peter is 29 years old." );
|
||||
CHECK( env.render("Hello {{ name }}! I come from {{ city }}.", data) == "Hello Peter! I come from Brunswick." );
|
||||
CHECK( env.render("Hello {{ names/1 }}!", data) == "Hello Seb!" );
|
||||
CHECK( env.render("Hello {{ brother/name }}!", data) == "Hello Chris!" );
|
||||
CHECK( env.render("Hello {{ brother/daughter0/name }}!", data) == "Hello Maria!" );
|
||||
CHECK( env.render("Hello {{ names.1 }}!", data) == "Hello Seb!" );
|
||||
CHECK( env.render("Hello {{ brother.name }}!", data) == "Hello Chris!" );
|
||||
CHECK( env.render("Hello {{ brother.daughter0.name }}!", data) == "Hello Maria!" );
|
||||
|
||||
CHECK_THROWS_WITH( env.render("{{unknown}}", data), "[inja.exception.render_error] variable '/unknown' not found" );
|
||||
CHECK_THROWS_WITH( env.render("{{unknown}}", data), "[inja.exception.render_error] variable 'unknown' not found" );
|
||||
}
|
||||
|
||||
SECTION("comments") {
|
||||
@@ -49,17 +55,17 @@ TEST_CASE("types") {
|
||||
SECTION("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 %}{{ type }}: {{ name }}, {% endfor %}", data) == "brother: Chris, mother: Maria, 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 loop/is_last == false %}, {% 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!" );
|
||||
|
||||
data["empty_loop"] = {};
|
||||
CHECK( env.render("{% for name in empty_loop %}a{% endfor %}", data) == "" );
|
||||
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] unknown loop statement: for name ins names" );
|
||||
CHECK_THROWS_WITH( env.render("{% for name ins names %}a{% endfor %}", data), "[inja.exception.parser_error] expected 'in', got 'ins'" );
|
||||
// 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" );
|
||||
}
|
||||
|
||||
@@ -77,25 +83,28 @@ TEST_CASE("types") {
|
||||
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] misordered if statement" );
|
||||
CHECK_THROWS_WITH( env.render("{% if is_happy %}{% else if is_happy %}{% end if %}", data), "[inja.exception.parser_error] misordered if statement" );
|
||||
CHECK_THROWS_WITH( env.render("{% if is_happy %}{% if is_happy %}{% endif %}", data), "[inja.exception.parser_error] unmatched if" );
|
||||
CHECK_THROWS_WITH( env.render("{% if is_happy %}{% else if is_happy %}{% end if %}", data), "[inja.exception.parser_error] expected statement, got 'end'" );
|
||||
}
|
||||
|
||||
SECTION("line statements") {
|
||||
CHECK( env.render(R"(## if is_happy
|
||||
Yeah!
|
||||
## endif)", data) == "Yeah!" );
|
||||
## endif)", data) == R"(Yeah!
|
||||
)" );
|
||||
|
||||
CHECK( env.render(R"(## if is_happy
|
||||
## if is_happy
|
||||
Yeah!
|
||||
## endif
|
||||
## endif )", data) == "Yeah!" );
|
||||
}
|
||||
## endif )", data) == R"(Yeah!
|
||||
)" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("functions") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
|
||||
json data;
|
||||
data["name"] = "Peter";
|
||||
@@ -206,7 +215,7 @@ TEST_CASE("functions") {
|
||||
CHECK( env.render("{{ default(nothing, 0) }}", data) == "0" );
|
||||
CHECK( env.render("{{ default(name, \"nobody\") }}", data) == "Peter" );
|
||||
CHECK( env.render("{{ default(surname, \"nobody\") }}", data) == "nobody" );
|
||||
CHECK_THROWS_WITH( env.render("{{ default(surname, lastname) }}", data), "[inja.exception.render_error] variable '/lastname' not found" );
|
||||
CHECK_THROWS_WITH( env.render("{{ default(surname, lastname) }}", data), "[inja.exception.render_error] variable 'lastname' not found" );
|
||||
}
|
||||
|
||||
SECTION("exists") {
|
||||
@@ -221,8 +230,8 @@ 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] variable '/sister' not found" );
|
||||
CHECK_THROWS_WITH( env.render("{{ existsIn(brother, sister) }}", data), "[inja.exception.render_error] variable '/sister' not found" );
|
||||
CHECK_THROWS_WITH( env.render("{{ existsIn(sister, \"lastname\") }}", data), "[inja.exception.render_error] variable 'sister' not found" );
|
||||
CHECK_THROWS_WITH( env.render("{{ existsIn(brother, sister) }}", data), "[inja.exception.render_error] variable 'sister' not found" );
|
||||
}
|
||||
|
||||
SECTION("isType") {
|
||||
@@ -243,40 +252,41 @@ TEST_CASE("functions") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("callbacks") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
json data;
|
||||
data["age"] = 28;
|
||||
|
||||
env.add_callback("double", 1, [&env](inja::Parsed::Arguments args, json data) {
|
||||
int number = env.get_argument<double>(args, 0, data);
|
||||
env.add_callback("double", 1, [](inja::Arguments& args) {
|
||||
int number = args.at(0)->get<double>();
|
||||
return 2 * number;
|
||||
});
|
||||
|
||||
env.add_callback("half", 1, [&env](inja::Parsed::Arguments args, json data) {
|
||||
int number = env.get_argument<double>(args, 0, data);
|
||||
env.add_callback("half", 1, [](inja::Arguments args) {
|
||||
int number = args.at(0)->get<double>();
|
||||
return number / 2;
|
||||
});
|
||||
|
||||
std::string greet = "Hello";
|
||||
env.add_callback("double-greetings", 0, [greet](inja::Parsed::Arguments args, json data) {
|
||||
env.add_callback("double-greetings", 0, [greet](inja::Arguments args) {
|
||||
return greet + " " + greet + "!";
|
||||
});
|
||||
|
||||
env.add_callback("multiply", 2, [&env](inja::Parsed::Arguments args, json data) {
|
||||
double number1 = env.get_argument(args, 0, data);
|
||||
auto number2 = env.get_argument<double>(args, 1, data);
|
||||
env.add_callback("multiply", 2, [](inja::Arguments args) {
|
||||
double number1 = args.at(0)->get<double>();
|
||||
auto number2 = args.at(1)->get<double>();
|
||||
return number1 * number2;
|
||||
});
|
||||
|
||||
env.add_callback("multiply", 3, [&env](inja::Parsed::Arguments args, json data) {
|
||||
double number1 = env.get_argument(args, 0, data);
|
||||
double number2 = env.get_argument(args, 1, data);
|
||||
double number3 = env.get_argument(args, 2, data);
|
||||
env.add_callback("multiply", 3, [](inja::Arguments args) {
|
||||
double number1 = args.at(0)->get<double>();
|
||||
double number2 = args.at(1)->get<double>();
|
||||
double number3 = args.at(2)->get<double>();
|
||||
return number1 * number2 * number3;
|
||||
});
|
||||
|
||||
env.add_callback("multiply", 0, [](inja::Parsed::Arguments args, json data) {
|
||||
env.add_callback("multiply", 0, [](inja::Arguments args) {
|
||||
return 1.0;
|
||||
});
|
||||
|
||||
@@ -289,8 +299,9 @@ TEST_CASE("callbacks") {
|
||||
CHECK( env.render("{{ multiply }}", data) == "1.0" );
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("combinations") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
json data;
|
||||
data["name"] = "Peter";
|
||||
data["city"] = "Brunswick";
|
||||
@@ -303,7 +314,7 @@ TEST_CASE("combinations") {
|
||||
|
||||
CHECK( env.render("{% if upper(\"Peter\") == \"PETER\" %}TRUE{% endif %}", data) == "TRUE" );
|
||||
CHECK( env.render("{% if lower(upper(name)) == \"peter\" %}TRUE{% endif %}", data) == "TRUE" );
|
||||
CHECK( env.render("{% for i in range(4) %}{{ loop/index1 }}{% endfor %}", data) == "1234" );
|
||||
CHECK( env.render("{% for i in range(4) %}{{ loop.index1 }}{% endfor %}", data) == "1234" );
|
||||
}
|
||||
|
||||
TEST_CASE("templates") {
|
||||
@@ -313,26 +324,27 @@ TEST_CASE("templates") {
|
||||
data["is_happy"] = true;
|
||||
|
||||
SECTION("reuse") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
inja::Template temp = env.parse("{% if is_happy %}{{ name }}{% else %}{{ city }}{% endif %}");
|
||||
|
||||
CHECK( env.render_template(temp, data) == "Peter" );
|
||||
CHECK( env.render(temp, data) == "Peter" );
|
||||
|
||||
data["is_happy"] = false;
|
||||
|
||||
CHECK( env.render_template(temp, data) == "Brunswick" );
|
||||
CHECK( env.render(temp, data) == "Brunswick" );
|
||||
}
|
||||
|
||||
SECTION("include") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
inja::Template t1 = env.parse("Hello {{ name }}");
|
||||
env.include_template("greeting", t1);
|
||||
|
||||
inja::Template t2 = env.parse("{% include \"greeting\" %}!");
|
||||
CHECK( env.render_template(t2, data) == "Hello Peter!" );
|
||||
CHECK( env.render(t2, data) == "Hello Peter!" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("other-syntax") {
|
||||
json data;
|
||||
data["name"] = "Peter";
|
||||
@@ -345,31 +357,31 @@ TEST_CASE("other-syntax") {
|
||||
data["is_happy"] = true;
|
||||
|
||||
SECTION("variables") {
|
||||
inja::Environment env = inja::Environment();
|
||||
env.set_element_notation(inja::ElementNotation::Dot);
|
||||
inja::Environment env;
|
||||
env.set_element_notation(inja::ElementNotation::Pointer);
|
||||
|
||||
CHECK( env.render("{{ name }}", data) == "Peter" );
|
||||
CHECK( env.render("Hello {{ names.1 }}!", data) == "Hello Seb!" );
|
||||
CHECK( env.render("Hello {{ brother.name }}!", data) == "Hello Chris!" );
|
||||
CHECK( env.render("Hello {{ brother.daughter0.name }}!", data) == "Hello Maria!" );
|
||||
CHECK( env.render("Hello {{ names/1 }}!", data) == "Hello Seb!" );
|
||||
CHECK( env.render("Hello {{ brother/name }}!", data) == "Hello Chris!" );
|
||||
CHECK( env.render("Hello {{ brother/daughter0/name }}!", data) == "Hello Maria!" );
|
||||
|
||||
CHECK_THROWS_WITH( env.render("{{unknown.name}}", data), "[inja.exception.render_error] variable '/unknown/name' not found" );
|
||||
CHECK_THROWS_WITH( env.render("{{unknown/name}}", data), "[inja.exception.render_error] variable 'unknown/name' not found" );
|
||||
}
|
||||
|
||||
SECTION("other expression syntax") {
|
||||
inja::Environment env = inja::Environment();
|
||||
inja::Environment env;
|
||||
|
||||
CHECK( env.render("Hello {{ name }}!", data) == "Hello Peter!" );
|
||||
|
||||
env.set_expression("\\(&", "&\\)");
|
||||
env.set_expression("(&", "&)");
|
||||
|
||||
CHECK( env.render("Hello {{ name }}!", data) == "Hello {{ name }}!" );
|
||||
CHECK( env.render("Hello (& name &)!", data) == "Hello Peter!" );
|
||||
}
|
||||
|
||||
SECTION("other comment syntax") {
|
||||
inja::Environment env = inja::Environment();
|
||||
env.set_comment("\\(&", "&\\)");
|
||||
inja::Environment env;
|
||||
env.set_comment("(&", "&)");
|
||||
|
||||
CHECK( env.render("Hello {# Test #}", data) == "Hello {# Test #}" );
|
||||
CHECK( env.render("Hello (& Test &)", data) == "Hello " );
|
||||
File renamed without changes.
Reference in new issue
Block a user