This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,49 @@
#######################################################################
# Software License Agreement (AGPL-3 License)
#
# OpenViBE SDK Test Software
# Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
# Copyright (C) Inria, 2015-2017,V1.0
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License version 3,
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#######################################################################
FUNCTION(SETUP_TEST)
SET_BUILD_PLATFORM()
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBECommon")
INCLUDE("FindOpenViBEModuleXML")
INCLUDE("FindOpenViBEModuleFS")
INCLUDE("FindThirdPartyBoost")
INCLUDE("FindThirdPartyBoost_FileSystem")
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${TESTS_FOLDER}) # Place project in folder unit-test (for some IDE)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GTEST_BOTH_LIBRARIES})
# Add test with parameter to driver
ADD_DEFINITIONS("-DDATA_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/data\"")
ADD_DEFINITIONS("-DTEMP_DIR=\"${OVT_TEST_TEMPORARY_DIR}\"")
ENDFUNCTION()
PROJECT(openvibe-module-xml-reader-test)
ADD_EXECUTABLE(${PROJECT_NAME} uoXMLReaderTest.cpp)
SETUP_TEST()
ADD_TEST(NAME uoXMLReaderTest COMMAND ${PROJECT_NAME})
PROJECT(openvibe-module-xml-writer-test)
ADD_EXECUTABLE(${PROJECT_NAME} uoXMLWriterTest.cpp)
SETUP_TEST()
ADD_TEST(NAME uoXMLWriterTest COMMAND ${PROJECT_NAME})
@@ -0,0 +1,5 @@
<Document name="Français">
<Node>Français 1 (àèáéîôïç)</Node>
<Node>Français 2 (àèáéîôïç)</Node>
<Node>Français 3 (àèáéîôïç)</Node>
</Document>
@@ -0,0 +1,5 @@
<Document name="NB SP">
<Node>NB SP 1</Node>
<Node>NB SP 2</Node>
<Node>NB SP 3</Node>
</Document>
@@ -0,0 +1,11 @@
<Document name="test_reference">
<NodeWithChildren>
<ChildNodeWithData>child node data with more than 10 alphanumeric characters</ChildNodeWithData>
<ChildNodeEmpty></ChildNodeEmpty>
<ChildNodeWithChildren>
<ChildNodeEmpty></ChildNodeEmpty>
</ChildNodeWithChildren>
</NodeWithChildren>
<NodeWithData status="hasData">node data with special characters &lt;&gt;,;:!?./&amp;"'(-_)=~#{[|`\^@]}/*-+</NodeWithData>
<NodeEmptyWithNumber666 status="noData" ref="test"></NodeEmptyWithNumber666>
</Document>
@@ -0,0 +1,5 @@
<Document name="日本語">
<Node>日本語 1</Node>
<Node>日本語 2</Node>
<Node>日本語 3</Node>
</Document>
@@ -0,0 +1,202 @@
/*********************************************************************
* Software License Agreement (AGPL-3 License)
*
* OpenViBE SDK Test Software
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
* Copyright (C) Inria, 2015-2017,V1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <memory>
#include "xml/IReader.h"
#include "xml/IXMLHandler.h"
#include <fs/Files.h>
#include <gtest/gtest.h>
class CReaderCallBack final : public XML::IReaderCallBack
{
public:
struct SNode
{
std::string name;
std::string data;
std::map<std::string, std::string> attributes;
std::vector<std::shared_ptr<SNode>> children;
std::shared_ptr<SNode> parent{ nullptr };
};
std::shared_ptr<SNode> m_CurrentNode{ nullptr };
protected:
void openChild(const char* name, const char** attributeName, const char** attributeValue, const size_t nAttribute) override
{
auto node = std::make_shared<SNode>();
if (m_CurrentNode)
{
node->parent = m_CurrentNode;
m_CurrentNode->children.push_back(node);
}
m_CurrentNode = node;
m_CurrentNode->name = name;
for (size_t i = 0; i < nAttribute; ++i) { m_CurrentNode->attributes[attributeName[i]] = attributeValue[i]; }
}
void processChildData(const char* data) override { m_CurrentNode->data = data; }
void closeChild() override { if (m_CurrentNode->parent) { m_CurrentNode = m_CurrentNode->parent; } }
};
TEST(XML_Reader_Test_Case, validateReader)
{
std::string dataFile = std::string(DATA_DIR) + "/ref_data.xml";
CReaderCallBack callback;
XML::IReader* xmlReader = createReader(callback);
FILE* inputTestDataFile = fopen(dataFile.c_str(), "r");
ASSERT_NE(nullptr, inputTestDataFile);
char dataBuffer[1024];
while (!feof(inputTestDataFile))
{
size_t length = std::fread(dataBuffer, 1, sizeof(dataBuffer), inputTestDataFile);
xmlReader->processData(dataBuffer, length);
}
std::fclose(inputTestDataFile);
xmlReader->release();
// Analyze results
auto rootNode = callback.m_CurrentNode;
// Root node check
ASSERT_EQ("Document", rootNode->name);
ASSERT_EQ(1, rootNode->attributes.size());
ASSERT_EQ("test_reference", rootNode->attributes["name"]);
ASSERT_EQ(3, rootNode->children.size());
auto complexChild = rootNode->children[0];
auto dataChild = rootNode->children[1];
auto emptyChild = rootNode->children[2];
// Simple child with data check
ASSERT_EQ("NodeWithData", dataChild->name);
ASSERT_EQ("node data with special characters <>,;:!?./&\"'(-_)=~#{[|`\\^@]}/*-+", dataChild->data);
ASSERT_EQ(1, dataChild->attributes.size());
ASSERT_EQ("hasData", dataChild->attributes["status"]);
// Simple child with no data and multiple attributes check
ASSERT_EQ("NodeEmptyWithNumber666", emptyChild->name);
ASSERT_EQ(2, emptyChild->attributes.size());
ASSERT_EQ("noData", emptyChild->attributes["status"]);
ASSERT_EQ("test", emptyChild->attributes["ref"]);
// Complex child check
ASSERT_EQ("NodeWithChildren", complexChild->name);
ASSERT_TRUE(complexChild->attributes.empty());
ASSERT_EQ(3, complexChild->children.size());
dataChild = complexChild->children[0];
emptyChild = complexChild->children[1];
complexChild = complexChild->children[2];
ASSERT_EQ("ChildNodeWithData", dataChild->name);
ASSERT_EQ("child node data with more than 10 alphanumeric characters", dataChild->data);
ASSERT_EQ(0, dataChild->attributes.size());
ASSERT_EQ("ChildNodeEmpty", emptyChild->name);
ASSERT_TRUE(emptyChild->attributes.empty());
ASSERT_EQ("ChildNodeWithChildren", complexChild->name);
ASSERT_TRUE(complexChild->attributes.empty());
ASSERT_EQ(1, complexChild->children.size());
}
TEST(XML_Reader_Test_Case, validateHandlerReadJapanese)
{
const std::string dataFile = std::string(DATA_DIR) + "/日本語/ref_data_jp.xml";
XML::IXMLHandler* xmlHandler = XML::createXMLHandler();
XML::IXMLNode* rootNode = xmlHandler->parseFile(dataFile.c_str());
ASSERT_NE(nullptr, rootNode);
ASSERT_EQ(std::string("Document"), rootNode->getName());
ASSERT_TRUE(rootNode->hasAttribute("name"));
ASSERT_EQ(std::string("日本語"), rootNode->getAttribute("name"));
ASSERT_EQ(3, rootNode->getChildCount());
ASSERT_STREQ("日本語 1", rootNode->getChild(0)->getPCData());
xmlHandler->release();
}
TEST(XML_Reader_Test_Case, validateHandlerReadFrench)
{
const std::string dataFile = std::string(DATA_DIR) + "/Français/ref_data_fr.xml";
XML::IXMLHandler* xmlHandler = XML::createXMLHandler();
XML::IXMLNode* rootNode = xmlHandler->parseFile(dataFile.c_str());
ASSERT_NE(nullptr, rootNode);
ASSERT_EQ(std::string("Document"), rootNode->getName());
ASSERT_TRUE(rootNode->hasAttribute("name"));
ASSERT_EQ(std::string("Français"), rootNode->getAttribute("name"));
ASSERT_EQ(3, rootNode->getChildCount());
ASSERT_STREQ("Français 1 (àèáéîôïç)", rootNode->getChild(0)->getPCData());
xmlHandler->release();
}
TEST(XML_Reader_Test_Case, validateHandlerReadNBSP)
{
const std::string dataFile = std::string(DATA_DIR) + "/NB\xC2\xA0SP/ref_data_nbsp.xml";
XML::IXMLHandler* xmlHandler = XML::createXMLHandler();
XML::IXMLNode* rootNode = xmlHandler->parseFile(dataFile.c_str());
ASSERT_NE(nullptr, rootNode);
ASSERT_EQ(std::string("Document"), rootNode->getName());
ASSERT_TRUE(rootNode->hasAttribute("name"));
ASSERT_EQ(std::string("NB\xC2\xA0SP"), rootNode->getAttribute("name"));
ASSERT_EQ(3, rootNode->getChildCount());
ASSERT_STREQ("NB\xC2\xA0SP 1", rootNode->getChild(0)->getPCData());
xmlHandler->release();
}
int uoXMLReaderTest(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);
::testing::GTEST_FLAG(filter) = "XML_Reader_Test_Case.*";
return RUN_ALL_TESTS();
}
@@ -0,0 +1,176 @@
/*********************************************************************
* Software License Agreement (AGPL-3 License)
*
* OpenViBE SDK Test Software
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
* Copyright (C) Inria, 2015-2017,V1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <fstream>
#include <cstdio>
#include <xml/IWriter.h>
#include <xml/IXMLHandler.h>
#include <fs/Files.h>
#include <gtest/gtest.h>
#include <boost/filesystem.hpp>
class CWriterCallBack : public XML::IWriterCallBack
{
public:
CWriterCallBack(const char* filename) { m_file = FS::Files::open(filename, "wb"); }
~CWriterCallBack() override { if (m_file) { std::fclose(m_file); } } // in case release is not called
void write(const char* outputData) override { if (m_file) { std::fputs(outputData, m_file); } }
// necessary thjor the test to close the stream and re-open it for inspection
void release()
{
std::fclose(m_file);
m_file = nullptr;
}
private:
std::FILE* m_file{ nullptr };
};
TEST(XML_Writer_Test_Case, validateWriter)
{
std::string expectedFile = DATA_DIR "/ref_data.xml";
std::string outputFile = TEMP_DIR "/uoXMLWriterTest.xml";
FS::Files::createPath(TEMP_DIR);
ASSERT_TRUE(FS::Files::directoryExists(TEMP_DIR));
FS::Files::removeAll(outputFile.c_str());
ASSERT_FALSE(FS::Files::fileExists(outputFile.c_str()));
// The test serializes a known xml sequence and compares the output
// to a reference.
// serializing
CWriterCallBack callback(outputFile.c_str());
XML::IWriter* writer = createWriter(callback);
writer->openChild("Document"); ///< Document Node
writer->setAttribute("name", "test_reference");
writer->openChild("NodeWithChildren"); ///< NodeWithChildren Node
writer->openChild("ChildNodeWithData");
writer->setChildData("child node data with more than 10 alphanumeric characters");
writer->closeChild();
writer->openChild("ChildNodeEmpty");
writer->closeChild();
writer->openChild("ChildNodeWithChildren");
writer->openChild("ChildNodeEmpty");
writer->closeChild();
writer->closeChild();
writer->closeChild(); ///< NodeWithChildren END
writer->openChild("NodeWithData");
writer->setAttribute("status", "hasData");
writer->setChildData("node data with special characters <>,;:!?./&\"'(-_)=~#{[|`\\^@]}/*-+");
writer->closeChild();
writer->openChild("NodeEmptyWithNumber666");
writer->setAttribute("status", "noData");
writer->setAttribute("ref", "test");
writer->closeChild();
writer->closeChild(); ///< Document Node END
writer->release();
callback.release();
// comparison part
std::ifstream generatedStream;
std::ifstream expectedStream;
FS::Files::openIFStream(generatedStream, outputFile.c_str());
FS::Files::openIFStream(expectedStream, expectedFile.c_str());
ASSERT_TRUE(generatedStream.is_open());
ASSERT_TRUE(expectedStream.is_open());
std::string generatedString;
std::string expectedString;
while (std::getline(expectedStream, expectedString))
{
std::getline(generatedStream, generatedString);
ASSERT_EQ(expectedString, generatedString);
}
// last check to verify the expected file has no additional line
std::getline(generatedStream, generatedString);
}
TEST(XML_Writer_Test_Case, validateHandlerWriteToJapanesePath)
{
std::string expectedFile = DATA_DIR "/日本語/ref_data_jp.xml";
std::string outputFile = TEMP_DIR "/オッペンヴィベ/日本語.xml";
FS::Files::createPath(TEMP_DIR);
ASSERT_TRUE(FS::Files::directoryExists(TEMP_DIR));
FS::Files::removeAll(outputFile.c_str());
ASSERT_FALSE(FS::Files::fileExists(outputFile.c_str()));
XML::IXMLHandler* xmlHandler = XML::createXMLHandler();
std::string testData = "<Document name=\"日本語\"><Node>日本語 1</Node><Node>日本語 2</Node><Node>日本語 3</Node></Document>";
XML::IXMLNode* rootNode = xmlHandler->parseString(testData.c_str(), testData.size());
xmlHandler->writeXMLInFile(*rootNode, outputFile.c_str());
// comparison part
std::ifstream generatedStream;
std::ifstream expectedStream;
FS::Files::openIFStream(generatedStream, outputFile.c_str());
FS::Files::openIFStream(expectedStream, expectedFile.c_str());
ASSERT_TRUE(generatedStream.is_open());
ASSERT_TRUE(expectedStream.is_open());
std::string generatedString;
std::string expectedString;
while (std::getline(expectedStream, expectedString))
{
std::getline(generatedStream, generatedString);
ASSERT_EQ(expectedString, generatedString);
}
// last check to verify the expected file has no additional line
std::getline(generatedStream, generatedString);
}
int uoXMLWriterTest(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);
::testing::GTEST_FLAG(filter) = "XML_Writer_Test_Case.*";
return RUN_ALL_TESTS();
}