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 "./parsingexception.h"
#include <c++utilities/conversion/stringbuilder.h>
#include <c++utilities/io/binaryreader.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()
*/
void Entry::makeLabelUnique()
@ -66,23 +67,22 @@ void Entry::makeLabelUnique()
if (!m_parent) {
return;
}
int index = 1;
string currentLabel(label());
checkLabel:
for (Entry *sibling : m_parent->children()) {
if (sibling == this || currentLabel != sibling->label()) {
continue;
string newLabel(label());
for (unsigned int index = 2;; ++index) {
bool needsNewLabel = false;
for (Entry *const sibling : m_parent->children()) {
if (sibling == this || newLabel != sibling->label()) {
continue;
}
needsNewLabel = true;
newLabel = argsToString(label(), ' ', index);
break;
}
stringstream newLabel(currentLabel);
newLabel.seekp(0, ios_base::end);
if (newLabel.tellp()) {
newLabel << ' ';
if (!needsNewLabel) {
break;
}
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(testNesting);
CPPUNIT_TEST(testEntryByPath);
CPPUNIT_TEST(testUniqueLabels);
CPPUNIT_TEST_SUITE_END();
public:
@ -44,6 +45,7 @@ public:
void testNewEntryCorrectlyInitialized();
void testNesting();
void testEntryByPath();
void testUniqueLabels();
};
CPPUNIT_TEST_SUITE_REGISTRATION(EntryTests);
@ -196,3 +198,14 @@ void EntryTests::testEntryByPath()
CPPUNIT_ASSERT_EQUAL_MESSAGE(
"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());
}