hemplate

Simple XML template engine
git clone git://git.dimitrijedobrota.com/hemplate.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit cac6d73e0f4c4f674875a911c1f4946d7bc690cb
parent d287efed0625b53751c1eb47d9a91d46a42c7218
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Wed, 23 Apr 2025 13:19:30 +0200

Attribute test, bug fixing, improved consistency

Diffstat:
M include/hemplate/attribute.hpp | +++++++++++++++++ ----------
M source/attribute.cpp | +++++++++ --------
M test/CMakeLists.txt | ++
A test/source/attribute.cpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

4 files changed, 87 insertions(+), 18 deletions(-)


diff --git a/ include/hemplate/attribute.hpp b/ include/hemplate/attribute.hpp

@@ -9,30 +9,37 @@ namespace hemplate {
struct HEMPLATE_EXPORT attribute
class HEMPLATE_EXPORT attribute
{
std::string name;
std::string value;
std::string m_name;
std::string m_value;
explicit attribute(std::string_view namee)
: name(namee)
public:
attribute(std::string_view name) // NOLINT *-explicit-constructor
: m_name(name)
{ }
attribute(std::string_view namee, std::string_view val)
: name(namee)
, value(val)
attribute(std::string_view name, std::string_view val)
: m_name(name)
, m_value(val)
{ } operator std::string() const // NOLINT *-explicit-constructor {
return name + "=\"" + value + "\"";
if (empty()) {
return name();
}
return name() + "=\"" + value() + "\"";
}
const std::string& name() const { return m_name; }
const std::string& value() const { return m_value; }
bool operator==(const attribute& rhs) const = default;
bool empty() const { return value.empty(); }
bool empty() const { return value().empty(); }
attribute& append(std::string_view delim, const std::string& val); };

diff --git a/ source/attribute.cpp b/ source/attribute.cpp

@@ -5,11 +5,11 @@ namespace hemplate attribute& attribute::append(std::string_view delim, const std::string& val) {
if (!value.empty()) {
if (!val.empty()) {
if (!empty()) {
value += std::string(delim);
m_value += std::string(delim);
}
value += val;
m_value += val;
} return *this; }

@@ -28,7 +28,8 @@ attribute_list::attribute_list(attribute attr) bool attribute_list::empty() const {
return m_attributes.empty() && m_class.value.empty() && m_style.value.empty();
return m_attributes.empty() && m_class.value().empty()
&& m_style.value().empty();
} attribute_list& attribute_list::set(const attribute_list& list)

@@ -45,10 +46,10 @@ attribute_list& attribute_list::set(const attribute_list& list) attribute_list& attribute_list::set(attribute attr) {
if (attr.name == "class") {
m_class.append(" ", attr.value);
} else if (attr.name == "style") {
m_style.append("; ", attr.value);
if (attr.name() == "class") {
m_class.append(" ", attr.value());
} else if (attr.name() == "style") {
m_style.append("; ", attr.value());
} else { m_attributes.emplace_back(std::move(attr)); }

diff --git a/ test/CMakeLists.txt b/ test/CMakeLists.txt

@@ -21,6 +21,8 @@ function(add_test NAME) catch_discover_tests("${NAME}") endfunction()
add_test(attribute)
# ---- End-of-file commands ---- add_folders(Test)

diff --git a/ test/source/attribute.cpp b/ test/source/attribute.cpp

@@ -0,0 +1,59 @@
#include "hemplate/attribute.hpp"
#include <catch2/catch_test_macros.hpp>
TEST_CASE("constructor", "[attribute]")
{
SECTION("name")
{
const hemplate::attribute attr {"class"};
REQUIRE(attr.name() == "class");
REQUIRE(attr.empty());
REQUIRE(std::string(attr) == "class");
}
SECTION("name, value")
{
const hemplate::attribute attr {"class", "test"};
REQUIRE(attr.name() == "class");
REQUIRE(attr.value() == "test");
REQUIRE(!attr.empty());
REQUIRE(std::string(attr) == R"(class="test")");
}
}
TEST_CASE("append", "[attribute]")
{
hemplate::attribute attr {"class"};
SECTION("empty")
{
attr.append(" ", "");
REQUIRE(attr.name() == "class");
REQUIRE(attr.empty());
REQUIRE(std::string(attr) == R"(class)");
}
SECTION("first")
{
attr.append(" ", "first");
REQUIRE(attr.name() == "class");
REQUIRE(attr.value() == "first");
REQUIRE(!attr.empty());
REQUIRE(std::string(attr) == R"(class="first")");
SECTION("second")
{
attr.append(" ", "second");
REQUIRE(attr.name() == "class");
REQUIRE(attr.value() == "first second");
REQUIRE(!attr.empty());
REQUIRE(std::string(attr) == R"(class="first second")");
}
}
}