Fix making labels unique

This commit is contained in:
Martchus 2018-06-09 22:09:33 +02:00
parent 76e5eec85b
commit 132be3fd8b
2 changed files with 28 additions and 15 deletions

View File

@ -1,6 +1,7 @@
#include "./entry.h" #include "./entry.h"
#include "./parsingexception.h" #include "./parsingexception.h"
#include <c++utilities/conversion/stringbuilder.h>
#include <c++utilities/io/binaryreader.h> #include <c++utilities/io/binaryreader.h>
#include <c++utilities/io/binarywriter.h> #include <c++utilities/io/binarywriter.h>
@ -58,7 +59,7 @@ Entry::~Entry()
} }
/*! /*!
* \brief Internally called to make the label unique. * \brief Internally called to make the entry's label unique within the parent.
* \sa setLabel() * \sa setLabel()
*/ */
void Entry::makeLabelUnique() void Entry::makeLabelUnique()
@ -66,23 +67,22 @@ void Entry::makeLabelUnique()
if (!m_parent) { if (!m_parent) {
return; return;
} }
int index = 1; string newLabel(label());
string currentLabel(label()); for (unsigned int index = 2;; ++index) {
checkLabel: bool needsNewLabel = false;
for (Entry *sibling : m_parent->children()) { for (Entry *const sibling : m_parent->children()) {
if (sibling == this || currentLabel != sibling->label()) { if (sibling == this || newLabel != sibling->label()) {
continue; continue;
}
needsNewLabel = true;
newLabel = argsToString(label(), ' ', index);
break;
} }
stringstream newLabel(currentLabel); if (!needsNewLabel) {
newLabel.seekp(0, ios_base::end); break;
if (newLabel.tellp()) {
newLabel << ' ';
} }
newLabel << ++index;
currentLabel = newLabel.str();
goto checkLabel;
} }
m_label = currentLabel; m_label.swap(newLabel);
} }
/*! /*!

View File

@ -35,6 +35,7 @@ class EntryTests : public TestFixture {
CPPUNIT_TEST(testNewEntryCorrectlyInitialized); CPPUNIT_TEST(testNewEntryCorrectlyInitialized);
CPPUNIT_TEST(testNesting); CPPUNIT_TEST(testNesting);
CPPUNIT_TEST(testEntryByPath); CPPUNIT_TEST(testEntryByPath);
CPPUNIT_TEST(testUniqueLabels);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
public: public:
@ -44,6 +45,7 @@ public:
void testNewEntryCorrectlyInitialized(); void testNewEntryCorrectlyInitialized();
void testNesting(); void testNesting();
void testEntryByPath(); void testEntryByPath();
void testUniqueLabels();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(EntryTests); CPPUNIT_TEST_SUITE_REGISTRATION(EntryTests);
@ -196,3 +198,14 @@ void EntryTests::testEntryByPath()
CPPUNIT_ASSERT_EQUAL_MESSAGE( CPPUNIT_ASSERT_EQUAL_MESSAGE(
"path actually correct", list<string>{ "root" CPP_UTILITIES_PP_COMMA "node" CPP_UTILITIES_PP_COMMA "foo" }, nestedAccount->path()); "path actually correct", list<string>{ "root" CPP_UTILITIES_PP_COMMA "node" CPP_UTILITIES_PP_COMMA "foo" }, nestedAccount->path());
} }
void EntryTests::testUniqueLabels()
{
NodeEntry root("root");
const auto *const fooEntry = new AccountEntry("foo", &root);
VAR_UNUSED(fooEntry)
const auto *const foo2Entry = new AccountEntry("foo", &root);
CPPUNIT_ASSERT_EQUAL_MESSAGE("2nd foo renamed to foo 2", "foo 2"s, foo2Entry->label());
const auto *const foo3Entry = new AccountEntry("foo", &root);
CPPUNIT_ASSERT_EQUAL_MESSAGE("3rd foo renamed to foo 3", "foo 3"s, foo3Entry->label());
}