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