GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/unittests/utils/xml.cc Lines: 238 238 100.0 %
Date: 2021-03-17 Branches: 948 2392 39.6 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2014-2019  The ManaPlus Developers
4
 *  Copyright (C) 2019-2021  Andrei Karas
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "unittests/unittests.h"
23
24
#include "client.h"
25
#include "configuration.h"
26
#include "configmanager.h"
27
#include "dirs.h"
28
#include "graphicsmanager.h"
29
30
#include "being/actorsprite.h"
31
32
#include "fs/virtfs/fs.h"
33
34
#include "gui/gui.h"
35
#include "gui/theme.h"
36
37
#include "utils/delete2.h"
38
#include "utils/env.h"
39
#ifdef ENABLE_PUGIXML
40
#include "utils/xmlwriter.h"
41
#endif  // ENABLE_PUGIXML
42
43
#include "render/sdlgraphics.h"
44
45
#include "resources/sdlimagehelper.h"
46
47
#include "resources/resourcemanager/resourcemanager.h"
48
49
#include "debug.h"
50
51
3
TEST_CASE("xml test1", "")
52
{
53



4
    REQUIRE(client == nullptr);
54



4
    REQUIRE(gui == nullptr);
55
1
    ResourceManager::cleanOrphans(true);
56
1
    ResourceManager::deleteInstance();
57
1
}
58
59
15
TEST_CASE("xml doc", "")
60
{
61
13
    setEnv("SDL_VIDEODRIVER", "dummy");
62
63
13
    client = new Client;
64
13
    XML::initXML();
65
39
    VirtFs::mountDirSilent("data", Append_false);
66
39
    VirtFs::mountDirSilent("../data", Append_false);
67
13
    mainGraphics = new SDLGraphics;
68
26
    imageHelper = new SDLImageHelper();
69
70
13
    Dirs::initRootDir();
71
13
    Dirs::initHomeDir();
72
73
13
    ConfigManager::initConfiguration();
74
13
    setConfigDefaults2(config);
75
13
    setBrandingDefaults(branding);
76
77
#ifdef USE_SDL2
78
13
    SDLImageHelper::setRenderer(graphicsManager.createRenderer(
79
        GraphicsManager::createWindow(640, 480, 0,
80
13
        SDL_WINDOW_SHOWN | SDL_SWSURFACE), SDL_RENDERER_SOFTWARE));
81
#else  // USE_SDL2
82
83
    GraphicsManager::createWindow(640, 480, 0, SDL_ANYFORMAT | SDL_SWSURFACE);
84
#endif  // USE_SDL2
85
86
13
    theme = new Theme;
87
13
    Theme::selectSkin();
88
89
13
    const char *const tempXmlName = "tempxml.xml";
90
13
    ActorSprite::load();
91
13
    gui = new Gui();
92
13
    gui->postInit(mainGraphics);
93
94



91
    SECTION("load1")
95
    {
96
        XML::Document doc("graphics/gui/browserbox.xml",
97
            UseVirtFs_true,
98

4
            SkipError_false);
99



5
        REQUIRE(doc.isLoaded() == true);
100



4
        REQUIRE(doc.isValid() == true);
101




4
        REQUIRE(doc.rootNode() != nullptr);
102




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "skinset") == true);
103




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "skinset123") == false);
104




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
105
//        REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
106
    }
107
108



91
    SECTION("load2")
109
    {
110
        const char *const xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
111
            "<root><data option1=\"false\" option2=\"true\"/>"
112
1
            "<cont>this is test</cont></root>";
113
2
        XML::Document doc(xml, strlen(xml));
114



5
        REQUIRE(doc.isLoaded() == true);
115



4
        REQUIRE(doc.isValid() == true);
116




4
        REQUIRE(doc.rootNode() != nullptr);
117




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
118




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root123") == false);
119




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
120




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
121




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
122





4
        REQUIRE(XmlHaveChildContent(doc.rootNode()) == false);
123
    }
124
125



91
    SECTION("load3")
126
    {
127
        const std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
128
            "<!-- comment here\nand here -->"
129
3
            "<root><data option1=\"false\" option2=\"true\"/></root>";
130
3
        XML::Document doc(xml.c_str(), xml.size());
131



5
        REQUIRE(doc.isLoaded() == true);
132



4
        REQUIRE(doc.isValid() == true);
133




4
        REQUIRE(doc.rootNode() != nullptr);
134




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
135




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root123") == false);
136




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
137




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
138




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
139





4
        REQUIRE(XmlHaveChildContent(doc.rootNode()) == false);
140
    }
141
142



91
    SECTION("load4")
143
    {
144
        const char *const xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
145
1
            "<root>this is test</root>";
146
2
        XML::Document doc(xml, strlen(xml));
147



5
        REQUIRE(doc.isLoaded() == true);
148



4
        REQUIRE(doc.isValid() == true);
149




4
        REQUIRE(doc.rootNode() != nullptr);
150




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
151




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root123") == false);
152




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
153




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
154




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
155





4
        REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
156




3
        REQUIRE(!strcmp(XmlChildContent(doc.rootNode()), "this is test"));
157
    }
158
159



91
    SECTION("load5")
160
    {
161


8
        XML::Document doc(pathJoin(VirtFs::getRealDir(
162
            "test/serverlistplus.xml"), "test/serverlistplus.xml"),
163
            UseVirtFs_false,
164
3
            SkipError_false);
165



5
        REQUIRE(doc.isLoaded() == true);
166



4
        REQUIRE(doc.isValid() == true);
167




4
        REQUIRE(doc.rootNode() != nullptr);
168




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "serverlist") == true);
169




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "serverlist123") == false);
170




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
171




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option1") == false);
172




4
        REQUIRE(XmlHasProp(doc.rootNode(), "option123") == false);
173




4
        REQUIRE(XmlHasProp(doc.rootNode(), "version") == true);
174
    }
175
176



91
    SECTION("properties")
177
    {
178
        XML::Document doc("graphics/gui/browserbox.xml",
179
            UseVirtFs_true,
180

4
            SkipError_false);
181
182
1
        XmlNodeConstPtr rootNode = doc.rootNode();
183




8
        REQUIRE(XML::getProperty(rootNode, "image", "") == "window.png");
184
    }
185
186



91
    SECTION("for each")
187
    {
188
        XML::Document doc("graphics/gui/browserbox.xml",
189
            UseVirtFs_true,
190

4
            SkipError_false);
191
192
1
        XmlNodeConstPtr rootNode = doc.rootNode();
193
//        REQUIRE(XmlHaveChildContent(rootNode) == true);
194
1
        XmlNodePtr node = XmlNodeDefault;
195
2
        for_each_xml_child_node(widgetNode, rootNode)
196
        {
197
2
            node = widgetNode;
198

2
            if (xmlNameEqual(node, "widget"))
199
                break;
200
        }
201



4
        REQUIRE(node != nullptr);
202



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
203




4
        REQUIRE(xmlNameEqual(node, "widget") == true);
204
//        REQUIRE(XmlHaveChildContent(node) == true);
205
2
        for_each_xml_child_node(optionNode, node)
206
        {
207
2
            node = optionNode;
208

2
            if (xmlNameEqual(node, "option"))
209
                break;
210
        }
211



4
        REQUIRE(node != nullptr);
212



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
213




4
        REQUIRE(xmlNameEqual(node, "option") == true);
214




4
        REQUIRE(XmlHaveChildContent(node) == false);
215




4
        REQUIRE(XmlHasProp(node, "name") == true);
216




4
        REQUIRE(XmlHasProp(node, "value") == true);
217




4
        REQUIRE(XmlHasProp(node, "option123") == false);
218




8
        REQUIRE(XML::getProperty(node, "name", "") == "padding");
219




8
        REQUIRE(XML::langProperty(node, "name", "") == "padding");
220




4
        REQUIRE(XML::getProperty(node, "value", 0) == 1);
221




4
        REQUIRE(XML::getBoolProperty(node, "value", true) == true);
222




4
        REQUIRE(XML::getBoolProperty(node, "value", false) == false);
223




4
        REQUIRE(XML::getIntProperty(node, "value", -1, -10, 100) == 1);
224
    }
225
226



91
    SECTION("child1")
227
    {
228
        XML::Document doc("graphics/gui/browserbox.xml",
229
            UseVirtFs_true,
230

4
            SkipError_false);
231
232
1
        XmlNodeConstPtr rootNode = doc.rootNode();
233
1
        XmlNodePtr node = XML::findFirstChildByName(rootNode, "widget");
234



4
        REQUIRE(node != nullptr);
235



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
236




4
        REQUIRE(xmlNameEqual(node, "widget") == true);
237
//        REQUIRE(XmlHaveChildContent(node) == true);
238
1
        node = XML::findFirstChildByName(node, "option");
239



4
        REQUIRE(node != nullptr);
240



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
241




4
        REQUIRE(xmlNameEqual(node, "option") == true);
242




4
        REQUIRE(XmlHaveChildContent(node) == false);
243




4
        REQUIRE(XmlHasProp(node, "name") == true);
244




4
        REQUIRE(XmlHasProp(node, "value") == true);
245




4
        REQUIRE(XmlHasProp(node, "option123") == false);
246




8
        REQUIRE(XML::getProperty(node, "name", "") == "padding");
247




8
        REQUIRE(XML::langProperty(node, "name", "") == "padding");
248




8
        REQUIRE(XML::langProperty(node, "name123", "").empty());
249




4
        REQUIRE(XML::getProperty(node, "value", 0) == 1);
250




4
        REQUIRE(XML::getProperty(node, "value123", -1) == -1);
251




4
        REQUIRE(XML::getBoolProperty(node, "value", true) == true);
252




4
        REQUIRE(XML::getBoolProperty(node, "value", false) == false);
253




4
        REQUIRE(XML::getBoolProperty(node, "value123", true) == true);
254




4
        REQUIRE(XML::getIntProperty(node, "value", -1, -10, 100) == 1);
255




4
        REQUIRE(XML::getIntProperty(node, "value123", -1, -10, 100) == -1);
256
    }
257
258



91
    SECTION("child2")
259
    {
260
        const char *const xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
261
            "<root><data option1=\"false\" option2=\"true\" "
262
1
            "option3=\"10.5\"/></root>";
263
2
        XML::Document doc(xml, strlen(xml));
264
1
        XmlNodeConstPtr rootNode = doc.rootNode();
265




4
        REQUIRE(XmlHaveChildContent(rootNode) == false);
266
1
        XmlNodePtr node = XML::findFirstChildByName(rootNode, "data");
267



4
        REQUIRE(node != nullptr);
268



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
269




4
        REQUIRE(xmlNameEqual(node, "data") == true);
270




4
        REQUIRE(XmlHaveChildContent(node) == false);
271




4
        REQUIRE(XmlHasProp(node, "option1") == true);
272




4
        REQUIRE(XmlHasProp(node, "option123") == false);
273




4
        REQUIRE(XML::getBoolProperty(node, "option1", true) == false);
274




4
        REQUIRE(XML::getBoolProperty(node, "option2", false) == true);
275
1
        const float opt3 = XML::getFloatProperty(node, "option3", 0.0);
276



4
        REQUIRE(opt3 > 10);
277



4
        REQUIRE(opt3 < 11);
278
    }
279
280



91
    SECTION("child3")
281
    {
282
        const std::string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
283
            "<!-- comment --><root><!-- comment -->"
284
            "<data option1=\"false\" option2=\"true\" "
285
3
            "option3=\"10.5\"/><!-- comment --></root>";
286
3
        XML::Document doc(xml.c_str(), xml.size());
287
1
        XmlNodeConstPtr rootNode = doc.rootNode();
288
//        REQUIRE(XmlHaveChildContent(rootNode) == true);
289
1
        XmlNodePtr node = XML::findFirstChildByName(rootNode, "data");
290



4
        REQUIRE(node != nullptr);
291



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
292




4
        REQUIRE(xmlNameEqual(node, "data") == true);
293




4
        REQUIRE(XmlHaveChildContent(node) == false);
294




4
        REQUIRE(XmlHasProp(node, "option1") == true);
295




4
        REQUIRE(XmlHasProp(node, "option123") == false);
296




4
        REQUIRE(XML::getBoolProperty(node, "option1", true) == false);
297




4
        REQUIRE(XML::getBoolProperty(node, "option2", false) == true);
298
1
        const float opt3 = XML::getFloatProperty(node, "option3", 0.0);
299



4
        REQUIRE(opt3 > 10);
300



4
        REQUIRE(opt3 < 11);
301
    }
302
303



91
    SECTION("validate")
304
    {
305
//        REQUIRE(XML::Document::validateXml(
306
//            "graphics/gui/browserbox.xml") == true);
307




7
        REQUIRE(XML::Document::validateXml(
308
            "graphics/gui/bubble.png") == false);
309




7
        REQUIRE(XML::Document::validateXml(
310
            "graphics/gui/testfile123.xml") == false);
311
    }
312
313



91
    SECTION("save1")
314
    {
315
        // clean
316
1
        ::remove(tempXmlName);
317
318
        // save
319
1
        FILE *const testFile = fopen(tempXmlName, "w");
320



3
        REQUIRE(testFile);
321
1
        fclose(testFile);
322
1
        XmlTextWriterPtr writer = XmlNewTextWriterFilename(
323
            tempXmlName,
324
            0);
325
1
        XmlTextWriterSetIndent(writer, 1);
326
1
        XmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr);
327
1
        XmlTextWriterStartRootElement(writer, "root");
328
1
        XmlTextWriterEndDocument(writer);
329
        XmlSaveTextWriterFilename(writer, tempXmlName);
330
1
        XmlFreeTextWriter(writer);
331
332
        // load
333
        XML::Document doc(tempXmlName,
334
            UseVirtFs_false,
335

4
            SkipError_false);
336



5
        REQUIRE(doc.isLoaded() == true);
337



4
        REQUIRE(doc.isValid() == true);
338




4
        REQUIRE(doc.rootNode() != nullptr);
339




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
340




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "skinset123") == false);
341




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
342
//        REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
343
344
        // clean again
345
1
        ::remove(tempXmlName);
346
    }
347
348



91
    SECTION("save2")
349
    {
350
        // clean
351
1
        ::remove(tempXmlName);
352
353
        // save
354
1
        FILE *const testFile = fopen(tempXmlName, "w");
355



3
        REQUIRE(testFile);
356
1
        fclose(testFile);
357
1
        XmlTextWriterPtr writer = XmlNewTextWriterFilename(
358
            tempXmlName,
359
            0);
360
1
        XmlTextWriterSetIndent(writer, 1);
361
1
        XmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr);
362
1
        XmlTextWriterStartRootElement(writer, "root");
363
364
1
        XmlTextWriterStartElement(writer, "option");
365
1
        XmlTextWriterWriteAttribute(writer, "name", "the name");
366
1
        XmlTextWriterWriteAttribute(writer, "value", "the value");
367
1
        XmlTextWriterEndElement(writer);
368
369
1
        XmlTextWriterEndDocument(writer);
370
        XmlSaveTextWriterFilename(writer, tempXmlName);
371
1
        XmlFreeTextWriter(writer);
372
373
        // load
374
        XML::Document doc(tempXmlName,
375
            UseVirtFs_false,
376

4
            SkipError_false);
377



5
        REQUIRE(doc.isLoaded() == true);
378



4
        REQUIRE(doc.isValid() == true);
379




4
        REQUIRE(doc.rootNode() != nullptr);
380




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "root") == true);
381




4
        REQUIRE(xmlNameEqual(doc.rootNode(), "skinset123") == false);
382




4
        REQUIRE(xmlTypeEqual(doc.rootNode(), XML_ELEMENT_NODE) == true);
383
//        REQUIRE(XmlHaveChildContent(doc.rootNode()) == true);
384

1
        XmlNodePtr node = XML::findFirstChildByName(doc.rootNode(), "option");
385



4
        REQUIRE(node != nullptr);
386



4
        REQUIRE(xmlTypeEqual(node, XML_ELEMENT_NODE) == true);
387




4
        REQUIRE(xmlNameEqual(node, "option") == true);
388




4
        REQUIRE(XmlHaveChildContent(node) == false);
389




4
        REQUIRE(XmlHasProp(node, "name") == true);
390




4
        REQUIRE(XmlHasProp(node, "value") == true);
391




4
        REQUIRE(XmlHasProp(node, "option123") == false);
392




8
        REQUIRE(XML::getProperty(node, "name", "") == "the name");
393




8
        REQUIRE(XML::getProperty(node, "value", "") == "the value");
394
395
        // clean again
396
1
        ::remove(tempXmlName);
397
    }
398
399
13
    delete2(theme)
400
13
    delete2(client)
401
13
    ResourceManager::deleteInstance();
402
39
    VirtFs::unmountDirSilent("data");
403
39
    VirtFs::unmountDirSilent("../data");
404
13
}
405
406
3
TEST_CASE("xml test2", "")
407
{
408



4
    REQUIRE(gui == nullptr);
409
1
    ResourceManager::cleanOrphans(true);
410
1
    ResourceManager::deleteInstance();
411

4
}