Commit 85c3dbc0 authored by Andreas Cord-Landwehr's avatar Andreas Cord-Landwehr
Browse files

Switch to smart pointers

parent eccd9e1f
......@@ -22,10 +22,10 @@
#define RESOURCEREPOSITORYSTUB_H
#include "core/iresourcerepository.h"
#include "core/language.h"
#include <QObject>
#include <QVector>
class Language;
class ICourse;
/**
......@@ -35,9 +35,11 @@ class ResourceRepositoryStub : public IResourceRepository
{
Q_OBJECT
public:
ResourceRepositoryStub(QVector<Language *> languages)
ResourceRepositoryStub(std::vector<std::unique_ptr<Language>> languages)
{
m_languages = languages;
for (auto &language : languages) {
m_languages.append(std::move(language));
}
}
~ResourceRepositoryStub() override;
......@@ -47,15 +49,15 @@ public:
return m_storageLocation;
}
QVector<ICourse *> courses() const override
QVector<std::shared_ptr<ICourse>> courses() const override
{
return QVector<ICourse *>(); // do not return any courses: stub shall only provide languages
return QVector<std::shared_ptr<ICourse>>(); // do not return any courses: stub shall only provide languages
}
QVector<ICourse *> courses(Language *language) const override
QVector<std::shared_ptr<ICourse>> courses(const QString &languageId) const override
{
Q_UNUSED(language);
return QVector<ICourse *>(); // do not return any courses: stub shall only provide languages
Q_UNUSED(languageId);
return QVector<std::shared_ptr<ICourse>>(); // do not return any courses: stub shall only provide languages
}
void reloadCourses() override
......@@ -63,7 +65,7 @@ public:
; // do nothing, stub shall only provide languages
}
QVector<Language *> languages() const override
QVector<std::shared_ptr<Language>> languages() const override
{
return m_languages;
}
......@@ -75,7 +77,7 @@ Q_SIGNALS:
private:
QString m_storageLocation;
QVector<Language *> m_languages;
QVector<std::shared_ptr<Language>> m_languages;
};
#endif
......@@ -58,9 +58,12 @@ void TestCourseResource::courseSchemeValidationTest()
void TestCourseResource::loadCourseResource()
{
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
const QString courseDirectory = "data/courses/de/";
const QString courseFile = courseDirectory + "de.xml";
......@@ -96,15 +99,18 @@ void TestCourseResource::loadCourseResource()
void TestCourseResource::unitAddAndRemoveHandling()
{
// boilerplate
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
const QString courseDirectory = "data/courses/de/";
const QString courseFile = courseDirectory + "de.xml";
CourseResource course(QUrl::fromLocalFile(courseFile), &repository);
// begin of test
Unit *unit = new Unit;
std::unique_ptr<Unit> unit(new Unit);
unit->setId("testunit");
const int initialUnitNumber = course.unitList().count();
QCOMPARE(initialUnitNumber, 1);
......@@ -112,7 +118,7 @@ void TestCourseResource::unitAddAndRemoveHandling()
QSignalSpy spyAdded(&course, SIGNAL(unitAdded()));
QCOMPARE(spyAboutToBeAdded.count(), 0);
QCOMPARE(spyAdded.count(), 0);
course.addUnit(unit);
course.addUnit(std::move(unit));
QCOMPARE(course.unitList().count(), initialUnitNumber + 1);
QCOMPARE(spyAboutToBeAdded.count(), 1);
QCOMPARE(spyAdded.count(), 1);
......@@ -121,9 +127,12 @@ void TestCourseResource::unitAddAndRemoveHandling()
void TestCourseResource::coursePropertyChanges()
{
// boilerplate
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
const QString courseDirectory = "data/courses/de/";
const QString courseFile = courseDirectory + "de.xml";
CourseResource course(QUrl::fromLocalFile(courseFile), &repository);
......@@ -180,11 +189,11 @@ void TestCourseResource::coursePropertyChanges()
// language
{
Language testLanguage;
std::shared_ptr<Language> testLanguage;
QSignalSpy spy(&course, SIGNAL(languageChanged()));
QCOMPARE(spy.count(), 0);
course.setLanguage(&testLanguage);
QCOMPARE(course.language(), &testLanguage);
course.setLanguage(testLanguage);
QCOMPARE(course.language(), testLanguage);
QCOMPARE(spy.count(), 1);
}
}
......
......@@ -22,6 +22,7 @@
#define RESOURCEREPOSITORYSTUB_H
#include "core/iresourcerepository.h"
#include "core/language.h"
#include <QObject>
#include <QVector>
......@@ -35,9 +36,11 @@ class ResourceRepositoryStub : public IResourceRepository
{
Q_OBJECT
public:
ResourceRepositoryStub(QVector<Language *> languages)
ResourceRepositoryStub(std::vector<std::unique_ptr<Language>> languages)
{
m_languages = languages;
for (auto &language : languages) {
m_languages.append(std::move(language));
}
}
~ResourceRepositoryStub() override;
......@@ -47,15 +50,15 @@ public:
return m_storageLocation;
}
QVector<ICourse *> courses() const override
QVector<std::shared_ptr<ICourse>> courses() const override
{
return QVector<ICourse *>(); // do not return any courses: stub shall only provide languages
return QVector<std::shared_ptr<ICourse>>(); // do not return any courses: stub shall only provide languages
}
QVector<ICourse *> courses(Language *language) const override
QVector<std::shared_ptr<ICourse>> courses(const QString &languageId) const override
{
Q_UNUSED(language);
return QVector<ICourse *>(); // do not return any courses: stub shall only provide languages
Q_UNUSED(languageId);
return QVector<std::shared_ptr<ICourse>>(); // do not return any courses: stub shall only provide languages
}
void reloadCourses() override
......@@ -63,7 +66,7 @@ public:
; // do nothing, stub shall only provide languages
}
QVector<Language *> languages() const override
QVector<std::shared_ptr<Language>> languages() const override
{
return m_languages;
}
......@@ -75,7 +78,7 @@ Q_SIGNALS:
private:
QString m_storageLocation;
QVector<Language *> m_languages;
QVector<std::shared_ptr<Language>> m_languages;
};
#endif
......@@ -27,6 +27,7 @@
#include "core/resources/languageresource.h"
#include "core/resources/editablecourseresource.h"
#include <memory>
#include <QTest>
#include <QDebug>
#include <QTemporaryFile>
......@@ -65,9 +66,11 @@ void TestEditableCourseResource::courseSchemeValidationTest()
void TestEditableCourseResource::loadCourseResource()
{
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
EditableCourseResource course(QUrl::fromLocalFile(":/courses/de.xml"), &repository);
QCOMPARE(course.file().toLocalFile(), ":/courses/de.xml");
......@@ -101,13 +104,15 @@ void TestEditableCourseResource::loadCourseResource()
void TestEditableCourseResource::unitAddAndRemoveHandling()
{
// boilerplate
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
EditableCourseResource course(QUrl::fromLocalFile(":/courses/de.xml"), &repository);
// begin of test
Unit *unit = new Unit; // TODO: change to unique pointer when interface is changed to scoped pointers
std::unique_ptr<Unit> unit(new Unit);
unit->setId("testunit");
const int initialUnitNumber = course.unitList().count();
QCOMPARE(initialUnitNumber, 1);
......@@ -115,7 +120,7 @@ void TestEditableCourseResource::unitAddAndRemoveHandling()
QSignalSpy spyAdded(&course, SIGNAL(unitAdded()));
QCOMPARE(spyAboutToBeAdded.count(), 0);
QCOMPARE(spyAdded.count(), 0);
course.addUnit(unit);
course.addUnit(std::move(unit));
QCOMPARE(course.unitList().count(), initialUnitNumber + 1);
QCOMPARE(spyAboutToBeAdded.count(), 1);
QCOMPARE(spyAdded.count(), 1);
......@@ -124,9 +129,11 @@ void TestEditableCourseResource::unitAddAndRemoveHandling()
void TestEditableCourseResource::coursePropertyChanges()
{
// boilerplate
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
CourseResource course(QUrl::fromLocalFile(":/courses/de.xml"), &repository);
// id
......@@ -181,11 +188,11 @@ void TestEditableCourseResource::coursePropertyChanges()
// language
{
Language testLanguage;
std::shared_ptr<Language> testLanguage;
QSignalSpy spy(&course, SIGNAL(languageChanged()));
QCOMPARE(spy.count(), 0);
course.setLanguage(&testLanguage);
QCOMPARE(course.language(), &testLanguage);
course.setLanguage(testLanguage);
QCOMPARE(course.language(), testLanguage);
QCOMPARE(spy.count(), 1);
}
}
......@@ -193,9 +200,11 @@ void TestEditableCourseResource::coursePropertyChanges()
void TestEditableCourseResource::fileLoadSaveCompleteness()
{
// boilerplate
Language language;
language.setId("de");
ResourceRepositoryStub repository({&language});
std::unique_ptr<Language> language(new Language);
language->setId("de");
std::vector<std::unique_ptr<Language>> languages;
languages.push_back(std::move(language));
ResourceRepositoryStub repository(std::move(languages));
EditableCourseResource course(QUrl::fromLocalFile(":/courses/de.xml"), &repository);
QTemporaryFile outputFile;
......
......@@ -37,55 +37,61 @@ class EditableRepositoryStub : public IEditableRepository
Q_OBJECT
public:
EditableRepositoryStub(
QVector<Language *> languages,
QVector<IEditableCourse *> skeletons,
QVector<IEditableCourse *> courses)
: m_languages{ languages }
, m_skeletons{ skeletons }
, m_courses{ courses }
std::vector<std::shared_ptr<Language>> languages,
std::vector<std::shared_ptr<IEditableCourse>> skeletons,
std::vector<std::shared_ptr<IEditableCourse>> courses)
{
for (auto &language : languages) {
m_languages.append(std::move(language));
}
for (auto &skeleton : skeletons) {
m_skeletons.append(std::move(skeleton));
}
for (auto &course : courses) {
m_courses.append(course);
}
}
~EditableRepositoryStub() override;
QString storageLocation() const override
{
return QString();
}
QVector<IEditableCourse *> skeletons() const override
QVector<std::shared_ptr<IEditableCourse>> skeletons() const override
{
return m_skeletons;
}
QVector<IEditableCourse *> editableCourses() const override
QVector<std::shared_ptr<IEditableCourse>> editableCourses() const override
{
return m_courses;
}
QVector<ICourse *> courses() const override
QVector<std::shared_ptr<ICourse>> courses() const override
{
QVector<ICourse *> courses;
QVector<std::shared_ptr<ICourse>> courses;
for (auto course : m_courses) {
courses.push_back(course);
}
return courses;
}
QVector<ICourse *> courses(Language *language) const override
QVector<std::shared_ptr<ICourse>> courses(const QString &languageId) const override
{
Q_UNUSED(language);
return QVector<ICourse *>();
Q_UNUSED(languageId);
return QVector<std::shared_ptr<ICourse>>();
}
IEditableCourse * editableCourse(Language *language, int index) const override
std::shared_ptr<IEditableCourse> editableCourse(std::shared_ptr<Language> language, int index) const override
{
Q_UNUSED(language);
Q_UNUSED(index);
return nullptr;
return std::shared_ptr<IEditableCourse>();
}
void reloadCourses() override
{
// do nothing
}
QVector<Language *> languages() const override
QVector<std::shared_ptr<Language>> languages() const override
{
return m_languages;
}
void updateCourseFromSkeleton(IEditableCourse *course) override
void updateCourseFromSkeleton(std::shared_ptr<IEditableCourse> course) override
{
Q_UNUSED(course);
// do nothing
......@@ -98,9 +104,9 @@ Q_SIGNALS:
void courseRemoved() override;
private:
QVector<Language *> m_languages;
QVector<IEditableCourse *> m_skeletons;
QVector<IEditableCourse *> m_courses;
QVector<std::shared_ptr<Language>> m_languages;
QVector<std::shared_ptr<IEditableCourse>> m_skeletons;
QVector<std::shared_ptr<IEditableCourse>> m_courses;
};
#endif
......@@ -33,7 +33,7 @@
class EditableCourseStub : public IEditableCourse
{
public:
EditableCourseStub(Language *language, QVector<Unit *> units)
EditableCourseStub(std::shared_ptr<Language> language, QVector<std::shared_ptr<Unit>> units)
: IEditableCourse()
, m_language(language)
, m_units(units)
......@@ -84,22 +84,27 @@ public:
m_description = description;
emit descriptionChanged();
}
Language * language() const override
std::shared_ptr<Language> language() const override
{
return m_language;
}
void setLanguage(Language *language) override
void setLanguage(std::shared_ptr<Language> language) override
{
m_language = language;
emit languageChanged();
}
QList<Unit *> unitList() override
{
return m_units.toList();
QList<Unit *> rawList;
for (auto unit : m_units) {
rawList.append(unit.get());
}
return rawList;
}
void addUnit(Unit *unit) override
std::shared_ptr<Unit> addUnit(std::unique_ptr<Unit> unit) override
{
m_units.append(unit);
m_units.append(std::move(unit));
return m_units.last();
}
QUrl file() const override
{
......@@ -112,8 +117,8 @@ private:
QString m_title{ "title" };
QString m_i18nTitle{ "i18n title" };
QString m_description{ "description of the course" };
Language *m_language{nullptr};
QVector<Unit *> m_units;
std::shared_ptr<Language> m_language;
QVector<std::shared_ptr<Unit>> m_units;
};
// define one virtual method out of line to pin CourseStub to this translation unit
......@@ -132,17 +137,19 @@ void TestEditorSession::cleanup()
void TestEditorSession::createEditorSession()
{
Language languageGerman;
languageGerman.setId("de");
Language languageEnglish;
languageEnglish.setId("en");
EditableCourseStub course(&languageGerman, QVector<Unit *>());
course.setLanguage(&languageGerman); SkeletonResource skeleton(QUrl(), nullptr);
std::shared_ptr<Language> languageGerman(new Language);
languageGerman->setId("de");
std::shared_ptr<Language> languageEnglish(new Language);
languageEnglish->setId("en");
std::shared_ptr<IEditableCourse> course(new EditableCourseStub(languageGerman, QVector<std::shared_ptr<Unit>>()));
course->setLanguage(languageGerman);
std::shared_ptr<IEditableCourse> skeleton(new SkeletonResource(QUrl(), nullptr));
EditableRepositoryStub repository{
{&languageGerman, &languageEnglish}, // languages
{&skeleton},
{&course} // courses
{languageGerman, languageEnglish}, // languages
{skeleton}, // skeletons
{course} // courses
};
EditorSession session;
session.setRepository(&repository);
......@@ -153,83 +160,83 @@ void TestEditorSession::createEditorSession()
void TestEditorSession::nonSkeletonSwitchingBehavior()
{
Language languageGerman;
languageGerman.setId("de");
Language languageEnglish;
languageEnglish.setId("en");
EditableCourseStub courseGerman(&languageGerman, QVector<Unit *>());
courseGerman.setId("course-german");
EditableCourseStub courseEnglish(&languageEnglish, QVector<Unit *>());
courseEnglish.setId("course-english");
std::shared_ptr<Language> languageGerman;
languageGerman->setId("de");
std::shared_ptr<Language> languageEnglish;
languageEnglish->setId("en");
std::shared_ptr<IEditableCourse> courseGerman(new EditableCourseStub(languageGerman, QVector<std::shared_ptr<Unit>>()));
courseGerman->setId("course-german");
std::shared_ptr<IEditableCourse> courseEnglish(new EditableCourseStub(languageEnglish, QVector<std::shared_ptr<Unit>>()));
courseEnglish->setId("course-english");
EditableRepositoryStub repository{
{&languageGerman, &languageEnglish}, // languages
{languageGerman, languageEnglish}, // languages
{}, // skeletons
{&courseGerman, &courseEnglish} // courses
{courseGerman, courseEnglish} // courses
};
EditorSession session;
session.setRepository(&repository);
QVERIFY(session.course() == nullptr);
session.setCourse(&courseGerman);
QCOMPARE(session.course()->id(), courseGerman.id());
session.setCourse(courseGerman.get());
QCOMPARE(session.course()->id(), courseGerman->id());
QVERIFY(session.language() != nullptr);
QCOMPARE(session.language()->id(), languageGerman.id());
QCOMPARE(session.language()->id(), languageGerman->id());
QVERIFY(session.language() != nullptr);
QCOMPARE(session.language()->id(), languageGerman.id());
session.setCourse(&courseEnglish);
QCOMPARE(session.language()->id(), languageGerman->id());
session.setCourse(courseEnglish.get());
QVERIFY(session.course() != nullptr);
QCOMPARE(session.course()->id(), courseEnglish.id());
QCOMPARE(session.course()->id(), courseEnglish->id());
QVERIFY(session.language() != nullptr);
QCOMPARE(session.language()->id(), languageEnglish.id());
QCOMPARE(session.language()->id(), languageEnglish->id());
}
void TestEditorSession::skeletonSwitchingBehavior()
{
Language languageGerman;
languageGerman.setId("de");
Language languageEnglish;
languageEnglish.setId("en");
EditableCourseStub courseGermanA(&languageGerman, QVector<Unit *>());
courseGermanA.setId("course-german");
courseGermanA.setForeignId("testskeletonA");
EditableCourseStub courseGermanB(&languageGerman, QVector<Unit *>());
courseGermanB.setId("course-german");
courseGermanB.setForeignId("testskeletonB");
EditableCourseStub courseEnglishA(&languageEnglish, QVector<Unit *>());
courseEnglishA.setId("course-english");
courseEnglishA.setForeignId("testskeletonA");
SkeletonResource skeletonA(QUrl(), nullptr);
skeletonA.setId("testskeletonA");
SkeletonResource skeletonB(QUrl(), nullptr);
skeletonB.setId("testskeletonB");
std::shared_ptr<Language> languageGerman;
languageGerman->setId("de");
std::shared_ptr<Language> languageEnglish;
languageEnglish->setId("en");
std::shared_ptr<IEditableCourse> courseGermanA(new EditableCourseStub(languageGerman, QVector<std::shared_ptr<Unit>>()));
courseGermanA->setId("course-german");
courseGermanA->setForeignId("testskeletonA");
std::shared_ptr<IEditableCourse> courseGermanB(new EditableCourseStub(languageGerman, QVector<std::shared_ptr<Unit>>()));
courseGermanB->setId("course-german");
courseGermanB->setForeignId("testskeletonB");
std::shared_ptr<IEditableCourse> courseEnglishA(new EditableCourseStub(languageEnglish, QVector<std::shared_ptr<Unit>>()));
courseEnglishA->setId("course-english");
courseEnglishA->setForeignId("testskeletonA");
std::shared_ptr<IEditableCourse> skeletonA(new SkeletonResource(QUrl(), nullptr));
skeletonA->setId("testskeletonA");
std::shared_ptr<IEditableCourse> skeletonB(new SkeletonResource(QUrl(), nullptr));
skeletonB->setId("testskeletonB");
EditableRepositoryStub repository{
{&languageGerman, &languageEnglish}, // languages
{&skeletonA, &skeletonB}, // skeletons
{&courseGermanA, &courseEnglishA, &courseGermanB} // courses
{languageGerman, languageEnglish}, // languages
{skeletonA, skeletonB}, // skeletons
{courseGermanA, courseEnglishA, courseGermanB} // courses
};
EditorSession session;
session.setRepository(&repository);
session.setSkeleton(&skeletonA);
session.setSkeleton(skeletonA.get());
Q_ASSERT(session.skeleton() != nullptr);