Home | History | Annotate | Line # | Download | only in text
templates_test.cpp revision 1.1
      1  1.1  jmmv // Copyright 2012 Google Inc.
      2  1.1  jmmv // All rights reserved.
      3  1.1  jmmv //
      4  1.1  jmmv // Redistribution and use in source and binary forms, with or without
      5  1.1  jmmv // modification, are permitted provided that the following conditions are
      6  1.1  jmmv // met:
      7  1.1  jmmv //
      8  1.1  jmmv // * Redistributions of source code must retain the above copyright
      9  1.1  jmmv //   notice, this list of conditions and the following disclaimer.
     10  1.1  jmmv // * Redistributions in binary form must reproduce the above copyright
     11  1.1  jmmv //   notice, this list of conditions and the following disclaimer in the
     12  1.1  jmmv //   documentation and/or other materials provided with the distribution.
     13  1.1  jmmv // * Neither the name of Google Inc. nor the names of its contributors
     14  1.1  jmmv //   may be used to endorse or promote products derived from this software
     15  1.1  jmmv //   without specific prior written permission.
     16  1.1  jmmv //
     17  1.1  jmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18  1.1  jmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19  1.1  jmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20  1.1  jmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21  1.1  jmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22  1.1  jmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23  1.1  jmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  1.1  jmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  1.1  jmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  1.1  jmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27  1.1  jmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.1  jmmv 
     29  1.1  jmmv #include "utils/text/templates.hpp"
     30  1.1  jmmv 
     31  1.1  jmmv #include <fstream>
     32  1.1  jmmv #include <sstream>
     33  1.1  jmmv 
     34  1.1  jmmv #include <atf-c++.hpp>
     35  1.1  jmmv 
     36  1.1  jmmv #include "utils/fs/operations.hpp"
     37  1.1  jmmv #include "utils/fs/path.hpp"
     38  1.1  jmmv #include "utils/text/exceptions.hpp"
     39  1.1  jmmv 
     40  1.1  jmmv namespace fs = utils::fs;
     41  1.1  jmmv namespace text = utils::text;
     42  1.1  jmmv 
     43  1.1  jmmv 
     44  1.1  jmmv namespace {
     45  1.1  jmmv 
     46  1.1  jmmv 
     47  1.1  jmmv /// Applies a set of templates to an input string and validates the output.
     48  1.1  jmmv ///
     49  1.1  jmmv /// This fails the test case if exp_output does not match the document generated
     50  1.1  jmmv /// by the application of the templates.
     51  1.1  jmmv ///
     52  1.1  jmmv /// \param templates The templates to apply.
     53  1.1  jmmv /// \param input_str The input document to which to apply the templates.
     54  1.1  jmmv /// \param exp_output The expected output document.
     55  1.1  jmmv static void
     56  1.1  jmmv do_test_ok(const text::templates_def& templates, const std::string& input_str,
     57  1.1  jmmv            const std::string& exp_output)
     58  1.1  jmmv {
     59  1.1  jmmv     std::istringstream input(input_str);
     60  1.1  jmmv     std::ostringstream output;
     61  1.1  jmmv 
     62  1.1  jmmv     text::instantiate(templates, input, output);
     63  1.1  jmmv     ATF_REQUIRE_EQ(exp_output, output.str());
     64  1.1  jmmv }
     65  1.1  jmmv 
     66  1.1  jmmv 
     67  1.1  jmmv /// Applies a set of templates to an input string and checks for an error.
     68  1.1  jmmv ///
     69  1.1  jmmv /// This fails the test case if the exception raised by the template processing
     70  1.1  jmmv /// does not match the expected message.
     71  1.1  jmmv ///
     72  1.1  jmmv /// \param templates The templates to apply.
     73  1.1  jmmv /// \param input_str The input document to which to apply the templates.
     74  1.1  jmmv /// \param exp_message The expected error message in the raised exception.
     75  1.1  jmmv static void
     76  1.1  jmmv do_test_fail(const text::templates_def& templates, const std::string& input_str,
     77  1.1  jmmv              const std::string& exp_message)
     78  1.1  jmmv {
     79  1.1  jmmv     std::istringstream input(input_str);
     80  1.1  jmmv     std::ostringstream output;
     81  1.1  jmmv 
     82  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, exp_message,
     83  1.1  jmmv                          text::instantiate(templates, input, output));
     84  1.1  jmmv }
     85  1.1  jmmv 
     86  1.1  jmmv 
     87  1.1  jmmv }  // anonymous namespace
     88  1.1  jmmv 
     89  1.1  jmmv 
     90  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__add_variable__first);
     91  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__add_variable__first)
     92  1.1  jmmv {
     93  1.1  jmmv     text::templates_def templates;
     94  1.1  jmmv     templates.add_variable("the-name", "first-value");
     95  1.1  jmmv     ATF_REQUIRE_EQ("first-value", templates.get_variable("the-name"));
     96  1.1  jmmv }
     97  1.1  jmmv 
     98  1.1  jmmv 
     99  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__add_variable__replace);
    100  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__add_variable__replace)
    101  1.1  jmmv {
    102  1.1  jmmv     text::templates_def templates;
    103  1.1  jmmv     templates.add_variable("the-name", "first-value");
    104  1.1  jmmv     templates.add_variable("the-name", "second-value");
    105  1.1  jmmv     ATF_REQUIRE_EQ("second-value", templates.get_variable("the-name"));
    106  1.1  jmmv }
    107  1.1  jmmv 
    108  1.1  jmmv 
    109  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__remove_variable);
    110  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__remove_variable)
    111  1.1  jmmv {
    112  1.1  jmmv     text::templates_def templates;
    113  1.1  jmmv     templates.add_variable("the-name", "the-value");
    114  1.1  jmmv     templates.get_variable("the-name");  // Should not throw.
    115  1.1  jmmv     templates.remove_variable("the-name");
    116  1.1  jmmv     ATF_REQUIRE_THROW(text::syntax_error, templates.get_variable("the-name"));
    117  1.1  jmmv }
    118  1.1  jmmv 
    119  1.1  jmmv 
    120  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__add_vector__first);
    121  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__add_vector__first)
    122  1.1  jmmv {
    123  1.1  jmmv     text::templates_def templates;
    124  1.1  jmmv     templates.add_vector("the-name");
    125  1.1  jmmv     ATF_REQUIRE(templates.get_vector("the-name").empty());
    126  1.1  jmmv }
    127  1.1  jmmv 
    128  1.1  jmmv 
    129  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__add_vector__replace);
    130  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__add_vector__replace)
    131  1.1  jmmv {
    132  1.1  jmmv     text::templates_def templates;
    133  1.1  jmmv     templates.add_vector("the-name");
    134  1.1  jmmv     templates.add_to_vector("the-name", "foo");
    135  1.1  jmmv     ATF_REQUIRE(!templates.get_vector("the-name").empty());
    136  1.1  jmmv     templates.add_vector("the-name");
    137  1.1  jmmv     ATF_REQUIRE(templates.get_vector("the-name").empty());
    138  1.1  jmmv }
    139  1.1  jmmv 
    140  1.1  jmmv 
    141  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__add_to_vector);
    142  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__add_to_vector)
    143  1.1  jmmv {
    144  1.1  jmmv     text::templates_def templates;
    145  1.1  jmmv     templates.add_vector("the-name");
    146  1.1  jmmv     ATF_REQUIRE_EQ(0, templates.get_vector("the-name").size());
    147  1.1  jmmv     templates.add_to_vector("the-name", "first");
    148  1.1  jmmv     ATF_REQUIRE_EQ(1, templates.get_vector("the-name").size());
    149  1.1  jmmv     templates.add_to_vector("the-name", "second");
    150  1.1  jmmv     ATF_REQUIRE_EQ(2, templates.get_vector("the-name").size());
    151  1.1  jmmv     templates.add_to_vector("the-name", "third");
    152  1.1  jmmv     ATF_REQUIRE_EQ(3, templates.get_vector("the-name").size());
    153  1.1  jmmv 
    154  1.1  jmmv     std::vector< std::string > expected;
    155  1.1  jmmv     expected.push_back("first");
    156  1.1  jmmv     expected.push_back("second");
    157  1.1  jmmv     expected.push_back("third");
    158  1.1  jmmv     ATF_REQUIRE(expected == templates.get_vector("the-name"));
    159  1.1  jmmv }
    160  1.1  jmmv 
    161  1.1  jmmv 
    162  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__exists__variable);
    163  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__exists__variable)
    164  1.1  jmmv {
    165  1.1  jmmv     text::templates_def templates;
    166  1.1  jmmv     ATF_REQUIRE(!templates.exists("some-name"));
    167  1.1  jmmv     templates.add_variable("some-name ", "foo");
    168  1.1  jmmv     ATF_REQUIRE(!templates.exists("some-name"));
    169  1.1  jmmv     templates.add_variable("some-name", "foo");
    170  1.1  jmmv     ATF_REQUIRE(templates.exists("some-name"));
    171  1.1  jmmv }
    172  1.1  jmmv 
    173  1.1  jmmv 
    174  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__exists__vector);
    175  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__exists__vector)
    176  1.1  jmmv {
    177  1.1  jmmv     text::templates_def templates;
    178  1.1  jmmv     ATF_REQUIRE(!templates.exists("some-name"));
    179  1.1  jmmv     templates.add_vector("some-name ");
    180  1.1  jmmv     ATF_REQUIRE(!templates.exists("some-name"));
    181  1.1  jmmv     templates.add_vector("some-name");
    182  1.1  jmmv     ATF_REQUIRE(templates.exists("some-name"));
    183  1.1  jmmv }
    184  1.1  jmmv 
    185  1.1  jmmv 
    186  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__get_variable__ok);
    187  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__get_variable__ok)
    188  1.1  jmmv {
    189  1.1  jmmv     text::templates_def templates;
    190  1.1  jmmv     templates.add_variable("foo", "");
    191  1.1  jmmv     templates.add_variable("bar", "    baz  ");
    192  1.1  jmmv     ATF_REQUIRE_EQ("", templates.get_variable("foo"));
    193  1.1  jmmv     ATF_REQUIRE_EQ("    baz  ", templates.get_variable("bar"));
    194  1.1  jmmv }
    195  1.1  jmmv 
    196  1.1  jmmv 
    197  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__get_variable__unknown);
    198  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__get_variable__unknown)
    199  1.1  jmmv {
    200  1.1  jmmv     text::templates_def templates;
    201  1.1  jmmv     templates.add_variable("foo", "");
    202  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Unknown variable 'foo '",
    203  1.1  jmmv                          templates.get_variable("foo "));
    204  1.1  jmmv }
    205  1.1  jmmv 
    206  1.1  jmmv 
    207  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__get_vector__ok);
    208  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__get_vector__ok)
    209  1.1  jmmv {
    210  1.1  jmmv     text::templates_def templates;
    211  1.1  jmmv     templates.add_vector("foo");
    212  1.1  jmmv     templates.add_vector("bar");
    213  1.1  jmmv     templates.add_to_vector("bar", "baz");
    214  1.1  jmmv     ATF_REQUIRE_EQ(0, templates.get_vector("foo").size());
    215  1.1  jmmv     ATF_REQUIRE_EQ(1, templates.get_vector("bar").size());
    216  1.1  jmmv }
    217  1.1  jmmv 
    218  1.1  jmmv 
    219  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__get_vector__unknown);
    220  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__get_vector__unknown)
    221  1.1  jmmv {
    222  1.1  jmmv     text::templates_def templates;
    223  1.1  jmmv     templates.add_vector("foo");
    224  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Unknown vector 'foo '",
    225  1.1  jmmv                          templates.get_vector("foo "));
    226  1.1  jmmv }
    227  1.1  jmmv 
    228  1.1  jmmv 
    229  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__variable__ok);
    230  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__variable__ok)
    231  1.1  jmmv {
    232  1.1  jmmv     text::templates_def templates;
    233  1.1  jmmv     templates.add_variable("foo", "");
    234  1.1  jmmv     templates.add_variable("bar", "    baz  ");
    235  1.1  jmmv     ATF_REQUIRE_EQ("", templates.evaluate("foo"));
    236  1.1  jmmv     ATF_REQUIRE_EQ("    baz  ", templates.evaluate("bar"));
    237  1.1  jmmv }
    238  1.1  jmmv 
    239  1.1  jmmv 
    240  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__variable__unknown);
    241  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__variable__unknown)
    242  1.1  jmmv {
    243  1.1  jmmv     text::templates_def templates;
    244  1.1  jmmv     templates.add_variable("foo", "");
    245  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Unknown variable 'foo1'",
    246  1.1  jmmv                          templates.evaluate("foo1"));
    247  1.1  jmmv }
    248  1.1  jmmv 
    249  1.1  jmmv 
    250  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__vector__ok);
    251  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__vector__ok)
    252  1.1  jmmv {
    253  1.1  jmmv     text::templates_def templates;
    254  1.1  jmmv     templates.add_vector("v");
    255  1.1  jmmv     templates.add_to_vector("v", "foo");
    256  1.1  jmmv     templates.add_to_vector("v", "bar");
    257  1.1  jmmv     templates.add_to_vector("v", "baz");
    258  1.1  jmmv 
    259  1.1  jmmv     templates.add_variable("index", "0");
    260  1.1  jmmv     ATF_REQUIRE_EQ("foo", templates.evaluate("v(index)"));
    261  1.1  jmmv     templates.add_variable("index", "1");
    262  1.1  jmmv     ATF_REQUIRE_EQ("bar", templates.evaluate("v(index)"));
    263  1.1  jmmv     templates.add_variable("index", "2");
    264  1.1  jmmv     ATF_REQUIRE_EQ("baz", templates.evaluate("v(index)"));
    265  1.1  jmmv }
    266  1.1  jmmv 
    267  1.1  jmmv 
    268  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__vector__unknown_vector);
    269  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__vector__unknown_vector)
    270  1.1  jmmv {
    271  1.1  jmmv     text::templates_def templates;
    272  1.1  jmmv     templates.add_vector("v");
    273  1.1  jmmv     templates.add_to_vector("v", "foo");
    274  1.1  jmmv     templates.add_variable("index", "0");
    275  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Unknown vector 'fooz'",
    276  1.1  jmmv                          templates.evaluate("fooz(index)"));
    277  1.1  jmmv }
    278  1.1  jmmv 
    279  1.1  jmmv 
    280  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__vector__unknown_index);
    281  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__vector__unknown_index)
    282  1.1  jmmv {
    283  1.1  jmmv     text::templates_def templates;
    284  1.1  jmmv     templates.add_vector("v");
    285  1.1  jmmv     templates.add_to_vector("v", "foo");
    286  1.1  jmmv     templates.add_variable("index", "0");
    287  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Unknown variable 'indexz'",
    288  1.1  jmmv                          templates.evaluate("v(indexz)"));
    289  1.1  jmmv }
    290  1.1  jmmv 
    291  1.1  jmmv 
    292  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__vector__out_of_range);
    293  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__vector__out_of_range)
    294  1.1  jmmv {
    295  1.1  jmmv     text::templates_def templates;
    296  1.1  jmmv     templates.add_vector("v");
    297  1.1  jmmv     templates.add_to_vector("v", "foo");
    298  1.1  jmmv     templates.add_variable("index", "1");
    299  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Index 'index' out of range "
    300  1.1  jmmv                          "at position '1'", templates.evaluate("v(index)"));
    301  1.1  jmmv }
    302  1.1  jmmv 
    303  1.1  jmmv 
    304  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__defined);
    305  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__defined)
    306  1.1  jmmv {
    307  1.1  jmmv     text::templates_def templates;
    308  1.1  jmmv     templates.add_vector("the-variable");
    309  1.1  jmmv     templates.add_vector("the-vector");
    310  1.1  jmmv     ATF_REQUIRE_EQ("false", templates.evaluate("defined(the-variabl)"));
    311  1.1  jmmv     ATF_REQUIRE_EQ("false", templates.evaluate("defined(the-vecto)"));
    312  1.1  jmmv     ATF_REQUIRE_EQ("true", templates.evaluate("defined(the-variable)"));
    313  1.1  jmmv     ATF_REQUIRE_EQ("true", templates.evaluate("defined(the-vector)"));
    314  1.1  jmmv }
    315  1.1  jmmv 
    316  1.1  jmmv 
    317  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__length__ok);
    318  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__length__ok)
    319  1.1  jmmv {
    320  1.1  jmmv     text::templates_def templates;
    321  1.1  jmmv     templates.add_vector("v");
    322  1.1  jmmv     ATF_REQUIRE_EQ("0", templates.evaluate("length(v)"));
    323  1.1  jmmv     templates.add_to_vector("v", "foo");
    324  1.1  jmmv     ATF_REQUIRE_EQ("1", templates.evaluate("length(v)"));
    325  1.1  jmmv     templates.add_to_vector("v", "bar");
    326  1.1  jmmv     ATF_REQUIRE_EQ("2", templates.evaluate("length(v)"));
    327  1.1  jmmv     templates.add_to_vector("v", "baz");
    328  1.1  jmmv     ATF_REQUIRE_EQ("3", templates.evaluate("length(v)"));
    329  1.1  jmmv }
    330  1.1  jmmv 
    331  1.1  jmmv 
    332  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__length__unknown_vector);
    333  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__length__unknown_vector)
    334  1.1  jmmv {
    335  1.1  jmmv     text::templates_def templates;
    336  1.1  jmmv     templates.add_vector("foo1");
    337  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error, "Unknown vector 'foo'",
    338  1.1  jmmv                          templates.evaluate("length(foo)"));
    339  1.1  jmmv }
    340  1.1  jmmv 
    341  1.1  jmmv 
    342  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(templates_def__evaluate__parenthesis_error);
    343  1.1  jmmv ATF_TEST_CASE_BODY(templates_def__evaluate__parenthesis_error)
    344  1.1  jmmv {
    345  1.1  jmmv     text::templates_def templates;
    346  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error,
    347  1.1  jmmv                          "Expected '\\)' in.*'foo\\(abc'",
    348  1.1  jmmv                          templates.evaluate("foo(abc"));
    349  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::syntax_error,
    350  1.1  jmmv                          "Unexpected text.*'\\)' in.*'a\\(b\\)c'",
    351  1.1  jmmv                          templates.evaluate("a(b)c"));
    352  1.1  jmmv }
    353  1.1  jmmv 
    354  1.1  jmmv 
    355  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__empty_input);
    356  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__empty_input)
    357  1.1  jmmv {
    358  1.1  jmmv     const text::templates_def templates;
    359  1.1  jmmv     do_test_ok(templates, "", "");
    360  1.1  jmmv }
    361  1.1  jmmv 
    362  1.1  jmmv 
    363  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__value__ok);
    364  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__value__ok)
    365  1.1  jmmv {
    366  1.1  jmmv     const std::string input =
    367  1.1  jmmv         "first line\n"
    368  1.1  jmmv         "%%testvar1%%\n"
    369  1.1  jmmv         "third line\n"
    370  1.1  jmmv         "%%testvar2%% %%testvar3%%%%testvar4%%\n"
    371  1.1  jmmv         "fifth line\n";
    372  1.1  jmmv 
    373  1.1  jmmv     const std::string exp_output =
    374  1.1  jmmv         "first line\n"
    375  1.1  jmmv         "second line\n"
    376  1.1  jmmv         "third line\n"
    377  1.1  jmmv         "fourth line.\n"
    378  1.1  jmmv         "fifth line\n";
    379  1.1  jmmv 
    380  1.1  jmmv     text::templates_def templates;
    381  1.1  jmmv     templates.add_variable("testvar1", "second line");
    382  1.1  jmmv     templates.add_variable("testvar2", "fourth");
    383  1.1  jmmv     templates.add_variable("testvar3", "line");
    384  1.1  jmmv     templates.add_variable("testvar4", ".");
    385  1.1  jmmv 
    386  1.1  jmmv     do_test_ok(templates, input, exp_output);
    387  1.1  jmmv }
    388  1.1  jmmv 
    389  1.1  jmmv 
    390  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__value__unknown_variable);
    391  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__value__unknown_variable)
    392  1.1  jmmv {
    393  1.1  jmmv     const std::string input =
    394  1.1  jmmv         "%%testvar1%%\n";
    395  1.1  jmmv 
    396  1.1  jmmv     text::templates_def templates;
    397  1.1  jmmv     templates.add_variable("testvar2", "fourth line");
    398  1.1  jmmv 
    399  1.1  jmmv     do_test_fail(templates, input, "Unknown variable 'testvar1'");
    400  1.1  jmmv }
    401  1.1  jmmv 
    402  1.1  jmmv 
    403  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__vector_length__ok);
    404  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__vector_length__ok)
    405  1.1  jmmv {
    406  1.1  jmmv     const std::string input =
    407  1.1  jmmv         "%%length(testvector1)%%\n"
    408  1.1  jmmv         "%%length(testvector2)%% - %%length(testvector3)%%\n";
    409  1.1  jmmv 
    410  1.1  jmmv     const std::string exp_output =
    411  1.1  jmmv         "4\n"
    412  1.1  jmmv         "0 - 1\n";
    413  1.1  jmmv 
    414  1.1  jmmv     text::templates_def templates;
    415  1.1  jmmv     templates.add_vector("testvector1");
    416  1.1  jmmv     templates.add_to_vector("testvector1", "000");
    417  1.1  jmmv     templates.add_to_vector("testvector1", "111");
    418  1.1  jmmv     templates.add_to_vector("testvector1", "543");
    419  1.1  jmmv     templates.add_to_vector("testvector1", "999");
    420  1.1  jmmv     templates.add_vector("testvector2");
    421  1.1  jmmv     templates.add_vector("testvector3");
    422  1.1  jmmv     templates.add_to_vector("testvector3", "123");
    423  1.1  jmmv 
    424  1.1  jmmv     do_test_ok(templates, input, exp_output);
    425  1.1  jmmv }
    426  1.1  jmmv 
    427  1.1  jmmv 
    428  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__vector_length__unknown_vector);
    429  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__vector_length__unknown_vector)
    430  1.1  jmmv {
    431  1.1  jmmv     const std::string input =
    432  1.1  jmmv         "%%length(testvector)%%\n";
    433  1.1  jmmv 
    434  1.1  jmmv     text::templates_def templates;
    435  1.1  jmmv     templates.add_vector("testvector2");
    436  1.1  jmmv 
    437  1.1  jmmv     do_test_fail(templates, input, "Unknown vector 'testvector'");
    438  1.1  jmmv }
    439  1.1  jmmv 
    440  1.1  jmmv 
    441  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__vector_value__ok);
    442  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__vector_value__ok)
    443  1.1  jmmv {
    444  1.1  jmmv     const std::string input =
    445  1.1  jmmv         "first line\n"
    446  1.1  jmmv         "%%testvector1(i)%%\n"
    447  1.1  jmmv         "third line\n"
    448  1.1  jmmv         "%%testvector2(j)%%\n"
    449  1.1  jmmv         "fifth line\n";
    450  1.1  jmmv 
    451  1.1  jmmv     const std::string exp_output =
    452  1.1  jmmv         "first line\n"
    453  1.1  jmmv         "543\n"
    454  1.1  jmmv         "third line\n"
    455  1.1  jmmv         "123\n"
    456  1.1  jmmv         "fifth line\n";
    457  1.1  jmmv 
    458  1.1  jmmv     text::templates_def templates;
    459  1.1  jmmv     templates.add_variable("i", "2");
    460  1.1  jmmv     templates.add_variable("j", "0");
    461  1.1  jmmv     templates.add_vector("testvector1");
    462  1.1  jmmv     templates.add_to_vector("testvector1", "000");
    463  1.1  jmmv     templates.add_to_vector("testvector1", "111");
    464  1.1  jmmv     templates.add_to_vector("testvector1", "543");
    465  1.1  jmmv     templates.add_to_vector("testvector1", "999");
    466  1.1  jmmv     templates.add_vector("testvector2");
    467  1.1  jmmv     templates.add_to_vector("testvector2", "123");
    468  1.1  jmmv 
    469  1.1  jmmv     do_test_ok(templates, input, exp_output);
    470  1.1  jmmv }
    471  1.1  jmmv 
    472  1.1  jmmv 
    473  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__vector_value__unknown_vector);
    474  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__vector_value__unknown_vector)
    475  1.1  jmmv {
    476  1.1  jmmv     const std::string input =
    477  1.1  jmmv         "%%testvector(j)%%\n";
    478  1.1  jmmv 
    479  1.1  jmmv     text::templates_def templates;
    480  1.1  jmmv     templates.add_vector("testvector2");
    481  1.1  jmmv 
    482  1.1  jmmv     do_test_fail(templates, input, "Unknown vector 'testvector'");
    483  1.1  jmmv }
    484  1.1  jmmv 
    485  1.1  jmmv 
    486  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__vector_value__out_of_range__empty);
    487  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__vector_value__out_of_range__empty)
    488  1.1  jmmv {
    489  1.1  jmmv     const std::string input =
    490  1.1  jmmv         "%%testvector(j)%%\n";
    491  1.1  jmmv 
    492  1.1  jmmv     text::templates_def templates;
    493  1.1  jmmv     templates.add_vector("testvector");
    494  1.1  jmmv     templates.add_variable("j", "0");
    495  1.1  jmmv 
    496  1.1  jmmv     do_test_fail(templates, input, "Index 'j' out of range at position '0'");
    497  1.1  jmmv }
    498  1.1  jmmv 
    499  1.1  jmmv 
    500  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__vector_value__out_of_range__not_empty);
    501  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__vector_value__out_of_range__not_empty)
    502  1.1  jmmv {
    503  1.1  jmmv     const std::string input =
    504  1.1  jmmv         "%%testvector(j)%%\n";
    505  1.1  jmmv 
    506  1.1  jmmv     text::templates_def templates;
    507  1.1  jmmv     templates.add_vector("testvector");
    508  1.1  jmmv     templates.add_to_vector("testvector", "a");
    509  1.1  jmmv     templates.add_to_vector("testvector", "b");
    510  1.1  jmmv     templates.add_variable("j", "2");
    511  1.1  jmmv 
    512  1.1  jmmv     do_test_fail(templates, input, "Index 'j' out of range at position '2'");
    513  1.1  jmmv }
    514  1.1  jmmv 
    515  1.1  jmmv 
    516  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__if__one_level__taken);
    517  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__if__one_level__taken)
    518  1.1  jmmv {
    519  1.1  jmmv     const std::string input =
    520  1.1  jmmv         "first line\n"
    521  1.1  jmmv         "%if defined(some_var)\n"
    522  1.1  jmmv         "hello from within the variable conditional\n"
    523  1.1  jmmv         "%endif\n"
    524  1.1  jmmv         "%if defined(some_vector)\n"
    525  1.1  jmmv         "hello from within the vector conditional\n"
    526  1.1  jmmv         "%else\n"
    527  1.1  jmmv         "bye from within the vector conditional\n"
    528  1.1  jmmv         "%endif\n"
    529  1.1  jmmv         "some more\n";
    530  1.1  jmmv 
    531  1.1  jmmv     const std::string exp_output =
    532  1.1  jmmv         "first line\n"
    533  1.1  jmmv         "hello from within the variable conditional\n"
    534  1.1  jmmv         "hello from within the vector conditional\n"
    535  1.1  jmmv         "some more\n";
    536  1.1  jmmv 
    537  1.1  jmmv     text::templates_def templates;
    538  1.1  jmmv     templates.add_variable("some_var", "zzz");
    539  1.1  jmmv     templates.add_vector("some_vector");
    540  1.1  jmmv 
    541  1.1  jmmv     do_test_ok(templates, input, exp_output);
    542  1.1  jmmv }
    543  1.1  jmmv 
    544  1.1  jmmv 
    545  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__if__one_level__not_taken);
    546  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__if__one_level__not_taken)
    547  1.1  jmmv {
    548  1.1  jmmv     const std::string input =
    549  1.1  jmmv         "first line\n"
    550  1.1  jmmv         "%if defined(some_var)\n"
    551  1.1  jmmv         "hello from within the variable conditional\n"
    552  1.1  jmmv         "%endif\n"
    553  1.1  jmmv         "%if defined(some_vector)\n"
    554  1.1  jmmv         "hello from within the vector conditional\n"
    555  1.1  jmmv         "%else\n"
    556  1.1  jmmv         "bye from within the vector conditional\n"
    557  1.1  jmmv         "%endif\n"
    558  1.1  jmmv         "some more\n";
    559  1.1  jmmv 
    560  1.1  jmmv     const std::string exp_output =
    561  1.1  jmmv         "first line\n"
    562  1.1  jmmv         "bye from within the vector conditional\n"
    563  1.1  jmmv         "some more\n";
    564  1.1  jmmv 
    565  1.1  jmmv     text::templates_def templates;
    566  1.1  jmmv 
    567  1.1  jmmv     do_test_ok(templates, input, exp_output);
    568  1.1  jmmv }
    569  1.1  jmmv 
    570  1.1  jmmv 
    571  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__if__multiple_levels__taken);
    572  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__if__multiple_levels__taken)
    573  1.1  jmmv {
    574  1.1  jmmv     const std::string input =
    575  1.1  jmmv         "first line\n"
    576  1.1  jmmv         "%if defined(var1)\n"
    577  1.1  jmmv         "first before\n"
    578  1.1  jmmv         "%if length(var2)\n"
    579  1.1  jmmv         "second before\n"
    580  1.1  jmmv         "%if defined(var3)\n"
    581  1.1  jmmv         "third before\n"
    582  1.1  jmmv         "hello from within the conditional\n"
    583  1.1  jmmv         "third after\n"
    584  1.1  jmmv         "%endif\n"
    585  1.1  jmmv         "second after\n"
    586  1.1  jmmv         "%else\n"
    587  1.1  jmmv         "second after not shown\n"
    588  1.1  jmmv         "%endif\n"
    589  1.1  jmmv         "first after\n"
    590  1.1  jmmv         "%endif\n"
    591  1.1  jmmv         "some more\n";
    592  1.1  jmmv 
    593  1.1  jmmv     const std::string exp_output =
    594  1.1  jmmv         "first line\n"
    595  1.1  jmmv         "first before\n"
    596  1.1  jmmv         "second before\n"
    597  1.1  jmmv         "third before\n"
    598  1.1  jmmv         "hello from within the conditional\n"
    599  1.1  jmmv         "third after\n"
    600  1.1  jmmv         "second after\n"
    601  1.1  jmmv         "first after\n"
    602  1.1  jmmv         "some more\n";
    603  1.1  jmmv 
    604  1.1  jmmv     text::templates_def templates;
    605  1.1  jmmv     templates.add_variable("var1", "false");
    606  1.1  jmmv     templates.add_vector("var2");
    607  1.1  jmmv     templates.add_to_vector("var2", "not-empty");
    608  1.1  jmmv     templates.add_variable("var3", "foobar");
    609  1.1  jmmv 
    610  1.1  jmmv     do_test_ok(templates, input, exp_output);
    611  1.1  jmmv }
    612  1.1  jmmv 
    613  1.1  jmmv 
    614  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__if__multiple_levels__not_taken);
    615  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__if__multiple_levels__not_taken)
    616  1.1  jmmv {
    617  1.1  jmmv     const std::string input =
    618  1.1  jmmv         "first line\n"
    619  1.1  jmmv         "%if defined(var1)\n"
    620  1.1  jmmv         "first before\n"
    621  1.1  jmmv         "%if length(var2)\n"
    622  1.1  jmmv         "second before\n"
    623  1.1  jmmv         "%if defined(var3)\n"
    624  1.1  jmmv         "third before\n"
    625  1.1  jmmv         "hello from within the conditional\n"
    626  1.1  jmmv         "third after\n"
    627  1.1  jmmv         "%else\n"
    628  1.1  jmmv         "will not be shown either\n"
    629  1.1  jmmv         "%endif\n"
    630  1.1  jmmv         "second after\n"
    631  1.1  jmmv         "%else\n"
    632  1.1  jmmv         "second after shown\n"
    633  1.1  jmmv         "%endif\n"
    634  1.1  jmmv         "first after\n"
    635  1.1  jmmv         "%endif\n"
    636  1.1  jmmv         "some more\n";
    637  1.1  jmmv 
    638  1.1  jmmv     const std::string exp_output =
    639  1.1  jmmv         "first line\n"
    640  1.1  jmmv         "first before\n"
    641  1.1  jmmv         "second after shown\n"
    642  1.1  jmmv         "first after\n"
    643  1.1  jmmv         "some more\n";
    644  1.1  jmmv 
    645  1.1  jmmv     text::templates_def templates;
    646  1.1  jmmv     templates.add_variable("var1", "false");
    647  1.1  jmmv     templates.add_vector("var2");
    648  1.1  jmmv     templates.add_vector("var3");
    649  1.1  jmmv 
    650  1.1  jmmv     do_test_ok(templates, input, exp_output);
    651  1.1  jmmv }
    652  1.1  jmmv 
    653  1.1  jmmv 
    654  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__loop__no_iterations);
    655  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__loop__no_iterations)
    656  1.1  jmmv {
    657  1.1  jmmv     const std::string input =
    658  1.1  jmmv         "first line\n"
    659  1.1  jmmv         "%loop table1 i\n"
    660  1.1  jmmv         "hello\n"
    661  1.1  jmmv         "value in vector: %%table1(i)%%\n"
    662  1.1  jmmv         "%if defined(var1)\n" "some other text\n" "%endif\n"
    663  1.1  jmmv         "%endloop\n"
    664  1.1  jmmv         "some more\n";
    665  1.1  jmmv 
    666  1.1  jmmv     const std::string exp_output =
    667  1.1  jmmv         "first line\n"
    668  1.1  jmmv         "some more\n";
    669  1.1  jmmv 
    670  1.1  jmmv     text::templates_def templates;
    671  1.1  jmmv     templates.add_variable("var1", "defined");
    672  1.1  jmmv     templates.add_vector("table1");
    673  1.1  jmmv 
    674  1.1  jmmv     do_test_ok(templates, input, exp_output);
    675  1.1  jmmv }
    676  1.1  jmmv 
    677  1.1  jmmv 
    678  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__loop__multiple_iterations);
    679  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__loop__multiple_iterations)
    680  1.1  jmmv {
    681  1.1  jmmv     const std::string input =
    682  1.1  jmmv         "first line\n"
    683  1.1  jmmv         "%loop table1 i\n"
    684  1.1  jmmv         "hello %%table1(i)%% %%table2(i)%%\n"
    685  1.1  jmmv         "%endloop\n"
    686  1.1  jmmv         "some more\n";
    687  1.1  jmmv 
    688  1.1  jmmv     const std::string exp_output =
    689  1.1  jmmv         "first line\n"
    690  1.1  jmmv         "hello foo1 foo2\n"
    691  1.1  jmmv         "hello bar1 bar2\n"
    692  1.1  jmmv         "some more\n";
    693  1.1  jmmv 
    694  1.1  jmmv     text::templates_def templates;
    695  1.1  jmmv     templates.add_vector("table1");
    696  1.1  jmmv     templates.add_to_vector("table1", "foo1");
    697  1.1  jmmv     templates.add_to_vector("table1", "bar1");
    698  1.1  jmmv     templates.add_vector("table2");
    699  1.1  jmmv     templates.add_to_vector("table2", "foo2");
    700  1.1  jmmv     templates.add_to_vector("table2", "bar2");
    701  1.1  jmmv 
    702  1.1  jmmv     do_test_ok(templates, input, exp_output);
    703  1.1  jmmv }
    704  1.1  jmmv 
    705  1.1  jmmv 
    706  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__loop__nested__no_iterations);
    707  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__loop__nested__no_iterations)
    708  1.1  jmmv {
    709  1.1  jmmv     const std::string input =
    710  1.1  jmmv         "first line\n"
    711  1.1  jmmv         "%loop table1 i\n"
    712  1.1  jmmv         "before: %%table1(i)%%\n"
    713  1.1  jmmv         "%loop table2 j\n"
    714  1.1  jmmv         "before: %%table2(j)%%\n"
    715  1.1  jmmv         "%loop table3 k\n"
    716  1.1  jmmv         "%%table3(k)%%\n"
    717  1.1  jmmv         "%endloop\n"
    718  1.1  jmmv         "after: %%table2(i)%%\n"
    719  1.1  jmmv         "%endloop\n"
    720  1.1  jmmv         "after: %%table1(i)%%\n"
    721  1.1  jmmv         "%endloop\n"
    722  1.1  jmmv         "some more\n";
    723  1.1  jmmv 
    724  1.1  jmmv     const std::string exp_output =
    725  1.1  jmmv         "first line\n"
    726  1.1  jmmv         "before: a\n"
    727  1.1  jmmv         "after: a\n"
    728  1.1  jmmv         "before: b\n"
    729  1.1  jmmv         "after: b\n"
    730  1.1  jmmv         "some more\n";
    731  1.1  jmmv 
    732  1.1  jmmv     text::templates_def templates;
    733  1.1  jmmv     templates.add_vector("table1");
    734  1.1  jmmv     templates.add_to_vector("table1", "a");
    735  1.1  jmmv     templates.add_to_vector("table1", "b");
    736  1.1  jmmv     templates.add_vector("table2");
    737  1.1  jmmv     templates.add_vector("table3");
    738  1.1  jmmv     templates.add_to_vector("table3", "1");
    739  1.1  jmmv 
    740  1.1  jmmv     do_test_ok(templates, input, exp_output);
    741  1.1  jmmv }
    742  1.1  jmmv 
    743  1.1  jmmv 
    744  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__loop__nested__multiple_iterations);
    745  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__loop__nested__multiple_iterations)
    746  1.1  jmmv {
    747  1.1  jmmv     const std::string input =
    748  1.1  jmmv         "first line\n"
    749  1.1  jmmv         "%loop table1 i\n"
    750  1.1  jmmv         "%loop table2 j\n"
    751  1.1  jmmv         "%%table1(i)%% %%table2(j)%%\n"
    752  1.1  jmmv         "%endloop\n"
    753  1.1  jmmv         "%endloop\n"
    754  1.1  jmmv         "some more\n";
    755  1.1  jmmv 
    756  1.1  jmmv     const std::string exp_output =
    757  1.1  jmmv         "first line\n"
    758  1.1  jmmv         "a 1\n"
    759  1.1  jmmv         "a 2\n"
    760  1.1  jmmv         "a 3\n"
    761  1.1  jmmv         "b 1\n"
    762  1.1  jmmv         "b 2\n"
    763  1.1  jmmv         "b 3\n"
    764  1.1  jmmv         "some more\n";
    765  1.1  jmmv 
    766  1.1  jmmv     text::templates_def templates;
    767  1.1  jmmv     templates.add_vector("table1");
    768  1.1  jmmv     templates.add_to_vector("table1", "a");
    769  1.1  jmmv     templates.add_to_vector("table1", "b");
    770  1.1  jmmv     templates.add_vector("table2");
    771  1.1  jmmv     templates.add_to_vector("table2", "1");
    772  1.1  jmmv     templates.add_to_vector("table2", "2");
    773  1.1  jmmv     templates.add_to_vector("table2", "3");
    774  1.1  jmmv 
    775  1.1  jmmv     do_test_ok(templates, input, exp_output);
    776  1.1  jmmv }
    777  1.1  jmmv 
    778  1.1  jmmv 
    779  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__loop__sequential);
    780  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__loop__sequential)
    781  1.1  jmmv {
    782  1.1  jmmv     const std::string input =
    783  1.1  jmmv         "first line\n"
    784  1.1  jmmv         "%loop table1 iter\n"
    785  1.1  jmmv         "1: %%table1(iter)%%\n"
    786  1.1  jmmv         "%endloop\n"
    787  1.1  jmmv         "divider\n"
    788  1.1  jmmv         "%loop table2 iter\n"
    789  1.1  jmmv         "2: %%table2(iter)%%\n"
    790  1.1  jmmv         "%endloop\n"
    791  1.1  jmmv         "divider\n"
    792  1.1  jmmv         "%loop table3 iter\n"
    793  1.1  jmmv         "3: %%table3(iter)%%\n"
    794  1.1  jmmv         "%endloop\n"
    795  1.1  jmmv         "divider\n"
    796  1.1  jmmv         "%loop table4 iter\n"
    797  1.1  jmmv         "4: %%table4(iter)%%\n"
    798  1.1  jmmv         "%endloop\n"
    799  1.1  jmmv         "some more\n";
    800  1.1  jmmv 
    801  1.1  jmmv     const std::string exp_output =
    802  1.1  jmmv         "first line\n"
    803  1.1  jmmv         "1: a\n"
    804  1.1  jmmv         "1: b\n"
    805  1.1  jmmv         "divider\n"
    806  1.1  jmmv         "divider\n"
    807  1.1  jmmv         "divider\n"
    808  1.1  jmmv         "4: 1\n"
    809  1.1  jmmv         "4: 2\n"
    810  1.1  jmmv         "4: 3\n"
    811  1.1  jmmv         "some more\n";
    812  1.1  jmmv 
    813  1.1  jmmv     text::templates_def templates;
    814  1.1  jmmv     templates.add_vector("table1");
    815  1.1  jmmv     templates.add_to_vector("table1", "a");
    816  1.1  jmmv     templates.add_to_vector("table1", "b");
    817  1.1  jmmv     templates.add_vector("table2");
    818  1.1  jmmv     templates.add_vector("table3");
    819  1.1  jmmv     templates.add_vector("table4");
    820  1.1  jmmv     templates.add_to_vector("table4", "1");
    821  1.1  jmmv     templates.add_to_vector("table4", "2");
    822  1.1  jmmv     templates.add_to_vector("table4", "3");
    823  1.1  jmmv 
    824  1.1  jmmv     do_test_ok(templates, input, exp_output);
    825  1.1  jmmv }
    826  1.1  jmmv 
    827  1.1  jmmv 
    828  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__loop__scoping);
    829  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__loop__scoping)
    830  1.1  jmmv {
    831  1.1  jmmv     const std::string input =
    832  1.1  jmmv         "%loop table1 i\n"
    833  1.1  jmmv         "%if defined(i)\n" "i defined inside scope 1\n" "%endif\n"
    834  1.1  jmmv         "%loop table2 j\n"
    835  1.1  jmmv         "%if defined(i)\n" "i defined inside scope 2\n" "%endif\n"
    836  1.1  jmmv         "%if defined(j)\n" "j defined inside scope 2\n" "%endif\n"
    837  1.1  jmmv         "%endloop\n"
    838  1.1  jmmv         "%if defined(j)\n" "j defined inside scope 1\n" "%endif\n"
    839  1.1  jmmv         "%endloop\n"
    840  1.1  jmmv         "%if defined(i)\n" "i defined outside\n" "%endif\n"
    841  1.1  jmmv         "%if defined(j)\n" "j defined outside\n" "%endif\n";
    842  1.1  jmmv 
    843  1.1  jmmv     const std::string exp_output =
    844  1.1  jmmv         "i defined inside scope 1\n"
    845  1.1  jmmv         "i defined inside scope 2\n"
    846  1.1  jmmv         "j defined inside scope 2\n"
    847  1.1  jmmv         "i defined inside scope 1\n"
    848  1.1  jmmv         "i defined inside scope 2\n"
    849  1.1  jmmv         "j defined inside scope 2\n";
    850  1.1  jmmv 
    851  1.1  jmmv     text::templates_def templates;
    852  1.1  jmmv     templates.add_vector("table1");
    853  1.1  jmmv     templates.add_to_vector("table1", "first");
    854  1.1  jmmv     templates.add_to_vector("table1", "second");
    855  1.1  jmmv     templates.add_vector("table2");
    856  1.1  jmmv     templates.add_to_vector("table2", "first");
    857  1.1  jmmv 
    858  1.1  jmmv     do_test_ok(templates, input, exp_output);
    859  1.1  jmmv }
    860  1.1  jmmv 
    861  1.1  jmmv 
    862  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__mismatched_delimiters);
    863  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__mismatched_delimiters)
    864  1.1  jmmv {
    865  1.1  jmmv     const std::string input =
    866  1.1  jmmv         "this is some %% text\n"
    867  1.1  jmmv         "and this is %%var%% text%%\n";
    868  1.1  jmmv 
    869  1.1  jmmv     const std::string exp_output =
    870  1.1  jmmv         "this is some %% text\n"
    871  1.1  jmmv         "and this is some more text%%\n";
    872  1.1  jmmv 
    873  1.1  jmmv     text::templates_def templates;
    874  1.1  jmmv     templates.add_variable("var", "some more");
    875  1.1  jmmv 
    876  1.1  jmmv     do_test_ok(templates, input, exp_output);
    877  1.1  jmmv }
    878  1.1  jmmv 
    879  1.1  jmmv 
    880  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__empty_statement);
    881  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__empty_statement)
    882  1.1  jmmv {
    883  1.1  jmmv     do_test_fail(text::templates_def(), "%\n", "Empty statement");
    884  1.1  jmmv }
    885  1.1  jmmv 
    886  1.1  jmmv 
    887  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__unknown_statement);
    888  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__unknown_statement)
    889  1.1  jmmv {
    890  1.1  jmmv     do_test_fail(text::templates_def(), "%if2\n", "Unknown statement 'if2'");
    891  1.1  jmmv }
    892  1.1  jmmv 
    893  1.1  jmmv 
    894  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__invalid_narguments);
    895  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__invalid_narguments)
    896  1.1  jmmv {
    897  1.1  jmmv     do_test_fail(text::templates_def(), "%if a b\n",
    898  1.1  jmmv                  "Invalid number of arguments for statement 'if'");
    899  1.1  jmmv }
    900  1.1  jmmv 
    901  1.1  jmmv 
    902  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__files__ok);
    903  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__files__ok)
    904  1.1  jmmv {
    905  1.1  jmmv     text::templates_def templates;
    906  1.1  jmmv     templates.add_variable("string", "Hello, world!");
    907  1.1  jmmv 
    908  1.1  jmmv     atf::utils::create_file("input.txt", "The string is: %%string%%\n");
    909  1.1  jmmv 
    910  1.1  jmmv     text::instantiate(templates, fs::path("input.txt"), fs::path("output.txt"));
    911  1.1  jmmv 
    912  1.1  jmmv     std::ifstream output("output.txt");
    913  1.1  jmmv     std::string line;
    914  1.1  jmmv     ATF_REQUIRE(std::getline(output, line).good());
    915  1.1  jmmv     ATF_REQUIRE_EQ(line, "The string is: Hello, world!");
    916  1.1  jmmv     ATF_REQUIRE(std::getline(output, line).eof());
    917  1.1  jmmv }
    918  1.1  jmmv 
    919  1.1  jmmv 
    920  1.1  jmmv ATF_TEST_CASE_WITHOUT_HEAD(instantiate__files__input_error);
    921  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__files__input_error)
    922  1.1  jmmv {
    923  1.1  jmmv     text::templates_def templates;
    924  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::error, "Failed to open input.txt for read",
    925  1.1  jmmv                          text::instantiate(templates, fs::path("input.txt"),
    926  1.1  jmmv                                            fs::path("output.txt")));
    927  1.1  jmmv }
    928  1.1  jmmv 
    929  1.1  jmmv 
    930  1.1  jmmv ATF_TEST_CASE(instantiate__files__output_error);
    931  1.1  jmmv ATF_TEST_CASE_HEAD(instantiate__files__output_error)
    932  1.1  jmmv {
    933  1.1  jmmv     set_md_var("require.user", "unprivileged");
    934  1.1  jmmv }
    935  1.1  jmmv ATF_TEST_CASE_BODY(instantiate__files__output_error)
    936  1.1  jmmv {
    937  1.1  jmmv     text::templates_def templates;
    938  1.1  jmmv 
    939  1.1  jmmv     atf::utils::create_file("input.txt", "");
    940  1.1  jmmv 
    941  1.1  jmmv     fs::mkdir(fs::path("dir"), 0444);
    942  1.1  jmmv 
    943  1.1  jmmv     ATF_REQUIRE_THROW_RE(text::error, "Failed to open dir/output.txt for write",
    944  1.1  jmmv                          text::instantiate(templates, fs::path("input.txt"),
    945  1.1  jmmv                                            fs::path("dir/output.txt")));
    946  1.1  jmmv }
    947  1.1  jmmv 
    948  1.1  jmmv 
    949  1.1  jmmv ATF_INIT_TEST_CASES(tcs)
    950  1.1  jmmv {
    951  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__add_variable__first);
    952  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__add_variable__replace);
    953  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__remove_variable);
    954  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__add_vector__first);
    955  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__add_vector__replace);
    956  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__add_to_vector);
    957  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__exists__variable);
    958  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__exists__vector);
    959  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__get_variable__ok);
    960  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__get_variable__unknown);
    961  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__get_vector__ok);
    962  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__get_vector__unknown);
    963  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__variable__ok);
    964  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__variable__unknown);
    965  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__vector__ok);
    966  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__vector__unknown_vector);
    967  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__vector__unknown_index);
    968  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__vector__out_of_range);
    969  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__defined);
    970  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__length__ok);
    971  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__length__unknown_vector);
    972  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, templates_def__evaluate__parenthesis_error);
    973  1.1  jmmv 
    974  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__empty_input);
    975  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__value__ok);
    976  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__value__unknown_variable);
    977  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__vector_length__ok);
    978  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__vector_length__unknown_vector);
    979  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__vector_value__ok);
    980  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__vector_value__unknown_vector);
    981  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__vector_value__out_of_range__empty);
    982  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__vector_value__out_of_range__not_empty);
    983  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__if__one_level__taken);
    984  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__if__one_level__not_taken);
    985  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__if__multiple_levels__taken);
    986  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__if__multiple_levels__not_taken);
    987  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__loop__no_iterations);
    988  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__loop__multiple_iterations);
    989  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__loop__nested__no_iterations);
    990  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__loop__nested__multiple_iterations);
    991  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__loop__sequential);
    992  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__loop__scoping);
    993  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__mismatched_delimiters);
    994  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__empty_statement);
    995  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__unknown_statement);
    996  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__invalid_narguments);
    997  1.1  jmmv 
    998  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__files__ok);
    999  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__files__input_error);
   1000  1.1  jmmv     ATF_ADD_TEST_CASE(tcs, instantiate__files__output_error);
   1001  1.1  jmmv }
   1002