Team Ai
Datasetpublic

echodict/llama.cpp

version https://git-lfs.github.com/spec/v1 oid sha256:cfc44b7ba25614df70e6b65e3341cae0310163bd32fd31a6b928a542df433faf size 30786

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes479downloads
test-jinja.cpp2515 linesDownload Raw Back to tests
1#include <string>2#include <iostream>3#include <random>4#include <cstdlib>5 6#include <nlohmann/json.hpp>7#include <sheredom/subprocess.h>8 9#include "jinja/runtime.h"10#include "jinja/parser.h"11#include "jinja/lexer.h"12#include "jinja/utils.h"13 14#include "testing.h"15 16using json = nlohmann::ordered_json;17 18static void test_template(testing & t, const std::string & name, const std::string & tmpl, const json & vars, const std::string & expect);19 20static void test_whitespace_control(testing & t);21static void test_conditionals(testing & t);22static void test_loops(testing & t);23static void test_expressions(testing & t);24static void test_set_statement(testing & t);25static void test_filters(testing & t);26static void test_literals(testing & t);27static void test_comments(testing & t);28static void test_macros(testing & t);29static void test_namespace(testing & t);30static void test_tests(testing & t);31static void test_string_methods(testing & t);32static void test_array_methods(testing & t);33static void test_object_methods(testing & t);34static void test_hasher(testing & t);35static void test_stats(testing & t);36static void test_fuzzing(testing & t);37 38static bool g_python_mode = false;39 40int main(int argc, char *argv[]) {41    testing t(std::cout);42    t.verbose = true;43 44    // usage: test-jinja [-py] [filter_regex]45    //  -py : enable python mode (use python jinja2 for rendering expected output)46    //        only use this for cross-checking, not for correctness47    //        note: the implementation of this flag is basic, only intented to be used by maintainers48 49    for (int i = 1; i < argc; i++) {50        std::string arg = argv[i];51        if (arg == "-py") {52            g_python_mode = true;53        } else {54            t.set_filter(arg);55        }56    }57 58    t.test("whitespace control", test_whitespace_control);59    t.test("conditionals", test_conditionals);60    t.test("loops", test_loops);61    t.test("expressions", test_expressions);62    t.test("set statement", test_set_statement);63    t.test("filters", test_filters);64    t.test("literals", test_literals);65    t.test("comments", test_comments);66    t.test("macros", test_macros);67    t.test("namespace", test_namespace);68    t.test("tests", test_tests);69    t.test("string methods", test_string_methods);70    t.test("array methods", test_array_methods);71    t.test("object methods", test_object_methods);72    if (!g_python_mode) {73        t.test("hasher", test_hasher);74        t.test("stats", test_stats);75        t.test("fuzzing", test_fuzzing);76    }77 78    return t.summary();79}80 81static void test_whitespace_control(testing & t) {82    test_template(t, "trim_blocks removes newline after tag",83        "{% if true %}\n"84        "hello\n"85        "{% endif %}\n",86        json::object(),87        "hello\n"88    );89 90    test_template(t, "lstrip_blocks removes leading whitespace",91        "    {% if true %}\n"92        "    hello\n"93        "    {% endif %}\n",94        json::object(),95        "    hello\n"96    );97 98    test_template(t, "for loop with trim_blocks",99        "{% for i in items %}\n"100        "{{ i }}\n"101        "{% endfor %}\n",102        {{"items", json::array({1, 2, 3})}},103        "1\n2\n3\n"104    );105 106    test_template(t, "explicit strip both",107        "  {%- if true -%}  \n"108        "hello\n"109        "  {%- endif -%}  \n",110        json::object(),111        "hello"112    );113 114    test_template(t, "expression whitespace control",115        "  {{- 'hello' -}}  \n",116        json::object(),117        "hello"118    );119 120    test_template(t, "inline block no newline",121        "{% if true %}yes{% endif %}",122        json::object(),123        "yes"124    );125}126 127static void test_conditionals(testing & t) {128    test_template(t, "if true",129        "{% if cond %}yes{% endif %}",130        {{"cond", true}},131        "yes"132    );133 134    test_template(t, "if false",135        "{% if cond %}yes{% endif %}",136        {{"cond", false}},137        ""138    );139 140    test_template(t, "if else",141        "{% if cond %}yes{% else %}no{% endif %}",142        {{"cond", false}},143        "no"144    );145 146    test_template(t, "if elif else",147        "{% if a %}A{% elif b %}B{% else %}C{% endif %}",148        {{"a", false}, {"b", true}},149        "B"150    );151 152    test_template(t, "nested if",153        "{% if outer %}{% if inner %}both{% endif %}{% endif %}",154        {{"outer", true}, {"inner", true}},155        "both"156    );157 158    test_template(t, "comparison operators",159        "{% if x > 5 %}big{% endif %}",160        {{"x", 10}},161        "big"162    );163 164    test_template(t, "object comparison",165        "{% if {0: 1, none: 2, 1.0: 3, '0': 4, true: 5} == {false: 1, none: 2, 1: 5, '0': 4} %}equal{% endif %}",166        json::object(),167        "equal"168    );169 170    test_template(t, "array comparison",171        "{% if [0, 1.0, false] == [false, 1, 0.0] %}equal{% endif %}",172        json::object(),173        "equal"174    );175 176    test_template(t, "logical and",177        "{% if a and b %}both{% endif %}",178        {{"a", true}, {"b", true}},179        "both"180    );181 182    test_template(t, "logical or",183        "{% if a or b %}either{% endif %}",184        {{"a", false}, {"b", true}},185        "either"186    );187 188    test_template(t, "logical not",189        "{% if not a %}negated{% endif %}",190        {{"a", false}},191        "negated"192    );193 194    test_template(t, "in operator (element in array)",195        "{% if 'x' in items %}found{% endif %}",196        {{"items", json::array({"x", "y"})}},197        "found"198    );199 200    test_template(t, "in operator (substring)",201        "{% if 'bc' in 'abcd' %}found{% endif %}",202        json::object(),203        "found"204    );205 206    test_template(t, "in operator (object key)",207        "{% if 'key' in obj %}found{% endif %}",208        {{"obj", {{"key", 1}, {"other", 2}}}},209        "found"210    );211 212    test_template(t, "is defined",213        "{% if x is defined %}yes{% else %}no{% endif %}",214        {{"x", 1}},215        "yes"216    );217 218    test_template(t, "is not defined",219        "{% if y is not defined %}yes{% else %}no{% endif %}",220        json::object(),221        "yes"222    );223 224    test_template(t, "is undefined falsy",225        "{{ 'yes' if not y else 'no' }}",226        json::object(),227        "yes"228    );229 230    test_template(t, "is undefined attribute falsy",231        "{{ 'yes' if not y.x else 'no' }}",232        {{"y", true}},233        "yes"234    );235 236    test_template(t, "is undefined key falsy",237        "{{ 'yes' if not y['x'] else 'no' }}",238        {{"y", {{}}}},239        "yes"240    );241 242    test_template(t, "is empty array falsy",243        "{{ 'yes' if not y else 'no' }}",244        {{"y", json::array()}},245        "yes"246    );247 248    test_template(t, "is empty object falsy",249        "{{ 'yes' if not y else 'no' }}",250        {{"y", json::object()}},251        "yes"252    );253 254    test_template(t, "is empty string falsy",255        "{{ 'yes' if not y else 'no' }}",256        {{"y", ""}},257        "yes"258    );259 260    test_template(t, "is 0 falsy",261        "{{ 'yes' if not y else 'no' }}",262        {{"y", 0}},263        "yes"264    );265 266    test_template(t, "is 0.0 falsy",267        "{{ 'yes' if not y else 'no' }}",268        {{"y", 0.0}},269        "yes"270    );271 272    test_template(t, "is non-empty array truthy",273        "{{ 'yes' if y else 'no' }}",274        {{"y", json::array({""})}},275        "yes"276    );277 278    test_template(t, "is non-empty object truthy",279        "{{ 'yes' if y else 'no' }}",280        {{"y", {"x", false}}},281        "yes"282    );283 284    test_template(t, "is non-empty string truthy",285        "{{ 'yes' if y else 'no' }}",286        {{"y", "0"}},287        "yes"288    );289 290    test_template(t, "is 1 truthy",291        "{{ 'yes' if y else 'no' }}",292        {{"y", 1}},293        "yes"294    );295 296    test_template(t, "is 1.0 truthy",297        "{{ 'yes' if y else 'no' }}",298        {{"y", 1.0}},299        "yes"300    );301}302 303static void test_loops(testing & t) {304    test_template(t, "simple for",305        "{% for i in items %}{{ i }}{% endfor %}",306        {{"items", json::array({1, 2, 3})}},307        "123"308    );309 310    test_template(t, "loop.index",311        "{% for i in items %}{{ loop.index }}{% endfor %}",312        {{"items", json::array({"a", "b", "c"})}},313        "123"314    );315 316    test_template(t, "loop.index0",317        "{% for i in items %}{{ loop.index0 }}{% endfor %}",318        {{"items", json::array({"a", "b", "c"})}},319        "012"320    );321 322    test_template(t, "loop.first and loop.last",323        "{% for i in items %}{% if loop.first %}[{% endif %}{{ i }}{% if loop.last %}]{% endif %}{% endfor %}",324        {{"items", json::array({1, 2, 3})}},325        "[123]"326    );327 328    test_template(t, "loop.length",329        "{% for i in items %}{{ loop.length }}{% endfor %}",330        {{"items", json::array({"a", "b"})}},331        "22"332    );333 334    test_template(t, "for over dict items",335        "{% for k, v in data.items() %}{{ k }}={{ v }} {% endfor %}",336        {{"data", {{"x", 1}, {"y", 2}}}},337        "x=1 y=2 "338    );339 340    test_template(t, "for else empty",341        "{% for i in items %}{{ i }}{% else %}empty{% endfor %}",342        {{"items", json::array()}},343        "empty"344    );345 346    test_template(t, "for undefined empty",347        "{% for i in items %}{{ i }}{% else %}empty{% endfor %}",348        json::object(),349        "empty"350    );351 352    test_template(t, "nested for",353        "{% for i in a %}{% for j in b %}{{ i }}{{ j }}{% endfor %}{% endfor %}",354        {{"a", json::array({1, 2})}, {"b", json::array({"x", "y"})}},355        "1x1y2x2y"356    );357 358    test_template(t, "for with range",359        "{% for i in range(3) %}{{ i }}{% endfor %}",360        json::object(),361        "012"362    );363}364 365static void test_expressions(testing & t) {366    test_template(t, "simple variable",367        "{{ x }}",368        {{"x", 42}},369        "42"370    );371 372    test_template(t, "dot notation",373        "{{ user.name }}",374        {{"user", {{"name", "Bob"}}}},375        "Bob"376    );377 378    test_template(t, "negative float (not dot notation)",379        "{{ -1.0 }}",380        json::object(),381        "-1.0"382    );383 384    test_template(t, "bracket notation",385        "{{ user['name'] }}",386        {{"user", {{"name", "Bob"}}}},387        "Bob"388    );389 390    test_template(t, "empty computed member defaults to undefined",391        "{{ a[]|default('fallback') }}",392        {{"a", {{"name", "Bob"}}}},393        "fallback"394    );395 396    test_template(t, "empty computed member is undefined",397        "{{ a[] is undefined }}",398        {{"a", {{"name", "Bob"}}}},399        "True"400    );401 402    test_template(t, "undefined computed member is undefined",403        "{{ a[undefined] is undefined }}",404        {{"a", {{"name", "Bob"}}}},405        "True"406    );407 408    test_template(t, "array access",409        "{{ items[1] }}",410        {{"items", json::array({"a", "b", "c"})}},411        "b"412    );413 414    test_template(t, "array negative access",415        "{{ items[-1] }}",416        {{"items", json::array({"a", "b", "c"})}},417        "c"418    );419 420    test_template(t, "array slice",421        "{{ items[1:-1]|string }}",422        {{"items", json::array({"a", "b", "c"})}},423        "['b']"424    );425 426    test_template(t, "array slice step",427        "{{ items[::2]|string }}",428        {{"items", json::array({"a", "b", "c"})}},429        "['a', 'c']"430    );431 432    test_template(t, "tuple slice",433        "{{ ('a', 'b', 'c')[::-1]|string }}",434        json::object(),435        "('c', 'b', 'a')"436    );437 438    test_template(t, "arithmetic",439        "{{ (a + b) * c }}",440        {{"a", 2}, {"b", 3}, {"c", 4}},441        "20"442    );443 444    test_template(t, "string concat ~",445        "{{ 'hello' ~ ' ' ~ 'world' }}",446        json::object(),447        "hello world"448    );449 450    test_template(t, "string repetition",451        "{{ 'ab' * 3 }}",452        json::object(),453        "ababab"454    );455 456    test_template(t, "reversed string repetition",457        "{{ 3 * 'ab' }}",458        json::object(),459        "ababab"460    );461 462    test_template(t, "ternary",463        "{{ 'yes' if cond else 'no' }}",464        {{"cond", true}},465        "yes"466    );467}468 469static void test_set_statement(testing & t) {470    test_template(t, "simple set",471        "{% set x = 5 %}{{ x }}",472        json::object(),473        "5"474    );475 476    test_template(t, "set with expression",477        "{% set x = a + b %}{{ x }}",478        {{"a", 10}, {"b", 20}},479        "30"480    );481 482    test_template(t, "set list",483        "{% set items = [1, 2, 3] %}{{ items|length }}",484        json::object(),485        "3"486    );487 488    test_template(t, "set dict",489        "{% set d = {'a': 1} %}{{ d.a }}",490        json::object(),491        "1"492    );493 494    test_template(t, "set dict with mixed type keys",495        "{% set d = {0: 1, none: 2, 1.0: 3, '0': 4, (0, 0): 5, false: 6, 1: 7} %}{{ d[(0, 0)] + d[0] + d[none] + d['0'] + d[false] + d[1.0] + d[1] }}",496        json::object(),497        "37"498    );499 500    test_template(t, "print dict with mixed type keys",501        "{% set d = {0: 1, none: 2, 1.0: 3, '0': 4, (0, 0): 5, true: 6} %}{{ d|string }}",502        json::object(),503        "{0: 1, None: 2, 1.0: 6, '0': 4, (0, 0): 5}"504    );505 506    test_template(t, "print array with mixed types",507        "{% set d = [0, none, 1.0, '0', true, (0, 0)] %}{{ d|string }}",508        json::object(),509        "[0, None, 1.0, '0', True, (0, 0)]"510    );511 512    test_template(t, "object member assignment with mixed key types",513        "{% set d = namespace() %}{% set d.a = 123 %}{{ d['a'] == 123 }}",514        json::object(),515        "True"516    );517 518    test_template(t, "tuple unpacking",519        "{% set t = (1, 2, 3) %}{% set a, b, c = t %}{{ a + b + c }}",520        json::object(),521        "6"522    );523}524 525static void test_filters(testing & t) {526    test_template(t, "upper",527        "{{ 'hello'|upper }}",528        json::object(),529        "HELLO"530    );531 532    test_template(t, "lower",533        "{{ 'HELLO'|lower }}",534        json::object(),535        "hello"536    );537 538    test_template(t, "upper array",539        "{{ items|upper }}",540        {{"items", json::array({"hello", "world"})}},541        "['HELLO', 'WORLD']"542    );543 544    test_template(t, "upper dict",545        "{{ items|upper }}",546        {{"items", {{"hello", "world"}}}},547        "{'HELLO': 'WORLD'}"548    );549 550    test_template(t, "capitalize",551        "{{ 'heLlo World'|capitalize }}",552        json::object(),553        "Hello world"554    );555 556    test_template(t, "title",557        "{{ 'hello world'|title }}",558        json::object(),559        "Hello World"560    );561 562    test_template(t, "trim",563        "{{ '  \r\n\thello\t\n\r  '|trim }}",564        json::object(),565        "hello"566    );567 568    test_template(t, "trim chars",569        "{{ 'xyxhelloxyx'|trim('xy') }}",570        json::object(),571        "hello"572    );573 574    test_template(t, "length string",575        "{{ 'hello'|length }}",576        json::object(),577        "5"578    );579 580    test_template(t, "replace",581        "{{ 'hello world'|replace('world', 'jinja') }}",582        json::object(),583        "hello jinja"584    );585 586    test_template(t, "length list",587        "{{ items|length }}",588        {{"items", json::array({1, 2, 3})}},589        "3"590    );591 592    test_template(t, "first",593        "{{ items|first }}",594        {{"items", json::array({10, 20, 30})}},595        "10"596    );597 598    test_template(t, "last",599        "{{ items|last }}",600        {{"items", json::array({10, 20, 30})}},601        "30"602    );603 604    test_template(t, "reverse",605        "{% for i in items|reverse %}{{ i }}{% endfor %}",606        {{"items", json::array({1, 2, 3})}},607        "321"608    );609 610    test_template(t, "sort",611        "{% for i in items|sort %}{{ i }}{% endfor %}",612        {{"items", json::array({3, 1, 2})}},613        "123"614    );615 616    test_template(t, "sort reverse",617        "{% for i in items|sort(true) %}{{ i }}{% endfor %}",618        {{"items", json::array({3, 1, 2})}},619        "321"620    );621 622    test_template(t, "sort with attribute",623        "{{ items|sort(attribute='name')|join(attribute='age') }}",624        {{"items", json::array({625            json({{"name", "c"}, {"age", 3}}),626            json({{"name", "a"}, {"age", 1}}),627            json({{"name", "b"}, {"age", 2}}),628        })}},629        "123"630    );631 632    test_template(t, "sort with numeric attribute",633        "{{ items|sort(attribute=0)|join(attribute=1) }}",634        {{"items", json::array({635            json::array({3, "z"}),636            json::array({1, "x"}),637            json::array({2, "y"}),638        })}},639        "xyz"640    );641 642    test_template(t, "join",643        "{{ items|join(', ') }}",644        {{"items", json::array({"a", "b", "c"})}},645        "a, b, c"646    );647 648    test_template(t, "join default separator",649        "{{ items|join }}",650        {{"items", json::array({"x", "y", "z"})}},651        "xyz"652    );653 654    test_template(t, "abs",655        "{{ -5|abs }}",656        json::object(),657        "5"658    );659 660    test_template(t, "int from string",661        "{{ '42'|int }}",662        json::object(),663        "42"664    );665 666    test_template(t, "int from string with default",667        "{{ ''|int(1) }}",668        json::object(),669        "1"670    );671 672    test_template(t, "int from string with base",673        "{{ '11'|int(base=2) }}",674        json::object(),675        "3"676    );677 678    test_template(t, "float from string",679        "{{ '3.14'|float }}",680        json::object(),681        "3.14"682    );683 684    test_template(t, "default with value",685        "{{ x|default('fallback') }}",686        {{"x", "actual"}},687        "actual"688    );689 690    test_template(t, "default without value",691        "{{ y|default('fallback') }}",692        json::object(),693        "fallback"694    );695 696    test_template(t, "default with falsy value",697        "{{ ''|default('fallback', true) }}",698        json::object(),699        "fallback"700    );701 702    test_template(t, "tojson ensure_ascii=true",703        "{{ data|tojson(ensure_ascii=true) }}",704        {{"data", "\u2713"}},705        "\"\\u2713\""706    );707 708    test_template(t, "tojson ensure_ascii=true nested object",709        "{{ data|tojson(ensure_ascii=true) }}",710        {{"data", {711            {"text", "\u2713"},712            {"items", json::array({"รฉ", {{"snowman", "โ˜ƒ"}}})}713        }}},714        "{\"text\": \"\\u2713\", \"items\": [\"\\u00e9\", {\"snowman\": \"\\u2603\"}]}"715    );716 717    test_template(t, "tojson ensure_ascii=true indent=2",718        "{{ data|tojson(ensure_ascii=true, indent=2) }}",719        {{"data", {720            {"text", "\u2713"},721            {"nested", {{"accent", "รฉ"}}}722        }}},723        "{\n  \"text\": \"\\u2713\",\n  \"nested\": {\n    \"accent\": \"\\u00e9\"\n  }\n}"724    );725 726    test_template(t, "tojson ensure_ascii=true preserves existing escapes",727        "{{ data|tojson(ensure_ascii=true) }}",728        {{"data", {729            {"emoji", "๐Ÿ˜€"},730            {"line", "a\nb"}731        }}},732        "{\"emoji\": \"\\ud83d\\ude00\", \"line\": \"a\\nb\"}"733    );734 735    test_template(t, "tojson sort_keys=true",736        "{{ data|tojson(sort_keys=true) }}",737        {{"data", {{"b", 2}, {"a", 1}}}},738        "{\"a\": 1, \"b\": 2}"739    );740 741    test_template(t, "tojson",742        "{{ data|tojson }}",743        {{"data", {{"a", 1}, {"b", json::array({1, 2})}}}},744        "{\"a\": 1, \"b\": [1, 2]}"745    );746 747    test_template(t, "tojson indent=4",748        "{{ data|tojson(indent=4) }}",749        {{"data", {{"a", 1}, {"b", json::array({1, 2})}}}},750        "{\n    \"a\": 1,\n    \"b\": [\n        1,\n        2\n    ]\n}"751    );752 753    test_template(t, "tojson separators=(',',':')",754        "{{ data|tojson(separators=(',',':')) }}",755        {{"data", {{"a", 1}, {"b", json::array({1, 2})}}}},756        "{\"a\":1,\"b\":[1,2]}"757    );758 759    test_template(t, "tojson separators=(',',': ') indent=2",760        "{{ data|tojson(separators=(',',': '), indent=2) }}",761        {{"data", {{"a", 1}, {"b", json::array({1, 2})}}}},762        "{\n  \"a\": 1,\n  \"b\": [\n    1,\n    2\n  ]\n}"763    );764 765    test_template(t, "indent",766        "{{ data|indent(2) }}",767        {{ "data", "foo\nbar" }},768        "foo\n  bar"769    );770 771    test_template(t, "indent first only",772        "{{ data|indent(width=3,first=true) }}",773        {{ "data", "foo\nbar" }},774        "   foo\n   bar"775    );776 777    test_template(t, "indent blank lines and first line",778        "{{ data|indent(width=5,blank=true,first=true) }}",779        {{ "data", "foo\n\nbar" }},780        "     foo\n     \n     bar"781    );782 783    test_template(t, "indent with default width",784        "{{ data|indent() }}",785        {{ "data", "foo\nbar" }},786        "foo\n    bar"787    );788 789    test_template(t, "indent with no newline",790        "{{ data|indent }}",791        {{ "data", "foo" }},792        "foo"793    );794 795    test_template(t, "indent with trailing newline",796        "{{ data|indent(blank=true) }}",797        {{ "data", "foo\n" }},798        "foo\n    "799    );800 801    test_template(t, "indent with string",802        "{{ data|indent(width='>>>>') }}",803        {{ "data", "foo\nbar" }},804        "foo\n>>>>bar"805    );806 807    test_template(t, "chained filters",808        "{{ '  HELLO  '|trim|lower }}",809        json::object(),810        "hello"811    );812 813    test_template(t, "int filter on integer is identity",814        "{{ value|int }}",815        {{"value", 7}},816        "7"817    );818 819    test_template(t, "none to string",820        "{{ x|string }}",821        {{"x", nullptr}},822        "None"823    );824}825 826static void test_literals(testing & t) {827    test_template(t, "integer",828        "{{ 42 }}",829        json::object(),830        "42"831    );832 833    test_template(t, "float",834        "{{ 3.14 }}",835        json::object(),836        "3.14"837    );838 839    test_template(t, "string",840        "{{ 'hello' }}",841        json::object(),842        "hello"843    );844 845    test_template(t, "boolean true",846        "{{ true }}",847        json::object(),848        "True"849    );850 851    test_template(t, "boolean false",852        "{{ false }}",853        json::object(),854        "False"855    );856 857    test_template(t, "none",858        "{% if x is none %}null{% endif %}",859        {{"x", nullptr}},860        "null"861    );862 863    test_template(t, "list literal",864        "{% for i in [1, 2, 3] %}{{ i }}{% endfor %}",865        json::object(),866        "123"867    );868 869    test_template(t, "dict literal",870        "{% set d = {'a': 1} %}{{ d.a }}",871        json::object(),872        "1"873    );874 875    test_template(t, "integer|abs",876        "{{ -42 | abs }}",877        json::object(),878        "42"879    );880 881    test_template(t, "integer|float",882        "{{ 42 | float }}",883        json::object(),884        "42.0"885    );886 887    test_template(t, "integer|tojson",888        "{{ 42 | tojson }}",889        json::object(),890        "42"891    );892 893    test_template(t, "float|abs",894        "{{ -3.14 | abs }}",895        json::object(),896        "3.14"897    );898 899    test_template(t, "float|int",900        "{{ 3.14 | int }}",901        json::object(),902        "3"903    );904 905    test_template(t, "float|tojson",906        "{{ 3.14 | tojson }}",907        json::object(),908        "3.14"909    );910 911    test_template(t, "string|tojson",912        "{{ 'hello' | tojson }}",913        json::object(),914        "\"hello\""915    );916 917    test_template(t, "boolean|int",918        "{{ true | int }}",919        json::object(),920        "1"921    );922 923    test_template(t, "boolean|float",924        "{{ true | float }}",925        json::object(),926        "1.0"927    );928 929    test_template(t, "boolean|tojson",930        "{{ true | tojson }}",931        json::object(),932        "true"933    );934}935 936static void test_comments(testing & t) {937    test_template(t, "inline comment",938        "before{# comment #}after",939        json::object(),940        "beforeafter"941    );942 943    test_template(t, "comment ignores code",944        "{% set x = 1 %}{# {% set x = 999 %} #}{{ x }}",945        json::object(),946        "1"947    );948}949 950static void test_macros(testing & t) {951    test_template(t, "simple macro",952        "{% macro greet(name) %}Hello {{ name }}{% endmacro %}{{ greet('World') }}",953        json::object(),954        "Hello World"955    );956 957    test_template(t, "macro default arg",958        "{% macro greet(name='Guest') %}Hi {{ name }}{% endmacro %}{{ greet() }}",959        json::object(),960        "Hi Guest"961    );962 963    test_template(t, "macro kwargs input",964        "{% macro my_func(a, b=False) %}{% if b %}{{ a }}{% else %}nope{% endif %}{% endmacro %}{{ my_func(1, b=True) }}",965        json::object(),966        "1"967    );968 969    test_template(t, "macro with multiple args",970        "{% macro add(a, b, c=0) %}{{ a + b + c }}{% endmacro %}{{ add(1, 2) }},{{ add(1, 2, 3) }},{{ add(1, b=10) }},{{ add(1, 2, c=5) }}",971        json::object(),972        "3,6,11,8"973    );974 975    test_template(t, "macro with kwarg out-of-order input",976        "{% macro greet(first, last, greeting='Hello') %}{{ greeting }}, {{ first }} {{ last }}{% endmacro %}{{ greet(last='Smith', first='John') }},{{ greet(last='Doe', greeting='Hi', first='Jane') }}",977        json::object(),978        "Hello, John Smith,Hi, Jane Doe"979    );980}981 982static void test_namespace(testing & t) {983    test_template(t, "namespace counter",984        "{% set ns = namespace(count=0) %}{% for i in range(3) %}{% set ns.count = ns.count + 1 %}{% endfor %}{{ ns.count }}",985        json::object(),986        "3"987    );988}989 990static void test_tests(testing & t) {991    test_template(t, "is odd",992        "{% if 3 is odd %}yes{% endif %}",993        json::object(),994        "yes"995    );996 997    test_template(t, "is even",998        "{% if 4 is even %}yes{% endif %}",999        json::object(),1000        "yes"1001    );1002 1003    test_template(t, "is false",1004        "{{ 'yes' if x is false }}",1005        {{"x", false}},1006        "yes"1007    );1008 1009    test_template(t, "is true",1010        "{{ 'yes' if x is true }}",1011        {{"x", true}},1012        "yes"1013    );1014 1015    test_template(t, "string is false",1016        "{{ 'yes' if x is false else 'no' }}",1017        {{"x", ""}},1018        "no"1019    );1020 1021    test_template(t, "is divisibleby",1022        "{{ 'yes' if x is divisibleby(2) }}",1023        {{"x", 2}},1024        "yes"1025    );1026 1027    test_template(t, "is eq",1028        "{{ 'yes' if 3 is eq(3) }}",1029        json::object(),1030        "yes"1031    );1032 1033    test_template(t, "is not equalto",1034        "{{ 'yes' if 3 is not equalto(4) }}",1035        json::object(),1036        "yes"1037    );1038 1039    test_template(t, "is ge",1040        "{{ 'yes' if 3 is ge(3) }}",1041        json::object(),1042        "yes"1043    );1044 1045    test_template(t, "is gt",1046        "{{ 'yes' if 3 is gt(2) }}",1047        json::object(),1048        "yes"1049    );1050 1051    test_template(t, "is greaterthan",1052        "{{ 'yes' if 3 is greaterthan(2) }}",1053        json::object(),1054        "yes"1055    );1056 1057    test_template(t, "is lt",1058        "{{ 'yes' if 2 is lt(3) }}",1059        json::object(),1060        "yes"1061    );1062 1063    test_template(t, "is lessthan",1064        "{{ 'yes' if 2 is lessthan(3) }}",1065        json::object(),1066        "yes"1067    );1068 1069    test_template(t, "is ne",1070        "{{ 'yes' if 2 is ne(3) }}",1071        json::object(),1072        "yes"1073    );1074 1075    test_template(t, "is lower",1076        "{{ 'yes' if 'lowercase' is lower }}",1077        json::object(),1078        "yes"1079    );1080 1081    test_template(t, "is upper",1082        "{{ 'yes' if 'UPPERCASE' is upper }}",1083        json::object(),1084        "yes"1085    );1086 1087    test_template(t, "is sameas",1088        "{{ 'yes' if x is sameas(false) }}",1089        {{"x", false}},1090        "yes"1091    );1092 1093    test_template(t, "is boolean",1094        "{{ 'yes' if x is boolean }}",1095        {{"x", true}},1096        "yes"1097    );1098 1099    test_template(t, "is callable",1100        "{{ 'yes' if ''.strip is callable }}",1101        json::object(),1102        "yes"1103    );1104 1105    test_template(t, "is escaped",1106        "{{ 'yes' if 'foo'|safe is escaped }}",1107        json::object(),1108        "yes"1109    );1110 1111    test_template(t, "is filter",1112        "{{ 'yes' if 'trim' is filter }}",1113        json::object(),1114        "yes"1115    );1116 1117    test_template(t, "is float",1118        "{{ 'yes' if x is float }}",1119        {{"x", 1.1}},1120        "yes"1121    );1122 1123    test_template(t, "is integer",1124        "{{ 'yes' if x is integer }}",1125        {{"x", 1}},1126        "yes"1127    );1128 1129    test_template(t, "is sequence",1130        "{{ 'yes' if x is sequence }}",1131        {{"x", json::array({1, 2, 3})}},1132        "yes"1133    );1134 1135    test_template(t, "is test",1136        "{{ 'yes' if 'sequence' is test }}",1137        json::object(),1138        "yes"1139    );1140 1141    test_template(t, "is undefined",1142        "{{ 'yes' if x is undefined }}",1143        json::object(),1144        "yes"1145    );1146 1147    test_template(t, "is none",1148        "{% if x is none %}yes{% endif %}",1149        {{"x", nullptr}},1150        "yes"1151    );1152 1153    test_template(t, "is string",1154        "{% if x is string %}yes{% endif %}",1155        {{"x", "hello"}},1156        "yes"1157    );1158 1159    test_template(t, "is number",1160        "{% if x is number %}yes{% endif %}",1161        {{"x", 42}},1162        "yes"1163    );1164 1165    test_template(t, "is iterable",1166        "{% if x is iterable %}yes{% endif %}",1167        {{"x", json::array({1, 2, 3})}},1168        "yes"1169    );1170 1171    test_template(t, "is mapping",1172        "{% if x is mapping %}yes{% endif %}",1173        {{"x", {{"a", 1}}}},1174        "yes"1175    );1176 1177    test_template(t, "undefined is sequence",1178        "{{ 'yes' if x is sequence }}",1179        json::object(),1180        "yes"1181    );1182 1183    test_template(t, "undefined is iterable",1184        "{{ 'yes' if x is iterable }}",1185        json::object(),1186        "yes"1187    );1188 1189    test_template(t, "is in (array, true)",1190        "{{ 'yes' if 2 is in([1, 2, 3]) }}",1191        json::object(),1192        "yes"1193    );1194 1195    test_template(t, "is in (array, false)",1196        "{{ 'yes' if 5 is in([1, 2, 3]) else 'no' }}",1197        json::object(),1198        "no"1199    );1200 

Showing the first 1,200 of 2515 lines. Download the file for the rest.