Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Education
Artikulate
Commits
87eb2daa
Commit
87eb2daa
authored
Jul 13, 2019
by
Andreas Cord-Landwehr
Browse files
Implement sync from skeleton and add tests
parent
50da0459
Changes
9
Hide whitespace changes
Inline
Side-by-side
autotests/unittests/CMakeLists.txt
View file @
87eb2daa
...
...
@@ -115,6 +115,7 @@ ecm_mark_as_test(test_skeletonresource)
set
(
TestEditableCourseResource_SRCS
editablecourseresource/test_editablecourseresource.cpp
../mocks/resourcerepositorystub.cpp
../mocks/coursestub.cpp
../mocks/languagestub.cpp
)
qt5_add_resources
(
TestEditableCourseResource_SRCS ../../data/languages.qrc
)
...
...
autotests/unittests/editablecourseresource/test_editablecourseresource.cpp
View file @
87eb2daa
...
...
@@ -26,6 +26,7 @@
#include "core/resources/courseparser.h"
#include "core/resources/editablecourseresource.h"
#include "../mocks/languagestub.h"
#include "../mocks/coursestub.h"
#include <memory>
#include <QTest>
...
...
@@ -314,4 +315,49 @@ void TestEditableCourseResource::modifiedStatus()
}
}
void
TestEditableCourseResource
::
skeletonUpdate
()
{
std
::
shared_ptr
<
ILanguage
>
language
(
new
LanguageStub
(
"de"
));
ResourceRepositoryStub
repository
({
language
});
auto
course
=
EditableCourseResource
::
create
(
QUrl
::
fromLocalFile
(
":/courses/de.xml"
),
&
repository
);
QCOMPARE
(
course
->
units
().
count
(),
1
);
// create skeleton stub
auto
importPhrase
=
new
Phrase
;
importPhrase
->
setId
(
"importPhraseId"
);
importPhrase
->
setText
(
"phraseText"
);
importPhrase
->
setType
(
Phrase
::
Sentence
);
auto
importUnit
=
std
::
shared_ptr
<
Unit
>
(
new
Unit
);
importUnit
->
setId
(
"importId"
);
importUnit
->
addPhrase
(
importPhrase
);
auto
skeleton
=
CourseStub
::
create
(
language
,
{
importUnit
});
// test import
course
->
updateFrom
(
skeleton
);
QCOMPARE
(
course
->
units
().
count
(),
2
);
{
std
::
shared_ptr
<
Unit
>
importedUnit
;
for
(
auto
unit
:
course
->
units
())
{
if
(
unit
->
foreignId
()
==
importUnit
->
id
())
{
importedUnit
=
unit
;
break
;
}
}
QVERIFY
(
importedUnit
!=
nullptr
);
QCOMPARE
(
importedUnit
->
foreignId
(),
importUnit
->
id
());
QCOMPARE
(
importedUnit
->
id
(),
importUnit
->
id
());
QCOMPARE
(
importedUnit
->
title
(),
importUnit
->
title
());
QCOMPARE
(
importedUnit
->
phraseList
().
count
(),
1
);
auto
importedPhrase
=
importedUnit
->
phraseList
().
first
();
QCOMPARE
(
importedPhrase
->
id
(),
importPhrase
->
id
());
QCOMPARE
(
importedPhrase
->
foreignId
(),
importPhrase
->
id
());
QCOMPARE
(
importedPhrase
->
text
(),
importPhrase
->
text
());
QCOMPARE
(
importedPhrase
->
type
(),
importPhrase
->
type
());
}
// test that re-import does not change course
course
->
updateFrom
(
skeleton
);
QCOMPARE
(
course
->
units
().
count
(),
2
);
}
QTEST_GUILESS_MAIN
(
TestEditableCourseResource
)
autotests/unittests/editablecourseresource/test_editablecourseresource.h
View file @
87eb2daa
...
...
@@ -66,6 +66,11 @@ private Q_SLOTS:
* Test if the modified status is correctly set.
*/
void
modifiedStatus
();
/**
* Test correct update of course from a skeleton
*/
void
skeletonUpdate
();
};
#endif
autotests/unittests/editorsession/test_editorsession.cpp
View file @
87eb2daa
...
...
@@ -121,6 +121,10 @@ public:
{
return
false
;
}
void
updateFrom
(
std
::
shared_ptr
<
ICourse
>
)
override
{
// not implemented
}
bool
isModified
()
const
override
{
return
false
;
...
...
src/core/ieditablecourse.h
View file @
87eb2daa
...
...
@@ -51,6 +51,13 @@ public:
* @return true if no errors occured
*/
virtual
bool
sync
()
=
0
;
/**
* @brief Update course from skeleton
* This method imports all units and phrases from the specified skeleton
*
* @param skeleton
*/
virtual
void
updateFrom
(
std
::
shared_ptr
<
ICourse
>
skeleton
)
=
0
;
virtual
bool
isModified
()
const
=
0
;
protected:
...
...
src/core/resources/editablecourseresource.cpp
View file @
87eb2daa
...
...
@@ -19,21 +19,21 @@
*/
#include "editablecourseresource.h"
#include "courseparser.h"
#include "artikulate_debug.h"
#include "core/unit.h"
#include "core/phrase.h"
#include "core/phoneme.h"
#include "core/phrase.h"
#include "core/unit.h"
#include "courseparser.h"
#include <QObject>
#include <QQmlEngine>
#include <QDomDocument>
#include <KLocalizedString>
#include <KTar>
#include <QDir>
#include <QDomDocument>
#include <QFile>
#include <QFileInfo>
#include <QObject>
#include <QQmlEngine>
#include <QUuid>
#include <KTar>
#include <KLocalizedString>
EditableCourseResource
::
EditableCourseResource
(
const
QUrl
&
path
,
IResourceRepository
*
repository
)
:
IEditableCourse
()
...
...
@@ -48,29 +48,27 @@ EditableCourseResource::EditableCourseResource(const QUrl &path, IResourceReposi
connect
(
m_course
.
get
(),
&
ICourse
::
unitAboutToBeAdded
,
this
,
&
ICourse
::
unitAboutToBeAdded
);
connect
(
m_course
.
get
(),
&
ICourse
::
unitAdded
,
this
,
&
ICourse
::
unitAdded
);
connect
(
m_course
.
get
(),
&
CourseResource
::
idChanged
,
this
,
&
EditableCourseResource
::
idChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
foreignIdChanged
,
this
,
&
EditableCourseResource
::
foreignIdChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
titleChanged
,
this
,
&
EditableCourseResource
::
titleChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
descriptionChanged
,
this
,
&
EditableCourseResource
::
descriptionChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
languageChanged
,
this
,
&
EditableCourseResource
::
languageChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
foreignIdChanged
,
this
,
&
EditableCourseResource
::
foreignIdChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
titleChanged
,
this
,
&
EditableCourseResource
::
titleChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
descriptionChanged
,
this
,
&
EditableCourseResource
::
descriptionChanged
);
connect
(
m_course
.
get
(),
&
CourseResource
::
languageChanged
,
this
,
&
EditableCourseResource
::
languageChanged
);
}
std
::
shared_ptr
<
EditableCourseResource
>
EditableCourseResource
::
create
(
const
QUrl
&
path
,
IResourceRepository
*
repository
)
std
::
shared_ptr
<
EditableCourseResource
>
EditableCourseResource
::
create
(
const
QUrl
&
path
,
IResourceRepository
*
repository
)
{
std
::
shared_ptr
<
EditableCourseResource
>
course
(
new
EditableCourseResource
(
path
,
repository
));
course
->
setSelf
(
course
);
return
course
;
}
void
EditableCourseResource
::
setSelf
(
std
::
shared_ptr
<
ICourse
>
self
)
{
m_course
->
setSelf
(
self
);
}
void
EditableCourseResource
::
setSelf
(
std
::
shared_ptr
<
ICourse
>
self
)
{
m_course
->
setSelf
(
self
);
}
QString
EditableCourseResource
::
id
()
const
{
return
m_course
->
id
();
}
QString
EditableCourseResource
::
id
()
const
{
return
m_course
->
id
();
}
void
EditableCourseResource
::
setId
(
QString
id
)
{
...
...
@@ -80,20 +78,14 @@ void EditableCourseResource::setId(QString id)
}
}
QString
EditableCourseResource
::
foreignId
()
const
{
return
m_course
->
foreignId
();
}
QString
EditableCourseResource
::
foreignId
()
const
{
return
m_course
->
foreignId
();
}
void
EditableCourseResource
::
setForeignId
(
QString
foreignId
)
{
m_course
->
setForeignId
(
std
::
move
(
foreignId
));
}
QString
EditableCourseResource
::
title
()
const
{
return
m_course
->
title
();
}
QString
EditableCourseResource
::
title
()
const
{
return
m_course
->
title
();
}
void
EditableCourseResource
::
setTitle
(
QString
title
)
{
...
...
@@ -103,10 +95,7 @@ void EditableCourseResource::setTitle(QString title)
}
}
QString
EditableCourseResource
::
i18nTitle
()
const
{
return
m_course
->
i18nTitle
();
}
QString
EditableCourseResource
::
i18nTitle
()
const
{
return
m_course
->
i18nTitle
();
}
void
EditableCourseResource
::
setI18nTitle
(
QString
i18nTitle
)
{
...
...
@@ -116,10 +105,7 @@ void EditableCourseResource::setI18nTitle(QString i18nTitle)
}
}
QString
EditableCourseResource
::
description
()
const
{
return
m_course
->
description
();
}
QString
EditableCourseResource
::
description
()
const
{
return
m_course
->
description
();
}
void
EditableCourseResource
::
setDescription
(
QString
description
)
{
...
...
@@ -129,10 +115,7 @@ void EditableCourseResource::setDescription(QString description)
}
}
std
::
shared_ptr
<
ILanguage
>
EditableCourseResource
::
language
()
const
{
return
m_course
->
language
();
}
std
::
shared_ptr
<
ILanguage
>
EditableCourseResource
::
language
()
const
{
return
m_course
->
language
();
}
void
EditableCourseResource
::
setLanguage
(
std
::
shared_ptr
<
ILanguage
>
language
)
{
...
...
@@ -142,10 +125,7 @@ void EditableCourseResource::setLanguage(std::shared_ptr<ILanguage> language)
}
}
QUrl
EditableCourseResource
::
file
()
const
{
return
m_course
->
file
();
}
QUrl
EditableCourseResource
::
file
()
const
{
return
m_course
->
file
();
}
bool
EditableCourseResource
::
sync
()
{
...
...
@@ -169,17 +149,18 @@ bool EditableCourseResource::exportToFile(const QUrl &filePath) const
{
// write back to file
// create directories if necessary
QFileInfo
info
(
filePath
.
adjusted
(
QUrl
::
RemoveFilename
|
QUrl
::
StripTrailingSlash
).
path
());
QFileInfo
info
(
filePath
.
adjusted
(
QUrl
::
RemoveFilename
|
QUrl
::
StripTrailingSlash
).
path
());
if
(
!
info
.
exists
())
{
qCDebug
(
ARTIKULATE_LOG
())
<<
"create xml output file directory, not existing"
;
QDir
dir
;
dir
.
mkpath
(
filePath
.
adjusted
(
QUrl
::
RemoveFilename
|
QUrl
::
StripTrailingSlash
).
path
());
dir
.
mkpath
(
filePath
.
adjusted
(
QUrl
::
RemoveFilename
|
QUrl
::
StripTrailingSlash
).
path
());
}
//TODO port to KSaveFile
//
TODO port to KSaveFile
QFile
file
(
filePath
.
toLocalFile
());
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
))
{
qCWarning
(
ARTIKULATE_LOG
())
<<
"Unable to open file "
<<
file
.
fileName
()
<<
" in write mode, aborting."
;
qCWarning
(
ARTIKULATE_LOG
())
<<
"Unable to open file "
<<
file
.
fileName
()
<<
" in write mode, aborting."
;
return
false
;
}
...
...
@@ -195,17 +176,55 @@ std::shared_ptr<Unit> EditableCourseResource::addUnit(std::unique_ptr<Unit> unit
return
sharedUnit
;
}
QVector
<
std
::
shared_ptr
<
Unit
>>
EditableCourseResource
::
units
()
{
return
m_course
->
units
();
}
QVector
<
std
::
shared_ptr
<
Unit
>>
EditableCourseResource
::
units
()
{
return
m_course
->
units
();
}
bool
EditableCourseResource
::
isModified
()
const
void
EditableCourseResource
::
updateFrom
(
std
::
shared_ptr
<
ICourse
>
skeleton
)
{
return
m_modified
;
for
(
auto
skeletonUnit
:
skeleton
->
units
())
{
// find matching unit or create one
std
::
shared_ptr
<
Unit
>
matchingUnit
;
auto
it
=
std
::
find_if
(
m_course
->
units
().
cbegin
(),
m_course
->
units
().
cend
(),
[
skeletonUnit
](
std
::
shared_ptr
<
Unit
>
compareUnit
)
{
return
compareUnit
->
foreignId
()
==
skeletonUnit
->
id
();
});
if
(
it
==
m_course
->
units
().
cend
())
{
// import complete unit
auto
importUnit
=
std
::
unique_ptr
<
Unit
>
(
new
Unit
);
importUnit
->
setId
(
skeletonUnit
->
id
());
importUnit
->
setForeignId
(
skeletonUnit
->
id
());
importUnit
->
setTitle
(
skeletonUnit
->
title
());
matchingUnit
=
m_course
->
addUnit
(
std
::
move
(
importUnit
));
}
else
{
matchingUnit
=
*
it
;
}
// import phrases
for
(
auto
skeletonPhrase
:
skeletonUnit
->
phraseList
())
{
auto
it
=
std
::
find_if
(
matchingUnit
->
phraseList
().
cbegin
(),
matchingUnit
->
phraseList
().
cend
(),
[
skeletonPhrase
](
Phrase
*
comparePhrase
)
{
return
comparePhrase
->
foreignId
()
==
skeletonPhrase
->
id
();
});
if
(
it
==
matchingUnit
->
phraseList
().
cend
())
{
// import complete Phrase
Phrase
*
importPhrase
=
new
Phrase
(
matchingUnit
.
get
());
importPhrase
->
setId
(
skeletonPhrase
->
id
());
importPhrase
->
setForeignId
(
skeletonPhrase
->
id
());
importPhrase
->
setText
(
skeletonPhrase
->
text
());
importPhrase
->
seti18nText
(
skeletonPhrase
->
i18nText
());
importPhrase
->
setType
(
skeletonPhrase
->
type
());
importPhrase
->
setUnit
(
matchingUnit
.
get
());
matchingUnit
->
addPhrase
(
importPhrase
);
}
}
}
qCInfo
(
ARTIKULATE_LOG
())
<<
"Update performed!"
;
}
Unit
*
EditableCourseResource
::
createUnit
()
bool
EditableCourseResource
::
isModified
()
const
{
return
m_modified
;
}
Unit
*
EditableCourseResource
::
createUnit
()
{
// find first unused id
QStringList
unitIds
;
...
...
@@ -228,7 +247,7 @@ Unit * EditableCourseResource::createUnit()
return
sharedUnit
.
get
();
}
Phrase
*
EditableCourseResource
::
createPhrase
(
Unit
*
unit
)
Phrase
*
EditableCourseResource
::
createPhrase
(
Unit
*
unit
)
{
// find globally unique phrase id inside course
QStringList
phraseIds
;
...
...
src/core/resources/editablecourseresource.h
View file @
87eb2daa
...
...
@@ -96,6 +96,7 @@ public:
std
::
shared_ptr
<
Unit
>
addUnit
(
std
::
unique_ptr
<
Unit
>
unit
)
override
;
QVector
<
std
::
shared_ptr
<
Unit
>>
units
()
override
;
void
updateFrom
(
std
::
shared_ptr
<
ICourse
>
course
)
override
;
bool
isModified
()
const
override
;
QUrl
file
()
const
override
;
...
...
src/core/resources/skeletonresource.cpp
View file @
87eb2daa
...
...
@@ -327,6 +327,11 @@ bool SkeletonResource::sync()
return
ok
;
}
void
SkeletonResource
::
updateFrom
(
std
::
shared_ptr
<
ICourse
>
)
{
// not supported
}
bool
SkeletonResource
::
isModified
()
const
{
return
d
->
m_modified
;
...
...
src/core/resources/skeletonresource.h
View file @
87eb2daa
...
...
@@ -58,6 +58,7 @@ public:
bool
exportToFile
(
const
QUrl
&
filePath
)
const
override
;
std
::
shared_ptr
<
Unit
>
addUnit
(
std
::
unique_ptr
<
Unit
>
unit
)
override
;
bool
sync
()
override
;
void
updateFrom
(
std
::
shared_ptr
<
ICourse
>
);
bool
isModified
()
const
override
;
private:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment