How To Use
 All Modules Pages
////////////////////////////////////////////////////////////////////////////////
///
/// \file
/// \author Gerald Fahrnholz
///
////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <set>
#include <map>
#include <memory>
#include <vector>
//-----------------------------------------------------------------------------
namespace pugi
{
class xml_document;
class xml_node;
}
//-----------------------------------------------------------------------------
namespace TestToolBox
{
// Forward declarations
struct IEventReceiver;
enum EventContext;
struct SettingsBase;
typedef std::shared_ptr<SettingsBase> SettingsBaseSp;
struct XmlCheckSettings;
typedef std::shared_ptr<XmlCheckSettings> XmlCheckSettingsSp;
class XmlCheck;
typedef std::shared_ptr<XmlCheck> XmlCheckSp;
//-----------------------------------------------------------------------------
namespace XmlServices
{
typedef void(*FuncToChangeAttributeValue)(
char const * in_attributeName,
std::string & io_attributeValue);
void DoNotChangeAttributeValue(
char const * in_attributeName,
std::string & io_attributeValue);
}
//-----------------------------------------------------------------------------
/// Helper class to automatically restore settings of singleton
/// TheXmlCheck() within destructor
class AutoRestoreXmlCheck
{
public:
AutoRestoreXmlCheck();
~AutoRestoreXmlCheck();
private:
SettingsBaseSp m_spSettings;
};
//-----------------------------------------------------------------------------
/// Check an XML tree/subtree or compare two trees/subtrees.
class XmlCheck
{
public:
///\cond do not document
// Constructor
XmlCheck() {};
// Destructor
virtual ~XmlCheck() {};
// Get the pointer to the only instance of this class
static XmlCheck* Get(void);
static XmlCheck* s_pXmlCheck;
virtual void Dump(EventContext in_context) const = 0;
// Release all resources
static void Cleanup(void);
// Support for creating an independent local instance of XmlCheck
static XmlCheckSp CreateLocalInstance(IEventReceiver* in_pEventReceiver);
///\endcond
/// Basic initialization
/// Define to which destination test events (e.g. failures) are reported
/// \return previous EventReceiver
virtual IEventReceiver* SetEventReceiver(IEventReceiver* in_pEventReceiver) = 0;
//---------------------------------------------------------------
//! \name General settings
//! \{
/// Set default values for checking XML data
virtual void SetDefaults(void) = 0;
/// Copy current settings to support later restoring
virtual SettingsBaseSp CopyCurrentSettings() const = 0;
virtual void RestoreCurrentSettings(SettingsBaseSp in_spSettings) = 0;
/// Set output mode for writing XML contents
/// Allowed values: CTX_PROT, CTX_INFO, CTX_TEST_EVENT
virtual void SetOutputModeForWritingXmlContents(EventContext in_outputMode) = 0;
/// Set amount of data written to test output
virtual void SetDetailedOutput(bool in_detailedOutput) = 0;
/// You can ignore or check the declaration block of an xml document
virtual void SetIgnoreDeclaration(bool in_ignoreDeclaration) = 0;
/// Define whether the given attribute shall be ignored when checking XML data
virtual void IgnoreAttribute(std::string const & in_attribute, bool in_ignore = true) = 0;
/// Return whether the given attribute shall be ignored when checking XML data
virtual bool IsAttributeToIgnore(std::string const & in_attribute) const = 0;
/// Define whether the given node shall be ignored when checking XML data
virtual void IgnoreNode(std::string const & in_nodeName, bool in_ignore = true) = 0;
/// Return whether the given node shall be ignored when checking XML data
virtual bool IsNodeToIgnore(std::string const & in_nodeName) const = 0;
/// \brief Define whether the given attribute is of type double and
/// in case of type double specify the precision to be used for
/// checking the value.
virtual void UseAsDoubleAttribute(std::string const & in_attribute, bool in_useAsDouble = true, int in_precision = 4) = 0;
/// Return whether the given attribute is of type double
virtual bool IsDoubleAttribute(std::string const & in_attribute) const = 0;
/// Return the precision used for checking of the given double attribute
virtual int GetPrecisionOfDoubleAttribute(std::string const & in_attribute) const = 0;
/// \brief Define whether the given node is of type double and
/// in case of type double specify the precision to be used for
/// checking the value.
virtual void UseAsDoubleNode(std::string const & in_nodeName, bool in_useAsDouble = true, int in_precision = 4) = 0;
/// Return whether the given node is of type double
virtual bool IsDoubleNode(std::string const & in_nodeName) const = 0;
/// Return the precision used for checking of the given double node
virtual int GetPrecisionOfDoubleNode(std::string const & in_nodeName) const = 0;
/// \brief Define whether the given attribute is of pointer type
/// If property is set then the contents will only be checked
/// whether value exists and is different from 0
virtual void UseAsPointerAttribute(std::string const & in_attribute, bool in_useAsPointer = true) = 0;
/// Return whether the given attribute is of type pointer
virtual bool IsPointerAttribute(std::string const & in_attribute) const = 0;
/// \brief Define whether the given node is of pointer type
/// If property is set then the contents will only be checked
/// whether value exists and is different from 0
virtual void UseAsPointerNode(std::string const & in_nodeName, bool in_useAsPointer = true) = 0;
/// Return whether the given node is of type pointer
virtual bool IsPointerNode(std::string const & in_nodeName) const = 0;
/// The user can optionally define an external function to change
/// textual attribute values before they are processed
virtual void SetFuncToChangeAttributeValue(XmlServices::FuncToChangeAttributeValue in_func) = 0;
/// \}
//---------------------------------------------------------------
/// \name Check XML contents (using PugiXml interface)
/// \{
/// \brief Writes contents of given XML node to EventReceiver.
/// Each attribute and text is reported with a separate call
/// to EventReceiver.
virtual void CheckNode(
pugi::xml_node const & in_rNode, ///< XML (sub)tree to check
char const * in_file = 0, ///< optional file name used in case of error
long in_lineNum = 0 ///< optional line number used in case of error
) = 0;
/// \brief Writes contents of given XML node to EventReceiver.
/// Each attribute and text is reported with a separate call
/// to EventReceiver.
virtual void CheckSubNode(
pugi::xml_node const & in_rNode, ///< XML (sub)tree to check
std::string const & in_xPathExpression, ///< XPath expression defining a subnode
char const * in_file = 0, ///< optional file name used in case of error
long in_lineNum = 0 ///< optional line number used in case of error
) = 0;
virtual void CheckSubNodeWithMaxChilds(
int in_maxChilds, ///< max number of childs to check
pugi::xml_node const & in_rNode, ///< XML (sub)tree to check
std::string const & in_xPathExpression, ///< XPath expression defining a subnode
char const * in_file = 0, ///< optional file name used in case of error
long in_lineNum = 0 ///< optional line number used in case of error
) = 0;
/// \brief Compares two XML (sub) trees. The result depends on the settings
/// for attributes/nodes to ignore and for the used precision of double values.
/// \return true if the XML trees are identical
virtual bool Compare(
pugi::xml_node const & in_rNodeA, ///< XML (sub)tree A to check
pugi::xml_node const & in_rNodeB, ///< XML (sub)tree B to check
char const * in_file = 0, ///< optional file name used in case of error
long in_lineNum = 0 ///< optional line number used in case of error
) = 0;
/// Get a textual description from the differences foound at the
/// last call to Compare()
virtual std::string GetCompareResult(void) const = 0;
/// Get the node from the given parent node and the given xpath description
static pugi::xml_node NodeFromXPath(
pugi::xml_node const & in_rParentNode,
std::string const & in_xPathExpression);
/// Simple comfort functions which allow direct usage of a pugi::xml_document whoose
/// root element will be checked
virtual void CheckNode(
pugi::xml_document const & in_rDoc,
char const * in_file = 0, long in_lineNum = 0) = 0;
virtual void CheckSubNode(
pugi::xml_document const & in_rDoc,
std::string const & in_xPathExpression,
char const * in_file = 0, long in_lineNum = 0) = 0;
virtual void CheckSubNodeWithMaxChilds(
int in_maxChilds,
pugi::xml_document const & in_rDoc,
std::string const & in_xPathExpression,
char const * in_file = 0, long in_lineNum = 0) = 0;
virtual bool Compare(
pugi::xml_document const & in_rDocA,
pugi::xml_document const & in_rDocB,
char const * in_file = 0, long in_lineNum = 0) = 0;
/// Change the contents of given XML document / tree according to
/// current filter settings:
/// - all attributes or nodes to ignore are removed from the tree
/// - double values are adjusted to desired precision
/// - pointer values are changed to "0" or "exists"
virtual void ApplyFilterToXmlTree(pugi::xml_document& io_docFromFile) = 0;
virtual void ApplyFilterToXmlTree(pugi::xml_node& io_docFromFile) = 0;
// Helper functions to convert between xml string, file and document
virtual pugi::xml_node ReadFromFile(pugi::xml_document& io_docFromFile, std::string const & in_xmlFilePath) = 0;
virtual bool SaveToFile(pugi::xml_document& io_docFromFile, std::string const & in_xmlFilePath) = 0;
virtual pugi::xml_node ReadFromString(pugi::xml_document& io_docFromString, std::string const & in_xmlTreeAsString) = 0;
/// \}
};
/// Access/create the singleton instance of XmlCheck
XmlCheck* TheXmlCheck(void);
} // namespace TestToolBox