Commit 50da0459 authored by Andreas Cord-Landwehr's avatar Andreas Cord-Landwehr
Browse files

Fix modified status and add unit tests

parent 981225af
......@@ -223,4 +223,95 @@ void TestEditableCourseResource::fileLoadSaveCompleteness()
QVERIFY(testPhrase->phonemes().count() == comparePhrase->phonemes().count());
}
void TestEditableCourseResource::modifiedStatus()
{
// boilerplate
std::shared_ptr<ILanguage> language(new LanguageStub("de"));
ResourceRepositoryStub repository({language});
auto course = EditableCourseResource::create(QUrl::fromLocalFile(":/courses/de.xml"), &repository);
{ // initial file loading
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
}
{ // set ID
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
loadedCourse->setId("ASDF");
QCOMPARE(loadedCourse->isModified(), true);
loadedCourse->sync();
QCOMPARE(loadedCourse->isModified(), false);
}
{ // set title
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
loadedCourse->setTitle("ASDF");
QCOMPARE(loadedCourse->isModified(), true);
loadedCourse->sync();
QCOMPARE(loadedCourse->isModified(), false);
}
{ // set i18n title
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
loadedCourse->setI18nTitle("ASDF");
QCOMPARE(loadedCourse->isModified(), true);
loadedCourse->sync();
QCOMPARE(loadedCourse->isModified(), false);
}
{ // set description
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
loadedCourse->setDescription("ASDF");
QCOMPARE(loadedCourse->isModified(), true);
loadedCourse->sync();
QCOMPARE(loadedCourse->isModified(), false);
}
{ // set language
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
std::shared_ptr<ILanguage> newLanguage(new LanguageStub("en"));
loadedCourse->setLanguage(newLanguage);
QCOMPARE(loadedCourse->isModified(), true);
loadedCourse->sync();
QCOMPARE(loadedCourse->isModified(), false);
}
{ // add unit
QTemporaryFile outputFile;
outputFile.open();
course->exportToFile(QUrl::fromLocalFile(outputFile.fileName()));
auto loadedCourse = EditableCourseResource::create(QUrl::fromLocalFile(outputFile.fileName()), &repository);
QCOMPARE(loadedCourse->isModified(), false);
std::unique_ptr<Unit> unit(new Unit);
unit->setId("testunit");
loadedCourse->addUnit(std::move(unit));
QCOMPARE(loadedCourse->isModified(), true);
loadedCourse->sync();
QCOMPARE(loadedCourse->isModified(), false);
}
}
QTEST_GUILESS_MAIN(TestEditableCourseResource)
......@@ -61,6 +61,11 @@ private Q_SLOTS:
* Test if serialization of unserialized file gives original file.
*/
void fileLoadSaveCompleteness();
/**
* Test if the modified status is correctly set.
*/
void modifiedStatus();
};
#endif
......@@ -117,6 +117,10 @@ public:
{
return QUrl();
}
bool sync() override
{
return false;
}
bool isModified() const override
{
return false;
......
......@@ -63,15 +63,14 @@ void ContributorRepository::loadLanguageResources()
void ContributorRepository::sync()
{
// QMap< QString, QList< CourseResource* > >::iterator iter;
// for (iter = m_courseResources.begin(); iter != m_courseResources.end(); ++iter) {
// foreach (auto const &courseRes, iter.value()) {
// courseRes->sync();
// }
// }
// foreach (auto const &courseRes, m_skeletonResources) {
// courseRes->sync();
// }
for (auto iter = m_courses.begin(); iter != m_courses.end(); ++iter) {
for (auto course : iter.value()) {
course->sync();
}
}
for (auto skeleton : m_skeletonResources) {
skeleton->sync();
}
}
bool ContributorRepository::modified() const
......
......@@ -40,7 +40,17 @@ public:
virtual void setDescription(QString description) = 0;
virtual void setLanguage(std::shared_ptr<ILanguage> language) = 0;
virtual std::shared_ptr<Unit> addUnit(std::unique_ptr<Unit> unit) = 0;
/**
* @brief Export course to specified file.
* @param filePath the absolute path to the export file
* @return true of export finished without errors
*/
virtual bool exportToFile(const QUrl &filePath) const = 0;
/**
* @brief store editable course in file and set modified to false
* @return true if no errors occured
*/
virtual bool sync() = 0;
virtual bool isModified() const = 0;
protected:
......
......@@ -74,7 +74,10 @@ QString EditableCourseResource::id() const
void EditableCourseResource::setId(QString id)
{
m_course->setId(id);
if (m_course->id() != id) {
m_course->setId(id);
m_modified = true;
}
}
QString EditableCourseResource::foreignId() const
......@@ -94,7 +97,10 @@ QString EditableCourseResource::title() const
void EditableCourseResource::setTitle(QString title)
{
m_course->setTitle(title);
if (m_course->title() != title) {
m_course->setTitle(title);
m_modified = true;
}
}
QString EditableCourseResource::i18nTitle() const
......@@ -104,7 +110,10 @@ QString EditableCourseResource::i18nTitle() const
void EditableCourseResource::setI18nTitle(QString i18nTitle)
{
m_course->setI18nTitle(i18nTitle);
if (m_course->i18nTitle() != i18nTitle) {
m_course->setI18nTitle(i18nTitle);
m_modified = true;
}
}
QString EditableCourseResource::description() const
......@@ -114,7 +123,10 @@ QString EditableCourseResource::description() const
void EditableCourseResource::setDescription(QString description)
{
m_course->setDescription(description);
if (m_course->description() != description) {
m_course->setDescription(description);
m_modified = true;
}
}
std::shared_ptr<ILanguage> EditableCourseResource::language() const
......@@ -124,7 +136,10 @@ std::shared_ptr<ILanguage> EditableCourseResource::language() const
void EditableCourseResource::setLanguage(std::shared_ptr<ILanguage> language)
{
m_course->setLanguage(language);
if (m_course->language() != language) {
m_course->setLanguage(language);
m_modified = true;
}
}
QUrl EditableCourseResource::file() const
......@@ -132,7 +147,7 @@ QUrl EditableCourseResource::file() const
return m_course->file();
}
void EditableCourseResource::sync()
bool EditableCourseResource::sync()
{
Q_ASSERT(file().isValid());
Q_ASSERT(file().isLocalFile());
......@@ -141,9 +156,13 @@ void EditableCourseResource::sync()
// not writing back if not modified
if (!m_modified) {
qCDebug(ARTIKULATE_LOG()) << "Aborting sync, course was not modified.";
return;
return false;
}
bool ok = exportToFile(file());
if (ok) {
m_modified = false;
}
exportToFile(file());
return ok;
}
bool EditableCourseResource::exportToFile(const QUrl &filePath) const
......@@ -170,7 +189,7 @@ bool EditableCourseResource::exportToFile(const QUrl &filePath) const
std::shared_ptr<Unit> EditableCourseResource::addUnit(std::unique_ptr<Unit> unit)
{
setModified(true);
m_modified = true;
auto sharedUnit = m_course->addUnit(std::move(unit));
sharedUnit->setCourse(this);
return sharedUnit;
......@@ -186,11 +205,6 @@ bool EditableCourseResource::isModified() const
return m_modified;
}
void EditableCourseResource::setModified(bool modified)
{
m_modified = modified;
}
Unit * EditableCourseResource::createUnit()
{
// find first unused id
......
......@@ -86,28 +86,17 @@ public:
QString description() const override;
void setDescription(QString description) override;
/**
* \return language identifier of this course
*/
std::shared_ptr<ILanguage> language() const override;
void setLanguage(std::shared_ptr<ILanguage> language) override;
void sync();
/**
* @brief Export course to specified file.
* @param filePath the absolute path to the export file
* @return true of export finished without errors
*/
bool sync() override;
bool exportToFile(const QUrl &filePath) const override;
std::shared_ptr<Unit> addUnit(std::unique_ptr<Unit> unit) override;
QVector<std::shared_ptr<Unit>> units() override;
bool isModified() const override;
QUrl file() const override;
Q_INVOKABLE Unit * createUnit();
......@@ -128,7 +117,6 @@ private:
*/
explicit EditableCourseResource(const QUrl &path, IResourceRepository *repository);
void setSelf(std::shared_ptr<ICourse> self) override;
void setModified(bool modified);
bool m_modified{ false };
const std::unique_ptr<CourseResource> m_course;
};
......
......@@ -78,6 +78,7 @@ public:
}
xml.clear();
file.close();
m_modified = false;
}
QVector<std::shared_ptr<Unit>> units();
......@@ -95,6 +96,7 @@ public:
QString m_title;
QString m_description;
bool m_unitsParsed{ false };
bool m_modified{ false };
protected:
QVector<std::shared_ptr<Unit>> m_units; ///!< the units variable is loaded lazily and shall never be access directly
......@@ -116,6 +118,7 @@ QVector<std::shared_ptr<Unit>> SkeletonResourcePrivate::units()
std::shared_ptr<Unit> SkeletonResourcePrivate::appendUnit(std::shared_ptr<Unit> unit) {
units(); // ensure that units are parsed
m_units.append(unit);
m_modified = true;
return m_units.last();
}
......@@ -195,6 +198,16 @@ SkeletonResource::SkeletonResource(const QUrl &path, IResourceRepository *reposi
, d(new SkeletonResourcePrivate(path))
{
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
connect(this, &SkeletonResource::idChanged, this, [=]() {
d->m_modified = true;
});
connect(this, &SkeletonResource::titleChanged, this, [=]() {
d->m_modified = true;
});
connect(this, &SkeletonResource::descriptionChanged, this, [=]() {
d->m_modified = true;
});
Q_UNUSED(repository);
}
......@@ -301,9 +314,22 @@ std::shared_ptr<Unit> SkeletonResource::addUnit(std::unique_ptr<Unit> unit)
return storedUnit;
}
bool SkeletonResource::sync()
{
if (!d->m_modified) {
qCDebug(ARTIKULATE_LOG()) << "Aborting sync, skeleton was not modified.";
return false;
}
bool ok = exportToFile(file());
if (ok) {
d->m_modified = false;
}
return ok;
}
bool SkeletonResource::isModified() const
{
return false; //FIXME
return d->m_modified;
}
std::shared_ptr<ILanguage> SkeletonResource::language() const
......
......@@ -57,6 +57,7 @@ public:
QUrl file() const override;
bool exportToFile(const QUrl &filePath) const override;
std::shared_ptr<Unit> addUnit(std::unique_ptr<Unit> unit) override;
bool sync() override;
bool isModified() const override;
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment