Cutelee  6.1.0
testscriptabletags.cpp
1 /*
2  This file is part of the Cutelee template system.
3 
4  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2.1 of the Licence, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #ifndef SCRIPTABLETAGSTEST_H
22 #define SCRIPTABLETAGSTEST_H
23 
24 #include <QtCore/QDebug>
25 #include <QtCore/QDir>
26 #include <QtCore/QFileInfo>
27 #include <QtTest/QTest>
28 
29 #include "context.h"
30 #include "coverageobject.h"
31 #include "engine.h"
32 #include "filterexpression.h"
33 #include "cutelee_paths.h"
34 #include "template.h"
35 
36 typedef QHash<QString, QVariant> Dict;
37 
38 Q_DECLARE_METATYPE(Cutelee::Error)
39 
40 using namespace Cutelee;
41 
43 {
44  Q_OBJECT
45 
46 private Q_SLOTS:
47  void initTestCase();
48 
49  void testBasicSyntax_data();
50  void testBasicSyntax() { doTest(); }
51 
52  void testResolve_data();
53  void testResolve() { doTest(); }
54 
55  void cleanupTestCase();
56 
57 private:
58  void doTest();
59 
60  Engine *m_engine;
61 };
62 
63 void TestScriptableTagsSyntax::initTestCase()
64 {
65  Q_INIT_RESOURCE(testresource);
66 
67  m_engine = new Engine(this);
68  m_engine->setPluginPaths({
69  QStringLiteral(CUTELEE_PLUGIN_PATH),
70  QStringLiteral(":/plugins/") // For scripteddefaults.qs
71  });
72  m_engine->addDefaultLibrary(QStringLiteral("cutelee_scriptabletags"));
73 }
74 
75 void TestScriptableTagsSyntax::cleanupTestCase() { delete m_engine; }
76 
77 void TestScriptableTagsSyntax::doTest()
78 {
79  QFETCH(QString, input);
80  QFETCH(Dict, dict);
81  QFETCH(QString, output);
82  QFETCH(Cutelee::Error, error);
83 
84  auto t = m_engine->newTemplate(input, QLatin1String(QTest::currentDataTag()));
85 
86  if (t->error() != NoError) {
87  if (t->error() != error)
88  qDebug() << t->errorString();
89  QCOMPARE(t->error(), error);
90  return;
91  }
92 
93  Context context(dict);
94 
95  auto result = t->render(&context);
96 
97  if (t->error() != NoError) {
98  if (t->error() != error)
99  qDebug() << t->errorString();
100  QCOMPARE(t->error(), error);
101  return;
102  }
103 
104  QCOMPARE(t->error(), NoError);
105 
106  // Didn't catch any errors, so make sure I didn't expect any.
107  QCOMPARE(NoError, error);
108 
109  QCOMPARE(t->error(), NoError);
110 
111  QCOMPARE(result, output);
112 }
113 
114 void TestScriptableTagsSyntax::testBasicSyntax_data()
115 {
116  QTest::addColumn<QString>("input");
117  QTest::addColumn<Dict>("dict");
118  QTest::addColumn<QString>("output");
119  QTest::addColumn<Cutelee::Error>("error");
120 
121  Dict dict;
122 
123  dict.insert(QStringLiteral("boo"), QStringLiteral("Far"));
124  dict.insert(QStringLiteral("booList"),
125  QVariantList{QStringLiteral("Tom"), QStringLiteral("Dick"),
126  QStringLiteral("Harry")});
127 
128  QTest::newRow("scriptable-tags01")
129  << "{% load scripteddefaults %}{% if2 "
130  "\"something\\\" stupid\" %}{{ boo "
131  "}}{% endif2 %}"
132  << dict << QStringLiteral("Far") << NoError;
133 
134  // Nest c++ tags inside scripted tags.
135  QTest::newRow("scriptable-tags02")
136  << "{% load scripteddefaults %}{% if2 \"something\\\" stupid\" %}{% "
137  "for "
138  "name in booList %}:{{ name }};{% endfor %}{% endif2 %}"
139  << dict << QStringLiteral(":Tom;:Dick;:Harry;") << NoError;
140 
141  // Nest c++ tags inside scripted tags.
142  QTest::newRow("scriptable-tags03") << QStringLiteral(
143  "{% load scripteddefaults %}{% if2 boo %}yes{% else %}no{% endif2 %}")
144  << dict << QStringLiteral("yes")
145  << NoError;
146  QTest::newRow("scriptable-tags04") << QStringLiteral(
147  "{% load scripteddefaults %}{% if2 foo %}yes{% else %}no{% endif2 %}")
148  << dict << QStringLiteral("no") << NoError;
149 
150  QTest::newRow("scriptable-tags05")
151  << QStringLiteral("{% load scripteddefaults %}{{ boo|upper }}") << dict
152  << QStringLiteral("FAR") << NoError;
153 
154  dict.insert(QStringLiteral("boo"), QStringLiteral("Far & away"));
155  // Variables are escaped ...
156  QTest::newRow("scriptable-tags06")
157  << QStringLiteral("{% load scripteddefaults %}{{ boo }}") << dict
158  << QStringLiteral("Far &amp; away") << NoError;
159  // and scripted filters can mark output as 'safe'.
160  QTest::newRow("scriptable-tags07")
161  << QStringLiteral("{% load scripteddefaults %}{{ boo|safe2 }}") << dict
162  << QStringLiteral("Far & away") << NoError;
163 
164  // Filters can take arguments
165  QTest::newRow("scriptable-tags08")
166  << "{% load scripteddefaults %}{{ booList|join2:\" \" }}" << dict
167  << QStringLiteral("Tom Dick Harry") << NoError;
168 
169  // Literals in tags are compared un-escaped.
170  QTest::newRow("scriptable-tags09")
171  << "{% load scripteddefaults %}{% ifequal2 boo \"Far & away\" %}yes{% "
172  "endifequal2 %}"
173  << dict << QStringLiteral("yes") << NoError;
174 
175  // Literals in arguments to filters are not escaped.
176  QTest::newRow("scriptable-tags10")
177  << "{% load scripteddefaults %}{{ booList|join2:\" & \" }}" << dict
178  << QStringLiteral("Tom & Dick & Harry") << NoError;
179 
180  // Nor are variables.
181  dict.insert(QStringLiteral("amp"), QStringLiteral(" & "));
182  QTest::newRow("scriptable-tags11")
183  << QStringLiteral("{% load scripteddefaults %}{{ booList|join2:amp }}")
184  << dict << QStringLiteral("Tom & Dick & Harry") << NoError;
185 
186  QTest::newRow("scriptable-load-error01")
187  << QStringLiteral("{% load %}{{ booList|join2:amp }}") << dict
188  << QString() << TagSyntaxError;
189 
190  dict.clear();
191 }
192 
193 void TestScriptableTagsSyntax::testResolve_data()
194 {
195  QTest::addColumn<QString>("input");
196  QTest::addColumn<Dict>("dict");
197  QTest::addColumn<QString>("output");
198  QTest::addColumn<Cutelee::Error>("error");
199 
200  Dict dict;
201  dict.insert(QStringLiteral("boo"), QStringLiteral("Far"));
202  dict.insert(QStringLiteral("zing"), QStringLiteral("Bang"));
203 
204  QTest::newRow("resolve-01")
205  << "{% load scripteddefaults %}{% resolver boo zing %}" << dict
206  << QStringLiteral("Far - Bang") << NoError;
207 }
208 
209 QTEST_MAIN(TestScriptableTagsSyntax)
210 #include "testscriptabletags.moc"
211 
212 #endif
The Context class holds the context to render a Template with.
Definition: context.h:119
Cutelee::Engine is the main entry point for creating Cutelee Templates.
Definition: engine.h:121
The Cutelee namespace holds all public Cutelee API.
Definition: Mainpage.dox:8