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

Introduce editibale course and editable repository interfaces

parent ff5655d1
......@@ -47,6 +47,7 @@ target_link_libraries(test_resourcerepository
add_test(test_resourcerepository test_resourcerepository)
ecm_mark_as_test(test_resourcerepository)
# integration tests for iresource repository interface derived classes
set(TestIResourceRepository_SRCS iresourcerepository_integration/test_iresourcerepository.cpp)
qt5_add_resources(TestIResourceRepository_SRCS ../data/languages.qrc)
......@@ -58,6 +59,7 @@ target_link_libraries(test_iresourcerepository_integration
add_test(test_iresourcerepository_integration test_iresourcerepository_integration)
ecm_mark_as_test(test_iresourcerepository_integration)
# training session tests
set(TestTrainingSession_SRCS trainingsession/test_trainingsession.cpp)
add_executable(test_trainingsession ${TestTrainingSession_SRCS})
......@@ -68,6 +70,21 @@ target_link_libraries(test_trainingsession
add_test(test_trainingsession test_trainingsession)
ecm_mark_as_test(test_trainingsession)
# editor session tests
set(TestEditorSession_SRCS
editorsession/test_editorsession.cpp
editorsession/editablerepositorystub.cpp
)
add_executable(test_editorsession ${TestEditorSession_SRCS})
target_link_libraries(test_editorsession
artikulatecore
Qt5::Test
)
add_test(test_editorsession test_editorsession)
ecm_mark_as_test(test_editorsession)
# test course resource class
set(TestCourseResource_SRCS
courseresource/test_courseresource.cpp
......@@ -82,6 +99,7 @@ target_link_libraries(test_courseresource
add_test(test_courseresource test_courseresource)
ecm_mark_as_test(test_courseresource)
# test skeleton resource class
set(TestSkeletonResource_SRCS
skeletonresource/test_skeletonresource.cpp
......@@ -96,6 +114,7 @@ target_link_libraries(test_skeletonresource
add_test(test_skeletonresource test_skeletonresource)
ecm_mark_as_test(test_skeletonresource)
# test editable course resource class
set(TestEditableCourseResource_SRCS
editablecourseresource/test_editablecourseresource.cpp
......@@ -111,6 +130,7 @@ target_link_libraries(test_editablecourseresource
add_test(test_editablecourseresource test_editablecourseresource)
ecm_mark_as_test(test_editablecourseresource)
# basic tests language files (input/output)
set(TestLanguageFiles_SRCS testlanguagefiles.cpp)
add_executable(TestLanguageFiles ${TestLanguageFiles_SRCS} )
......
/*
* Copyright 2019 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "editablerepositorystub.h"
// define one virtual method out of line to pin EditableRepositoryStub to this translation unit
EditableRepositoryStub::~EditableRepositoryStub() = default;
/*
* Copyright 2019 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EDITABLEREPOSITORYSTUB_H
#define EDITABLEREPOSITORYSTUB_H
#include "core/ieditablerepository.h"
#include "core/ieditablecourse.h"
#include <QObject>
#include <QVector>
class Language;
/**
* @brief The EditableRepositoryStub is simple sub class only for testing
*/
class EditableRepositoryStub : public IEditableRepository
{
Q_OBJECT
public:
EditableRepositoryStub(QVector<IEditableCourse *> courses)
: m_courses{ courses }
{
}
~EditableRepositoryStub() override;
QString storageLocation() const override
{
return QString();
}
QVector<IEditableCourse *> editableCourses() const override
{
return m_courses;
}
QVector<ICourse *> courses() const override
{
QVector<ICourse *> courses;
for (auto course : m_courses) {
courses.push_back(course);
}
return courses;
}
QVector<ICourse *> courses(Language *language) const override
{
Q_UNUSED(language);
return QVector<ICourse *>();
}
IEditableCourse * editableCourse(Language *language, int index) const override
{
Q_UNUSED(language);
Q_UNUSED(index);
return nullptr;
}
void reloadCourses() override
{
// do nothing
}
QVector<Language *> languages() const override
{
return QVector<Language *>();
}
Q_SIGNALS:
void courseAboutToBeAdded(ICourse*,int) override;
void courseAdded() override;
void courseAboutToBeRemoved(int) override;
void courseRemoved() override;
private:
QVector<IEditableCourse *> m_courses;
};
#endif
/*
* Copyright 2019 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "test_editorsession.h"
#include "editablerepositorystub.h"
#include "src/core/editorsession.h"
#include "src/core/icourse.h"
#include "src/core/ieditablecourse.h"
#include "src/core/ieditablerepository.h"
#include "src/core/language.h"
#include "src/core/unit.h"
#include <QTest>
#include <QSignalSpy>
class EditableCourseStub : public IEditableCourse
{
public:
EditableCourseStub(Language *language, QVector<Unit *> units)
: m_language(language)
, m_units(units)
{
}
~EditableCourseStub() override;
QString id() const override
{
return m_id;
}
void setId(QString id) override
{
m_id = id;
emit idChanged();
}
QString foreignId() const override
{
return m_foreignId;
}
void setForeignId(QString id) override
{
m_foreignId = id;
}
QString title() const override
{
return m_title;
}
void setTitle(QString title) override
{
m_title = title;
emit titleChanged();
}
QString i18nTitle() const override
{
return m_i18nTitle;
}
void setI18nTitle(QString title) override
{
m_i18nTitle = title;
}
QString description() const override
{
return m_description;
}
void setDescription(QString description) override
{
m_description = description;
emit descriptionChanged();
}
Language * language() const override
{
return m_language;
}
void setLanguage(Language *language) override
{
m_language = language;
emit languageChanged();
}
QList<Unit *> unitList() override
{
return m_units.toList();
}
QUrl file() const override
{
return QUrl();
}
private:
QString m_id{ "courseid" };
QString m_foreignId{ "foreigncourseid" };
QString m_title{ "title" };
QString m_i18nTitle{ "i18n title" };
QString m_description{ "description of the course" };
Language *m_language{nullptr};
QVector<Unit *> m_units;
};
// define one virtual method out of line to pin CourseStub to this translation unit
EditableCourseStub::~EditableCourseStub() = default;
void TestEditorSession::init()
{
// TODO initialization of test case
}
void TestEditorSession::cleanup()
{
// TODO cleanup after test run
}
void TestEditorSession::createEditorSession()
{
Language language;
EditableCourseStub course(&language, QVector<Unit *>());
EditableRepositoryStub repository{ {&course} };
EditorSession session;
session.setRepository(&repository);
QVERIFY(session.course() != nullptr);
QCOMPARE(session.course()->id(), course.id());
}
QTEST_GUILESS_MAIN(TestEditorSession)
/*
* Copyright 2019 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TEST_EDITORSESSION_H
#define TEST_EDITORSESSION_H
#include <QObject>
class TestEditorSession : public QObject
{
Q_OBJECT
public:
TestEditorSession() = default;
private Q_SLOTS:
/**
* Called before every test case.
*/
void init();
/**
* Called after every test case.
*/
void cleanup();
/**
* @brief Construct and destruct editor session
*/
void createEditorSession();
};
#endif
......@@ -40,8 +40,10 @@ include_directories(
# set the source code files from which Artikulate is compiled
set(artikulateCore_SRCS
core/icourse.h
core/drawertrainingactions.cpp
core/ieditablecourse.h
core/ieditablerepository.h
core/iresourcerepository.h
core/drawertrainingactions.cpp
core/resourcerepository.cpp
core/contributorrepository.cpp
core/language.cpp
......
......@@ -39,7 +39,7 @@
#include <QStandardPaths>
ContributorRepository::ContributorRepository(QObject *parent)
: IResourceRepository()
: IEditableRepository()
{
loadLanguageResources();
}
......@@ -180,6 +180,17 @@ QVector<ICourse *> ContributorRepository::courses() const
return courses;
}
QVector<IEditableCourse *> ContributorRepository::editableCourses() const
{
QVector<IEditableCourse *> courses;
for (const auto &courseList : m_courses) {
for (const auto &course : courseList) {
courses.append(course);
}
}
return courses;
}
QVector<ICourse *> ContributorRepository::courses(Language *language) const
{
if (language == nullptr) {
......@@ -195,7 +206,7 @@ QVector<ICourse *> ContributorRepository::courses(Language *language) const
return courses;
}
EditableCourseResource * ContributorRepository::course(Language *language, int index) const
IEditableCourse * ContributorRepository::editableCourse(Language *language, int index) const
{
Q_ASSERT(m_courses.contains(language->id()));
Q_ASSERT(index >= 0 && index < m_courses[language->id()].count());
......
......@@ -22,7 +22,7 @@
#define CONTRIBUTORREPOSITORY_H
#include "artikulatecore_export.h"
#include "iresourcerepository.h"
#include "ieditablerepository.h"
#include <QObject>
#include <QMap>
#include <QHash>
......@@ -41,10 +41,11 @@ class QUrl;
* @class ContributorRepository
* This class handles the resources of a contributor.
*/
class ARTIKULATECORE_EXPORT ContributorRepository : public IResourceRepository
class ARTIKULATECORE_EXPORT ContributorRepository : public IEditableRepository
{
Q_OBJECT
Q_INTERFACES(IResourceRepository)
Q_INTERFACES(IEditableRepository)
Q_PROPERTY(QString repositoryUrl READ storageLocation NOTIFY repositoryChanged)
......@@ -77,9 +78,6 @@ public:
*/
Q_DECL_DEPRECATED QList<LanguageResource *> languageResources() const;
/**
* \return list of all available language specifications
*/
QVector<Language *> languages() const override;
/**
......@@ -93,6 +91,7 @@ public:
Q_INVOKABLE Language * language(LearnerProfile::LearningGoal* learningGoal) const;
QVector<ICourse *> courses() const override;
QVector<IEditableCourse *> editableCourses() const override;
QVector<ICourse *> courses(Language *language) const override;
/**
......@@ -100,7 +99,7 @@ public:
*/
QList<EditableCourseResource *> courseResources(Language *language);
Q_INVOKABLE EditableCourseResource * course(Language *language, int index) const;
Q_INVOKABLE IEditableCourse * editableCourse(Language *language, int index) const override;
/**
* Reset the file for this course or skeleton.
......
......@@ -43,9 +43,12 @@ EditorSession::EditorSession(QObject *parent)
}
void EditorSession::setContributorRepository(ContributorRepository *repository)
void EditorSession::setRepository(IEditableRepository *repository)
{
m_repository = repository;
if (!repository->editableCourses().isEmpty()) {
setCourse(repository->editableCourses().first());
}
}
void EditorSession::setSkeletonMode(bool enabled)
......@@ -102,9 +105,9 @@ void EditorSession::setSkeleton(SkeletonResource *skeleton)
if (m_skeleton) {
bool found = false;
int resources = m_repository->courseResources(language).count();
int resources = m_repository->courses(language).count();
for (int i=0; i < resources; ++i) {
EditableCourseResource * course = m_repository->course(language, i);
auto course = m_repository->editableCourse(language, i);
if (course->foreignId() == m_skeleton->id()) {
setCourse(course);
found = true;
......@@ -133,9 +136,9 @@ void EditorSession::setLanguage(Language *language)
if (m_skeletonMode) {
bool found = false;
if (m_skeleton) {
int resources = m_repository->courseResources(m_language).count();
int resources = m_repository->courses(m_language).count();
for (int i=0; i < resources; ++i) {
EditableCourseResource * course = m_repository->course(m_language, i);
IEditableCourse *course = m_repository->editableCourse(m_language, i);
if (course->foreignId() == m_skeleton->id()) {
setCourse(course);
found = true;
......@@ -148,19 +151,19 @@ void EditorSession::setLanguage(Language *language)
}
}
else { // not skeleton mode
if (m_repository->courseResources(m_language).count() > 0) {
setCourse(m_repository->course(m_language, 0));
if (m_repository->courses(m_language).count() > 0) {
setCourse(m_repository->editableCourse(m_language, 0));
}
}
emit languageChanged();
}
EditableCourseResource * EditorSession::course() const
IEditableCourse * EditorSession::course() const
{
return m_course;
}
void EditorSession::setCourse(EditableCourseResource *course)
void EditorSession::setCourse(IEditableCourse *course)
{
if (m_course == course) {
return;
......
......@@ -26,10 +26,10 @@
class QString;
class Language;
class EditableCourseResource;
class IEditableCourse;
class Unit;
class SkeletonResource;
class ContributorRepository;
class IEditableRepository;
/**
* \class EditorSession
......@@ -59,7 +59,7 @@ class ARTIKULATECORE_EXPORT EditorSession : public QObject
Q_PROPERTY(bool editSkeleton READ isEditSkeleton WRITE setEditSkeleton NOTIFY editSkeletonChanged)
Q_PROPERTY(SkeletonResource *skeleton READ skeleton WRITE setSkeleton NOTIFY skeletonChanged)
Q_PROPERTY(Language *language READ language WRITE setLanguage NOTIFY languageChanged)
Q_PROPERTY(EditableCourseResource *course READ course WRITE setCourse NOTIFY courseChanged) //TODO interface should provde ICourse
Q_PROPERTY(IEditableCourse *course READ course WRITE setCourse NOTIFY courseChanged)
Q_PROPERTY(Unit *unit READ unit WRITE setUnit NOTIFY unitChanged)
Q_PROPERTY(Phrase *phrase READ phrase WRITE setPhrase NOTIFY phraseChanged)
Q_PROPERTY(bool hasNextPhrase READ hasNextPhrase NOTIFY phraseChanged)
......@@ -68,7 +68,7 @@ class ARTIKULATECORE_EXPORT EditorSession : public QObject
public:
explicit EditorSession(QObject *parent = nullptr);
void setContributorRepository(ContributorRepository *manager);
void setRepository(IEditableRepository *repository);
void setSkeletonMode(bool enabled=true);
bool skeletonMode() const;
void setEditSkeleton(bool enabled=true);
......@@ -77,8 +77,8 @@ public:
void setSkeleton(SkeletonResource *skeleton);
Language * language() const;
void setLanguage(Language *language);
EditableCourseResource * course() const;
void setCourse(EditableCourseResource *course);
IEditableCourse * course() const;
void setCourse(IEditableCourse *course);
Unit * unit() const;
void setUnit(Unit *unit);
Phrase * phrase() const;
......@@ -106,13 +106,13 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(EditorSession)
ContributorRepository * m_repository;
IEditableRepository * m_repository;
bool m_skeletonMode;
bool m_editSkeleton;
SkeletonResource *m_skeleton;
Language *m_language;
EditableCourseResource *m_course;
EditableCourseResource *m_tmpCourseWhileSkeletonEditing;
IEditableCourse *m_course;
IEditableCourse *m_tmpCourseWhileSkeletonEditing;
Unit *m_unit;
Phrase *m_phrase;
};
......
/*
* Copyright 2019 Andreas Cord-Landwehr <cordlandwehr@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef IEDITABLECOURSE_H
#define IEDITABLECOURSE_H
#include "artikulatecore_export.h"
#include "icourse.h"
#include <QObject>
class QString;
class Language;
class ARTIKULATECORE_EXPORT IEditableCourse : public ICourse
{
public:
virtual ~IEditableCourse() = default;
virtual void setId(QString id) = 0;
virtual void setForeignId(QString foreignId) = 0;