diff --git a/src/akonadi/akonadiconfigdialog.cpp b/src/akonadi/akonadiconfigdialog.cpp index 41061486..3c276e7e 100644 --- a/src/akonadi/akonadiconfigdialog.cpp +++ b/src/akonadi/akonadiconfigdialog.cpp @@ -1,136 +1,136 @@ /* This file is part of Zanshin Copyright 2011-2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadiconfigdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Akonadi; ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("Configure")); auto description = new QLabel(this); description->setWordWrap(true); description->setText(tr("Please select or create a resource which will be used by the application to store and query its TODOs.")); m_agentInstanceWidget = new Akonadi::AgentInstanceWidget(this); - m_agentInstanceWidget->agentFilterProxyModel()->addMimeTypeFilter("application/x-vnd.akonadi.calendar.todo"); + m_agentInstanceWidget->agentFilterProxyModel()->addMimeTypeFilter(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); auto toolBar = new QToolBar(this); toolBar->setIconSize(QSize(16, 16)); toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); auto addAction = new QAction(this); - addAction->setObjectName("addAction"); + addAction->setObjectName(QStringLiteral("addAction")); addAction->setText(tr("Add resource")); - addAction->setIcon(QIcon::fromTheme("list-add")); + addAction->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); connect(addAction, &QAction::triggered, this, &ConfigDialog::onAddTriggered); toolBar->addAction(addAction); auto removeAction = new QAction(this); - removeAction->setObjectName("removeAction"); + removeAction->setObjectName(QStringLiteral("removeAction")); removeAction->setText(tr("Remove resource")); - removeAction->setIcon(QIcon::fromTheme("list-remove")); + removeAction->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); connect(removeAction, &QAction::triggered, this, &ConfigDialog::onRemoveTriggered); toolBar->addAction(removeAction); auto configureAction = new QAction(this); - configureAction->setObjectName("settingsAction"); + configureAction->setObjectName(QStringLiteral("settingsAction")); configureAction->setText(tr("Configure resource...")); - configureAction->setIcon(QIcon::fromTheme("configure")); + configureAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); connect(configureAction, &QAction::triggered, this, &ConfigDialog::onConfigureTriggered); toolBar->addAction(configureAction); auto buttons = new QDialogButtonBox(this); buttons->setStandardButtons(QDialogButtonBox::Close); connect(buttons, &QDialogButtonBox::accepted, this, &ConfigDialog::accept); connect(buttons, &QDialogButtonBox::rejected, this, &ConfigDialog::reject); auto layout = new QVBoxLayout; layout->addWidget(description); layout->addWidget(m_agentInstanceWidget); auto toolBarLayout = new QHBoxLayout; toolBarLayout->setAlignment(Qt::AlignRight); toolBarLayout->addWidget(toolBar); layout->addLayout(toolBarLayout); layout->addWidget(buttons); setLayout(layout); } void ConfigDialog::onAddTriggered() { Akonadi::AgentTypeDialog dlg(this); - dlg.agentFilterProxyModel()->addMimeTypeFilter("application/x-vnd.akonadi.calendar.todo"); + dlg.agentFilterProxyModel()->addMimeTypeFilter(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); if (dlg.exec()) { const auto agentType = dlg.agentType(); if (agentType.isValid()) { auto job = new Akonadi::AgentInstanceCreateJob(agentType, this); job->configure(this); job->start(); } } } void ConfigDialog::onRemoveTriggered() { auto list = m_agentInstanceWidget->selectedAgentInstances(); if (!list.isEmpty()) { auto answer = QMessageBox::question(this, tr("Multiple Agent Deletion"), tr("Do you really want to delect the selected agent instances?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (answer == QMessageBox::Yes) { foreach (const auto &agent, list) { Akonadi::AgentManager::self()->removeInstance(agent); } } } } void ConfigDialog::onConfigureTriggered() { auto agent = m_agentInstanceWidget->currentAgentInstance(); if (agent.isValid()) agent.configure(this); } diff --git a/src/akonadi/akonadiserializer.cpp b/src/akonadi/akonadiserializer.cpp index 9cc6af3e..200b5ca7 100644 --- a/src/akonadi/akonadiserializer.cpp +++ b/src/akonadi/akonadiserializer.cpp @@ -1,637 +1,637 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Rémi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadiserializer.h" #include #include #include #include #include #include #include #include "utils/mem_fn.h" #include "akonadi/akonadiapplicationselectedattribute.h" #include "akonadi/akonaditimestampattribute.h" using namespace Akonadi; Serializer::Serializer() { } Serializer::~Serializer() { } bool Serializer::representsCollection(SerializerInterface::QObjectPtr object, Collection collection) { return object->property("collectionId").toLongLong() == collection.id(); } bool Serializer::representsItem(QObjectPtr object, Item item) { return object->property("itemId").toLongLong() == item.id(); } bool Serializer::representsAkonadiTag(Domain::Tag::Ptr tag, Tag akonadiTag) const { return tag->property("tagId").toLongLong() == akonadiTag.id(); } QString Serializer::objectUid(SerializerInterface::QObjectPtr object) { return object->property("todoUid").toString(); } Domain::DataSource::Ptr Serializer::createDataSourceFromCollection(Collection collection, DataSourceNameScheme naming) { if (!collection.isValid()) return Domain::DataSource::Ptr(); auto dataSource = Domain::DataSource::Ptr::create(); updateDataSourceFromCollection(dataSource, collection, naming); return dataSource; } void Serializer::updateDataSourceFromCollection(Domain::DataSource::Ptr dataSource, Collection collection, DataSourceNameScheme naming) { if (!collection.isValid()) return; QString name = collection.displayName(); if (naming == FullPath) { auto parent = collection.parentCollection(); while (parent.isValid() && parent != Akonadi::Collection::root()) { name = parent.displayName() + "/" + name; parent = parent.parentCollection(); } } dataSource->setName(name); const auto mimeTypes = collection.contentMimeTypes(); auto types = Domain::DataSource::ContentTypes(); if (mimeTypes.contains(NoteUtils::noteMimeType())) types |= Domain::DataSource::Notes; if (mimeTypes.contains(KCalCore::Todo::todoMimeType())) types |= Domain::DataSource::Tasks; dataSource->setContentTypes(types); if (collection.hasAttribute()) { auto iconName = collection.attribute()->iconName(); dataSource->setIconName(iconName); } if (!collection.hasAttribute()) { dataSource->setSelected(true); } else { auto isSelected = collection.attribute()->isSelected(); dataSource->setSelected(isSelected); } if (collection.enabled()) dataSource->setListStatus(Domain::DataSource::Bookmarked); else if (collection.referenced()) dataSource->setListStatus(Domain::DataSource::Listed); else dataSource->setListStatus(Domain::DataSource::Unlisted); dataSource->setProperty("collectionId", collection.id()); } Collection Serializer::createCollectionFromDataSource(Domain::DataSource::Ptr dataSource) { const auto id = dataSource->property("collectionId").value(); auto collection = Collection(id); collection.attribute(Akonadi::Collection::AddIfMissing); auto selectedAttribute = collection.attribute(Akonadi::Collection::AddIfMissing); selectedAttribute->setSelected(dataSource->isSelected()); switch (dataSource->listStatus()) { case Domain::DataSource::Unlisted: collection.setReferenced(false); collection.setEnabled(false); break; case Domain::DataSource::Listed: collection.setReferenced(true); collection.setEnabled(false); break; case Domain::DataSource::Bookmarked: collection.setReferenced(false); collection.setEnabled(true); break; default: qFatal("Shouldn't happen"); break; } return collection; } bool Serializer::isListedCollection(Collection collection) { return collection.enabled() || collection.referenced(); } bool Serializer::isSelectedCollection(Collection collection) { if (!isListedCollection(collection)) return false; if (!isNoteCollection(collection) && !isTaskCollection(collection)) return false; if (!collection.hasAttribute()) return true; return collection.attribute()->isSelected(); } bool Akonadi::Serializer::isNoteCollection(Akonadi::Collection collection) { return collection.contentMimeTypes().contains(NoteUtils::noteMimeType()); } bool Akonadi::Serializer::isTaskCollection(Akonadi::Collection collection) { return collection.contentMimeTypes().contains(KCalCore::Todo::todoMimeType()); } bool Serializer::isTaskItem(Item item) { if (!item.hasPayload()) return false; auto todo = item.payload(); return todo->customProperty("Zanshin", "Project").isEmpty(); } Domain::Task::Ptr Serializer::createTaskFromItem(Item item) { if (!isTaskItem(item)) return Domain::Task::Ptr(); auto task = Domain::Task::Ptr::create(); updateTaskFromItem(task, item); return task; } void Serializer::updateTaskFromItem(Domain::Task::Ptr task, Item item) { if (!isTaskItem(item)) return; auto todo = item.payload(); task->setTitle(todo->summary()); task->setText(todo->description()); task->setDone(todo->isCompleted()); task->setDoneDate(todo->completed().dateTime().toUTC()); task->setStartDate(todo->dtStart().dateTime().toUTC()); task->setDueDate(todo->dtDue().dateTime().toUTC()); task->setProperty("itemId", item.id()); task->setProperty("parentCollectionId", item.parentCollection().id()); task->setProperty("todoUid", todo->uid()); task->setProperty("relatedUid", todo->relatedTo()); if (todo->attendeeCount() > 0) { const auto attendees = todo->attendees(); const auto delegate = std::find_if(attendees.begin(), attendees.end(), [] (const KCalCore::Attendee::Ptr &attendee) { return attendee->status() == KCalCore::Attendee::Accepted; }); if (delegate != attendees.end()) { task->setDelegate(Domain::Task::Delegate((*delegate)->name(), (*delegate)->email())); } } } bool Serializer::isTaskChild(Domain::Task::Ptr task, Akonadi::Item item) { if (!isTaskItem(item)) return false; auto todo = item.payload(); if (todo->relatedTo() == task->property("todoUid")) return true; return false; } Akonadi::Item Serializer::createItemFromTask(Domain::Task::Ptr task) { auto todo = KCalCore::Todo::Ptr::create(); todo->setSummary(task->title()); todo->setDescription(task->text()); if (task->isDone()) todo->setCompleted(KDateTime(task->doneDate())); else todo->setCompleted(task->isDone()); todo->setDtStart(KDateTime(task->startDate())); todo->setDtDue(KDateTime(task->dueDate())); if (task->property("todoUid").isValid()) { todo->setUid(task->property("todoUid").toString()); } if (task->property("relatedUid").isValid()) { todo->setRelatedTo(task->property("relatedUid").toString()); } if (task->delegate().isValid()) { KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(task->delegate().name(), task->delegate().email(), true, KCalCore::Attendee::Accepted)); todo->addAttendee(attendee); } Akonadi::Item item; if (task->property("itemId").isValid()) { item.setId(task->property("itemId").value()); } if (task->property("parentCollectionId").isValid()) { auto parentId = task->property("parentCollectionId").value(); item.setParentCollection(Akonadi::Collection(parentId)); } item.setMimeType(KCalCore::Todo::todoMimeType()); item.setPayload(todo); return item; } QString Serializer::relatedUidFromItem(Akonadi::Item item) { if (isTaskItem(item)) { const auto todo = item.payload(); return todo->relatedTo(); } else if (isNoteItem(item)) { const auto message = item.payload(); const auto relatedHeader = message->headerByType("X-Zanshin-RelatedProjectUid"); return relatedHeader ? relatedHeader->asUnicodeString() : QString(); } else { return QString(); } } void Serializer::updateItemParent(Akonadi::Item item, Domain::Task::Ptr parent) { if (!isTaskItem(item)) return; auto todo = item.payload(); todo->setRelatedTo(parent->property("todoUid").toString()); } void Serializer::updateItemProject(Item item, Domain::Project::Ptr project) { if (isTaskItem(item)) { auto todo = item.payload(); todo->setRelatedTo(project->property("todoUid").toString()); } else if (isNoteItem(item)) { auto note = item.payload(); note->removeHeader("X-Zanshin-RelatedProjectUid"); const QByteArray parentUid = project->property("todoUid").toString().toUtf8(); if (!parentUid.isEmpty()) { auto relatedHeader = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader->from7BitString(parentUid); note->appendHeader(relatedHeader); } note->assemble(); } } void Serializer::removeItemParent(Akonadi::Item item) { if (!isTaskItem(item)) return; auto todo = item.payload(); todo->setRelatedTo(QString()); } void Serializer::promoteItemToProject(Akonadi::Item item) { if (!isTaskItem(item)) return; auto todo = item.payload(); todo->setRelatedTo(QString()); - todo->setCustomProperty("Zanshin", "Project", "1"); + todo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); } void Serializer::clearItem(Akonadi::Item *item) { Q_ASSERT(item); if (!isTaskItem(*item)) return; // NOTE : Currently not working, when akonadistorage test will make it pass, we will use it // item->clearTags(); foreach (const Tag& tag, item->tags()) item->clearTag(tag); } Akonadi::Item::List Serializer::filterDescendantItems(const Akonadi::Item::List &potentialChildren, const Akonadi::Item &ancestorItem) { if (potentialChildren.isEmpty()) return Akonadi::Item::List(); Akonadi::Item::List itemsToProcess = potentialChildren; Q_ASSERT(ancestorItem.isValid() && ancestorItem.hasPayload()); KCalCore::Todo::Ptr todo = ancestorItem.payload(); const auto bound = std::partition(itemsToProcess.begin(), itemsToProcess.end(), [ancestorItem, todo](Akonadi::Item currentItem) { return (!currentItem.hasPayload() || currentItem == ancestorItem || currentItem.payload()->relatedTo() != todo->uid()); }); Akonadi::Item::List itemsRemoved; std::copy(itemsToProcess.begin(), bound, std::back_inserter(itemsRemoved)); itemsToProcess.erase(itemsToProcess.begin(), bound); auto result = std::accumulate(itemsToProcess.begin(), itemsToProcess.end(), Akonadi::Item::List(), [this, itemsRemoved](Akonadi::Item::List result, Akonadi::Item currentItem) { result << currentItem; return result += filterDescendantItems(itemsRemoved, currentItem); }); return result; } bool Serializer::isNoteItem(Item item) { return item.hasPayload(); } Domain::Note::Ptr Serializer::createNoteFromItem(Akonadi::Item item) { if (!isNoteItem(item)) return Domain::Note::Ptr(); Domain::Note::Ptr note = Domain::Note::Ptr::create(); updateNoteFromItem(note, item); return note; } void Serializer::updateNoteFromItem(Domain::Note::Ptr note, Item item) { if (!isNoteItem(item)) return; auto message = item.payload(); note->setTitle(message->subject(true)->asUnicodeString()); note->setText(message->mainBodyPart()->decodedText()); note->setProperty("itemId", item.id()); if (auto relatedHeader = message->headerByType("X-Zanshin-RelatedProjectUid")) { note->setProperty("relatedUid", relatedHeader->asUnicodeString()); } else { note->setProperty("relatedUid", QVariant()); } } Item Serializer::createItemFromNote(Domain::Note::Ptr note) { NoteUtils::NoteMessageWrapper builder; builder.setTitle(note->title()); builder.setText(note->text() + '\n'); // Adding an extra '\n' because KMime always removes it... KMime::Message::Ptr message = builder.message(); if (!note->property("relatedUid").toString().isEmpty()) { auto relatedHeader = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader->from7BitString(note->property("relatedUid").toString().toUtf8()); message->appendHeader(relatedHeader); } Akonadi::Item item; if (note->property("itemId").isValid()) { item.setId(note->property("itemId").value()); } item.setMimeType(Akonadi::NoteUtils::noteMimeType()); item.setPayload(message); return item; } bool Serializer::isProjectItem(Item item) { if (!item.hasPayload()) return false; return !isTaskItem(item); } Domain::Project::Ptr Serializer::createProjectFromItem(Item item) { if (!isProjectItem(item)) return Domain::Project::Ptr(); auto project = Domain::Project::Ptr::create(); updateProjectFromItem(project, item); return project; } void Serializer::updateProjectFromItem(Domain::Project::Ptr project, Item item) { if (!isProjectItem(item)) return; auto todo = item.payload(); project->setName(todo->summary()); project->setProperty("itemId", item.id()); project->setProperty("parentCollectionId", item.parentCollection().id()); project->setProperty("todoUid", todo->uid()); } Item Serializer::createItemFromProject(Domain::Project::Ptr project) { auto todo = KCalCore::Todo::Ptr::create(); todo->setSummary(project->name()); - todo->setCustomProperty("Zanshin", "Project", "1"); + todo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); if (project->property("todoUid").isValid()) { todo->setUid(project->property("todoUid").toString()); } Akonadi::Item item; if (project->property("itemId").isValid()) { item.setId(project->property("itemId").value()); } if (project->property("parentCollectionId").isValid()) { auto parentId = project->property("parentCollectionId").value(); item.setParentCollection(Akonadi::Collection(parentId)); } item.setMimeType(KCalCore::Todo::todoMimeType()); item.setPayload(todo); return item; } bool Serializer::isProjectChild(Domain::Project::Ptr project, Item item) { const QString todoUid = project->property("todoUid").toString(); const QString relatedUid = relatedUidFromItem(item); return !todoUid.isEmpty() && !relatedUid.isEmpty() && todoUid == relatedUid; } Domain::Context::Ptr Serializer::createContextFromTag(Akonadi::Tag tag) { if (!isContext(tag)) return Domain::Context::Ptr(); auto context = Domain::Context::Ptr::create(); updateContextFromTag(context, tag); return context; } Akonadi::Tag Serializer::createTagFromContext(Domain::Context::Ptr context) { auto tag = Akonadi::Tag(); tag.setName(context->name()); tag.setType(Akonadi::SerializerInterface::contextTagType()); tag.setGid(QByteArray(context->name().toLatin1())); if (context->property("tagId").isValid()) tag.setId(context->property("tagId").value()); return tag; } void Serializer::updateContextFromTag(Domain::Context::Ptr context, Akonadi::Tag tag) { if (!isContext(tag)) return; context->setProperty("tagId", tag.id()); context->setName(tag.name()); } bool Serializer::hasContextTags(Item item) const { using namespace std::placeholders; Tag::List tags = item.tags(); return std::any_of(tags.constBegin(), tags.constEnd(), std::bind(Utils::mem_fn(&Serializer::isContext), this, _1)); } bool Serializer::hasAkonadiTags(Item item) const { using namespace std::placeholders; Tag::List tags = item.tags(); return std::any_of(tags.constBegin(), tags.constEnd(), std::bind(Utils::mem_fn(&Serializer::isAkonadiTag), this, _1)); } bool Serializer::isContext(const Akonadi::Tag &tag) const { return (tag.type() == Akonadi::SerializerInterface::contextTagType()); } bool Serializer::isAkonadiTag(const Tag &tag) const { return tag.type() == Akonadi::Tag::PLAIN; } bool Serializer::isContextTag(const Domain::Context::Ptr &context, const Akonadi::Tag &tag) const { return (context->property("tagId").value() == tag.id()); } bool Serializer::isContextChild(Domain::Context::Ptr context, Item item) const { if (!context->property("tagId").isValid()) return false; auto tagId = context->property("tagId").value(); Akonadi::Tag tag(tagId); return item.hasTag(tag); } Domain::Tag::Ptr Serializer::createTagFromAkonadiTag(Akonadi::Tag akonadiTag) { if (!isAkonadiTag(akonadiTag)) return Domain::Tag::Ptr(); auto tag = Domain::Tag::Ptr::create(); updateTagFromAkonadiTag(tag, akonadiTag); return tag; } void Serializer::updateTagFromAkonadiTag(Domain::Tag::Ptr tag, Akonadi::Tag akonadiTag) { if (!isAkonadiTag(akonadiTag)) return; tag->setProperty("tagId", akonadiTag.id()); tag->setName(akonadiTag.name()); } Akonadi::Tag Serializer::createAkonadiTagFromTag(Domain::Tag::Ptr tag) { auto akonadiTag = Akonadi::Tag(); akonadiTag.setName(tag->name()); akonadiTag.setType(Akonadi::Tag::PLAIN); akonadiTag.setGid(QByteArray(tag->name().toLatin1())); const auto tagProperty = tag->property("tagId"); if (tagProperty.isValid()) akonadiTag.setId(tagProperty.value()); return akonadiTag; } bool Serializer::isTagChild(Domain::Tag::Ptr tag, Akonadi::Item item) { if (!tag->property("tagId").isValid()) return false; auto tagId = tag->property("tagId").value(); Akonadi::Tag akonadiTag(tagId); return item.hasTag(akonadiTag); } diff --git a/src/presentation/availablenotepagesmodel.cpp b/src/presentation/availablenotepagesmodel.cpp index 5e9d3705..0b36f6f1 100644 --- a/src/presentation/availablenotepagesmodel.cpp +++ b/src/presentation/availablenotepagesmodel.cpp @@ -1,257 +1,257 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "availablenotepagesmodel.h" #include #include #include "presentation/availablepagessortfilterproxymodel.h" #include "presentation/noteinboxpagemodel.h" #include "presentation/querytreemodel.h" #include "presentation/tagpagemodel.h" #include "utils/jobhandler.h" using namespace Presentation; AvailableNotePagesModel::AvailableNotePagesModel(const Domain::NoteQueries::Ptr ¬eQueries, const Domain::NoteRepository::Ptr ¬eRepository, const Domain::TagQueries::Ptr &tagQueries, const Domain::TagRepository::Ptr &tagRepository, QObject *parent) : AvailablePagesModelInterface(parent), m_pageListModel(Q_NULLPTR), m_sortProxyModel(Q_NULLPTR), m_noteQueries(noteQueries), m_noteRepository(noteRepository), m_tagQueries(tagQueries), m_tagRepository(tagRepository) { } QAbstractItemModel *AvailableNotePagesModel::pageListModel() { if (!m_pageListModel) m_pageListModel = createPageListModel(); if (!m_sortProxyModel) { m_sortProxyModel = new AvailablePagesSortFilterProxyModel(this); m_sortProxyModel->setSourceModel(m_pageListModel); } return m_sortProxyModel; } bool AvailableNotePagesModel::hasProjectPages() const { return false; } bool AvailableNotePagesModel::hasContextPages() const { return false; } bool AvailableNotePagesModel::hasTagPages() const { return true; } QObject *AvailableNotePagesModel::createPageForIndex(const QModelIndex &index) { QObjectPtr object = index.data(QueryTreeModelBase::ObjectRole).value(); if (object == m_inboxObject) { auto inboxPageModel = new NoteInboxPageModel(m_noteQueries, m_noteRepository, this); inboxPageModel->setErrorHandler(errorHandler()); return inboxPageModel; } else if (auto tag = object.objectCast()) { auto tagPageModel = new TagPageModel(tag, m_tagQueries, m_tagRepository, m_noteRepository, this); tagPageModel->setErrorHandler(errorHandler()); return tagPageModel; } return Q_NULLPTR; } void AvailableNotePagesModel::addProject(const QString &, const Domain::DataSource::Ptr &) { qFatal("Not supported"); } void AvailableNotePagesModel::addContext(const QString &) { qFatal("Not supported"); } void AvailableNotePagesModel::addTag(const QString &name) { auto tag = Domain::Tag::Ptr::create(); tag->setName(name); const auto job = m_tagRepository->create(tag); installHandler(job, tr("Cannot add tag %1").arg(name)); } void AvailableNotePagesModel::removeItem(const QModelIndex &index) { QObjectPtr object = index.data(QueryTreeModelBase::ObjectRole).value(); if (auto tag = object.objectCast()) { const auto job = m_tagRepository->remove(tag); installHandler(job, tr("Cannot remove tag %1").arg(tag->name())); } else { Q_ASSERT(false); } } QAbstractItemModel *AvailableNotePagesModel::createPageListModel() { m_inboxObject = QObjectPtr::create(); m_inboxObject->setProperty("name", tr("Inbox")); m_tagsObject = QObjectPtr::create(); m_tagsObject->setProperty("name", tr("Tags")); m_rootsProvider = Domain::QueryResultProvider::Ptr::create(); m_rootsProvider->append(m_inboxObject); m_rootsProvider->append(m_tagsObject); auto query = [this](const QObjectPtr &object) -> Domain::QueryResultInterface::Ptr { if (!object) return Domain::QueryResult::create(m_rootsProvider); else if (object == m_tagsObject) return Domain::QueryResult::copy(m_tagQueries->findAll()); else return Domain::QueryResult::Ptr(); }; auto flags = [this](const QObjectPtr &object) { const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; const Qt::ItemFlags immutableNodeFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; const Qt::ItemFlags structureNodeFlags = Qt::NoItemFlags; return object.objectCast() ? defaultFlags : object == m_inboxObject ? immutableNodeFlags : structureNodeFlags; }; auto data = [this](const QObjectPtr &object, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::DecorationRole && role != QueryTreeModelBase::IconNameRole) { return QVariant(); } if (role == Qt::EditRole && (object == m_inboxObject || object == m_tagsObject)) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return object->property("name").toString(); } else if (role == Qt::DecorationRole || role == QueryTreeModelBase::IconNameRole) { - const QString iconName = (object == m_inboxObject) ? "mail-folder-inbox" - : (object == m_tagsObject) ? "folder" - : "view-pim-tasks"; + const QString iconName = (object == m_inboxObject) ? QStringLiteral("mail-folder-inbox") + : (object == m_tagsObject) ? QStringLiteral("folder") + : QStringLiteral("view-pim-tasks"); if (role == Qt::DecorationRole) return QVariant::fromValue(QIcon::fromTheme(iconName)); else return iconName; } else { return QVariant(); } }; auto setData = [this](const QObjectPtr &object, const QVariant &, int role) { if (role != Qt::EditRole) { return false; } if (object == m_inboxObject || object == m_tagsObject) { return false; } if (object.objectCast()) { return false; // Tag renaming is NOT allowed } else { Q_ASSERT(false); } return true; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const QObjectPtr &object) { - if (!mimeData->hasFormat("application/x-zanshin-object")) + if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedArtifacts = mimeData->property("objects").value(); if (droppedArtifacts.isEmpty()) return false; if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), [](const Domain::Artifact::Ptr &droppedArtifact) { return !droppedArtifact.objectCast(); })) { return false; } if (auto tag = object.objectCast()) { foreach (const auto &droppedArtifact, droppedArtifacts) { auto note = droppedArtifact.staticCast(); const auto job = m_tagRepository->associate(tag, note); installHandler(job, tr("Cannot tag %1 with %2").arg(note->title()).arg(tag->name())); } return true; } else if (object == m_inboxObject) { foreach (const auto &droppedArtifact, droppedArtifacts) { auto note = droppedArtifact.staticCast(); const auto job = m_tagRepository->dissociateAll(note); installHandler(job, tr("Cannot move %1 to Inbox").arg(note->title())); } return true; } return false; }; auto drag = [](const QObjectPtrList &) -> QMimeData* { return Q_NULLPTR; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/availablesourcesmodel.cpp b/src/presentation/availablesourcesmodel.cpp index 16c1f795..1574b5ff 100644 --- a/src/presentation/availablesourcesmodel.cpp +++ b/src/presentation/availablesourcesmodel.cpp @@ -1,262 +1,262 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "availablesourcesmodel.h" #include #include "domain/datasourcequeries.h" #include "domain/datasourcerepository.h" #include "presentation/querytreemodel.h" using namespace Presentation; AvailableSourcesModel::AvailableSourcesModel(const Domain::DataSourceQueries::Ptr &dataSourceQueries, const Domain::DataSourceRepository::Ptr &dataSourceRepository, QObject *parent) : QObject(parent), m_sourceListModel(Q_NULLPTR), m_searchListModel(Q_NULLPTR), m_dataSourceQueries(dataSourceQueries), m_dataSourceRepository(dataSourceRepository) { } QAbstractItemModel *AvailableSourcesModel::sourceListModel() { if (!m_sourceListModel) m_sourceListModel = createSourceListModel(); return m_sourceListModel; } QAbstractItemModel *AvailableSourcesModel::searchListModel() { if (!m_searchListModel) m_searchListModel = createSearchListModel(); return m_searchListModel; } void AvailableSourcesModel::listSource(const Domain::DataSource::Ptr &source) { Q_ASSERT(source); source->setSelected(true); source->setListStatus(Domain::DataSource::Listed); const auto job = m_dataSourceRepository->update(source); installHandler(job, tr("Cannot modify source %1").arg(source->name())); } void AvailableSourcesModel::unlistSource(const Domain::DataSource::Ptr &source) { Q_ASSERT(source); source->setSelected(false); source->setListStatus(Domain::DataSource::Unlisted); const auto job = m_dataSourceRepository->update(source); installHandler(job, tr("Cannot modify source %1").arg(source->name())); } void AvailableSourcesModel::bookmarkSource(const Domain::DataSource::Ptr &source) { Q_ASSERT(source); if (source->listStatus() == Domain::DataSource::Bookmarked) source->setListStatus(Domain::DataSource::Listed); else source->setListStatus(Domain::DataSource::Bookmarked); const auto job = m_dataSourceRepository->update(source); installHandler(job, tr("Cannot modify source %1").arg(source->name())); } void AvailableSourcesModel::showConfigDialog() { m_dataSourceRepository->showConfigDialog(); } QAbstractItemModel *AvailableSourcesModel::createSourceListModel() { auto query = [this] (const Domain::DataSource::Ptr &source) { if (!source) return m_dataSourceQueries->findTopLevel(); else return m_dataSourceQueries->findChildren(source); }; auto flags = [] (const Domain::DataSource::Ptr &source) -> Qt::ItemFlags { const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; if (source->contentTypes() != Domain::DataSource::NoContent) return defaultFlags | Qt::ItemIsUserCheckable; else return defaultFlags; }; auto data = [this] (const Domain::DataSource::Ptr &source, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::DecorationRole && role != Qt::CheckStateRole && role != QueryTreeModelBase::IconNameRole && role != QueryTreeModelBase::IsDefaultRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return source->name(); } else if (role == Qt::DecorationRole || role == QueryTreeModelBase::IconNameRole) { - const QString iconName = source->iconName().isEmpty() ? "folder" : source->iconName(); + const QString iconName = source->iconName().isEmpty() ? QStringLiteral("folder") : source->iconName(); if (role == Qt::DecorationRole) return QVariant::fromValue(QIcon::fromTheme(iconName)); else return iconName; } else if (role == Qt::CheckStateRole) { if (source->contentTypes() != Domain::DataSource::NoContent) return source->isSelected() ? Qt::Checked : Qt::Unchecked; else return QVariant(); } else if (role == QueryTreeModelBase::IsDefaultRole) { return m_dataSourceQueries->isDefaultSource(source); } else { return QVariant(); } }; auto setData = [this] (const Domain::DataSource::Ptr &source, const QVariant &value, int role) { if (role != Qt::CheckStateRole) return false; if (source->contentTypes() == Domain::DataSource::NoContent) return false; source->setSelected(value.toInt() == Qt::Checked); const auto job = m_dataSourceRepository->update(source); installHandler(job, tr("Cannot modify source %1").arg(source->name())); return true; }; auto drop = [] (const QMimeData *mimeData, Qt::DropAction, const Domain::DataSource::Ptr &source) { Q_UNUSED(mimeData) Q_UNUSED(source) return false; }; auto drag = [](const Domain::DataSource::List &) -> QMimeData* { return Q_NULLPTR; }; connect(m_dataSourceQueries->notifier(), &Domain::DataSourceQueriesNotifier::defaultSourceChanged, this, &AvailableSourcesModel::onDefaultSourceChanged); return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } QAbstractItemModel *AvailableSourcesModel::createSearchListModel() { auto query = [this] (const Domain::DataSource::Ptr &source) { if (!source) return m_dataSourceQueries->findSearchTopLevel(); else return m_dataSourceQueries->findSearchChildren(source); }; auto flags = [] (const Domain::DataSource::Ptr &source) { Q_UNUSED(source) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }; auto data = [] (const Domain::DataSource::Ptr &source, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::DecorationRole && role != QueryTreeModelBase::IconNameRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return source->name(); } else if (role == Qt::DecorationRole || role == QueryTreeModelBase::IconNameRole) { - const QString iconName = source->iconName().isEmpty() ? "folder" : source->iconName(); + const QString iconName = source->iconName().isEmpty() ? QStringLiteral("folder") : source->iconName(); if (role == Qt::DecorationRole) return QVariant::fromValue(QIcon::fromTheme(iconName)); else return iconName; } else { return QVariant(); } }; auto setData = [this] (const Domain::DataSource::Ptr &source, const QVariant &value, int role) { Q_UNUSED(source) Q_UNUSED(value) Q_UNUSED(role) return false; }; auto drop = [] (const QMimeData *mimeData, Qt::DropAction, const Domain::DataSource::Ptr &source) { Q_UNUSED(mimeData) Q_UNUSED(source) return false; }; auto drag = [](const Domain::DataSource::List &) -> QMimeData* { return Q_NULLPTR; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } QString AvailableSourcesModel::searchTerm() const { return m_dataSourceQueries->searchTerm(); } void AvailableSourcesModel::setSearchTerm(const QString &term) { if (term == searchTerm()) return; m_dataSourceQueries->setSearchTerm(term); emit searchTermChanged(term); } void AvailableSourcesModel::setDefaultItem(const QModelIndex &index) { auto source = index.data(QueryTreeModelBase::ObjectRole).value(); Q_ASSERT(source); m_dataSourceQueries->setDefaultSource(source); } void AvailableSourcesModel::onDefaultSourceChanged() { emitDefaultSourceChanged(QModelIndex()); } void AvailableSourcesModel::emitDefaultSourceChanged(const QModelIndex &root) { const auto rowCount = m_sourceListModel->rowCount(root); for (int row = 0; row < rowCount; row++) { const auto index = m_sourceListModel->index(row, 0, root); // TODO Qt5: Remove static_cast emit static_cast(m_sourceListModel)->dataChanged(index, index); emitDefaultSourceChanged(index); } } diff --git a/src/presentation/availabletaskpagesmodel.cpp b/src/presentation/availabletaskpagesmodel.cpp index 07243379..90a2d799 100644 --- a/src/presentation/availabletaskpagesmodel.cpp +++ b/src/presentation/availabletaskpagesmodel.cpp @@ -1,341 +1,341 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "availabletaskpagesmodel.h" #include #include #include "domain/contextqueries.h" #include "domain/contextrepository.h" #include "domain/projectqueries.h" #include "domain/projectrepository.h" #include "domain/taskrepository.h" #include "presentation/availablepagessortfilterproxymodel.h" #include "presentation/contextpagemodel.h" #include "presentation/metatypes.h" #include "presentation/projectpagemodel.h" #include "presentation/querytreemodel.h" #include "presentation/taskinboxpagemodel.h" #include "presentation/workdaypagemodel.h" #include "utils/jobhandler.h" #include "utils/datetime.h" using namespace Presentation; AvailableTaskPagesModel::AvailableTaskPagesModel(const Domain::ProjectQueries::Ptr &projectQueries, const Domain::ProjectRepository::Ptr &projectRepository, const Domain::ContextQueries::Ptr &contextQueries, const Domain::ContextRepository::Ptr &contextRepository, const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, QObject *parent) : AvailablePagesModelInterface(parent), m_pageListModel(Q_NULLPTR), m_sortProxyModel(Q_NULLPTR), m_projectQueries(projectQueries), m_projectRepository(projectRepository), m_contextQueries(contextQueries), m_contextRepository(contextRepository), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } QAbstractItemModel *AvailableTaskPagesModel::pageListModel() { if (!m_pageListModel) m_pageListModel = createPageListModel(); if (!m_sortProxyModel) { m_sortProxyModel = new AvailablePagesSortFilterProxyModel(this); m_sortProxyModel->setSourceModel(m_pageListModel); } return m_sortProxyModel; } bool AvailableTaskPagesModel::hasProjectPages() const { return true; } bool AvailableTaskPagesModel::hasContextPages() const { return true; } bool AvailableTaskPagesModel::hasTagPages() const { return false; } QObject *AvailableTaskPagesModel::createPageForIndex(const QModelIndex &index) { QObjectPtr object = index.data(QueryTreeModelBase::ObjectRole).value(); if (object == m_inboxObject) { auto inboxPageModel = new TaskInboxPageModel(m_taskQueries, m_taskRepository, this); inboxPageModel->setErrorHandler(errorHandler()); return inboxPageModel; } else if (object == m_workdayObject) { auto workdayPageModel = new WorkdayPageModel(m_taskQueries, m_taskRepository, this); workdayPageModel->setErrorHandler(errorHandler()); return workdayPageModel; } else if (auto project = object.objectCast()) { auto projectPageModel = new ProjectPageModel(project, m_projectQueries, m_projectRepository, m_taskQueries, m_taskRepository, this); projectPageModel->setErrorHandler(errorHandler()); return projectPageModel; } else if (auto context = object.objectCast()) { auto contextPageModel = new ContextPageModel(context, m_contextQueries, m_contextRepository, m_taskQueries, m_taskRepository, this); contextPageModel->setErrorHandler(errorHandler()); return contextPageModel; } return Q_NULLPTR; } void AvailableTaskPagesModel::addProject(const QString &name, const Domain::DataSource::Ptr &source) { auto project = Domain::Project::Ptr::create(); project->setName(name); const auto job = m_projectRepository->create(project, source); installHandler(job, tr("Cannot add project %1 in dataSource %2").arg(name).arg(source->name())); } void AvailableTaskPagesModel::addContext(const QString &name) { auto context = Domain::Context::Ptr::create(); context->setName(name); const auto job = m_contextRepository->create(context); installHandler(job, tr("Cannot add context %1").arg(name)); } void AvailableTaskPagesModel::addTag(const QString &) { qFatal("Not supported"); } void AvailableTaskPagesModel::removeItem(const QModelIndex &index) { QObjectPtr object = index.data(QueryTreeModelBase::ObjectRole).value(); if (auto project = object.objectCast()) { const auto job = m_projectRepository->remove(project); installHandler(job, tr("Cannot remove project %1").arg(project->name())); } else if (auto context = object.objectCast()) { const auto job = m_contextRepository->remove(context); installHandler(job, tr("Cannot remove context %1").arg(context->name())); } else { Q_ASSERT(false); } } QAbstractItemModel *AvailableTaskPagesModel::createPageListModel() { m_inboxObject = QObjectPtr::create(); m_inboxObject->setProperty("name", tr("Inbox")); m_workdayObject = QObjectPtr::create(); m_workdayObject->setProperty("name", tr("Workday")); m_projectsObject = QObjectPtr::create(); m_projectsObject->setProperty("name", tr("Projects")); m_contextsObject = QObjectPtr::create(); m_contextsObject->setProperty("name", tr("Contexts")); m_rootsProvider = Domain::QueryResultProvider::Ptr::create(); m_rootsProvider->append(m_inboxObject); m_rootsProvider->append(m_workdayObject); m_rootsProvider->append(m_projectsObject); m_rootsProvider->append(m_contextsObject); auto query = [this](const QObjectPtr &object) -> Domain::QueryResultInterface::Ptr { if (!object) return Domain::QueryResult::create(m_rootsProvider); else if (object == m_projectsObject) return Domain::QueryResult::copy(m_projectQueries->findAll()); else if (object == m_contextsObject) return Domain::QueryResult::copy(m_contextQueries->findAll()); else return Domain::QueryResult::Ptr(); }; auto flags = [this](const QObjectPtr &object) { const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; const Qt::ItemFlags immutableNodeFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; const Qt::ItemFlags structureNodeFlags = Qt::NoItemFlags; return object.objectCast() ? defaultFlags : object.objectCast() ? defaultFlags : object == m_inboxObject ? immutableNodeFlags : object == m_workdayObject ? immutableNodeFlags : structureNodeFlags; }; auto data = [this](const QObjectPtr &object, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::DecorationRole && role != QueryTreeModelBase::IconNameRole) { return QVariant(); } if (role == Qt::EditRole && (object == m_inboxObject || object == m_workdayObject || object == m_projectsObject || object == m_contextsObject)) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return object->property("name").toString(); } else if (role == Qt::DecorationRole || role == QueryTreeModelBase::IconNameRole) { - const QString iconName = object == m_inboxObject ? "mail-folder-inbox" - : (object == m_workdayObject) ? "go-jump-today" - : (object == m_projectsObject) ? "folder" - : (object == m_contextsObject) ? "folder" - : object.objectCast() ? "view-pim-notes" - : "view-pim-tasks"; + const QString iconName = object == m_inboxObject ? QStringLiteral("mail-folder-inbox") + : (object == m_workdayObject) ? QStringLiteral("go-jump-today") + : (object == m_projectsObject) ? QStringLiteral("folder") + : (object == m_contextsObject) ? QStringLiteral("folder") + : object.objectCast() ? QStringLiteral("view-pim-notes") + : QStringLiteral("view-pim-tasks"); if (role == Qt::DecorationRole) return QVariant::fromValue(QIcon::fromTheme(iconName)); else return iconName; } else { return QVariant(); } }; auto setData = [this](const QObjectPtr &object, const QVariant &value, int role) { if (role != Qt::EditRole) { return false; } if (object == m_inboxObject || object == m_workdayObject || object == m_projectsObject || object == m_contextsObject) { return false; } if (auto project = object.objectCast()) { const auto currentName = project->name(); project->setName(value.toString()); const auto job = m_projectRepository->update(project); installHandler(job, tr("Cannot modify project %1").arg(currentName)); } else if (auto context = object.objectCast()) { const auto currentName = context->name(); context->setName(value.toString()); const auto job = m_contextRepository->update(context); installHandler(job, tr("Cannot modify context %1").arg(currentName)); } else { Q_ASSERT(false); } return true; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const QObjectPtr &object) { - if (!mimeData->hasFormat("application/x-zanshin-object")) + if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedArtifacts = mimeData->property("objects").value(); if (droppedArtifacts.isEmpty()) return false; if (auto project = object.objectCast()) { foreach (const auto &droppedArtifact, droppedArtifacts) { const auto job = m_projectRepository->associate(project, droppedArtifact); installHandler(job, tr("Cannot add %1 to project %2").arg(droppedArtifact->title()).arg(project->name())); } return true; } else if (auto context = object.objectCast()) { if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), [](const Domain::Artifact::Ptr &droppedArtifact) { return !droppedArtifact.objectCast(); })) { return false; } foreach (const auto &droppedArtifact, droppedArtifacts) { auto task = droppedArtifact.staticCast(); const auto job = m_contextRepository->associate(context, task); installHandler(job, tr("Cannot add %1 to context %2").arg(task->title()).arg(context->name())); } return true; } else if (object == m_inboxObject) { foreach (const auto &droppedArtifact, droppedArtifacts) { const auto job = m_projectRepository->dissociate(droppedArtifact); installHandler(job, tr("Cannot move %1 to Inbox").arg(droppedArtifact->title())); if (auto task = droppedArtifact.objectCast()) { Utils::JobHandler::install(job, [this, task] { const auto dissociateJob = m_taskRepository->dissociateAll(task); installHandler(dissociateJob, tr("Cannot move task %1 to Inbox").arg(task->title())); }); } } return true; } else if (object == m_workdayObject) { foreach (const auto &droppedArtifact, droppedArtifacts) { if (auto task = droppedArtifact.objectCast()) { task->setStartDate(Utils::DateTime::currentDateTime()); const auto job = m_taskRepository->update(task); installHandler(job, tr("Cannot update task %1 to Workday").arg(task->title())); } } return true; } return false; }; auto drag = [](const QObjectPtrList &) -> QMimeData* { return Q_NULLPTR; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/contextpagemodel.cpp b/src/presentation/contextpagemodel.cpp index cc3ebd45..22544353 100644 --- a/src/presentation/contextpagemodel.cpp +++ b/src/presentation/contextpagemodel.cpp @@ -1,204 +1,204 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Rémi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "contextpagemodel.h" #include #include "domain/task.h" #include "domain/contextqueries.h" #include "domain/contextrepository.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/querytreemodel.h" using namespace Presentation; ContextPageModel::ContextPageModel(const Domain::Context::Ptr &context, const Domain::ContextQueries::Ptr &contextQueries, const Domain::ContextRepository::Ptr &contextRepository, const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, QObject *parent) : PageModel(parent), m_context(context), m_contextQueries(contextQueries), m_contextRepository(contextRepository), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } Domain::Context::Ptr ContextPageModel::context() const { return m_context; } Domain::Artifact::Ptr ContextPageModel::addItem(const QString &title, const QModelIndex &parentIndex) { const auto parentData = parentIndex.data(QueryTreeModel::ObjectRole); const auto parentArtifact = parentData.value(); const auto parentTask = parentArtifact.objectCast(); auto task = Domain::Task::Ptr::create(); task->setTitle(title); const auto job = parentTask ? m_taskRepository->createChild(task, parentTask) : m_taskRepository->createInContext(task, m_context); installHandler(job, tr("Cannot add task %1 in context %2").arg(title).arg(m_context->name())); return task; } void ContextPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); const auto job = index.parent().isValid() ? m_taskRepository->dissociate(task) : m_contextRepository->dissociate(m_context, task); installHandler(job, tr("Cannot remove task %1 from context %2").arg(task->title()).arg(m_context->name())); } void ContextPageModel::promoteItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); Q_ASSERT(task); const auto job = m_taskRepository->promoteToProject(task); installHandler(job, tr("Cannot promote task %1 to be a project").arg(task->title())); } QAbstractItemModel *ContextPageModel::createCentralListModel() { auto query = [this] (const Domain::Task::Ptr &task) -> Domain::QueryResultInterface::Ptr { if (!task) return m_contextQueries->findTopLevelTasks(m_context); else return m_taskQueries->findChildren(task); }; auto flags = [] (const Domain::Task::Ptr &task) { Q_UNUSED(task); return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled; }; auto data = [] (const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return task->title(); } else if (role == Qt::CheckStateRole){ return task->isDone() ? Qt::Checked : Qt::Unchecked; } else { return QVariant(); } }; auto setData = [this] (const Domain::Task::Ptr &task, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) return false; const auto currentTitle = task->title(); if (role == Qt::EditRole) task->setTitle(value.toString()); else task->setDone(value.toInt() == Qt::Checked); const auto job = m_taskRepository->update(task); installHandler(job, tr("Cannot modify task %1 in context %2").arg(currentTitle).arg(m_context->name())); return true; }; auto drop = [this] (const QMimeData *mimeData, Qt::DropAction, const Domain::Task::Ptr &parentTask) { - if (!mimeData->hasFormat("application/x-zanshin-object")) + if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedArtifacts = mimeData->property("objects").value(); if (droppedArtifacts.isEmpty()) return false; if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), [](const Domain::Artifact::Ptr &droppedArtifact) { return !droppedArtifact.objectCast(); })) { return false; } using namespace std::placeholders; auto associate = std::function(); auto dissociate = std::function(); auto parentTitle = QString(); if (parentTask) { associate = std::bind(&Domain::TaskRepository::associate, m_taskRepository, parentTask, _1); dissociate = [] (Domain::Task::Ptr) -> KJob* { return Q_NULLPTR; }; parentTitle = parentTask->title(); } else { associate = std::bind(&Domain::ContextRepository::associate, m_contextRepository, m_context, _1); dissociate = std::bind(&Domain::TaskRepository::dissociate, m_taskRepository, _1); parentTitle = m_context->name(); } foreach(const Domain::Artifact::Ptr &droppedArtifact, droppedArtifacts) { auto childTask = droppedArtifact.objectCast(); auto job = associate(childTask); installHandler(job, tr("Cannot move task %1 as sub-task of %2").arg(childTask->title(), parentTitle)); job = dissociate(childTask); if (job) installHandler(job, tr("Cannot dissociate task %1 from its parent").arg(childTask->title())); } return true; }; auto drag = [] (const Domain::Task::List &tasks) -> QMimeData* { if (tasks.isEmpty()) return Q_NULLPTR; auto draggedArtifacts = Domain::Artifact::List(); foreach (const Domain::Task::Ptr &task, tasks) { draggedArtifacts.append(task.objectCast()); } auto data = new QMimeData(); - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(draggedArtifacts)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/errorhandler.cpp b/src/presentation/errorhandler.cpp index 5797b67f..3ecfcb85 100644 --- a/src/presentation/errorhandler.cpp +++ b/src/presentation/errorhandler.cpp @@ -1,49 +1,49 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "errorhandler.h" #include #include "utils/jobhandler.h" #include "utils/mem_fn.h" using namespace Presentation; ErrorHandler::~ErrorHandler() { } void ErrorHandler::installHandler(KJob *job, const QString &message) { auto resultHandler = std::function(std::bind(Utils::mem_fn(&ErrorHandler::displayMessage), this, job, message)); Utils::JobHandler::install(job, resultHandler); } void ErrorHandler::displayMessage(KJob *job, const QString &message) { if (job->error() != KJob::NoError) { - doDisplayMessage(QString("%1: %2").arg(message).arg(job->errorString())); + doDisplayMessage(QStringLiteral("%1: %2").arg(message).arg(job->errorString())); } } diff --git a/src/presentation/noteinboxpagemodel.cpp b/src/presentation/noteinboxpagemodel.cpp index ec71975c..c21864c2 100644 --- a/src/presentation/noteinboxpagemodel.cpp +++ b/src/presentation/noteinboxpagemodel.cpp @@ -1,123 +1,123 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "noteinboxpagemodel.h" #include #include "presentation/querytreemodel.h" using namespace Presentation; NoteInboxPageModel::NoteInboxPageModel(const Domain::NoteQueries::Ptr ¬eQueries, const Domain::NoteRepository::Ptr ¬eRepository, QObject *parent) : PageModel(parent), m_noteQueries(noteQueries), m_noteRepository(noteRepository) { } Domain::Artifact::Ptr NoteInboxPageModel::addItem(const QString &title, const QModelIndex &) { auto note = Domain::Note::Ptr::create(); note->setTitle(title); const auto job = m_noteRepository->create(note); installHandler(job, tr("Cannot add note %1 in Inbox").arg(title)); return note; } void NoteInboxPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto note = artifact.objectCast(); Q_ASSERT(note); const auto job = m_noteRepository->remove(note); installHandler(job, tr("Cannot remove note %1 from Inbox").arg(note->title())); } void NoteInboxPageModel::promoteItem(const QModelIndex &) { qFatal("Not supported"); } QAbstractItemModel *NoteInboxPageModel::createCentralListModel() { auto query = [this](const Domain::Note::Ptr ¬e) -> Domain::QueryResultInterface::Ptr { if (!note) return m_noteQueries->findInbox(); else return Domain::QueryResult::Ptr(); }; auto flags = [](const Domain::Note::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; }; auto data = [](const Domain::Note::Ptr ¬e, int role) -> QVariant { if (role == Qt::DisplayRole || role == Qt::EditRole) { return note->title(); } else { return QVariant(); } }; auto setData = [this](const Domain::Note::Ptr ¬e, const QVariant &value, int role) { if (role != Qt::EditRole) { return false; } const auto currentTitle = note->title(); note->setTitle(value.toString()); const auto job = m_noteRepository->update(note); installHandler(job, tr("Cannot modify note %1 in Inbox").arg(currentTitle)); return true; }; auto drop = [this](const QMimeData *, Qt::DropAction, const Domain::Artifact::Ptr &) { return false; }; auto drag = [](const Domain::Note::List ¬es) -> QMimeData* { if (notes.isEmpty()) return Q_NULLPTR; auto artifacts = Domain::Artifact::List(); artifacts.reserve(notes.size()); std::copy(notes.constBegin(), notes.constEnd(), std::back_inserter(artifacts)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(artifacts)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/projectpagemodel.cpp b/src/presentation/projectpagemodel.cpp index a1166b41..3cd3d7b8 100644 --- a/src/presentation/projectpagemodel.cpp +++ b/src/presentation/projectpagemodel.cpp @@ -1,189 +1,189 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "projectpagemodel.h" #include #include "presentation/querytreemodel.h" using namespace Presentation; ProjectPageModel::ProjectPageModel(const Domain::Project::Ptr &project, const Domain::ProjectQueries::Ptr &projectQueries, const Domain::ProjectRepository::Ptr &projectRepository, const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, QObject *parent) : PageModel(parent), m_projectQueries(projectQueries), m_projectRepository(projectRepository), m_project(project), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } Domain::Project::Ptr ProjectPageModel::project() const { return m_project; } Domain::Artifact::Ptr ProjectPageModel::addItem(const QString &title, const QModelIndex &parentIndex) { const auto parentData = parentIndex.data(QueryTreeModel::ObjectRole); const auto parentArtifact = parentData.value(); const auto parentTask = parentArtifact.objectCast(); auto task = Domain::Task::Ptr::create(); task->setTitle(title); const auto job = parentTask ? m_taskRepository->createChild(task, parentTask) : m_taskRepository->createInProject(task, m_project); installHandler(job, tr("Cannot add task %1 in project %2").arg(title).arg(m_project->name())); return task; } void ProjectPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); Q_ASSERT(task); const auto job = m_taskRepository->remove(task); installHandler(job, tr("Cannot remove task %1 from project %2").arg(task->title()).arg(m_project->name())); } void ProjectPageModel::promoteItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); Q_ASSERT(task); const auto job = m_taskRepository->promoteToProject(task); installHandler(job, tr("Cannot promote task %1 to be a project").arg(task->title())); } QAbstractItemModel *ProjectPageModel::createCentralListModel() { auto query = [this](const Domain::Task::Ptr &task) -> Domain::QueryResultInterface::Ptr { if (!task) return m_projectQueries->findTopLevel(m_project); else return m_taskQueries->findChildren(task); }; auto flags = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled; }; auto data = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return task->title(); } else { return task->isDone() ? Qt::Checked : Qt::Unchecked; } }; auto setData = [this](const Domain::Task::Ptr &task, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } const auto currentTitle = task->title(); if (role == Qt::EditRole) task->setTitle(value.toString()); else task->setDone(value.toInt() == Qt::Checked); const auto job = m_taskRepository->update(task); installHandler(job, tr("Cannot modify task %1 in project %2").arg(currentTitle).arg(m_project->name())); return true; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const Domain::Task::Ptr &parentTask) { - if (!mimeData->hasFormat("application/x-zanshin-object")) + if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedArtifacts = mimeData->property("objects").value(); if (droppedArtifacts.isEmpty()) return false; if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), [](const Domain::Artifact::Ptr &droppedArtifact) { return !droppedArtifact.objectCast(); })) { return false; } using namespace std::placeholders; auto associate = std::function(); auto parentTitle = QString(); if (parentTask) { associate = std::bind(&Domain::TaskRepository::associate, m_taskRepository, parentTask, _1); parentTitle = parentTask->title(); } else { associate = std::bind(&Domain::ProjectRepository::associate, m_projectRepository, m_project, _1); parentTitle = m_project->name(); } foreach(const Domain::Artifact::Ptr &droppedArtifact, droppedArtifacts) { auto childTask = droppedArtifact.objectCast(); const auto job = associate(childTask); installHandler(job, tr("Cannot move task %1 as a sub-task of %2").arg(childTask->title(), parentTitle)); } return true; }; auto drag = [](const Domain::Task::List &tasks) -> QMimeData* { if (tasks.isEmpty()) return Q_NULLPTR; auto draggedArtifacts = Domain::Artifact::List(); foreach (const Domain::Task::Ptr &task, tasks) { draggedArtifacts.append(task.objectCast()); } auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(draggedArtifacts)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/querytreemodelbase.cpp b/src/presentation/querytreemodelbase.cpp index 7e98cda4..c51860a0 100644 --- a/src/presentation/querytreemodelbase.cpp +++ b/src/presentation/querytreemodelbase.cpp @@ -1,261 +1,262 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "querytreemodelbase.h" #include #include #include using namespace Presentation; QueryTreeNodeBase::QueryTreeNodeBase(QueryTreeNodeBase *parent, QueryTreeModelBase *model) : m_parent(parent), m_model(model) { } QueryTreeNodeBase::~QueryTreeNodeBase() { qDeleteAll(m_childNode); } int QueryTreeNodeBase::row() { return m_parent ? m_parent->m_childNode.indexOf(this) : -1; } QueryTreeNodeBase *QueryTreeNodeBase::parent() const { return m_parent; } QueryTreeNodeBase *QueryTreeNodeBase::child(int row) const { if (row >= 0 && row < m_childNode.size()) return m_childNode.value(row); else return Q_NULLPTR; } void QueryTreeNodeBase::insertChild(int row, QueryTreeNodeBase *node) { m_childNode.insert(row, node); } void QueryTreeNodeBase::appendChild(QueryTreeNodeBase *node) { m_childNode.append(node); } void QueryTreeNodeBase::removeChildAt(int row) { delete m_childNode.takeAt(row); } int QueryTreeNodeBase::childCount() const { return m_childNode.size(); } QModelIndex QueryTreeNodeBase::index(int row, int column, const QModelIndex &parent) const { return m_model->index(row, column, parent); } QModelIndex QueryTreeNodeBase::createIndex(int row, int column, void *data) const { return m_model->createIndex(row, column, data); } void QueryTreeNodeBase::beginInsertRows(const QModelIndex &parent, int first, int last) { m_model->beginInsertRows(parent, first, last); } void QueryTreeNodeBase::endInsertRows() { m_model->endInsertRows(); } void QueryTreeNodeBase::beginRemoveRows(const QModelIndex &parent, int first, int last) { m_model->beginRemoveRows(parent, first, last); } void QueryTreeNodeBase::endRemoveRows() { m_model->endRemoveRows(); } void QueryTreeNodeBase::emitDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { emit m_model->dataChanged(topLeft, bottomRight); } QueryTreeModelBase::QueryTreeModelBase(QueryTreeNodeBase *rootNode, QObject *parent) : QAbstractItemModel(parent), m_rootIndexFlag(Qt::ItemIsDropEnabled), m_rootNode(rootNode) { auto roles = roleNames(); roles.insert(ObjectRole, "object"); roles.insert(IconNameRole, "icon"); roles.insert(IsDefaultRole, "default"); setRoleNames(roles); } QueryTreeModelBase::~QueryTreeModelBase() { delete m_rootNode; } Qt::ItemFlags QueryTreeModelBase::flags(const QModelIndex &index) const { if (!isModelIndexValid(index)) return m_rootIndexFlag; return nodeFromIndex(index)->flags(); } QModelIndex QueryTreeModelBase::index(int row, int column, const QModelIndex &parent) const { if (row < 0 || column != 0) return QModelIndex(); const QueryTreeNodeBase *parentNode = nodeFromIndex(parent); if (row < parentNode->childCount()) { QueryTreeNodeBase *node = parentNode->child(row); return createIndex(row, column, node); } else { return QModelIndex(); } } QModelIndex QueryTreeModelBase::parent(const QModelIndex &index) const { QueryTreeNodeBase *node = nodeFromIndex(index); if (!node->parent() || node->parent() == m_rootNode) return QModelIndex(); else return createIndex(node->parent()->row(), 0, node->parent()); } int QueryTreeModelBase::rowCount(const QModelIndex &index) const { return nodeFromIndex(index)->childCount(); } int QueryTreeModelBase::columnCount(const QModelIndex &) const { return 1; } QVariant QueryTreeModelBase::data(const QModelIndex &index, int role) const { if (!isModelIndexValid(index)) { return QVariant(); } return nodeFromIndex(index)->data(role); } bool QueryTreeModelBase::setData(const QModelIndex &index, const QVariant &value, int role) { if (!isModelIndexValid(index)) { return false; } return nodeFromIndex(index)->setData(value, role); } bool QueryTreeModelBase::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { Q_UNUSED(row); Q_UNUSED(column); // If that's not holding that mime type we can't do the cycle checking // this is relevant only for internal drag and drop anyway - if (data->hasFormat("application/x-zanshin-indexes")) { + if (data->hasFormat(QStringLiteral("application/x-zanshin-indexes"))) { const auto indexes = data->property("indexes").value(); foreach (const auto &index, indexes) { auto p = parent; while (p.isValid()) { if (p == index) // Oops, we found a cycle (one of the indexes is parent of the drop point) return false; p = p.parent(); } } } return nodeFromIndex(parent)->dropMimeData(data, action); } QMimeData *QueryTreeModelBase::mimeData(const QModelIndexList &indexes) const { if (indexes.isEmpty()) return Q_NULLPTR; auto data = createMimeData(indexes); - data->setData("application/x-zanshin-indexes", "indexes"); + data->setData(QStringLiteral("application/x-zanshin-indexes"), "indexes"); data->setProperty("indexes", QVariant::fromValue(indexes)); return data; } QStringList QueryTreeModelBase::mimeTypes() const { - return QAbstractItemModel::mimeTypes() << "application/x-zanshin-object" << "application/x-zanshin-indexes"; + return QAbstractItemModel::mimeTypes() << QStringLiteral("application/x-zanshin-object") + << QStringLiteral("application/x-zanshin-indexes"); } Qt::DropActions QueryTreeModelBase::supportedDropActions() const { return Qt::MoveAction; } QueryTreeNodeBase *QueryTreeModelBase::nodeFromIndex(const QModelIndex &index) const { return index.isValid() ? static_cast(index.internalPointer()) : m_rootNode; } void QueryTreeModelBase::setRootIndexFlag(const Qt::ItemFlags &flags) { m_rootIndexFlag = flags; } bool QueryTreeModelBase::isModelIndexValid(const QModelIndex &index) const { bool valid = index.isValid() && index.column() == 0 && index.row() >= 0; if (!valid) return false; const QueryTreeNodeBase *parentNode = nodeFromIndex(index.parent()); const int count = parentNode->childCount(); return index.row() < count; } diff --git a/src/presentation/tagpagemodel.cpp b/src/presentation/tagpagemodel.cpp index e0e6dcc4..39f55e9f 100644 --- a/src/presentation/tagpagemodel.cpp +++ b/src/presentation/tagpagemodel.cpp @@ -1,143 +1,143 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Rémi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tagpagemodel.h" #include #include "domain/noterepository.h" #include "domain/task.h" #include "domain/tagqueries.h" #include "domain/tagrepository.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/querytreemodel.h" using namespace Presentation; TagPageModel::TagPageModel(const Domain::Tag::Ptr &tag, const Domain::TagQueries::Ptr &tagQueries, const Domain::TagRepository::Ptr &tagRepository, const Domain::NoteRepository::Ptr ¬eRepository, QObject *parent) : PageModel(parent), m_tag(tag), m_tagQueries(tagQueries), m_tagRepository(tagRepository), m_noteRepository(noteRepository) { } Domain::Tag::Ptr TagPageModel::tag() const { return m_tag; } Domain::Artifact::Ptr TagPageModel::addItem(const QString &title, const QModelIndex &) { auto note = Domain::Note::Ptr::create(); note->setTitle(title); const auto job = m_noteRepository->createInTag(note, m_tag); installHandler(job, tr("Cannot add note %1 in tag %2").arg(title).arg(m_tag->name())); return note; } void TagPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto note = artifact.objectCast(); Q_ASSERT(note); const auto job = m_tagRepository->dissociate(m_tag, note); installHandler(job, tr("Cannot remove note %1 from tag %2").arg(note->title()).arg(m_tag->name())); } void TagPageModel::promoteItem(const QModelIndex &) { qFatal("Not supported"); } QAbstractItemModel *TagPageModel::createCentralListModel() { auto query = [this] (const Domain::Note::Ptr ¬e) -> Domain::QueryResultInterface::Ptr { if (!note) return m_tagQueries->findNotes(m_tag); else return Domain::QueryResult::Ptr(); }; auto flags = [](const Domain::Note::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; }; auto data = [](const Domain::Note::Ptr ¬e, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return note->title(); } else { return QVariant(); } }; auto setData = [this] (const Domain::Note::Ptr ¬e, const QVariant &value, int role) { if (role != Qt::EditRole) { return false; } const auto currentTitle = note->title(); note->setTitle(value.toString()); const auto job = m_noteRepository->update(note); installHandler(job, tr("Cannot modify note %1 in tag %2").arg(currentTitle).arg(m_tag->name())); return true; }; auto drop = [this] (const QMimeData *, Qt::DropAction, const Domain::Note::Ptr &) { return false; }; auto drag = [] (const Domain::Note::List ¬es) -> QMimeData* { if (notes.isEmpty()) return Q_NULLPTR; auto draggedArtifacts = Domain::Artifact::List(); std::copy(notes.constBegin(), notes.constEnd(), std::back_inserter(draggedArtifacts)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(draggedArtifacts)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/taskinboxpagemodel.cpp b/src/presentation/taskinboxpagemodel.cpp index 9450e667..69eaebaf 100644 --- a/src/presentation/taskinboxpagemodel.cpp +++ b/src/presentation/taskinboxpagemodel.cpp @@ -1,173 +1,173 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "taskinboxpagemodel.h" #include #include "presentation/querytreemodel.h" using namespace Presentation; TaskInboxPageModel::TaskInboxPageModel(const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, QObject *parent) : PageModel(parent), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } Domain::Artifact::Ptr TaskInboxPageModel::addItem(const QString &title, const QModelIndex &parentIndex) { const auto parentData = parentIndex.data(QueryTreeModel::ObjectRole); const auto parentArtifact = parentData.value(); const auto parentTask = parentArtifact.objectCast(); auto task = Domain::Task::Ptr::create(); task->setTitle(title); const auto job = parentTask ? m_taskRepository->createChild(task, parentTask) : m_taskRepository->create(task); installHandler(job, tr("Cannot add task %1 in Inbox").arg(title)); return task; } void TaskInboxPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); Q_ASSERT(task); const auto job = m_taskRepository->remove(task); installHandler(job, tr("Cannot remove task %1 from Inbox").arg(task->title())); } void TaskInboxPageModel::promoteItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); Q_ASSERT(task); const auto job = m_taskRepository->promoteToProject(task); installHandler(job, tr("Cannot promote task %1 to be a project").arg(task->title())); } QAbstractItemModel *TaskInboxPageModel::createCentralListModel() { auto query = [this](const Domain::Task::Ptr &task) -> Domain::QueryResultInterface::Ptr { if (!task) return m_taskQueries->findInboxTopLevel(); else return m_taskQueries->findChildren(task); }; auto flags = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled; }; auto data = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return task->title(); } else { return task->isDone() ? Qt::Checked : Qt::Unchecked; } }; auto setData = [this](const Domain::Task::Ptr &task, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } const auto currentTitle = task->title(); if (role == Qt::EditRole) task->setTitle(value.toString()); else task->setDone(value.toInt() == Qt::Checked); const auto job = m_taskRepository->update(task); installHandler(job, tr("Cannot modify task %1 in Inbox").arg(currentTitle)); return true; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const Domain::Task::Ptr &task) { auto parentTask = task.objectCast(); - if (!mimeData->hasFormat("application/x-zanshin-object")) + if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedArtifacts = mimeData->property("objects").value(); if (droppedArtifacts.isEmpty()) return false; if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), [](const Domain::Artifact::Ptr &droppedArtifact) { return !droppedArtifact.objectCast(); })) { return false; } foreach(const auto &droppedArtifact, droppedArtifacts) { auto childTask = droppedArtifact.objectCast(); if (parentTask) { const auto job = m_taskRepository->associate(parentTask, childTask); installHandler(job, tr("Cannot move task %1 as sub-task of %2").arg(childTask->title()).arg(parentTask->title())); } else { const auto job = m_taskRepository->dissociate(childTask); installHandler(job, tr("Cannot deparent task %1 from its parent").arg(childTask->title())); } } return true; }; auto drag = [](const Domain::Task::List &tasks) -> QMimeData* { if (tasks.isEmpty()) return Q_NULLPTR; auto draggedArtifacts = Domain::Artifact::List(); foreach (const Domain::Task::Ptr &task, tasks) { draggedArtifacts.append(task.objectCast()); } auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(draggedArtifacts)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/presentation/workdaypagemodel.cpp b/src/presentation/workdaypagemodel.cpp index 0eede952..ffcfcc61 100644 --- a/src/presentation/workdaypagemodel.cpp +++ b/src/presentation/workdaypagemodel.cpp @@ -1,190 +1,190 @@ /* This file is part of Zanshin Copyright 2015 Theo Vaucher 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "workdaypagemodel.h" #include #include "domain/noterepository.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/querytreemodel.h" #include "utils/datetime.h" using namespace Presentation; WorkdayPageModel::WorkdayPageModel(const Domain::TaskQueries::Ptr &taskQueries, const Domain::TaskRepository::Ptr &taskRepository, QObject *parent) : PageModel(parent), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } Domain::Artifact::Ptr WorkdayPageModel::addItem(const QString &title, const QModelIndex &parentIndex) { const auto parentData = parentIndex.data(QueryTreeModel::ObjectRole); const auto parentArtifact = parentData.value(); const auto parentTask = parentArtifact.objectCast(); auto task = Domain::Task::Ptr::create(); task->setTitle(title); if (!parentTask) task->setStartDate(Utils::DateTime::currentDateTime()); const auto job = parentTask ? m_taskRepository->createChild(task, parentTask) : m_taskRepository->create(task); installHandler(job, tr("Cannot add task %1 in Workday").arg(title)); return task; } void WorkdayPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); if (task) { const auto job = m_taskRepository->remove(task); installHandler(job, tr("Cannot remove task %1 from Workday").arg(task->title())); } } void WorkdayPageModel::promoteItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModel::ObjectRole); auto artifact = data.value(); auto task = artifact.objectCast(); Q_ASSERT(task); const auto job = m_taskRepository->promoteToProject(task); installHandler(job, tr("Cannot promote task %1 to be a project").arg(task->title())); } QAbstractItemModel *WorkdayPageModel::createCentralListModel() { auto query = [this](const Domain::Artifact::Ptr &artifact) -> Domain::QueryResultInterface::Ptr { if (!artifact) return Domain::QueryResult::copy(m_taskQueries->findWorkdayTopLevel()); else if (auto task = artifact.dynamicCast()) return Domain::QueryResult::copy(m_taskQueries->findChildren(task)); else return Domain::QueryResult::Ptr(); }; auto flags = [](const Domain::Artifact::Ptr &artifact) { const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; return artifact.dynamicCast() ? (defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled) : defaultFlags; }; auto data = [](const Domain::Artifact::Ptr &artifact, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return artifact->title(); } else if (auto task = artifact.dynamicCast()) { return task->isDone() ? Qt::Checked : Qt::Unchecked; } else { return QVariant(); } }; auto setData = [this](const Domain::Artifact::Ptr &artifact, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } if (auto task = artifact.dynamicCast()) { const auto currentTitle = task->title(); if (role == Qt::EditRole) task->setTitle(value.toString()); else task->setDone(value.toInt() == Qt::Checked); const auto job = m_taskRepository->update(task); installHandler(job, tr("Cannot modify task %1 in Workday").arg(currentTitle)); return true; } return false; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const Domain::Artifact::Ptr &artifact) { auto parentTask = artifact.objectCast(); - if (!mimeData->hasFormat("application/x-zanshin-object")) + if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedArtifacts = mimeData->property("objects").value(); if (droppedArtifacts.isEmpty()) return false; if (std::any_of(droppedArtifacts.begin(), droppedArtifacts.end(), [](const Domain::Artifact::Ptr &droppedArtifact) { return !droppedArtifact.objectCast(); })) { return false; } foreach(const auto &droppedArtifact, droppedArtifacts) { auto childTask = droppedArtifact.objectCast(); if (parentTask) { const auto job = m_taskRepository->associate(parentTask, childTask); installHandler(job, tr("Cannot move task %1 as sub-task of %2").arg(childTask->title()).arg(parentTask->title())); } else { childTask->setStartDate(Utils::DateTime::currentDateTime()); auto job = m_taskRepository->update(childTask); installHandler(job, tr("Cannot update task %1").arg(childTask->title())); job = m_taskRepository->dissociate(childTask); installHandler(job, tr("Cannot deparent task %1 from its parent").arg(childTask->title())); } } return true; }; auto drag = [](const Domain::Artifact::List &artifacts) -> QMimeData* { if (artifacts.isEmpty()) return Q_NULLPTR; auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(artifacts)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, this); } diff --git a/src/renku/app/aboutdata.cpp b/src/renku/app/aboutdata.cpp index 73943ca1..12aa8d13 100644 --- a/src/renku/app/aboutdata.cpp +++ b/src/renku/app/aboutdata.cpp @@ -1,50 +1,50 @@ /* This file is part of Renku Notes Copyright 2011-2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "aboutdata.h" #include "../../appversion.h" #include KAboutData App::getAboutData() { - KAboutData about("renku", - i18n("Renku Notes"), APPLICATION_VERSION, + KAboutData about(QStringLiteral("renku"), + i18n("Renku Notes"), QStringLiteral(APPLICATION_VERSION), i18n("A note taking application which aims at getting your mind like water"), KAboutLicense::GPL_V3, i18n("Copyright 2008-2015, Kevin Ottens ")); about.addAuthor(i18n("Kevin Ottens"), i18n("Lead Developer"), - "ervin@kde.org"); + QStringLiteral("ervin@kde.org")); about.addAuthor(i18n("Mario Bensi"), i18n("Developer"), - "nef@ipsquad.net"); + QStringLiteral("nef@ipsquad.net")); about.addAuthor(i18n("Franck Arrecot"), i18n("Developer"), - "franck.arrecot@gmail.com"); + QStringLiteral("franck.arrecot@gmail.com")); return about; } diff --git a/src/renku/app/main.cpp b/src/renku/app/main.cpp index e886c948..7f4f0155 100644 --- a/src/renku/app/main.cpp +++ b/src/renku/app/main.cpp @@ -1,107 +1,107 @@ /* This file is part of Renku Notes Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "widgets/applicationcomponents.h" #include "widgets/availablepagesview.h" #include "widgets/availablesourcesview.h" #include "widgets/editorview.h" #include "widgets/pageview.h" #include "presentation/applicationmodel.h" #include "aboutdata.h" #include "dependencies.h" int main(int argc, char **argv) { QApplication app(argc, argv); App::initializeDependencies(); auto aboutData = App::getAboutData(); QCommandLineParser parser; KAboutData::setApplicationData(aboutData); parser.addVersionOption(); parser.addHelpOption(); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); auto widget = new QWidget; auto components = new Widgets::ApplicationComponents(widget); components->setModel(Presentation::ApplicationModel::Ptr::create()); auto layout = new QVBoxLayout; layout->addWidget(components->pageView()); widget->setLayout(layout); auto sourcesDock = new QDockWidget(QObject::tr("Sources")); - sourcesDock->setObjectName("sourcesDock"); + sourcesDock->setObjectName(QStringLiteral("sourcesDock")); sourcesDock->setWidget(components->availableSourcesView()); auto pagesDock = new QDockWidget(QObject::tr("Pages")); - pagesDock->setObjectName("pagesDock"); + pagesDock->setObjectName(QStringLiteral("pagesDock")); pagesDock->setWidget(components->availablePagesView()); auto editorDock = new QDockWidget(QObject::tr("Editor")); - editorDock->setObjectName("editorDock"); + editorDock->setObjectName(QStringLiteral("editorDock")); editorDock->setWidget(components->editorView()); auto window = new KXmlGuiWindow; window->setCentralWidget(widget); window->addDockWidget(Qt::RightDockWidgetArea, editorDock); window->addDockWidget(Qt::LeftDockWidgetArea, pagesDock); window->addDockWidget(Qt::LeftDockWidgetArea, sourcesDock); auto actions = components->globalActions(); - actions.insert("dock_sources", sourcesDock->toggleViewAction()); - actions.insert("dock_pages", pagesDock->toggleViewAction()); - actions.insert("dock_editor", editorDock->toggleViewAction()); + actions.insert(QStringLiteral("dock_sources"), sourcesDock->toggleViewAction()); + actions.insert(QStringLiteral("dock_pages"), pagesDock->toggleViewAction()); + actions.insert(QStringLiteral("dock_editor"), editorDock->toggleViewAction()); auto ac = window->actionCollection(); ac->addAction(KStandardAction::Quit, window, SLOT(close())); for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) { ac->addAction(it.key(), it.value()); } window->setupGUI(QSize(1024, 600), KXmlGuiWindow::ToolBar | KXmlGuiWindow::Keys | KXmlGuiWindow::Save | KXmlGuiWindow::Create); window->show(); return app.exec(); } diff --git a/src/renku/kontact/part.cpp b/src/renku/kontact/part.cpp index 171e2e6e..8207fcd3 100644 --- a/src/renku/kontact/part.cpp +++ b/src/renku/kontact/part.cpp @@ -1,91 +1,91 @@ /* This file is part of Renku Notes Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "part.h" #include #include #include #include #include #include #include "../app/aboutdata.h" #include "../app/dependencies.h" #include "presentation/applicationmodel.h" #include "widgets/applicationcomponents.h" #include "widgets/availablepagesview.h" #include "widgets/availablesourcesview.h" #include "widgets/editorview.h" #include "widgets/pageview.h" #include "utils/dependencymanager.h" K_PLUGIN_FACTORY(PartFactory, registerPlugin();) Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList &) : KParts::ReadOnlyPart(parent) { App::initializeDependencies(); setComponentName(QStringLiteral("renku"), QStringLiteral("renku")); auto splitter = new QSplitter(parentWidget); auto sidebar = new QSplitter(Qt::Vertical, parentWidget); auto components = new Widgets::ApplicationComponents(parentWidget); components->setModel(Presentation::ApplicationModel::Ptr::create()); sidebar->addWidget(components->availablePagesView()); sidebar->addWidget(components->availableSourcesView()); splitter->addWidget(sidebar); splitter->addWidget(components->pageView()); splitter->addWidget(components->editorView()); setWidget(splitter); auto actions = QHash(); actions.unite(components->availableSourcesView()->globalActions()); actions.unite(components->availablePagesView()->globalActions()); actions.unite(components->pageView()->globalActions()); auto ac = actionCollection(); for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) { ac->addAction(it.key(), it.value()); } - setXMLFile(KStandardDirs::locate("data", "renku/renku_part.rc")); + setXMLFile(KStandardDirs::locate("data", QStringLiteral("renku/renku_part.rc"))); } Part::~Part() { } bool Part::openFile() { return false; } #include "part.moc" diff --git a/src/scripting/scripthandler.cpp b/src/scripting/scripthandler.cpp index f4e57ac9..3f4b0674 100644 --- a/src/scripting/scripthandler.cpp +++ b/src/scripting/scripthandler.cpp @@ -1,59 +1,60 @@ /* This file is part of Zanshin Copyright 2015 Theo Vaucher 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "scripthandler.h" #include "taskaction.h" #include #include using namespace Scripting; ScriptHandler::ScriptHandler(const Domain::TaskRepository::Ptr &taskRepository) : m_taskRepository(taskRepository), m_engine(new QScriptEngine(this)) { - m_engine->globalObject().setProperty("task", m_engine->newQObject(new TaskAction(m_taskRepository))); + m_engine->globalObject().setProperty(QStringLiteral("task"), + m_engine->newQObject(new TaskAction(m_taskRepository))); } QScriptValue ScriptHandler::evaluateFile(const QString &filename) { QFile file(filename); file.open(QIODevice::ReadOnly); QByteArray filecontent = file.readAll(); file.close(); return m_engine->evaluate(filecontent, filename); } QScriptValue ScriptHandler::evaluateString(const QString &string) { return m_engine->evaluate(string); } QScriptEngine *ScriptHandler::engine() { return m_engine; } diff --git a/src/widgets/applicationcomponents.cpp b/src/widgets/applicationcomponents.cpp index 53fc1337..27e15f73 100644 --- a/src/widgets/applicationcomponents.cpp +++ b/src/widgets/applicationcomponents.cpp @@ -1,257 +1,257 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "applicationcomponents.h" #include #include #include #include #include #include "availablepagesview.h" #include "availablesourcesview.h" #include "editorview.h" #include "pageview.h" #include "quickselectdialog.h" using namespace Widgets; ApplicationComponents::ApplicationComponents(QWidget *parent) : QObject(parent), m_parent(parent), m_availableSourcesView(Q_NULLPTR), m_availablePagesView(Q_NULLPTR), m_pageView(Q_NULLPTR), m_editorView(Q_NULLPTR) { m_quickSelectDialogFactory = [] (QWidget *parent) { return QuickSelectDialogPtr(new QuickSelectDialog(parent)); }; auto moveItemAction = new QAction(this); - moveItemAction->setObjectName("moveItemAction"); + moveItemAction->setObjectName(QStringLiteral("moveItemAction")); moveItemAction->setText("Move item"); moveItemAction->setShortcut(Qt::Key_M); connect(moveItemAction, &QAction::triggered, this, &ApplicationComponents::onMoveItemsRequested); - m_actions.insert("page_view_move", moveItemAction); + m_actions.insert(QStringLiteral("page_view_move"), moveItemAction); } ApplicationComponents::~ApplicationComponents() { setModel({}); } QHash ApplicationComponents::globalActions() const { auto actions = QHash(); actions.unite(availableSourcesView()->globalActions()); actions.unite(availablePagesView()->globalActions()); actions.unite(pageView()->globalActions()); actions.unite(m_actions); return actions; } QObjectPtr ApplicationComponents::model() const { return m_model; } AvailableSourcesView *ApplicationComponents::availableSourcesView() const { if (!m_availableSourcesView) { auto availableSourcesView = new AvailableSourcesView(m_parent); if (m_model) { availableSourcesView->setModel(m_model->property("availableSources").value()); } ApplicationComponents *self = const_cast(this); self->m_availableSourcesView = availableSourcesView; } return m_availableSourcesView; } AvailablePagesView *ApplicationComponents::availablePagesView() const { if (!m_availablePagesView) { auto availablePagesView = new AvailablePagesView(m_parent); if (m_model) { availablePagesView->setModel(m_model->property("availablePages").value()); auto availableSources = m_model->property("availableSources").value(); if (availableSources) availablePagesView->setProjectSourcesModel(availableSources->property("sourceListModel").value()); } ApplicationComponents *self = const_cast(this); self->m_availablePagesView = availablePagesView; connect(self->m_availablePagesView, &AvailablePagesView::currentPageChanged, self, &ApplicationComponents::onCurrentPageChanged); } return m_availablePagesView; } PageView *ApplicationComponents::pageView() const { if (!m_pageView) { auto pageView = new PageView(m_parent); if (m_model) { pageView->setModel(m_model->property("currentPage").value()); connect(m_model.data(), SIGNAL(currentPageChanged(QObject*)), pageView, SLOT(setModel(QObject*))); } ApplicationComponents *self = const_cast(this); self->m_pageView = pageView; connect(self->m_pageView, &PageView::currentArtifactChanged, self, &ApplicationComponents::onCurrentArtifactChanged); } return m_pageView; } EditorView *ApplicationComponents::editorView() const { if (!m_editorView) { auto editorView = new EditorView(m_parent); if (m_model) { editorView->setModel(m_model->property("editor").value()); } auto self = const_cast(this); self->m_editorView = editorView; } return m_editorView; } ApplicationComponents::QuickSelectDialogFactory ApplicationComponents::quickSelectDialogFactory() const { return m_quickSelectDialogFactory; } void ApplicationComponents::setModel(const QObjectPtr &model) { if (m_model == model) return; if (m_model && m_pageView) { disconnect(m_model.data(), 0, m_pageView, 0); } // Delay deletion of the old model until we're out of scope auto tmp = m_model; Q_UNUSED(tmp); m_model = model; if (m_availableSourcesView) { m_availableSourcesView->setModel(m_model ? m_model->property("availableSources").value() : Q_NULLPTR); } if (m_availablePagesView) { m_availablePagesView->setModel(m_model ? m_model->property("availablePages").value() : Q_NULLPTR); m_availablePagesView->setProjectSourcesModel(m_model ? m_model->property("dataSourcesModel").value() : Q_NULLPTR); } if (m_pageView) { m_pageView->setModel(m_model ? m_model->property("currentPage").value() : Q_NULLPTR); if (m_model) { connect(m_model.data(), SIGNAL(currentPageChanged(QObject*)), m_pageView, SLOT(setModel(QObject*))); } } if (m_editorView) { m_editorView->setModel(m_model ? m_model->property("editor").value() : Q_NULLPTR); } } void ApplicationComponents::setQuickSelectDialogFactory(const QuickSelectDialogFactory &factory) { m_quickSelectDialogFactory = factory; } void ApplicationComponents::onCurrentPageChanged(QObject *page) { if (!m_model) return; m_model->setProperty("currentPage", QVariant::fromValue(page)); QObject *editorModel = m_model->property("editor").value(); if (editorModel) editorModel->setProperty("artifact", QVariant::fromValue(Domain::Artifact::Ptr())); } void ApplicationComponents::onCurrentArtifactChanged(const Domain::Artifact::Ptr &artifact) { if (!m_model) return; auto editorModel = m_model->property("editor").value(); if (editorModel) editorModel->setProperty("artifact", QVariant::fromValue(artifact)); } void ApplicationComponents::onMoveItemsRequested() { if (!m_model) return; if (m_pageView->selectedIndexes().size() == 0) return; auto pageListModel = m_availablePagesView->model()->property("pageListModel").value(); Q_ASSERT(pageListModel); QuickSelectDialogInterface::Ptr dlg = m_quickSelectDialogFactory(m_pageView); dlg->setModel(pageListModel); if (dlg->exec() == QDialog::Accepted) moveItems(dlg->selectedIndex(), m_pageView->selectedIndexes()); } void ApplicationComponents::moveItems(const QModelIndex &destination, const QModelIndexList &droppedItems) { Q_ASSERT(destination.isValid()); Q_ASSERT(!droppedItems.isEmpty()); auto centralListModel = droppedItems.first().model(); auto availablePagesModel = const_cast(destination.model()); // drag const auto data = centralListModel->mimeData(droppedItems); // drop availablePagesModel->dropMimeData(data, Qt::MoveAction, -1, -1, destination); } diff --git a/src/widgets/availablepagesview.cpp b/src/widgets/availablepagesview.cpp index e5e1d5f0..96324121 100644 --- a/src/widgets/availablepagesview.cpp +++ b/src/widgets/availablepagesview.cpp @@ -1,346 +1,346 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "availablepagesview.h" #include #include #include #include #include #include #include #include "presentation/metatypes.h" #include "presentation/querytreemodelbase.h" #include "widgets/messagebox.h" #include "widgets/newprojectdialog.h" #include "widgets/quickselectdialog.h" #include "domain/project.h" #include "domain/context.h" #include "domain/tag.h" using namespace Widgets; using namespace Presentation; AvailablePagesView::AvailablePagesView(QWidget *parent) : QWidget(parent), m_addProjectAction(new QAction(this)), m_addContextAction(new QAction(this)), m_addTagAction(new QAction(this)), m_removeAction(new QAction(this)), m_model(Q_NULLPTR), m_sources(Q_NULLPTR), m_pagesView(new QTreeView(this)) { - m_pagesView->setObjectName("pagesView"); + m_pagesView->setObjectName(QStringLiteral("pagesView")); m_pagesView->header()->hide(); m_pagesView->setDragDropMode(QTreeView::DropOnly); auto actionBar = new QToolBar(this); - actionBar->setObjectName("actionBar"); + actionBar->setObjectName(QStringLiteral("actionBar")); actionBar->setIconSize(QSize(16, 16)); - m_addProjectAction->setObjectName("addProjectAction"); + m_addProjectAction->setObjectName(QStringLiteral("addProjectAction")); m_addProjectAction->setText(tr("New project")); - m_addProjectAction->setIcon(QIcon::fromTheme("view-pim-tasks")); + m_addProjectAction->setIcon(QIcon::fromTheme(QStringLiteral("view-pim-tasks"))); connect(m_addProjectAction, &QAction::triggered, this, &AvailablePagesView::onAddProjectTriggered); actionBar->addAction(m_addProjectAction); - m_addContextAction->setObjectName("addContextAction"); + m_addContextAction->setObjectName(QStringLiteral("addContextAction")); m_addContextAction->setText(tr("New context")); - m_addContextAction->setIcon(QIcon::fromTheme("view-pim-notes")); + m_addContextAction->setIcon(QIcon::fromTheme(QStringLiteral("view-pim-notes"))); connect(m_addContextAction, &QAction::triggered, this, &AvailablePagesView::onAddContextTriggered); actionBar->addAction(m_addContextAction); - m_addTagAction->setObjectName("addTagAction"); + m_addTagAction->setObjectName(QStringLiteral("addTagAction")); m_addTagAction->setText(tr("New tag")); - m_addTagAction->setIcon(QIcon::fromTheme("view-pim-tasks")); + m_addTagAction->setIcon(QIcon::fromTheme(QStringLiteral("view-pim-tasks"))); connect(m_addTagAction, &QAction::triggered, this, &AvailablePagesView::onAddTagTriggered); actionBar->addAction(m_addTagAction); - m_removeAction->setObjectName("removeAction"); + m_removeAction->setObjectName(QStringLiteral("removeAction")); m_removeAction->setText(tr("Remove page")); - m_removeAction->setIcon(QIcon::fromTheme("list-remove")); + m_removeAction->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); connect(m_removeAction, &QAction::triggered, this, &AvailablePagesView::onRemoveTriggered); actionBar->addAction(m_removeAction); auto actionBarLayout = new QHBoxLayout; actionBarLayout->setAlignment(Qt::AlignRight); actionBarLayout->addWidget(actionBar); auto layout = new QVBoxLayout; layout->addWidget(m_pagesView); layout->addLayout(actionBarLayout); setLayout(layout); m_projectDialogFactory = [] (QWidget *parent) { return NewProjectDialogPtr(new NewProjectDialog(parent)); }; m_quickSelectDialogFactory = [] (QWidget *parent) { return QuickSelectDialogPtr(new QuickSelectDialog(parent)); }; m_messageBoxInterface = MessageBox::Ptr::create(); auto goPreviousAction = new QAction(this); - goPreviousAction->setObjectName("goPreviousAction"); + goPreviousAction->setObjectName(QStringLiteral("goPreviousAction")); goPreviousAction->setText(tr("Previous page")); - goPreviousAction->setIcon(QIcon::fromTheme("go-up")); + goPreviousAction->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); goPreviousAction->setShortcut(Qt::ALT | Qt::Key_Up); connect(goPreviousAction, &QAction::triggered, this, &AvailablePagesView::onGoPreviousTriggered); auto goNextAction = new QAction(this); - goNextAction->setObjectName("goNextAction"); + goNextAction->setObjectName(QStringLiteral("goNextAction")); goNextAction->setText(tr("Next page")); - goNextAction->setIcon(QIcon::fromTheme("go-down")); + goNextAction->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); goNextAction->setShortcut(Qt::ALT | Qt::Key_Down); connect(goNextAction, &QAction::triggered, this, &AvailablePagesView::onGoNextTriggered); auto goToAction = new QAction(this); - goToAction->setObjectName("goToAction"); + goToAction->setObjectName(QStringLiteral("goToAction")); goToAction->setText(tr("Go to page...")); goToAction->setShortcut(Qt::Key_J); connect(goToAction, &QAction::triggered, this, &AvailablePagesView::onGoToTriggered); - m_actions.insert("pages_project_add", m_addProjectAction); - m_actions.insert("pages_context_add", m_addContextAction); - m_actions.insert("pages_tag_add", m_addTagAction); - m_actions.insert("pages_remove", m_removeAction); - m_actions.insert("pages_go_previous", goPreviousAction); - m_actions.insert("pages_go_next", goNextAction); - m_actions.insert("pages_go_to", goToAction); + m_actions.insert(QStringLiteral("pages_project_add"), m_addProjectAction); + m_actions.insert(QStringLiteral("pages_context_add"), m_addContextAction); + m_actions.insert(QStringLiteral("pages_tag_add"), m_addTagAction); + m_actions.insert(QStringLiteral("pages_remove"), m_removeAction); + m_actions.insert(QStringLiteral("pages_go_previous"), goPreviousAction); + m_actions.insert(QStringLiteral("pages_go_next"), goNextAction); + m_actions.insert(QStringLiteral("pages_go_to"), goToAction); } QHash AvailablePagesView::globalActions() const { return m_actions; } QObject *AvailablePagesView::model() const { return m_model; } QAbstractItemModel *AvailablePagesView::projectSourcesModel() const { return m_sources; } Domain::DataSource::Ptr AvailablePagesView::defaultProjectSource() const { return m_defaultSource; } AvailablePagesView::ProjectDialogFactory AvailablePagesView::projectDialogFactory() const { return m_projectDialogFactory; } AvailablePagesView::QuickSelectDialogFactory AvailablePagesView::quickSelectDialogFactory() const { return m_quickSelectDialogFactory; } void AvailablePagesView::setModel(QObject *model) { if (model == m_model) return; if (m_pagesView->selectionModel()) { disconnect(m_pagesView->selectionModel(), Q_NULLPTR, this, Q_NULLPTR); } m_pagesView->setModel(Q_NULLPTR); m_model = model; setEnabled(m_model); if (!m_model) return; m_addProjectAction->setVisible(m_model->property("hasProjectPages").toBool()); m_addContextAction->setVisible(m_model->property("hasContextPages").toBool()); m_addTagAction->setVisible(m_model->property("hasTagPages").toBool()); QVariant modelProperty = m_model->property("pageListModel"); if (modelProperty.canConvert()) m_pagesView->setModel(modelProperty.value()); connect(m_pagesView->selectionModel(), &QItemSelectionModel::currentChanged, this, &AvailablePagesView::onCurrentChanged); QMetaObject::invokeMethod(this, "onInitTimeout", Qt::QueuedConnection); } void AvailablePagesView::setProjectSourcesModel(QAbstractItemModel *sources) { m_sources = sources; } void AvailablePagesView::setDefaultProjectSource(const Domain::DataSource::Ptr &source) { m_defaultSource = source; } void AvailablePagesView::setProjectDialogFactory(const AvailablePagesView::ProjectDialogFactory &factory) { m_projectDialogFactory = factory; } void AvailablePagesView::setQuickSelectDialogFactory(const AvailablePagesView::QuickSelectDialogFactory &factory) { m_quickSelectDialogFactory = factory; } void AvailablePagesView::setMessageBoxInterface(const MessageBoxInterface::Ptr &interface) { m_messageBoxInterface = interface; } void AvailablePagesView::onCurrentChanged(const QModelIndex ¤t) { QObject *page = Q_NULLPTR; QMetaObject::invokeMethod(m_model, "createPageForIndex", Q_RETURN_ARG(QObject*, page), Q_ARG(QModelIndex, current)); emit currentPageChanged(page); const auto object = current.data(QueryTreeModelBase::ObjectRole).value(); m_removeAction->setEnabled(object.objectCast() || object.objectCast() || object.objectCast()); } void AvailablePagesView::onAddProjectTriggered() { NewProjectDialogInterface::Ptr dialog = m_projectDialogFactory(this); dialog->setDataSourcesModel(m_sources); if (dialog->exec() == QDialog::Accepted) { m_defaultSource = dialog->dataSource(); QMetaObject::invokeMethod(m_model, "addProject", Q_ARG(QString, dialog->name()), Q_ARG(Domain::DataSource::Ptr, dialog->dataSource())); } } void AvailablePagesView::onAddContextTriggered() { const QString name = m_messageBoxInterface->askTextInput(this, tr("Add Context"), tr("Context name")); if (!name.isEmpty()) { QMetaObject::invokeMethod(m_model, "addContext", Q_ARG(QString, name)); } } void AvailablePagesView::onAddTagTriggered() { const QString name = m_messageBoxInterface->askTextInput(this, tr("Add Tag"), tr("Tag name")); if (!name.isEmpty()) { QMetaObject::invokeMethod(m_model, "addTag", Q_ARG(QString, name)); } } void AvailablePagesView::onRemoveTriggered() { const QModelIndex current = m_pagesView->currentIndex(); if (!current.isValid()) return; QString title; QString text; QObjectPtr object = current.data(QueryTreeModelBase::ObjectRole).value(); if (!object) { qDebug() << "Model doesn't have ObjectRole for" << current; return; } if (Domain::Project::Ptr project = object.objectCast()) { title = tr("Delete Project"); text = tr("Do you really want to delete the project '%1', with all its actions?").arg(project->name()); } else if (Domain::Context::Ptr context = object.objectCast()) { title = tr("Delete Context"); text = tr("Do you really want to delete the context '%1'?").arg(context->name()); } else if (Domain::Tag::Ptr tag = object.objectCast()) { title = tr("Delete Tag"); text = tr("Do you really want to delete the tag '%1'?").arg(tag->name()); } else { qFatal("Unrecognized object type"); return; } QMessageBox::Button button = m_messageBoxInterface->askConfirmation(this, title, text); if (button != QMessageBox::Yes) { return; } QMetaObject::invokeMethod(m_model, "removeItem", Q_ARG(QModelIndex, current)); } void AvailablePagesView::onGoPreviousTriggered() { auto index = m_pagesView->indexAbove(m_pagesView->currentIndex()); while (index.isValid() && !(index.flags() & Qt::ItemIsSelectable)) { index = m_pagesView->indexAbove(index); } if (index.isValid()) m_pagesView->setCurrentIndex(index); } void AvailablePagesView::onGoNextTriggered() { auto index = m_pagesView->indexBelow(m_pagesView->currentIndex()); while (index.isValid() && !(index.flags() & Qt::ItemIsSelectable)) { index = m_pagesView->indexBelow(index); } if (index.isValid()) m_pagesView->setCurrentIndex(index); } void AvailablePagesView::onGoToTriggered() { QuickSelectDialogInterface::Ptr dialog = m_quickSelectDialogFactory(this); dialog->setModel(m_pagesView->model()); if (dialog->exec() == QDialog::Accepted && dialog->selectedIndex().isValid()) { m_pagesView->setCurrentIndex(dialog->selectedIndex()); } } void AvailablePagesView::onInitTimeout() { if (m_pagesView->model()) { m_pagesView->setCurrentIndex(m_pagesView->model()->index(0, 0)); m_pagesView->expandAll(); } } diff --git a/src/widgets/availablesourcesview.cpp b/src/widgets/availablesourcesview.cpp index 48ade009..8111a272 100644 --- a/src/widgets/availablesourcesview.cpp +++ b/src/widgets/availablesourcesview.cpp @@ -1,204 +1,204 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "availablesourcesview.h" #include #include #include #include #include #include #include #include #include #include "presentation/metatypes.h" #include "presentation/querytreemodelbase.h" #include "widgets/datasourcedelegate.h" using namespace Widgets; AvailableSourcesView::AvailableSourcesView(QWidget *parent) : QWidget(parent), m_defaultAction(new QAction(this)), m_model(Q_NULLPTR), m_sortProxy(new QSortFilterProxyModel(this)), m_sourcesView(new QTreeView(this)) { m_sortProxy->setDynamicSortFilter(true); m_sortProxy->sort(0); auto searchEdit = new KLineEdit(this); - searchEdit->setObjectName("searchEdit"); + searchEdit->setObjectName(QStringLiteral("searchEdit")); searchEdit->setClearButtonShown(true); searchEdit->setPlaceholderText(tr("Search...")); connect(searchEdit, &QLineEdit::textChanged, this, &AvailableSourcesView::onSearchTextChanged); #ifndef ZANSHIN_HIDING_SOURCES_ENABLED searchEdit->hide(); #endif - m_sourcesView->setObjectName("sourcesView"); + m_sourcesView->setObjectName(QStringLiteral("sourcesView")); m_sourcesView->header()->hide(); m_sourcesView->setModel(m_sortProxy); connect(m_sourcesView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AvailableSourcesView::onSelectionChanged); connect(m_sourcesView->model(), &QAbstractItemModel::rowsInserted, m_sourcesView, &QTreeView::expand); connect(m_sourcesView->model(), &QAbstractItemModel::layoutChanged, m_sourcesView, &QTreeView::expandAll); connect(m_sourcesView->model(), &QAbstractItemModel::modelReset, m_sourcesView, &QTreeView::expandAll); auto delegate = new DataSourceDelegate(m_sourcesView); #ifndef ZANSHIN_HIDING_SOURCES_ENABLED delegate->setActionsEnabled(false); #endif connect(delegate, &DataSourceDelegate::actionTriggered, this, &AvailableSourcesView::onActionTriggered); m_sourcesView->setItemDelegate(delegate); auto actionBar = new QToolBar(this); - actionBar->setObjectName("actionBar"); + actionBar->setObjectName(QStringLiteral("actionBar")); actionBar->setIconSize(QSize(16, 16)); - m_defaultAction->setObjectName("defaultAction"); + m_defaultAction->setObjectName(QStringLiteral("defaultAction")); m_defaultAction->setText(tr("Use as default source")); - m_defaultAction->setIcon(QIcon::fromTheme("folder-favorites")); + m_defaultAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-favorites"))); connect(m_defaultAction, &QAction::triggered, this, &AvailableSourcesView::onDefaultTriggered); actionBar->addAction(m_defaultAction); auto layout = new QVBoxLayout; layout->addWidget(searchEdit); layout->addWidget(m_sourcesView); auto actionBarLayout = new QHBoxLayout; actionBarLayout->setAlignment(Qt::AlignRight); actionBarLayout->addWidget(actionBar); layout->addLayout(actionBarLayout); setLayout(layout); auto settingsAction = new QAction(this); - settingsAction->setObjectName("settingsAction"); + settingsAction->setObjectName(QStringLiteral("settingsAction")); settingsAction->setText(tr("Configure %1...").arg(QApplication::applicationName())); - settingsAction->setIcon(QIcon::fromTheme("configure")); + settingsAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); connect(settingsAction, &QAction::triggered, this, &AvailableSourcesView::onSettingsTriggered); - m_actions.insert("options_configure", settingsAction); + m_actions.insert(QStringLiteral("options_configure"), settingsAction); onSelectionChanged(); } QHash AvailableSourcesView::globalActions() const { return m_actions; } QObject *AvailableSourcesView::model() const { return m_model; } void AvailableSourcesView::setModel(QObject *model) { if (model == m_model) return; m_sortProxy->setSourceModel(Q_NULLPTR); m_model = model; setEnabled(m_model); if (!m_model) return; setSourceModel("sourceListModel"); } void AvailableSourcesView::onSelectionChanged() { const auto selectedIndexes = m_sourcesView->selectionModel()->selectedIndexes(); auto selectedSources = Domain::DataSource::List(); std::transform(selectedIndexes.constBegin(), selectedIndexes.constEnd(), std::back_inserter(selectedSources), [] (const QModelIndex &index) { return index.data(Presentation::QueryTreeModelBase::ObjectRole) .value(); }); m_defaultAction->setEnabled(selectedSources.size() == 1 && selectedSources.first()->contentTypes() != Domain::DataSource::NoContent); } void AvailableSourcesView::onSettingsTriggered() { QMetaObject::invokeMethod(m_model, "showConfigDialog"); } void AvailableSourcesView::onDefaultTriggered() { const auto currentIndex = m_sourcesView->currentIndex(); const auto index = m_sortProxy->mapToSource(currentIndex); if (index.isValid()) QMetaObject::invokeMethod(m_model, "setDefaultItem", Q_ARG(QModelIndex, index)); } void AvailableSourcesView::onActionTriggered(const Domain::DataSource::Ptr &source, int action) { switch (action) { case DataSourceDelegate::AddToList: QMetaObject::invokeMethod(m_model, "listSource", Q_ARG(Domain::DataSource::Ptr, source)); break; case DataSourceDelegate::RemoveFromList: QMetaObject::invokeMethod(m_model, "unlistSource", Q_ARG(Domain::DataSource::Ptr, source)); break; case DataSourceDelegate::Bookmark: QMetaObject::invokeMethod(m_model, "bookmarkSource", Q_ARG(Domain::DataSource::Ptr, source)); break; default: qFatal("Shouldn't happen"); break; } } void AvailableSourcesView::setSourceModel(const QByteArray &propertyName) { QVariant modelProperty = m_model->property(propertyName); if (modelProperty.canConvert()) m_sortProxy->setSourceModel(modelProperty.value()); } void AvailableSourcesView::onSearchTextChanged(const QString &text) { if (text.size() <= 2) { m_model->setProperty("searchTerm", QString()); setSourceModel("sourceListModel"); } else { m_model->setProperty("searchTerm", text); setSourceModel("searchListModel"); } } diff --git a/src/widgets/datasourcedelegate.cpp b/src/widgets/datasourcedelegate.cpp index 6f57d5b3..7ac9093f 100644 --- a/src/widgets/datasourcedelegate.cpp +++ b/src/widgets/datasourcedelegate.cpp @@ -1,200 +1,200 @@ /* This file is part of Zanshin Copyright 2014 Christian Mollekopf Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "datasourcedelegate.h" #include #include #include "presentation/querytreemodel.h" using namespace Widgets; const int DELEGATE_HEIGHT = 16; DataSourceDelegate::DataSourceDelegate(QObject *parent) : QStyledItemDelegate(parent), m_actionsEnabled(true) { - m_pixmaps[AddToList] = QIcon::fromTheme("list-add").pixmap(DELEGATE_HEIGHT); - m_pixmaps[RemoveFromList] = QIcon::fromTheme("list-remove").pixmap(DELEGATE_HEIGHT); - m_pixmaps[Bookmark] = QIcon::fromTheme("bookmarks").pixmap(DELEGATE_HEIGHT); + m_pixmaps[AddToList] = QIcon::fromTheme(QStringLiteral("list-add")).pixmap(DELEGATE_HEIGHT); + m_pixmaps[RemoveFromList] = QIcon::fromTheme(QStringLiteral("list-remove")).pixmap(DELEGATE_HEIGHT); + m_pixmaps[Bookmark] = QIcon::fromTheme(QStringLiteral("bookmarks")).pixmap(DELEGATE_HEIGHT); } bool DataSourceDelegate::isActionsEnabled() const { return m_actionsEnabled; } void DataSourceDelegate::setActionsEnabled(bool actionsEnabled) { m_actionsEnabled = actionsEnabled; } static QRect createButtonRect(const QRect &itemRect, int position) { static const int border = 2; const int side = itemRect.height() - (2 * border); const int offset = side * (position + 1) + border * (position + 2); return itemRect.adjusted(itemRect.width() - (offset + side), border, -offset, -border); } static QStyle *currentStyle(const QStyleOptionViewItem &option) { QWidget const *widget = Q_NULLPTR; if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast(&option)) { widget = v3->widget; } QStyle *style = widget ? widget->style() : QApplication::style(); return style; } static QStyleOptionButton createButtonOption(const QStyleOptionViewItemV4 &itemOption, const QPixmap &pixmap, int position) { const QRect itemRect = itemOption.rect; const QRect buttonRect = createButtonRect(itemRect, position); QStyleOptionButton buttonOption; buttonOption.state = QStyle::State_Active | QStyle::State_Enabled; buttonOption.icon = pixmap; buttonOption.rect = buttonRect; buttonOption.iconSize = pixmap.size(); return buttonOption; } static QList actionsForSource(const Domain::DataSource::Ptr &source, bool isHovered, bool enabled) { auto actions = QList(); if (!enabled) return actions; if (source->contentTypes() == Domain::DataSource::NoContent) return actions; if (source->listStatus() == Domain::DataSource::Unlisted) { actions << DataSourceDelegate::AddToList; } else { actions << DataSourceDelegate::Bookmark; if (isHovered) actions << DataSourceDelegate::RemoveFromList; } return actions; } static Domain::DataSource::Ptr sourceForIndex(const QModelIndex &index) { const auto data = index.data(Presentation::QueryTreeModel::ObjectRole); const auto source = data.value(); Q_ASSERT(source); return source; } void DataSourceDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const { Q_ASSERT(index.isValid()); const auto source = sourceForIndex(index); const auto isHovered = bool(opt.state & QStyle::State_MouseOver); const auto isDefault = index.data(Presentation::QueryTreeModel::IsDefaultRole).toBool(); QStyleOptionViewItemV4 option = opt; initStyleOption(&option, index); option.font.setBold(isDefault); QStyle *s = currentStyle(opt); int position = 0; foreach (Action action, actionsForSource(source, isHovered, m_actionsEnabled)) { QStyleOptionButton buttonOption = createButtonOption(option, m_pixmaps[action], position); if (action == Bookmark && source->listStatus() != Domain::DataSource::Bookmarked) { buttonOption.state &= ~QStyle::State_Enabled; } s->drawControl(QStyle::CE_PushButton, &buttonOption, painter, Q_NULLPTR); position++; } if (position != 0) { const auto firstButtonLeft = createButtonRect(option.rect, position - 1).left(); option.rect.setRight(firstButtonLeft); } QStyledItemDelegate::paint(painter, option, index); } bool DataSourceDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { Q_ASSERT(event); Q_ASSERT(model); int button = -1; switch (event->type()) { case QEvent::MouseButtonRelease: { QMouseEvent *mouseEvent = static_cast(event); for (int position = 0; position < 4; position++) { if (createButtonRect(option.rect, position).contains(mouseEvent->pos())) { button = position; break; } } if (mouseEvent->button() != Qt::LeftButton || button < 0) { return QStyledItemDelegate::editorEvent(event, model, option, index); } } break; default: return QStyledItemDelegate::editorEvent(event, model, option, index); } Q_ASSERT(button >= 0); QStyleOptionViewItem opt = option; opt.state |= QStyle::State_MouseOver; const auto source = sourceForIndex(index); auto actions = actionsForSource(source, true, m_actionsEnabled); if (actions.count() > button) { const Action a = actions.at(button); emit actionTriggered(source, a); return true; } return QStyledItemDelegate::editorEvent(event, model, option, index); } QSize DataSourceDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize size = QStyledItemDelegate::sizeHint(option, index); // Make sure we got a constant height suitable for the buttons size.setHeight(DELEGATE_HEIGHT + 4); return size; } diff --git a/src/widgets/editorview.cpp b/src/widgets/editorview.cpp index 52d71d1d..73a8d9ca 100644 --- a/src/widgets/editorview.cpp +++ b/src/widgets/editorview.cpp @@ -1,272 +1,272 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "editorview.h" #include #include #include #include #include #include "kdateedit.h" #include "addressline/addresseelineedit.h" #include "domain/artifact.h" using namespace Widgets; EditorView::EditorView(QWidget *parent) : QWidget(parent), m_model(Q_NULLPTR), m_delegateLabel(new QLabel(this)), m_textEdit(new QPlainTextEdit(this)), m_taskGroup(new QWidget(this)), m_startDateEdit(new KPIM::KDateEdit(m_taskGroup)), m_dueDateEdit(new KPIM::KDateEdit(m_taskGroup)), m_startTodayButton(new QPushButton(tr("Start today"), m_taskGroup)), m_doneButton(new QCheckBox(tr("Done"), m_taskGroup)), m_delegateEdit(Q_NULLPTR) { // To avoid having unit tests talking to akonadi // while we don't need the completion for them if (qgetenv("ZANSHIN_UNIT_TEST_RUN").isEmpty()) m_delegateEdit = new KPIM::AddresseeLineEdit(this); else m_delegateEdit = new KLineEdit(this); - m_delegateLabel->setObjectName("delegateLabel"); - m_delegateEdit->setObjectName("delegateEdit"); - m_textEdit->setObjectName("textEdit"); - m_startDateEdit->setObjectName("startDateEdit"); - m_dueDateEdit->setObjectName("dueDateEdit"); - m_doneButton->setObjectName("doneButton"); - m_startTodayButton->setObjectName("startTodayButton"); + m_delegateLabel->setObjectName(QStringLiteral("delegateLabel")); + m_delegateEdit->setObjectName(QStringLiteral("delegateEdit")); + m_textEdit->setObjectName(QStringLiteral("textEdit")); + m_startDateEdit->setObjectName(QStringLiteral("startDateEdit")); + m_dueDateEdit->setObjectName(QStringLiteral("dueDateEdit")); + m_doneButton->setObjectName(QStringLiteral("doneButton")); + m_startTodayButton->setObjectName(QStringLiteral("startTodayButton")); m_startDateEdit->setMinimumContentsLength(10); m_dueDateEdit->setMinimumContentsLength(10); auto layout = new QVBoxLayout; layout->addWidget(m_delegateLabel); layout->addWidget(m_textEdit); layout->addWidget(m_taskGroup); setLayout(layout); auto vbox = new QVBoxLayout; auto delegateHBox = new QHBoxLayout; delegateHBox->addWidget(new QLabel(tr("Delegate to"), m_taskGroup)); delegateHBox->addWidget(m_delegateEdit); vbox->addLayout(delegateHBox); auto datesHBox = new QHBoxLayout; datesHBox->addWidget(new QLabel(tr("Start date"), m_taskGroup)); datesHBox->addWidget(m_startDateEdit, 1); datesHBox->addWidget(new QLabel(tr("Due date"), m_taskGroup)); datesHBox->addWidget(m_dueDateEdit, 1); vbox->addLayout(datesHBox); auto bottomHBox = new QHBoxLayout; bottomHBox->addWidget(m_startTodayButton); bottomHBox->addWidget(m_doneButton); bottomHBox->addStretch(); vbox->addLayout(bottomHBox); m_taskGroup->setLayout(vbox); // Make sure our minimum width is always the one with // the task group visible layout->activate(); setMinimumWidth(minimumSizeHint().width()); m_delegateLabel->setVisible(false); m_taskGroup->setVisible(false); connect(m_textEdit, &QPlainTextEdit::textChanged, this, &EditorView::onTextEditChanged); connect(m_startDateEdit, &KPIM::KDateEdit::dateEntered, this, &EditorView::onStartEditEntered); connect(m_dueDateEdit, &KPIM::KDateEdit::dateEntered, this, &EditorView::onDueEditEntered); connect(m_doneButton, &QAbstractButton::toggled, this, &EditorView::onDoneButtonChanged); connect(m_startTodayButton, &QAbstractButton::clicked, this, &EditorView::onStartTodayClicked); connect(m_delegateEdit, &KLineEdit::returnPressed, this, &EditorView::onDelegateEntered); setEnabled(false); } QObject *EditorView::model() const { return m_model; } void EditorView::setModel(QObject *model) { if (model == m_model) return; if (m_model) { disconnect(m_model, Q_NULLPTR, this, Q_NULLPTR); disconnect(this, Q_NULLPTR, m_model, Q_NULLPTR); } m_model = model; setEnabled(m_model); if (!m_model) { m_taskGroup->setVisible(false); m_textEdit->clear(); return; } onArtifactChanged(); onTextOrTitleChanged(); onHasTaskPropertiesChanged(); onStartDateChanged(); onDueDateChanged(); onDoneChanged(); onDelegateTextChanged(); connect(m_model, SIGNAL(artifactChanged(Domain::Artifact::Ptr)), this, SLOT(onArtifactChanged())); connect(m_model, SIGNAL(hasTaskPropertiesChanged(bool)), this, SLOT(onHasTaskPropertiesChanged())); connect(m_model, SIGNAL(titleChanged(QString)), this, SLOT(onTextOrTitleChanged())); connect(m_model, SIGNAL(textChanged(QString)), this, SLOT(onTextOrTitleChanged())); connect(m_model, SIGNAL(startDateChanged(QDateTime)), this, SLOT(onStartDateChanged())); connect(m_model, SIGNAL(dueDateChanged(QDateTime)), this, SLOT(onDueDateChanged())); connect(m_model, SIGNAL(doneChanged(bool)), this, SLOT(onDoneChanged())); connect(m_model, SIGNAL(delegateTextChanged(QString)), this, SLOT(onDelegateTextChanged())); connect(this, SIGNAL(titleChanged(QString)), m_model, SLOT(setTitle(QString))); connect(this, SIGNAL(textChanged(QString)), m_model, SLOT(setText(QString))); connect(this, SIGNAL(startDateChanged(QDateTime)), m_model, SLOT(setStartDate(QDateTime))); connect(this, SIGNAL(dueDateChanged(QDateTime)), m_model, SLOT(setDueDate(QDateTime))); connect(this, SIGNAL(doneChanged(bool)), m_model, SLOT(setDone(bool))); } void EditorView::onArtifactChanged() { auto artifact = m_model->property("artifact").value(); setEnabled(artifact); m_delegateEdit->clear(); } void EditorView::onHasTaskPropertiesChanged() { m_taskGroup->setVisible(m_model->property("hasTaskProperties").toBool()); } void EditorView::onTextOrTitleChanged() { const auto title = m_model->property("title").toString(); const auto text = m_model->property("text").toString(); QRegExp reg("^" + QRegExp::escape(title) + "\\s*\\n?" + QRegExp::escape(text) + "\\s*$"); if (!reg.exactMatch(m_textEdit->toPlainText())) m_textEdit->setPlainText(title + '\n' + text); } void EditorView::onStartDateChanged() { m_startDateEdit->setDate(m_model->property("startDate").toDateTime().date()); } void EditorView::onDueDateChanged() { m_dueDateEdit->setDate(m_model->property("dueDate").toDateTime().date()); } void EditorView::onDoneChanged() { m_doneButton->setChecked(m_model->property("done").toBool()); } void EditorView::onDelegateTextChanged() { const auto delegateText = m_model->property("delegateText").toString(); const auto labelText = delegateText.isEmpty() ? QString() : tr("Delegated to: %1").arg(delegateText); m_delegateLabel->setVisible(!labelText.isEmpty()); m_delegateLabel->setText(labelText); } void EditorView::onTextEditChanged() { const QString plainText = m_textEdit->toPlainText(); const int index = plainText.indexOf('\n'); if (index < 0) { emit titleChanged(plainText); emit textChanged(QString()); } else { const QString title = plainText.left(index); const QString text = plainText.mid(index + 1); emit titleChanged(title); emit textChanged(text); } } void EditorView::onStartEditEntered(const QDate &start) { emit startDateChanged(QDateTime(start)); } void EditorView::onDueEditEntered(const QDate &due) { emit dueDateChanged(QDateTime(due)); } void EditorView::onDoneButtonChanged(bool checked) { emit doneChanged(checked); } void EditorView::onStartTodayClicked() { QDate today(QDate::currentDate()); m_startDateEdit->setDate(today); emit startDateChanged(QDateTime(today)); } void EditorView::onDelegateEntered() { const auto input = m_delegateEdit->text(); auto name = QString(); auto email = QString(); auto gotMatch = false; QRegExp fullRx("\\s*(.*) <([\\w\\.]+@[\\w\\.]+)>\\s*"); QRegExp emailOnlyRx("\\s*?\\s*"); if (input.contains(fullRx)) { name = fullRx.cap(1); email = fullRx.cap(2); gotMatch = true; } else if (input.contains(emailOnlyRx)) { email = emailOnlyRx.cap(1); gotMatch = true; } if (gotMatch) { QMetaObject::invokeMethod(m_model, "delegate", Q_ARG(QString, name), Q_ARG(QString, email)); m_delegateEdit->clear(); } } diff --git a/src/widgets/itemdelegate.cpp b/src/widgets/itemdelegate.cpp index 6b62b69f..155b1238 100644 --- a/src/widgets/itemdelegate.cpp +++ b/src/widgets/itemdelegate.cpp @@ -1,108 +1,108 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "itemdelegate.h" #include #include #include "domain/note.h" #include "domain/task.h" #include "presentation/querytreemodelbase.h" using namespace Widgets; ItemDelegate::ItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { } QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { // Make sure they all get the height needed for a check indicator QStyleOptionViewItemV4 opt = option; opt.features = QStyleOptionViewItemV4::HasCheckIndicator; QSize res = QStyledItemDelegate::sizeHint(opt, index); return res; } void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItemV4 opt = option; initStyleOption(&opt, index); Domain::Task::Ptr task; Domain::Note::Ptr note; QVariant data = index.data(Presentation::QueryTreeModelBase::ObjectRole); auto artifact = data.value(); if (artifact) { task = artifact.dynamicCast(); note = artifact.dynamicCast(); } else { task = data.value(); note = data.value(); } if (task) { if (task->isDone()) { opt.font.setStrikeOut(true); } else { if (task->startDate().isValid() && task->startDate().date() <= QDate::currentDate()) { opt.font.setBold(true); } if (task->dueDate().isValid()) { if (task->dueDate().date() < QDate::currentDate()) { opt.font.setBold(true); opt.palette.setColor(QPalette::Text, QColor(Qt::red)); opt.palette.setColor(QPalette::HighlightedText, QColor(Qt::red)); } else if (task->dueDate().date() == QDate::currentDate()) { opt.font.setBold(true); opt.palette.setColor(QPalette::Text, QColor("orange")); opt.palette.setColor(QPalette::HighlightedText, QColor("orange")); } } } if (task->delegate().isValid()) { - opt.text = QString("(%1) %2").arg(task->delegate().display(), opt.text); + opt.text = QStringLiteral("(%1) %2").arg(task->delegate().display(), opt.text); opt.font.setItalic(true); } } if (note) { opt.features |= QStyleOptionViewItemV4::HasDecoration; - opt.icon = QIcon::fromTheme("text-plain"); + opt.icon = QIcon::fromTheme(QStringLiteral("text-plain")); } const QWidget *widget = opt.widget; QStyle *style = widget ? widget->style() : QApplication::style(); style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); } diff --git a/src/widgets/pageview.cpp b/src/widgets/pageview.cpp index f83f7714..dac204c9 100644 --- a/src/widgets/pageview.cpp +++ b/src/widgets/pageview.cpp @@ -1,361 +1,361 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "pageview.h" #include #include #include #include #include #include #include #include #include #include "filterwidget.h" #include "itemdelegate.h" #include "messagebox.h" #include #include "presentation/artifactfilterproxymodel.h" #include "presentation/metatypes.h" #include "presentation/querytreemodelbase.h" namespace Widgets { class PageTreeView : public QTreeView { public: using QTreeView::QTreeView; protected: void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE { if (event->key() == Qt::Key_Escape && state() != EditingState) { selectionModel()->clear(); } QTreeView::keyPressEvent(event); } }; } class PassivePopup : public QFrame { public: explicit PassivePopup(QWidget *parent = Q_NULLPTR) : QFrame(parent), m_hideTimer(new QTimer(this)), m_label(new QLabel(this)) { setWindowFlags(Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); setFrameStyle(QFrame::Box | QFrame::Plain); setLineWidth(2); setAttribute(Qt::WA_DeleteOnClose); setLayout(new QVBoxLayout); layout()->addWidget(m_label); connect(m_hideTimer, &QTimer::timeout, this, &QWidget::hide); } void setVisible(bool visible) Q_DECL_OVERRIDE { if (visible) { m_hideTimer->start(2000); } QFrame::setVisible(visible); } void setText(const QString &text) { m_label->setText(text); } private: QTimer *m_hideTimer; QLabel *m_label; }; using namespace Widgets; PageView::PageView(QWidget *parent) : QWidget(parent), m_cancelAction(new QAction(this)), m_model(Q_NULLPTR), m_filterWidget(new FilterWidget(this)), m_centralView(new PageTreeView(this)), m_quickAddEdit(new QLineEdit(this)) { - m_filterWidget->setObjectName("filterWidget"); + m_filterWidget->setObjectName(QStringLiteral("filterWidget")); - m_centralView->setObjectName("centralView"); + m_centralView->setObjectName(QStringLiteral("centralView")); m_centralView->header()->hide(); m_centralView->setAlternatingRowColors(true); m_centralView->setItemDelegate(new ItemDelegate(this)); m_centralView->setDragDropMode(QTreeView::DragDrop); m_centralView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_centralView->setModel(m_filterWidget->proxyModel()); m_centralView->installEventFilter(this); m_centralView->setItemsExpandable(false); m_centralView->setRootIsDecorated(false); connect(m_centralView->model(), &QAbstractItemModel::rowsInserted, m_centralView, &QTreeView::expandAll); connect(m_centralView->model(), &QAbstractItemModel::layoutChanged, m_centralView, &QTreeView::expandAll); connect(m_centralView->model(), &QAbstractItemModel::modelReset, m_centralView, &QTreeView::expandAll); - m_centralView->setStyleSheet( "QTreeView::branch { border-image: url(none.png); }" ); + m_centralView->setStyleSheet(QStringLiteral("QTreeView::branch { border-image: url(none.png); }")); - m_quickAddEdit->setObjectName("quickAddEdit"); + m_quickAddEdit->setObjectName(QStringLiteral("quickAddEdit")); m_quickAddEdit->setPlaceholderText(tr("Type and press enter to add an item")); connect(m_quickAddEdit, &QLineEdit::editingFinished, this, &PageView::onEditingFinished); auto layout = new QVBoxLayout; layout->addWidget(m_filterWidget); layout->addWidget(m_centralView); layout->addWidget(m_quickAddEdit); setLayout(layout); m_messageBoxInterface = MessageBox::Ptr::create(); auto addItemAction = new QAction(this); - addItemAction->setObjectName("addItemAction"); + addItemAction->setObjectName(QStringLiteral("addItemAction")); addItemAction->setText(tr("New item")); - addItemAction->setIcon(QIcon::fromTheme("list-add")); + addItemAction->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); addItemAction->setShortcut(Qt::CTRL | Qt::Key_N); connect(addItemAction, &QAction::triggered, this, &PageView::onAddItemRequested); - m_cancelAction->setObjectName("cancelAddItemAction"); + m_cancelAction->setObjectName(QStringLiteral("cancelAddItemAction")); m_cancelAction->setShortcut(Qt::Key_Escape); addAction(m_cancelAction); connect(m_cancelAction, &QAction::triggered, m_centralView, static_cast(&QWidget::setFocus)); auto removeItemAction = new QAction(this); - removeItemAction->setObjectName("removeItemAction"); + removeItemAction->setObjectName(QStringLiteral("removeItemAction")); removeItemAction->setText(tr("Remove item")); - removeItemAction->setIcon(QIcon::fromTheme("list-remove")); + removeItemAction->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); removeItemAction->setShortcut(Qt::Key_Delete); connect(removeItemAction, &QAction::triggered, this, &PageView::onRemoveItemRequested); addAction(removeItemAction); auto promoteItemAction = new QAction(this); - promoteItemAction->setObjectName("promoteItemAction"); + promoteItemAction->setObjectName(QStringLiteral("promoteItemAction")); promoteItemAction->setText(tr("Promote item as project")); promoteItemAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_P); connect(promoteItemAction, &QAction::triggered, this, &PageView::onPromoteItemRequested); auto filterViewAction = new QAction(this); - filterViewAction->setObjectName("filterViewAction"); + filterViewAction->setObjectName(QStringLiteral("filterViewAction")); filterViewAction->setText(tr("Filter...")); - filterViewAction->setIcon(QIcon::fromTheme("edit-find")); + filterViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-find"))); filterViewAction->setShortcut(Qt::CTRL | Qt::Key_F); connect(filterViewAction, &QAction::triggered, m_filterWidget, static_cast(&QWidget::setFocus)); - m_actions.insert("page_view_add", addItemAction); - m_actions.insert("page_view_remove", removeItemAction); - m_actions.insert("page_view_promote", promoteItemAction); - m_actions.insert("page_view_filter", filterViewAction); + m_actions.insert(QStringLiteral("page_view_add"), addItemAction); + m_actions.insert(QStringLiteral("page_view_remove"), removeItemAction); + m_actions.insert(QStringLiteral("page_view_promote"), promoteItemAction); + m_actions.insert(QStringLiteral("page_view_filter"), filterViewAction); } QHash PageView::globalActions() const { return m_actions; } QObject *PageView::model() const { return m_model; } void PageView::setModel(QObject *model) { if (model == m_model) return; if (m_centralView->selectionModel()) { disconnect(m_centralView->selectionModel(), Q_NULLPTR, this, Q_NULLPTR); } m_filterWidget->proxyModel()->setSourceModel(Q_NULLPTR); m_model = model; setEnabled(m_model); if (!m_model) return; QVariant modelProperty = m_model->property("centralListModel"); if (modelProperty.canConvert()) m_filterWidget->proxyModel()->setSourceModel(modelProperty.value()); connect(m_centralView->selectionModel(), &QItemSelectionModel::currentChanged, this, &PageView::onCurrentChanged); } MessageBoxInterface::Ptr PageView::messageBoxInterface() const { return m_messageBoxInterface; } QModelIndexList PageView::selectedIndexes() const { using namespace std::placeholders; const auto selection = m_centralView->selectionModel()->selectedIndexes(); auto sourceIndices = QModelIndexList(); std::transform(selection.constBegin(), selection.constEnd(), std::back_inserter(sourceIndices ), std::bind(&QSortFilterProxyModel::mapToSource, m_filterWidget->proxyModel(), _1)); return sourceIndices; } void PageView::setMessageBoxInterface(const MessageBoxInterface::Ptr &interface) { m_messageBoxInterface = interface; } void PageView::onEditingFinished() { if (m_quickAddEdit->text().isEmpty()) return; auto parentIndex = QModelIndex(); if (m_centralView->selectionModel()->selectedIndexes().size() == 1) parentIndex = m_centralView->selectionModel()->selectedIndexes().first(); QMetaObject::invokeMethod(m_model, "addItem", Q_ARG(QString, m_quickAddEdit->text()), Q_ARG(QModelIndex, parentIndex)); m_quickAddEdit->clear(); } void PageView::onAddItemRequested() { if (m_quickAddEdit->hasFocus()) return; const auto editTopLeft = m_quickAddEdit->geometry().topLeft(); const auto pos = mapToGlobal(editTopLeft); auto popup = new PassivePopup(m_quickAddEdit); popup->setText(tr("Type and press enter to add an item")); popup->show(); popup->move(pos - QPoint(0, popup->height())); m_quickAddEdit->selectAll(); m_quickAddEdit->setFocus(); } void PageView::onRemoveItemRequested() { const QModelIndexList ¤tIndexes = m_centralView->selectionModel()->selectedIndexes(); if (currentIndexes.isEmpty()) return; QString text; if (currentIndexes.size() > 1) { bool hasDescendants = false; foreach (const QModelIndex ¤tIndex, currentIndexes) { if (!currentIndex.isValid()) continue; if (currentIndex.model()->rowCount(currentIndex) > 0) { hasDescendants = true; break; } } if (hasDescendants) text = tr("Do you really want to delete the selected items and their children?"); else text = tr("Do you really want to delete the selected items?"); } else { const QModelIndex ¤tIndex = currentIndexes.first(); if (!currentIndex.isValid()) return; if (currentIndex.model()->rowCount(currentIndex) > 0) text = tr("Do you really want to delete the selected task and all its children?"); } if (!text.isEmpty()) { QMessageBox::Button button = m_messageBoxInterface->askConfirmation(this, tr("Delete Tasks"), text); bool canRemove = (button == QMessageBox::Yes); if (!canRemove) return; } foreach (const QModelIndex ¤tIndex, currentIndexes) { if (!currentIndex.isValid()) continue; QMetaObject::invokeMethod(m_model, "removeItem", Q_ARG(QModelIndex, currentIndex)); } } void PageView::onPromoteItemRequested() { QModelIndex currentIndex = m_centralView->currentIndex(); if (!currentIndex.isValid()) return; QMetaObject::invokeMethod(m_model, "promoteItem", Q_ARG(QModelIndex, currentIndex)); } void PageView::onCurrentChanged(const QModelIndex ¤t) { auto data = current.data(Presentation::QueryTreeModelBase::ObjectRole); if (!data.isValid()) return; auto artifact = data.value(); if (!artifact) return; emit currentArtifactChanged(artifact); } bool PageView::eventFilter(QObject *object, QEvent *event) { Q_ASSERT(object == m_centralView); switch(event->type()) { case QEvent::FocusIn: m_cancelAction->setEnabled(false); break; case QEvent::FocusOut: m_cancelAction->setEnabled(true); break; default: break; } return false; } diff --git a/src/widgets/quickselectdialog.cpp b/src/widgets/quickselectdialog.cpp index e1e04d24..b5539f66 100644 --- a/src/widgets/quickselectdialog.cpp +++ b/src/widgets/quickselectdialog.cpp @@ -1,128 +1,128 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2015 Franck Arrecot 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "quickselectdialog.h" #include #include #include #include #include #include #include #include using namespace Widgets; QuickSelectDialog::QuickSelectDialog(QWidget *parent) : QDialog(parent), m_model(Q_NULLPTR), m_filterProxyModel(new KRecursiveFilterProxyModel(this)), m_label(new QLabel(this)), m_tree(new QTreeView(this)) { setWindowTitle("Quick Select Dialog"); m_label->setText(tr("You can start typing to filter the list of available pages")); m_filterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_tree->setModel(m_filterProxyModel); - m_tree->setObjectName("pagesView"); + m_tree->setObjectName(QStringLiteral("pagesView")); m_tree->header()->hide(); m_tree->expandAll(); m_tree->setFocus(); m_tree->setSelectionMode(QAbstractItemView::SingleSelection); m_tree->setSortingEnabled(false); m_tree->installEventFilter(this); auto buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); auto mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_label); mainLayout->addWidget(m_tree); mainLayout->addWidget(buttonBox); connect(buttonBox, &QDialogButtonBox::accepted, this, &QuickSelectDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QuickSelectDialog::reject); } int QuickSelectDialog::exec() { return QDialog::exec(); } QPersistentModelIndex QuickSelectDialog::selectedIndex() const { QModelIndex selected = m_tree->currentIndex(); return m_filterProxyModel->mapToSource(selected); } void QuickSelectDialog::applyFilterChanged(const QString &textFilter) { if (textFilter.isEmpty()) m_label->setText(tr("You can start typing to filter the list of available pages")); else m_label->setText(QString("Path: %1").arg(textFilter)); m_filterProxyModel->setFilterFixedString(textFilter); m_tree->expandAll(); } bool QuickSelectDialog::eventFilter(QObject *, QEvent *ev) { if (ev->type() == QEvent::KeyPress) { auto event = static_cast(ev); auto filter = m_filterProxyModel->filterRegExp().pattern(); switch (event->key()) { case Qt::Key_Backspace: filter.chop(1); break; case Qt::Key_Delete: filter = QString(); break; default: if (event->text().contains(QRegExp("^(\\w| )+$"))) { filter += event->text(); } break; } applyFilterChanged(filter); } return false; } void QuickSelectDialog::setModel(QAbstractItemModel *model) { if (model == m_model) return; m_model = model; m_filterProxyModel->setSourceModel(m_model); m_tree->expandAll(); } diff --git a/src/zanshin/app/aboutdata.cpp b/src/zanshin/app/aboutdata.cpp index 0701e30f..3b80acba 100644 --- a/src/zanshin/app/aboutdata.cpp +++ b/src/zanshin/app/aboutdata.cpp @@ -1,49 +1,50 @@ /* This file is part of Zanshin Copyright 2011-2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "aboutdata.h" #include "../../appversion.h" #include + KAboutData App::getAboutData() { - KAboutData about("zanshin", - i18n("Zanshin Todo"), APPLICATION_VERSION, + KAboutData about(QStringLiteral("zanshin"), + i18n("Zanshin Todo"), QStringLiteral(APPLICATION_VERSION), i18n("A Getting Things Done application which aims at getting your mind like water"), KAboutLicense::GPL_V3, i18n("Copyright 2008-2016, Kevin Ottens ")); about.addAuthor(i18n("Kevin Ottens"), i18n("Lead Developer"), - "ervin@kde.org"); + QStringLiteral("ervin@kde.org")); about.addAuthor(i18n("Mario Bensi"), i18n("Developer"), - "nef@ipsquad.net"); + QStringLiteral("nef@ipsquad.net")); about.addAuthor(i18n("Franck Arrecot"), i18n("Developer"), - "franck.arrecot@gmail.com"); + QStringLiteral("franck.arrecot@gmail.com")); return about; } diff --git a/src/zanshin/app/main.cpp b/src/zanshin/app/main.cpp index ecae5a4c..db5c7bf7 100644 --- a/src/zanshin/app/main.cpp +++ b/src/zanshin/app/main.cpp @@ -1,123 +1,123 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "widgets/applicationcomponents.h" #include "widgets/availablepagesview.h" #include "widgets/availablesourcesview.h" #include "widgets/editorview.h" #include "widgets/pageview.h" #include "presentation/applicationmodel.h" #include "aboutdata.h" #include "dependencies.h" #include #include #include #include int main(int argc, char **argv) { QApplication app(argc, argv); // PORTING SCRIPT: move this to before the KAboutData initialization App::initializeDependencies(); auto aboutData = App::getAboutData(); QCommandLineParser parser; KAboutData::setApplicationData(aboutData); parser.addVersionOption(); parser.addHelpOption(); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); - KSharedConfig::Ptr config = KSharedConfig::openConfig("zanshin-migratorrc"); + KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("zanshin-migratorrc")); KConfigGroup group = config->group("Migrations"); if (!group.readEntry("Migrated021Projects", false)) { std::cerr << "Migrating data from zanshin 0.2, please wait..." << std::endl; QProcess proc; - proc.start("zanshin-migrator"); + proc.start(QStringLiteral("zanshin-migrator")); proc.waitForFinished(); std::cerr << "Migration done" << std::endl; } auto widget = new QWidget; auto components = new Widgets::ApplicationComponents(widget); components->setModel(Presentation::ApplicationModel::Ptr::create()); auto layout = new QVBoxLayout; layout->addWidget(components->pageView()); widget->setLayout(layout); auto sourcesDock = new QDockWidget(QObject::tr("Sources")); - sourcesDock->setObjectName("sourcesDock"); + sourcesDock->setObjectName(QStringLiteral("sourcesDock")); sourcesDock->setWidget(components->availableSourcesView()); auto pagesDock = new QDockWidget(QObject::tr("Pages")); - pagesDock->setObjectName("pagesDock"); + pagesDock->setObjectName(QStringLiteral("pagesDock")); pagesDock->setWidget(components->availablePagesView()); auto editorDock = new QDockWidget(QObject::tr("Editor")); - editorDock->setObjectName("editorDock"); + editorDock->setObjectName(QStringLiteral("editorDock")); editorDock->setWidget(components->editorView()); auto window = new KXmlGuiWindow; window->setCentralWidget(widget); window->addDockWidget(Qt::RightDockWidgetArea, editorDock); window->addDockWidget(Qt::LeftDockWidgetArea, pagesDock); window->addDockWidget(Qt::LeftDockWidgetArea, sourcesDock); auto actions = components->globalActions(); - actions.insert("dock_sources", sourcesDock->toggleViewAction()); - actions.insert("dock_pages", pagesDock->toggleViewAction()); - actions.insert("dock_editor", editorDock->toggleViewAction()); + actions.insert(QStringLiteral("dock_sources"), sourcesDock->toggleViewAction()); + actions.insert(QStringLiteral("dock_pages"), pagesDock->toggleViewAction()); + actions.insert(QStringLiteral("dock_editor"), editorDock->toggleViewAction()); auto ac = window->actionCollection(); ac->addAction(KStandardAction::Quit, window, SLOT(close())); for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) { ac->addAction(it.key(), it.value()); } window->setupGUI(QSize(1024, 600), KXmlGuiWindow::ToolBar | KXmlGuiWindow::Keys | KXmlGuiWindow::Save | KXmlGuiWindow::Create); window->show(); return app.exec(); } diff --git a/src/zanshin/kontact/part.cpp b/src/zanshin/kontact/part.cpp index 8f7e19dc..0a3423a2 100644 --- a/src/zanshin/kontact/part.cpp +++ b/src/zanshin/kontact/part.cpp @@ -1,88 +1,88 @@ /* This file is part of Zanshin Todo. Copyright 2011 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "part.h" #include #include #include #include #include #include #include "../app/aboutdata.h" #include "../app/dependencies.h" #include "presentation/applicationmodel.h" #include "widgets/applicationcomponents.h" #include "widgets/availablepagesview.h" #include "widgets/availablesourcesview.h" #include "widgets/editorview.h" #include "widgets/pageview.h" #include "utils/dependencymanager.h" K_PLUGIN_FACTORY(PartFactory, registerPlugin();) Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList &) : KParts::ReadOnlyPart(parent) { App::initializeDependencies(); setComponentName(QStringLiteral("zanshin"), QStringLiteral("zanshin")); auto splitter = new QSplitter(parentWidget); auto sidebar = new QSplitter(Qt::Vertical, parentWidget); auto components = new Widgets::ApplicationComponents(parentWidget); components->setModel(Presentation::ApplicationModel::Ptr::create()); sidebar->addWidget(components->availablePagesView()); sidebar->addWidget(components->availableSourcesView()); splitter->addWidget(sidebar); splitter->addWidget(components->pageView()); splitter->addWidget(components->editorView()); setWidget(splitter); auto actions = components->globalActions(); auto ac = actionCollection(); for (auto it = actions.constBegin(); it != actions.constEnd(); ++it) { ac->addAction(it.key(), it.value()); } - setXMLFile(KStandardDirs::locate("data", "zanshin/zanshin_part.rc")); + setXMLFile(KStandardDirs::locate("data", QStringLiteral("zanshin/zanshin_part.rc"))); } Part::~Part() { } bool Part::openFile() { return false; } #include "part.moc" diff --git a/src/zanshin/migrator/main.cpp b/src/zanshin/migrator/main.cpp index b42bcdb7..24b7ae67 100644 --- a/src/zanshin/migrator/main.cpp +++ b/src/zanshin/migrator/main.cpp @@ -1,51 +1,51 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 David Faure 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "zanshin021migrator.h" int main(int argc, char **argv) { QApplication app(argc, argv); // Qt5 TODO use QCommandLineParser const bool force = (argc > 1 && QByteArray(argv[1]) == "--force"); Zanshin021Migrator migrator; - KSharedConfig::Ptr config = KSharedConfig::openConfig("zanshin-migratorrc"); + KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("zanshin-migratorrc")); KConfigGroup group = config->group("Migrations"); if (force || !group.readEntry("Migrated021Projects", false)) { if (!migrator.migrateProjects()) { return 1; } group.writeEntry("Migrated021Projects", true); } config->sync(); return 0; }; diff --git a/src/zanshin/migrator/zanshin021migrator.cpp b/src/zanshin/migrator/zanshin021migrator.cpp index 5cce2921..c6bc14ad 100644 --- a/src/zanshin/migrator/zanshin021migrator.cpp +++ b/src/zanshin/migrator/zanshin021migrator.cpp @@ -1,115 +1,115 @@ /* This file is part of Zanshin Copyright 2014 David Faure 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "zanshin021migrator.h" #include #include #include #include #include #include Zanshin021Migrator::Zanshin021Migrator() { } bool Zanshin021Migrator::isProject(const Akonadi::Item& item) { // same as Serializer::isProject, but we don't need the serializer here... return item.hasPayload() && !item.payload()->customProperty("Zanshin", "Project").isEmpty(); } Zanshin021Migrator::SeenItemHash Zanshin021Migrator::fetchAllItems() { SeenItemHash hash; auto collectionsJob = m_storage.fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::StorageInterface::Tasks); collectionsJob->kjob()->exec(); auto collections = collectionsJob->collections(); for (const auto &collection : collections) { auto job = m_storage.fetchItems(collection); job->kjob()->exec(); auto items = job->items(); for (const Akonadi::Item &item : items) { if (item.hasPayload()) { auto todo = item.payload(); hash.insert(todo->uid(), SeenItem(item)); } } } return hash; } void Zanshin021Migrator::markAsProject(SeenItem& seenItem, Akonadi::TransactionSequence* sequence) { Akonadi::Item &item = seenItem.item(); if (!isProject(item)) { auto todo = item.payload(); - todo->setCustomProperty("Zanshin", "Project", "1"); + todo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); item.setPayload(todo); seenItem.setDirty(); qDebug() << "Marking as project:" << item.id() << item.remoteId() << todo->summary(); new Akonadi::ItemModifyJob(item, sequence); } } void Zanshin021Migrator::migrateProjectComments(Zanshin021Migrator::SeenItemHash& items, Akonadi::TransactionSequence* sequence) { for (SeenItemHash::iterator it = items.begin(); it != items.end(); ++it) { SeenItem &seenItem = it.value(); Akonadi::Item &item = seenItem.item(); auto todo = item.payload(); - if (todo->comments().contains("X-Zanshin-Project")) + if (todo->comments().contains(QStringLiteral("X-Zanshin-Project"))) markAsProject(seenItem, sequence); } } void Zanshin021Migrator::migrateProjectWithChildren(Zanshin021Migrator::SeenItemHash& items, Akonadi::TransactionSequence* sequence) { for (SeenItemHash::iterator it = items.begin(); it != items.end(); ++it) { const SeenItem &seenItem = it.value(); const auto todo = seenItem.item().payload(); const QString parentUid = todo->relatedTo(); if (!parentUid.isEmpty()) { auto parentIt = items.find(parentUid); if (parentIt != items.end()) markAsProject(*parentIt, sequence); } } } bool Zanshin021Migrator::migrateProjects() { SeenItemHash items = fetchAllItems(); auto sequence = new Akonadi::TransactionSequence; migrateProjectComments(items, sequence); migrateProjectWithChildren(items, sequence); return sequence->exec(); } diff --git a/src/zanshin/runner/zanshinrunner.cpp b/src/zanshin/runner/zanshinrunner.cpp index 7dfb9ef2..56d78510 100644 --- a/src/zanshin/runner/zanshinrunner.cpp +++ b/src/zanshin/runner/zanshinrunner.cpp @@ -1,93 +1,93 @@ /* This file is part of Zanshin Todo. Copyright 2011 Kevin Ottens Copyright 2014 Mario Bensi 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "zanshinrunner.h" #include "domain/task.h" #include "akonadi/akonaditaskrepository.h" #include "akonadi/akonadiserializer.h" #include "akonadi/akonadistorage.h" #include K_EXPORT_PLASMA_RUNNER(zanshin, ZanshinRunner) Domain::TaskRepository::Ptr createTaskRepository() { using namespace Akonadi; auto repository = new TaskRepository(StorageInterface::Ptr(new Storage), SerializerInterface::Ptr(new Serializer), MessagingInterface::Ptr()); return Domain::TaskRepository::Ptr(repository); } ZanshinRunner::ZanshinRunner(QObject *parent, const QVariantList &args) : Plasma::AbstractRunner(parent, args), m_taskRepository(createTaskRepository()) { - setObjectName(QLatin1String("Zanshin")); + setObjectName(QStringLiteral("Zanshin")); setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Help); } ZanshinRunner::~ZanshinRunner() { } void ZanshinRunner::match(Plasma::RunnerContext &context) { const QString command = context.query().trimmed(); - if (!command.startsWith("todo:", Qt::CaseInsensitive)) { + if (!command.startsWith(QStringLiteral("todo:"), Qt::CaseInsensitive)) { return; } const QString summary = command.mid(5).trimmed(); if (summary.isEmpty()) { return; } QList matches; Plasma::QueryMatch match(this); match.setData(summary); match.setType(Plasma::QueryMatch::ExactMatch); - match.setIcon(QIcon::fromTheme("zanshin")); + match.setIcon(QIcon::fromTheme(QStringLiteral("zanshin"))); match.setText(tr("Add \"%1\" to your todo list").arg(summary)); match.setRelevance(1.0); matches << match; context.addMatches(matches); } void ZanshinRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) { Q_UNUSED(context) auto task = Domain::Task::Ptr::create(); task->setTitle(match.data().toString()); m_taskRepository->create(task); } #include "zanshinrunner.moc" diff --git a/tests/benchmarks/serializerTest.cpp b/tests/benchmarks/serializerTest.cpp index dc2d5243..c30177a6 100644 --- a/tests/benchmarks/serializerTest.cpp +++ b/tests/benchmarks/serializerTest.cpp @@ -1,114 +1,114 @@ /* This file is part of Zanshin Copyright 2014 Bensi Mario 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "domain/task.h" #include "akonadi/akonadiserializer.h" class SerializerBenchmark : public QObject { Q_OBJECT Akonadi::Item createTestItem(); private slots: void deserialize(); void checkPayloadAndDeserialize(); void deserializeAndDestroy(); void checkPayload(); }; Akonadi::Item SerializerBenchmark::createTestItem() { KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("summary"); - todo->setDescription("content"); + todo->setSummary(QStringLiteral("summary")); + todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDateTime(QDate(2013, 11, 24)))); todo->setDtDue(KDateTime(QDateTime(QDate(2014, 03, 01)))); - todo->setRelatedTo("5"); + todo->setRelatedTo(QStringLiteral("5")); // ... as payload of an item Akonadi::Item item; - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); return item; } void SerializerBenchmark::deserialize() { Akonadi::Item item = createTestItem(); Akonadi::Serializer serializer; Domain::Task::Ptr task(new Domain::Task); QBENCHMARK { task = serializer.createTaskFromItem(item); } } void SerializerBenchmark::checkPayloadAndDeserialize() { Akonadi::Item item = createTestItem(); Akonadi::Serializer serializer; Domain::Task::Ptr task(new Domain::Task); QBENCHMARK { if (!item.hasPayload()) return; auto todoCheck = item.payload(); - if (todoCheck->relatedTo() != "5") { + if (todoCheck->relatedTo() != QLatin1String("5")) { return; } task = serializer.createTaskFromItem(item); } } void SerializerBenchmark::deserializeAndDestroy() { Akonadi::Item item = createTestItem(); Akonadi::Serializer serializer; QBENCHMARK { auto task = serializer.createTaskFromItem(item); } } void SerializerBenchmark::checkPayload() { Akonadi::Item item = createTestItem(); QBENCHMARK { if (!item.hasPayload()) return; auto todoCheck = item.payload(); - if (todoCheck->relatedTo() != "5") { + if (todoCheck->relatedTo() != QLatin1String("5")) { return; } } } ZANSHIN_TEST_MAIN(SerializerBenchmark) #include "serializerTest.moc" diff --git a/tests/features/cuke-steps.cpp b/tests/features/cuke-steps.cpp index 512bf8a4..40ba7880 100644 --- a/tests/features/cuke-steps.cpp +++ b/tests/features/cuke-steps.cpp @@ -1,868 +1,868 @@ /* This file is part of Zanshin Copyright 2014-2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "presentation/applicationmodel.h" #include "presentation/errorhandler.h" #include "presentation/querytreemodelbase.h" #include "akonadi/akonadimonitorimpl.h" #include "akonadi/akonadimessaginginterface.h" #include "utils/dependencymanager.h" #include "utils/jobhandler.h" #include "testlib/akonadifakedata.h" #include "testlib/akonadifakedataxmlloader.h" #include "testlib/monitorspy.h" #include "testlib/testsafety.h" static int argc = 1; static char *argv0 = "cuke-steps"; static QApplication app(argc, &argv0); namespace CukeSteps { void initializeAppDependencies(); } namespace cucumber { namespace internal { template<> inline QString fromString(const std::string& s) { return QString::fromUtf8(s.data()); } } } using namespace cucumber; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &) { } }; class ZanshinContext : public QObject { Q_OBJECT public: explicit ZanshinContext(QObject *parent = Q_NULLPTR) : QObject(parent), app(Q_NULLPTR), presentation(Q_NULLPTR), editor(Q_NULLPTR), proxyModel(new QSortFilterProxyModel(this)), m_model(Q_NULLPTR), m_sourceModel(Q_NULLPTR), monitorSpy(Q_NULLPTR) { qputenv("ZANSHIN_OVERRIDE_DATETIME", "2015-03-10"); static bool initializedDependencies = false; if (!initializedDependencies) { CukeSteps::initializeAppDependencies(); QString xmlFile = QString::fromLocal8Bit(qgetenv("ZANSHIN_USER_XMLDATA")); if (!xmlFile.isEmpty()) { auto searchCollection = Akonadi::Collection(1); searchCollection.setParentCollection(Akonadi::Collection::root()); - searchCollection.setName("Search"); + searchCollection.setName(QStringLiteral("Search")); m_data.createCollection(searchCollection); MonitorSpy::setExpirationDelay(200); auto loader = Testlib::AkonadiFakeDataXmlLoader(&m_data); loader.load(xmlFile); // Swap regular dependencies for the fake data ones auto &deps = Utils::DependencyManager::globalInstance(); deps.add( [this] (Utils::DependencyManager *) { return m_data.createMonitor(); } ); deps.add( [this] (Utils::DependencyManager *) { return m_data.createStorage(); } ); deps.add( [this] (Utils::DependencyManager *) -> Akonadi::MessagingInterface* { return Q_NULLPTR; } ); } else if (!TestLib::TestSafety::checkTestIsIsolated()) { qDebug() << "FATAL ERROR! SEE ABOVE\n\n"; exit(1); } initializedDependencies = true; } using namespace Presentation; proxyModel->setDynamicSortFilter(true); auto appModel = ApplicationModel::Ptr::create(); appModel->setErrorHandler(&m_errorHandler); app = appModel; auto monitor = Utils::DependencyManager::globalInstance().create(); monitorSpy = new MonitorSpy(monitor.data(), this); } ~ZanshinContext() { } void setModel(QAbstractItemModel *model) { m_sourceModel = model; if (!qobject_cast(model)) { - proxyModel->setObjectName("m_proxyModel_in_ZanshinContext"); + proxyModel->setObjectName(QStringLiteral("m_proxyModel_in_ZanshinContext")); proxyModel->setSourceModel(model); proxyModel->setSortRole(Qt::DisplayRole); proxyModel->sort(0); m_model = proxyModel; } else { m_model = model; } } QAbstractItemModel *sourceModel() { return m_sourceModel; } QAbstractItemModel *model() { return m_model; } void waitForEmptyJobQueue() { while (Utils::JobHandler::jobCount() != 0) { QTest::qWait(20); } } void waitForStableState() { waitForEmptyJobQueue(); monitorSpy->waitForStableState(); } QObjectPtr app; QList indices; QPersistentModelIndex index; QObject *presentation; QObject *editor; QList dragIndices; private: static Testlib::AkonadiFakeData m_data; QSortFilterProxyModel *proxyModel; QAbstractItemModel *m_model; QAbstractItemModel *m_sourceModel; MonitorSpy *monitorSpy; FakeErrorHandler m_errorHandler; }; Testlib::AkonadiFakeData ZanshinContext::m_data = {}; namespace Zanshin { QString indexString(const QModelIndex &index, int role = Qt::DisplayRole) { if (role != Qt::DisplayRole) return index.data(role).toString(); QString data = index.data(role).toString(); if (index.parent().isValid()) return indexString(index.parent(), role) + " / " + data; else return data; } QModelIndex findIndex(QAbstractItemModel *model, const QString &string, int role = Qt::DisplayRole, const QModelIndex &root = QModelIndex()) { for (int row = 0; row < model->rowCount(root); row++) { const QModelIndex index = model->index(row, 0, root); if (indexString(index, role) == string) return index; if (model->rowCount(index) > 0) { const QModelIndex found = findIndex(model, string, role, index); if (found.isValid()) return found; } } return QModelIndex(); } void collectIndices(ZanshinContext *context, const QModelIndex &root = QModelIndex()) { QAbstractItemModel *model = context->model(); for (int row = 0; row < model->rowCount(root); row++) { const QModelIndex index = model->index(row, 0, root); context->indices << index; if (model->rowCount(index) > 0) collectIndices(context, index); } } void dumpIndices(const QList &indices) { qDebug() << "Dumping list of size:" << indices.size(); for (int row = 0; row < indices.size(); row++) { qDebug() << row << indexString(indices.at(row)); } } inline bool verify(bool statement, const char *str, const char *file, int line) { if (statement) return true; qDebug() << "Statement" << str << "returned FALSE"; qDebug() << "Loc:" << file << line; return false; } template inline bool compare(T const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line) { if (t1 == t2) return true; qDebug() << "Compared values are not the same"; qDebug() << "Actual (" << actual << ") :" << QTest::toString(t1); qDebug() << "Expected (" << expected << ") :" << QTest::toString(t2); qDebug() << "Loc:" << file << line; return false; } } // namespace Zanshin #define COMPARE(actual, expected) \ do {\ if (!Zanshin::compare(actual, expected, #actual, #expected, __FILE__, __LINE__))\ BOOST_REQUIRE(false);\ } while (0) #define COMPARE_OR_DUMP(actual, expected) \ do {\ if (!Zanshin::compare(actual, expected, #actual, #expected, __FILE__, __LINE__)) {\ Zanshin::dumpIndices(context->indices); \ BOOST_REQUIRE(false);\ }\ } while (0) #define VERIFY(statement) \ do {\ if (!Zanshin::verify((statement), #statement, __FILE__, __LINE__))\ BOOST_REQUIRE(false);\ } while (0) #define VERIFY_OR_DUMP(statement) \ do {\ if (!Zanshin::verify((statement), #statement, __FILE__, __LINE__)) {\ Zanshin::dumpIndices(context->indices); \ BOOST_REQUIRE(false);\ }\ } while (0) GIVEN("^I display the available data sources$") { ScenarioScope context; auto availableSources = context->app->property("availableSources").value(); VERIFY(availableSources); auto sourceListModel = availableSources->property("sourceListModel").value(); VERIFY(sourceListModel); context->presentation = availableSources; context->setModel(sourceListModel); } GIVEN("^I display the available pages$") { ScenarioScope context; context->presentation = context->app->property("availablePages").value(); context->setModel(context->presentation->property("pageListModel").value()); } GIVEN("^I display the \"(.*)\" page$") { REGEX_PARAM(QString, pageName); ScenarioScope context; auto availablePages = context->app->property("availablePages").value(); VERIFY(availablePages); auto pageListModel = availablePages->property("pageListModel").value(); VERIFY(pageListModel); context->waitForEmptyJobQueue(); QModelIndex pageIndex = Zanshin::findIndex(pageListModel, pageName); VERIFY(pageIndex.isValid()); QObject *page = Q_NULLPTR; QMetaObject::invokeMethod(availablePages, "createPageForIndex", Q_RETURN_ARG(QObject*, page), Q_ARG(QModelIndex, pageIndex)); VERIFY(page); VERIFY(context->app->setProperty("currentPage", QVariant::fromValue(page))); context->presentation = context->app->property("currentPage").value(); } GIVEN("^there is an item named \"(.+)\" in the central list$") { REGEX_PARAM(QString, itemName); ScenarioScope context; auto model = context->presentation->property("centralListModel").value(); context->setModel(model); context->waitForEmptyJobQueue(); context->index = Zanshin::findIndex(context->model(), itemName); VERIFY_OR_DUMP(context->index.isValid()); } GIVEN("^there is an item named \"(.+)\" in the available data sources$") { REGEX_PARAM(QString, itemName); ScenarioScope context; auto availableSources = context->app->property("availableSources").value(); VERIFY(availableSources); auto model = availableSources->property("sourceListModel").value(); VERIFY(model); context->waitForEmptyJobQueue(); context->setModel(model); context->index = Zanshin::findIndex(context->model(), itemName); VERIFY_OR_DUMP(context->index.isValid()); } GIVEN("^the central list contains items named:") { TABLE_PARAM(tableParam); ScenarioScope context; context->dragIndices.clear(); auto model = context->presentation->property("centralListModel").value(); context->waitForEmptyJobQueue(); context->setModel(model); for (const auto row : tableParam.hashes()) { for (const auto it : row) { const QString itemName = QString::fromUtf8(it.second.data()); QModelIndex index = Zanshin::findIndex(context->model(), itemName); VERIFY_OR_DUMP(index.isValid()); context->dragIndices << index; } } } WHEN("^I look at the central list$") { ScenarioScope context; auto model = context->presentation->property("centralListModel").value(); context->setModel(model); context->waitForStableState(); } WHEN("^I check the item$") { ScenarioScope context; VERIFY(context->model()->setData(context->index, Qt::Checked, Qt::CheckStateRole)); context->waitForStableState(); } WHEN("^I uncheck the item$") { ScenarioScope context; VERIFY(context->model()->setData(context->index, Qt::Unchecked, Qt::CheckStateRole)); context->waitForStableState(); } WHEN("^I remove the item$") { ScenarioScope context; VERIFY(QMetaObject::invokeMethod(context->presentation, "removeItem", Q_ARG(QModelIndex, context->index))); context->waitForStableState(); } WHEN("^I promote the item$") { ScenarioScope context; VERIFY(QMetaObject::invokeMethod(context->presentation, "promoteItem", Q_ARG(QModelIndex, context->index))); context->waitForStableState(); } WHEN("^I add a project named \"(.*)\" in the source named \"(.*)\"$") { REGEX_PARAM(QString, projectName); REGEX_PARAM(QString, sourceName); ScenarioScope context; auto availableSources = context->app->property("availableSources").value(); VERIFY(availableSources); auto sourceList = availableSources->property("sourceListModel").value(); VERIFY(sourceList); context->waitForStableState(); QModelIndex index = Zanshin::findIndex(sourceList, sourceName); VERIFY(index.isValid()); auto source = index.data(Presentation::QueryTreeModelBase::ObjectRole) .value(); VERIFY(source); VERIFY(QMetaObject::invokeMethod(context->presentation, "addProject", Q_ARG(QString, projectName), Q_ARG(Domain::DataSource::Ptr, source))); context->waitForStableState(); } WHEN("^I rename a \"(.*)\" named \"(.*)\" to \"(.*)\"$") { REGEX_PARAM(QString, objectType); REGEX_PARAM(QString, oldName); REGEX_PARAM(QString, newName); - const QString pageNodeName = (objectType == "project") ? "Projects / " - : (objectType == "context") ? "Contexts / " + const QString pageNodeName = (objectType == QStringLiteral("project")) ? QStringLiteral("Projects / ") + : (objectType == QStringLiteral("context")) ? QStringLiteral("Contexts / ") : QString(); VERIFY(!pageNodeName.isEmpty()); ScenarioScope context; auto availablePages = context->app->property("availablePages").value(); VERIFY(availablePages); auto pageListModel = availablePages->property("pageListModel").value(); VERIFY(pageListModel); context->waitForStableState(); QModelIndex pageIndex = Zanshin::findIndex(pageListModel, pageNodeName + oldName); VERIFY(pageIndex.isValid()); pageListModel->setData(pageIndex, newName); context->waitForStableState(); } WHEN("^I remove a \"(.*)\" named \"(.*)\"$") { REGEX_PARAM(QString, objectType); REGEX_PARAM(QString, objectName); - const QString pageNodeName = (objectType == "project") ? "Projects / " - : (objectType == "context") ? "Contexts / " - : (objectType == "tag") ? "Tags / " + const QString pageNodeName = (objectType == QStringLiteral("project")) ? QStringLiteral("Projects / ") + : (objectType == QStringLiteral("context")) ? QStringLiteral("Contexts / ") + : (objectType == QStringLiteral("tag")) ? QStringLiteral("Tags / ") : QString(); VERIFY(!pageNodeName.isEmpty()); ScenarioScope context; auto availablePages = context->app->property("availablePages").value(); VERIFY(availablePages); auto pageListModel = availablePages->property("pageListModel").value(); VERIFY(pageListModel); context->waitForStableState(); QModelIndex pageIndex = Zanshin::findIndex(pageListModel, pageNodeName + objectName); VERIFY(pageIndex.isValid()); VERIFY(QMetaObject::invokeMethod(availablePages, "removeItem", Q_ARG(QModelIndex, pageIndex))); context->waitForStableState(); } WHEN("^I add a \"(.*)\" named \"(.+)\"$") { REGEX_PARAM(QString, objectType); REGEX_PARAM(QString, objectName); - QByteArray actionName = (objectType == "context") ? "addContext" - : (objectType == "note") ? "addItem" - : (objectType == "task") ? "addItem" - : (objectType == "tag") ? "addTag" + QByteArray actionName = (objectType == QStringLiteral("context")) ? "addContext" + : (objectType == QStringLiteral("note")) ? "addItem" + : (objectType == QStringLiteral("task")) ? "addItem" + : (objectType == QStringLiteral("tag")) ? "addTag" : QByteArray(); VERIFY(!actionName.isEmpty()); ScenarioScope context; context->waitForStableState(); VERIFY(QMetaObject::invokeMethod(context->presentation, actionName.data(), Q_ARG(QString, objectName))); context->waitForStableState(); } WHEN("^I add a child named \"(.+)\" under the task named \"(.+)\"$") { REGEX_PARAM(QString, childName); REGEX_PARAM(QString, parentName); ScenarioScope context; context->waitForStableState(); auto parentIndex = QModelIndex(); for (int row = 0; row < context->indices.size(); row++) { auto index = context->indices.at(row); if (Zanshin::indexString(index) == parentName) { parentIndex = index; break; } } VERIFY_OR_DUMP(parentIndex.isValid()); VERIFY(QMetaObject::invokeMethod(context->presentation, "addItem", Q_ARG(QString, childName), Q_ARG(QModelIndex, parentIndex))); context->waitForStableState(); } WHEN("^I list the items$") { ScenarioScope context; context->waitForStableState(); context->indices.clear(); Zanshin::collectIndices(context.get()); context->waitForStableState(); } WHEN("^I open the item in the editor$") { ScenarioScope context; auto artifact = context->index.data(Presentation::QueryTreeModelBase::ObjectRole) .value(); VERIFY(artifact); context->editor = context->app->property("editor").value(); VERIFY(context->editor); VERIFY(context->editor->setProperty("artifact", QVariant::fromValue(artifact))); } WHEN("^I mark it done in the editor$") { ScenarioScope context; VERIFY(context->editor->setProperty("done", true)); } WHEN("^I change the editor (.*) to \"(.*)\"$") { REGEX_PARAM(QString, field); REGEX_PARAM(QString, string); - const QVariant value = (field == "text") ? string - : (field == "title") ? string - : (field == "start date") ? QDateTime::fromString(string, Qt::ISODate) - : (field == "due date") ? QDateTime::fromString(string, Qt::ISODate) + const QVariant value = (field == QStringLiteral("text")) ? string + : (field == QStringLiteral("title")) ? string + : (field == QStringLiteral("start date")) ? QDateTime::fromString(string, Qt::ISODate) + : (field == QStringLiteral("due date")) ? QDateTime::fromString(string, Qt::ISODate) : QVariant(); - const QByteArray property = (field == "text") ? field.toUtf8() - : (field == "title") ? field.toUtf8() - : (field == "start date") ? "startDate" - : (field == "due date") ? "dueDate" + const QByteArray property = (field == QStringLiteral("text")) ? field.toUtf8() + : (field == QStringLiteral("title")) ? field.toUtf8() + : (field == QStringLiteral("start date")) ? "startDate" + : (field == QStringLiteral("due date")) ? "dueDate" : QByteArray(); VERIFY(value.isValid()); VERIFY(!property.isEmpty()); ScenarioScope context; VERIFY(context->editor->setProperty(property, value)); } WHEN("^I open the item in the editor again$") { ScenarioScope context; auto artifact = context->index.data(Presentation::QueryTreeModelBase::ObjectRole) .value(); VERIFY(artifact); VERIFY(context->editor->setProperty("artifact", QVariant::fromValue(Domain::Artifact::Ptr()))); VERIFY(context->editor->setProperty("artifact", QVariant::fromValue(artifact))); context->waitForStableState(); } WHEN("^I drop the item on \"(.*)\" in the central list") { REGEX_PARAM(QString, itemName); ScenarioScope context; VERIFY(context->index.isValid()); const QMimeData *data = context->model()->mimeData(QModelIndexList() << context->index); QAbstractItemModel *destModel = context->model(); QModelIndex dropIndex = Zanshin::findIndex(destModel, itemName); VERIFY(dropIndex.isValid()); VERIFY(destModel->dropMimeData(data, Qt::MoveAction, -1, -1, dropIndex)); context->waitForStableState(); } WHEN("^I drop the item on the blank area of the central list") { ScenarioScope context; VERIFY(context->index.isValid()); const QMimeData *data = context->model()->mimeData(QModelIndexList() << context->index); QAbstractItemModel *destModel = context->model(); VERIFY(destModel->dropMimeData(data, Qt::MoveAction, -1, -1, QModelIndex())); context->waitForStableState(); } WHEN("^I drop items on \"(.*)\" in the central list") { REGEX_PARAM(QString, itemName); ScenarioScope context; VERIFY(!context->dragIndices.isEmpty()); QModelIndexList indexes; std::transform(context->dragIndices.constBegin(), context->dragIndices.constEnd(), std::back_inserter(indexes), [] (const QPersistentModelIndex &index) { VERIFY(index.isValid()); return index; }); const QMimeData *data = context->model()->mimeData(indexes); QAbstractItemModel *destModel = context->model(); QModelIndex dropIndex = Zanshin::findIndex(destModel, itemName); VERIFY(dropIndex.isValid()); VERIFY(destModel->dropMimeData(data, Qt::MoveAction, -1, -1, dropIndex)); context->waitForStableState(); } WHEN("^I drop the item on \"(.*)\" in the page list") { REGEX_PARAM(QString, itemName); ScenarioScope context; VERIFY(context->index.isValid()); const QMimeData *data = context->model()->mimeData(QModelIndexList() << context->index); auto availablePages = context->app->property("availablePages").value(); VERIFY(availablePages); auto destModel = availablePages->property("pageListModel").value(); VERIFY(destModel); context->waitForStableState(); QModelIndex dropIndex = Zanshin::findIndex(destModel, itemName); VERIFY(dropIndex.isValid()); VERIFY(destModel->dropMimeData(data, Qt::MoveAction, -1, -1, dropIndex)); context->waitForStableState(); } WHEN("^I drop items on \"(.*)\" in the page list") { REGEX_PARAM(QString, itemName); ScenarioScope context; VERIFY(!context->dragIndices.isEmpty()); QModelIndexList indexes; std::transform(context->dragIndices.constBegin(), context->dragIndices.constEnd(), std::back_inserter(indexes), [] (const QPersistentModelIndex &index) { VERIFY(index.isValid()); return index; }); const QMimeData *data = context->model()->mimeData(indexes); auto availablePages = context->app->property("availablePages").value(); VERIFY(availablePages); auto destModel = availablePages->property("pageListModel").value(); VERIFY(destModel); context->waitForStableState(); QModelIndex dropIndex = Zanshin::findIndex(destModel, itemName); VERIFY(dropIndex.isValid()); VERIFY(destModel->dropMimeData(data, Qt::MoveAction, -1, -1, dropIndex)); context->waitForStableState(); } WHEN("^the setting key (\\S+) changes to (\\d+)$") { REGEX_PARAM(QString, keyName); REGEX_PARAM(qint64, id); ScenarioScope context; KConfigGroup config(KSharedConfig::openConfig(), "General"); config.writeEntry(keyName, id); } WHEN("^the user changes the default data source to \"(.*)\"$") { REGEX_PARAM(QString, sourceName); ScenarioScope context; context->waitForStableState(); auto sourceIndex = Zanshin::findIndex(context->model(), sourceName); auto availableSources = context->app->property("availableSources").value(); VERIFY(availableSources); VERIFY(QMetaObject::invokeMethod(availableSources, "setDefaultItem", Q_ARG(QModelIndex, sourceIndex))); context->waitForStableState(); } THEN("^the list is") { TABLE_PARAM(tableParam); ScenarioScope context; auto roleNames = context->model()->roleNames(); QSet usedRoles; QStandardItemModel inputModel; for (const auto row : tableParam.hashes()) { QStandardItem *item = new QStandardItem; for (const auto it : row) { const QByteArray roleName = it.first.data(); const QString value = QString::fromUtf8(it.second.data()); const int role = roleNames.key(roleName, -1); VERIFY_OR_DUMP(role != -1); item->setData(value, role); usedRoles.insert(role); } inputModel.appendRow(item); } QSortFilterProxyModel proxy; QAbstractItemModel *referenceModel; if (!qobject_cast(context->sourceModel())) { referenceModel = &proxy; proxy.setSourceModel(&inputModel); proxy.setSortRole(Qt::DisplayRole); proxy.sort(0); - proxy.setObjectName("the_list_is_proxy"); + proxy.setObjectName(QStringLiteral("the_list_is_proxy")); } else { referenceModel = &inputModel; } for (int row = 0; row < context->indices.size(); row++) { QModelIndex expectedIndex = referenceModel->index(row, 0); QModelIndex resultIndex = context->indices.at(row); for (auto role : usedRoles) { COMPARE_OR_DUMP(Zanshin::indexString(resultIndex, role), Zanshin::indexString(expectedIndex, role)); } } COMPARE_OR_DUMP(context->indices.size(), referenceModel->rowCount()); } THEN("^the list contains \"(.+)\"$") { REGEX_PARAM(QString, itemName); ScenarioScope context; for (int row = 0; row < context->indices.size(); row++) { if (Zanshin::indexString(context->indices.at(row)) == itemName) return; } VERIFY_OR_DUMP(false); } THEN("^the list does not contain \"(.+)\"$") { REGEX_PARAM(QString, itemName); ScenarioScope context; for (int row = 0; row < context->indices.size(); row++) { VERIFY_OR_DUMP(Zanshin::indexString(context->indices.at(row)) != itemName); } } THEN("^the task corresponding to the item is done$") { ScenarioScope context; auto artifact = context->index.data(Presentation::QueryTreeModelBase::ObjectRole).value(); VERIFY(artifact); auto task = artifact.dynamicCast(); VERIFY(task); VERIFY(task->isDone()); } THEN("^the editor shows the task as done$") { ScenarioScope context; VERIFY(context->editor->property("done").toBool()); } THEN("^the editor shows \"(.*)\" as (.*)$") { REGEX_PARAM(QString, string); REGEX_PARAM(QString, field); - const QVariant value = (field == "text") ? string - : (field == "title") ? string - : (field == "delegate") ? string - : (field == "start date") ? QDateTime::fromString(string, Qt::ISODate) - : (field == "due date") ? QDateTime::fromString(string, Qt::ISODate) + const QVariant value = (field == QStringLiteral("text")) ? string + : (field == QStringLiteral("title")) ? string + : (field == QStringLiteral("delegate")) ? string + : (field == QStringLiteral("start date")) ? QDateTime::fromString(string, Qt::ISODate) + : (field == QStringLiteral("due date")) ? QDateTime::fromString(string, Qt::ISODate) : QVariant(); - const QByteArray property = (field == "text") ? field.toUtf8() - : (field == "title") ? field.toUtf8() - : (field == "delegate") ? "delegateText" - : (field == "start date") ? "startDate" - : (field == "due date") ? "dueDate" + const QByteArray property = (field == QStringLiteral("text")) ? field.toUtf8() + : (field == QStringLiteral("title")) ? field.toUtf8() + : (field == QStringLiteral("delegate")) ? "delegateText" + : (field == QStringLiteral("start date")) ? "startDate" + : (field == QStringLiteral("due date")) ? "dueDate" : QByteArray(); VERIFY(value.isValid()); VERIFY(!property.isEmpty()); ScenarioScope context; COMPARE(context->editor->property(property), value); } THEN("^the default data source is \"(.*)\"$") { REGEX_PARAM(QString, expectedName); ScenarioScope context; context->waitForStableState(); auto expectedIndex = Zanshin::findIndex(context->model(), expectedName); VERIFY(expectedIndex.isValid()); auto defaultRole = context->model()->roleNames().key("default", -1); VERIFY(expectedIndex.data(defaultRole).toBool()); } THEN("^the setting key (\\S+) is (\\d+)$") { REGEX_PARAM(QString, keyName); REGEX_PARAM(qint64, expectedId); KConfigGroup config(KSharedConfig::openConfig(), "General"); const qint64 id = config.readEntry(keyName, -1); COMPARE(id, expectedId); } #include "cuke-steps.moc" diff --git a/tests/features/features-run.cpp b/tests/features/features-run.cpp index 0ebd92a3..7efbff08 100644 --- a/tests/features/features-run.cpp +++ b/tests/features/features-run.cpp @@ -1,93 +1,93 @@ /* This file is part of Zanshin Copyright 2016 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include class ProcessKiller { public: explicit ProcessKiller(QProcess *process) : m_process(process) { } ~ProcessKiller() { m_process->kill(); m_process->waitForFinished(); } private: ProcessKiller(const ProcessKiller &other); ProcessKiller &operator=(const ProcessKiller &other); QProcess *m_process; }; bool waitForCukeSteps(qint64 timeout) { QElapsedTimer timer; timer.start(); QTcpSocket socket; - socket.connectToHost("localhost", 3902); + socket.connectToHost(QStringLiteral("localhost"), 3902); while (!socket.waitForConnected() && !timer.hasExpired(timeout)) { - socket.connectToHost("localhost", 3902); + socket.connectToHost(QStringLiteral("localhost"), 3902); } return socket.state() == QTcpSocket::ConnectedState; } int main(int argc, char **argv) { qputenv("ZANSHIN_USER_XMLDATA", USER_XMLDATA); QCoreApplication app(argc, argv); - QDir::setCurrent(FEATURES_DIR); + QDir::setCurrent(QStringLiteral(FEATURES_DIR)); QProcess cukeSteps; cukeSteps.setProcessChannelMode(QProcess::ForwardedChannels); - cukeSteps.start(CUKE_STEPS); + cukeSteps.start(QStringLiteral(CUKE_STEPS)); if (!cukeSteps.waitForStarted()) { qWarning() << "Couldn't start the cuke steps server, exiting..."; return 1; } ProcessKiller cukeStepsKiller(&cukeSteps); if (!waitForCukeSteps(10000)) { qWarning() << "The cuke steps server didn't show up as expected, exiting..."; return 1; } - const QStringList args = app.arguments().contains("wip") ? QStringList() - : QStringList({"--tags", "~@wip"}); - return QProcess::execute("cucumber", args); + const QStringList args = app.arguments().contains(QStringLiteral("wip")) ? QStringList() + : QStringList({"--tags", "~@wip"}); + return QProcess::execute(QStringLiteral("cucumber"), args); } diff --git a/tests/manual/tasklister.cpp b/tests/manual/tasklister.cpp index 3db93479..7012cb94 100644 --- a/tests/manual/tasklister.cpp +++ b/tests/manual/tasklister.cpp @@ -1,64 +1,64 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "zanshin/app/dependencies.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/tasklistmodel.h" #include "utils/dependencymanager.h" int main(int argc, char **argv) { QApplication app(argc, argv); App::initializeDependencies(); - KAboutData aboutData("tasklister", - i18n("Lists all the tasks"), "1.0"); + KAboutData aboutData(QStringLiteral("tasklister"), + i18n("Lists all the tasks"), QStringLiteral("1.0")); QCommandLineParser parser; KAboutData::setApplicationData(aboutData); parser.addVersionOption(); parser.addHelpOption(); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); auto repository = Utils::DependencyManager::globalInstance().create(); auto queries = Utils::DependencyManager::globalInstance().create(); auto taskList = queries->findAll(); QListView view; view.setModel(new Presentation::TaskListModel(taskList, repository, &view)); view.resize(640, 480); view.show(); return app.exec(); } diff --git a/tests/manual/tasktreeviewer.cpp b/tests/manual/tasktreeviewer.cpp index c20fb89d..dfe19582 100644 --- a/tests/manual/tasktreeviewer.cpp +++ b/tests/manual/tasktreeviewer.cpp @@ -1,106 +1,106 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "zanshin/app/dependencies.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/querytreemodel.h" #include "utils/dependencymanager.h" int main(int argc, char **argv) { QApplication app(argc, argv); // PORTING SCRIPT: move this to before the KAboutData initialization App::initializeDependencies(); - KAboutData aboutData("tasktreeviewer", - i18n("Show all the tasks in tree"), "1.0"); + KAboutData aboutData(QStringLiteral("tasktreeviewer"), + i18n("Show all the tasks in tree"), QStringLiteral("1.0")); QCommandLineParser parser; KAboutData::setApplicationData(aboutData); parser.addVersionOption(); parser.addHelpOption(); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); auto repository = Utils::DependencyManager::globalInstance().create(); auto queries = Utils::DependencyManager::globalInstance().create(); auto treeQuery = [&](const Domain::Task::Ptr &task) { if (!task) return queries->findTopLevel(); else return queries->findChildren(task); }; auto treeFlags = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto treeData = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto treeSetData = [&](const Domain::Task::Ptr &task, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } if (role == Qt::EditRole) { task->setTitle(value.toString()); } else { task->setDone(value.toInt() == Qt::Checked); } repository->update(task); return true; }; QTreeView view; view.setModel(new Presentation::QueryTreeModel(treeQuery, treeFlags, treeData, treeSetData, &view)); view.resize(640, 480); view.show(); return app.exec(); } diff --git a/tests/testlib/akonadifakestorage.cpp b/tests/testlib/akonadifakestorage.cpp index 69b77477..e09289a5 100644 --- a/tests/testlib/akonadifakestorage.cpp +++ b/tests/testlib/akonadifakestorage.cpp @@ -1,552 +1,552 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadifakestorage.h" #include #include #include #include "akonadi/akonadistoragesettings.h" #include "akonadifakedata.h" #include "akonadifakejobs.h" #include "utils/jobhandler.h" using namespace Testlib; class AkonadiFakeTransaction : public FakeJob { Q_OBJECT public: explicit AkonadiFakeTransaction() : FakeJob(), m_nextIdx(0) { } private slots: void onTimeout() Q_DECL_OVERRIDE { auto jobs = childJobs(); if (m_nextIdx == 0) { const auto it = std::find_if(jobs.constBegin(), jobs.constEnd(), [] (FakeJob *job) { return job->expectedError() != 0; }); if (it != jobs.constEnd()) { setError((*it)->expectedError()); setErrorText((*it)->expectedErrorText()); emitResult(); return; } } if (m_nextIdx >= jobs.size()) { emitResult(); return; } auto job = jobs[m_nextIdx]; connect(job, &KJob::result, this, &AkonadiFakeTransaction::onTimeout); job->start(); m_nextIdx++; } private: QList childJobs() const { QList jobs = findChildren(); jobs.erase(std::remove_if(jobs.begin(), jobs.end(), [this] (FakeJob *job) { return job->parent() != this; }), jobs.end()); return jobs; } int m_nextIdx; }; Utils::JobHandler::StartMode startModeForParent(QObject *parent) { bool isTransaction = qobject_cast(parent); return isTransaction ? Utils::JobHandler::ManualStart : Utils::JobHandler::AutoStart; } void noop() {} AkonadiFakeStorage::AkonadiFakeStorage(AkonadiFakeData *data) : m_data(data) { } Akonadi::Collection AkonadiFakeStorage::defaultTaskCollection() { return Akonadi::StorageSettings::instance().defaultTaskCollection(); } Akonadi::Collection AkonadiFakeStorage::defaultNoteCollection() { return Akonadi::StorageSettings::instance().defaultNoteCollection(); } KJob *AkonadiFakeStorage::createItem(Akonadi::Item item, Akonadi::Collection collection) { Q_ASSERT(!item.isValid()); auto job = new FakeJob; if (!m_data->item(item.id()).isValid()) { Utils::JobHandler::install(job, [=] () mutable { item.setId(m_data->maxItemId() + 1); item.setParentCollection(collection); // Force payload detach item.setPayloadFromData(item.payloadData()); m_data->createItem(item); }); } else { - job->setExpectedError(1, "Item already exists"); + job->setExpectedError(1, QStringLiteral("Item already exists")); Utils::JobHandler::install(job, noop); } return job; } KJob *AkonadiFakeStorage::updateItem(Akonadi::Item item, QObject *parent) { auto job = new FakeJob(parent); auto startMode = startModeForParent(parent); if (m_data->item(item.id()).isValid()) { Utils::JobHandler::install(job, [=] () mutable { // Force payload detach item.setPayloadFromData(item.payloadData()); m_data->modifyItem(item); }, startMode); } else { - job->setExpectedError(1, "Item doesn't exist"); + job->setExpectedError(1, QStringLiteral("Item doesn't exist")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::removeItem(Akonadi::Item item) { auto job = new FakeJob; if (m_data->item(item.id()).isValid()) { Utils::JobHandler::install(job, [=] { m_data->removeItem(item); }); } else { - job->setExpectedError(1, "Item doesn't exist"); + job->setExpectedError(1, QStringLiteral("Item doesn't exist")); Utils::JobHandler::install(job, noop); } return job; } KJob *AkonadiFakeStorage::removeItems(Akonadi::Item::List items, QObject *parent) { auto job = new FakeJob; auto startMode = startModeForParent(parent); bool allItemsExist = std::all_of(items.constBegin(), items.constEnd(), [=] (const Akonadi::Item &item) { return m_data->item(item.id()).isValid(); }); if (allItemsExist) { Utils::JobHandler::install(job, [=] { foreach (const Akonadi::Item &item, items) { m_data->removeItem(item); } }, startMode); } else { - job->setExpectedError(1, "At least one item doesn't exist"); + job->setExpectedError(1, QStringLiteral("At least one item doesn't exist")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::moveItem(Akonadi::Item item, Akonadi::Collection collection, QObject *parent) { auto job = new FakeJob(parent); auto startMode = startModeForParent(parent); if (m_data->item(item.id()).isValid() && m_data->collection(collection.id()).isValid()) { Utils::JobHandler::install(job, [=] () mutable { item.setParentCollection(collection); // Force payload detach item.setPayloadFromData(item.payloadData()); m_data->modifyItem(item); }, startMode); } else { - job->setExpectedError(1, "The item or the collection doesn't exist"); + job->setExpectedError(1, QStringLiteral("The item or the collection doesn't exist")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::moveItems(Akonadi::Item::List items, Akonadi::Collection collection, QObject *parent) { using namespace std::placeholders; auto job = new FakeJob(parent); auto startMode = startModeForParent(parent); bool allItemsExist = std::all_of(items.constBegin(), items.constEnd(), [=] (const Akonadi::Item &item) { return m_data->item(item.id()).isValid(); }); if (allItemsExist && m_data->collection(collection.id()).isValid()) { Utils::JobHandler::install(job, [=] () mutable { std::transform(items.constBegin(), items.constEnd(), items.begin(), [=] (const Akonadi::Item &item) { auto result = item; result.setParentCollection(collection); // Force payload detach result.setPayloadFromData(result.payloadData()); return result; }); foreach (const Akonadi::Item &item, items) { m_data->modifyItem(item); } }, startMode); } else { - job->setExpectedError(1, "One of the items or the collection doesn't exist"); + job->setExpectedError(1, QStringLiteral("One of the items or the collection doesn't exist")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::createCollection(Akonadi::Collection collection, QObject *parent) { Q_ASSERT(!collection.isValid()); auto job = new FakeJob(parent); auto startMode = startModeForParent(parent); if (!m_data->collection(collection.id()).isValid()) { Utils::JobHandler::install(job, [=] () mutable { collection.setId(m_data->maxCollectionId() + 1); m_data->createCollection(collection); }, startMode); } else { - job->setExpectedError(1, "The collection already exists"); + job->setExpectedError(1, QStringLiteral("The collection already exists")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::updateCollection(Akonadi::Collection collection, QObject *parent) { auto job = new FakeJob(parent); auto startMode = startModeForParent(parent); if (m_data->collection(collection.id()).isValid()) { Utils::JobHandler::install(job, [=] { m_data->modifyCollection(collection); }, startMode); } else { - job->setExpectedError(1, "The collection doesn't exist"); + job->setExpectedError(1, QStringLiteral("The collection doesn't exist")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::removeCollection(Akonadi::Collection collection, QObject *parent) { auto job = new FakeJob(parent); auto startMode = startModeForParent(parent); if (m_data->collection(collection.id()).isValid()) { Utils::JobHandler::install(job, [=] { m_data->removeCollection(collection); }, startMode); } else { - job->setExpectedError(1, "The collection doesn't exist"); + job->setExpectedError(1, QStringLiteral("The collection doesn't exist")); Utils::JobHandler::install(job, noop, startMode); } return job; } KJob *AkonadiFakeStorage::createTransaction() { auto job = new AkonadiFakeTransaction; Utils::JobHandler::install(job, noop); return job; } KJob *AkonadiFakeStorage::createTag(Akonadi::Tag tag) { Q_ASSERT(!tag.isValid()); auto job = new FakeJob; if (!m_data->tag(tag.id()).isValid()) { Utils::JobHandler::install(job, [=] () mutable { tag.setId(m_data->maxTagId() + 1); m_data->createTag(tag); }); } else { - job->setExpectedError(1, "The tag already exists"); + job->setExpectedError(1, QStringLiteral("The tag already exists")); Utils::JobHandler::install(job, noop); } return job; } KJob *AkonadiFakeStorage::updateTag(Akonadi::Tag tag) { auto job = new FakeJob; if (m_data->tag(tag.id()).isValid()) { Utils::JobHandler::install(job, [=] { m_data->modifyTag(tag); }); } else { - job->setExpectedError(1, "The tag doesn't exist"); + job->setExpectedError(1, QStringLiteral("The tag doesn't exist")); Utils::JobHandler::install(job, noop); } return job; } KJob *AkonadiFakeStorage::removeTag(Akonadi::Tag tag) { auto job = new FakeJob; if (m_data->tag(tag.id()).isValid()) { Utils::JobHandler::install(job, [=] { m_data->removeTag(tag); }); } else { - job->setExpectedError(1, "The tag doesn't exist"); + job->setExpectedError(1, QStringLiteral("The tag doesn't exist")); Utils::JobHandler::install(job, noop); } return job; } Akonadi::CollectionFetchJobInterface *AkonadiFakeStorage::fetchCollections(Akonadi::Collection collection, Akonadi::StorageInterface::FetchDepth depth, Akonadi::StorageInterface::FetchContentTypes types) { auto job = new AkonadiFakeCollectionFetchJob; auto children = Akonadi::Collection::List(); switch (depth) { case Base: children << m_data->collection(findId(collection)); break; case FirstLevel: children << m_data->childCollections(findId(collection)); break; case Recursive: children = collectChildren(collection); break; } auto collections = Akonadi::Collection::List(); if (types == Akonadi::StorageInterface::AllContent) { collections = children; } else { std::copy_if(children.constBegin(), children.constEnd(), std::back_inserter(collections), [types] (const Akonadi::Collection &col) { const auto mime = col.contentMimeTypes(); return ((types & Akonadi::StorageInterface::Tasks) && mime.contains(KCalCore::Todo::todoMimeType())) || ((types & Akonadi::StorageInterface::Notes) && mime.contains(Akonadi::NoteUtils::noteMimeType())); }); } if (depth != Base) { // Replace the dummy parents in the ancestor chain with proper ones // full of juicy data using namespace std::placeholders; auto completeCollection = std::bind(&AkonadiFakeData::reconstructAncestors, m_data, _1, collection); std::transform(collections.begin(), collections.end(), collections.begin(), completeCollection); } const auto behavior = m_data->storageBehavior().fetchCollectionsBehavior(collection.id()); if (behavior == AkonadiFakeStorageBehavior::NormalFetch) job->setCollections(collections); job->setExpectedError(m_data->storageBehavior().fetchCollectionsErrorCode(collection.id())); Utils::JobHandler::install(job, noop); return job; } Akonadi::CollectionSearchJobInterface *AkonadiFakeStorage::searchCollections(QString collectionName, FetchContentTypes types) { auto job = new AkonadiFakeCollectionSearchJob; const auto allCollections = m_data->collections(); auto foundCollections = Akonadi::Collection::List(); std::copy_if(allCollections.constBegin(), allCollections.constEnd(), std::back_inserter(foundCollections), [collectionName, types] (const Akonadi::Collection &col) { const auto mime = col.contentMimeTypes(); auto contentMimeTypes = QSet(); if (types & Notes) contentMimeTypes << Akonadi::NoteUtils::noteMimeType(); if (types & Tasks) contentMimeTypes << KCalCore::Todo::todoMimeType(); const bool supportedType = contentMimeTypes.isEmpty() || !mime.toSet().intersect(contentMimeTypes).isEmpty(); return supportedType && col.displayName().contains(collectionName, Qt::CaseInsensitive); }); // Replace the dummy parents in the ancestor chain with proper ones // full of juicy data using namespace std::placeholders; auto reconstructCollection = std::bind(&AkonadiFakeData::reconstructAncestors, m_data, _1, Akonadi::Collection::root()); std::transform(foundCollections.begin(), foundCollections.end(), foundCollections.begin(), reconstructCollection); const auto behavior = m_data->storageBehavior().searchCollectionsBehavior(collectionName); if (behavior == AkonadiFakeStorageBehavior::NormalFetch) job->setCollections(foundCollections); job->setExpectedError(m_data->storageBehavior().searchCollectionsErrorCode(collectionName)); Utils::JobHandler::install(job, noop); return job; } Akonadi::ItemFetchJobInterface *AkonadiFakeStorage::fetchItems(Akonadi::Collection collection) { auto items = m_data->childItems(findId(collection)); std::transform(items.begin(), items.end(), items.begin(), [this] (const Akonadi::Item &item) { auto result = m_data->reconstructItemDependencies(item); // Force payload detach result.setPayloadFromData(result.payloadData()); return result; }); auto job = new AkonadiFakeItemFetchJob; const auto behavior = m_data->storageBehavior().fetchItemsBehavior(collection.id()); if (behavior == AkonadiFakeStorageBehavior::NormalFetch) job->setItems(items); job->setExpectedError(m_data->storageBehavior().fetchItemsErrorCode(collection.id())); return job; } Akonadi::ItemFetchJobInterface *AkonadiFakeStorage::fetchItem(Akonadi::Item item) { auto fullItem = m_data->item(findId(item)); fullItem = m_data->reconstructItemDependencies(fullItem); // Force payload detach fullItem.setPayloadFromData(fullItem.payloadData()); auto job = new AkonadiFakeItemFetchJob; const auto behavior = m_data->storageBehavior().fetchItemBehavior(item.id()); if (behavior == AkonadiFakeStorageBehavior::NormalFetch) job->setItems(Akonadi::Item::List() << fullItem); job->setExpectedError(m_data->storageBehavior().fetchItemErrorCode(item.id())); return job; } Akonadi::ItemFetchJobInterface *AkonadiFakeStorage::fetchTagItems(Akonadi::Tag tag) { auto items = m_data->tagItems(findId(tag)); std::transform(items.begin(), items.end(), items.begin(), [this] (const Akonadi::Item &item) { auto collection = m_data->reconstructAncestors(item.parentCollection()); auto result = item; result.setParentCollection(collection); // Force payload detach result.setPayloadFromData(result.payloadData()); return result; }); auto job = new AkonadiFakeItemFetchJob; const auto behavior = m_data->storageBehavior().fetchTagItemsBehavior(tag.id()); if (behavior == AkonadiFakeStorageBehavior::NormalFetch) job->setItems(items); job->setExpectedError(m_data->storageBehavior().fetchTagItemsErrorCode(tag.id())); return job; } Akonadi::TagFetchJobInterface *AkonadiFakeStorage::fetchTags() { auto job = new AkonadiFakeTagFetchJob; const auto behavior = m_data->storageBehavior().fetchTagsBehavior(); if (behavior == AkonadiFakeStorageBehavior::NormalFetch) job->setTags(m_data->tags()); job->setExpectedError(m_data->storageBehavior().fetchTagsErrorCode()); return job; } Akonadi::Tag::Id AkonadiFakeStorage::findId(const Akonadi::Tag &tag) { if (tag.isValid() || tag.gid().isEmpty()) return tag.id(); const auto gid = tag.gid(); auto tags = m_data->tags(); auto result = std::find_if(tags.constBegin(), tags.constEnd(), [gid] (const Akonadi::Tag &tag) { return tag.gid() == gid; }); return (result != tags.constEnd()) ? result->id() : tag.id(); } Akonadi::Collection::Id AkonadiFakeStorage::findId(const Akonadi::Collection &collection) { if (collection.isValid() || collection.remoteId().isEmpty()) return collection.id(); const auto remoteId = collection.remoteId(); auto collections = m_data->collections(); auto result = std::find_if(collections.constBegin(), collections.constEnd(), [remoteId] (const Akonadi::Collection &collection) { return collection.remoteId() == remoteId; }); return (result != collections.constEnd()) ? result->id() : collection.id(); } Akonadi::Item::Id AkonadiFakeStorage::findId(const Akonadi::Item &item) { if (item.isValid() || item.remoteId().isEmpty()) return item.id(); const auto remoteId = item.remoteId(); auto items = m_data->items(); auto result = std::find_if(items.constBegin(), items.constEnd(), [remoteId] (const Akonadi::Item &item) { return item.remoteId() == remoteId; }); return (result != items.constEnd()) ? result->id() : item.id(); } Akonadi::Collection::List AkonadiFakeStorage::collectChildren(const Akonadi::Collection &root) { auto collections = Akonadi::Collection::List(); foreach (const auto &child, m_data->childCollections(findId(root))) { if (child.enabled() || child.referenced()) collections << m_data->collection(findId(child)); collections += collectChildren(child); } return collections; } #include "akonadifakestorage.moc" diff --git a/tests/testlib/akonadistoragetestbase.cpp b/tests/testlib/akonadistoragetestbase.cpp index 2c5ec9a9..72105a2a 100644 --- a/tests/testlib/akonadistoragetestbase.cpp +++ b/tests/testlib/akonadistoragetestbase.cpp @@ -1,1462 +1,1462 @@ /* This file is part of Zanshin Copyright 2014-2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadistoragetestbase.h" #include #include #include #include #include #include #include #include "utils/mem_fn.h" #include "AkonadiCore/qtest_akonadi.h" #include #include "akonadi/akonadiapplicationselectedattribute.h" #include "akonadi/akonadicollectionfetchjobinterface.h" #include "akonadi/akonadicollectionsearchjobinterface.h" #include "akonadi/akonadiitemfetchjobinterface.h" #include "akonadi/akonadimonitorimpl.h" #include "akonadi/akonadistorage.h" #include "akonadi/akonadistoragesettings.h" #include "akonadi/akonaditagfetchjobinterface.h" #include "akonadi/akonaditimestampattribute.h" using namespace Testlib; AkonadiStorageTestBase::AkonadiStorageTestBase(QObject *parent) : QObject(parent) { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } void AkonadiStorageTestBase::dumpTree() { TestLib::AkonadiDebug::dumpTree(createStorage()); } void AkonadiStorageTestBase::shouldListCollections_data() { QTest::addColumn("collection"); QTest::addColumn("expectedNames"); QTest::addColumn("depth"); QTest::addColumn("contentTypes"); QTest::addColumn("referenceCalendar1"); QTest::addColumn("enableCalendar1"); QTest::newRow("all") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("include referenced") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << true << false; QTest::newRow("include referenced + enabled") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << true << true; QTest::newRow("exclude !referenced + !enabled") << Akonadi::Collection::root() << QStringList({ "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << false << false; QTest::newRow("notes") << Akonadi::Collection::root() << QStringList({ "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes) << false << true; QTest::newRow("tasks") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("base type") << calendar2() << QStringList({"Calendar2"}) << Akonadi::Storage::Base << int(Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("firstLevel type") << calendar1() << QStringList({"Calendar2"}) << Akonadi::Storage::FirstLevel << int(Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("recursive type") << calendar1() << QStringList({"Calendar2", "Calendar3"}) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Tasks) << false << true; } void AkonadiStorageTestBase::shouldListCollections() { // GIVEN QFETCH(Akonadi::Collection, collection); QFETCH(QStringList, expectedNames); QFETCH(Akonadi::StorageInterface::FetchDepth, depth); QFETCH(int, contentTypes); QFETCH(bool, referenceCalendar1); QFETCH(bool, enableCalendar1); auto storage = createStorage(); // Default is not referenced and enabled // no need to feedle with the collection in that case if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(referenceCalendar1); cal1.setEnabled(enableCalendar1); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); } // WHEN auto job = storage->fetchCollections(collection, depth, Akonadi::StorageInterface::FetchContentTypes(contentTypes)); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); QStringList collectionNames; for (const auto &collection : collections) { collectionNames << collection.name(); } collectionNames.sort(); // Restore proper DB state if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(false); cal1.setEnabled(true); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); } QCOMPARE(collectionNames, expectedNames); } void AkonadiStorageTestBase::shouldRetrieveAllCollectionAncestors() { // GIVEN auto storage = createStorage(); // WHEN auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::Tasks|Akonadi::Storage::Notes); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); for (const auto &collection : collections) { auto parent = collection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); QVERIFY(!parent.displayName().isEmpty()); parent = parent.parentCollection(); } } } void AkonadiStorageTestBase::shouldListFullItemsInACollection() { // GIVEN auto storage = createStorage(); const QStringList expectedRemoteIds = { "{1d33862f-f274-4c67-ab6c-362d56521ff4}", "{1d33862f-f274-4c67-ab6c-362d56521ff5}", "{1d33862f-f274-4c67-ab6c-362d56521ff6}", "{7824df00-2fd6-47a4-8319-52659dc82005}", "{7824df00-2fd6-47a4-8319-52659dc82006}" }; // WHEN auto job = storage->fetchItems(calendar2()); AKVERIFYEXEC(job->kjob()); // THEN auto items = job->items(); QStringList itemRemoteIds; for (const auto &item : items) { itemRemoteIds << item.remoteId(); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); Akonadi::Tag::List tags = item.tags(); QVERIFY(!item.tags().isEmpty()); for (const auto &tag : tags) { QVERIFY(tag.isValid()); QVERIFY(!tag.name().isEmpty()); QVERIFY(!tag.type().isEmpty()); } auto parent = item.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } itemRemoteIds.sort(); QCOMPARE(itemRemoteIds, expectedRemoteIds); } void AkonadiStorageTestBase::shouldListTags() { // GIVEN auto storage = createStorage(); const QStringList expectedGids = { "change-me", "delete-me", "errands-context", "online-context", "philosophy-tag", "physics-tag" }; // WHEN auto job = storage->fetchTags(); AKVERIFYEXEC(job->kjob()); // THEN auto tags = job->tags(); QStringList tagGids; for (const Akonadi::Tag &tag : tags) { tagGids << tag.gid(); QVERIFY(!tag.name().isEmpty()); QVERIFY(!tag.type().isEmpty()); } tagGids.sort(); QCOMPARE(tagGids, expectedGids); } void AkonadiStorageTestBase::shouldListItemsAssociatedWithTag() { // GIVEN auto storage = createStorage(); - Akonadi::Tag tag = fetchTagByGID("errands-context"); + Akonadi::Tag tag = fetchTagByGID(QStringLiteral("errands-context")); const QStringList expectedRemoteIds = { "{1d33862f-f274-4c67-ab6c-362d56521ff4}", "{7824df00-2fd6-47a4-8319-52659dc82005}" }; // WHEN auto job = storage->fetchTagItems(tag); AKVERIFYEXEC(job->kjob()); // THEN auto items = job->items(); QStringList itemRemoteIds; for (const auto &item : items) { itemRemoteIds << item.remoteId(); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); auto parent = item.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } itemRemoteIds.sort(); QCOMPARE(itemRemoteIds, expectedRemoteIds); } void AkonadiStorageTestBase::shouldNotifyCollectionAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionAdded); MonitorSpy monitorSpy(monitor.data()); // A collection Akonadi::Collection collection; collection.setParentCollection(calendar2()); - collection.setName("Foo!"); - collection.setContentMimeTypes(QStringList() << "application/x-vnd.akonadi.calendar.todo"); + collection.setName(QStringLiteral("Foo!")); + collection.setContentMimeTypes(QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.todo")); // WHEN auto storage = createStorage(); auto job = storage->createCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedCollection = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.name(), collection.name()); auto parent = notifiedCollection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyCollectionRemoved() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data) - Akonadi::Collection collection = fetchCollectionByRID("{1f78b360-a01b-4785-9187-75450190342c}"); + Akonadi::Collection collection = fetchCollectionByRID(QStringLiteral("{1f78b360-a01b-4785-9187-75450190342c}")); QVERIFY(collection.isValid()); // WHEN auto storage = createStorage(); auto job = storage->removeCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedCollection= spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); } void AkonadiStorageTestBase::shouldNotifyCollectionChanged() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); MonitorSpy monitorSpy(monitor.data()); // A colection with an existing id (if we trust the test data) - Akonadi::Collection collection = fetchCollectionByRID("{28ef9f03-4ebc-4e33-970f-f379775894f9}"); + Akonadi::Collection collection = fetchCollectionByRID(QStringLiteral("{28ef9f03-4ebc-4e33-970f-f379775894f9}")); QVERIFY(collection.isValid()); - collection.setName("Bar!"); + collection.setName(QStringLiteral("Bar!")); // WHEN auto storage = createStorage(); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedCollection = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); QCOMPARE(notifiedCollection.name(), collection.name()); auto parent = notifiedCollection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemAdded); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("summary"); - todo->setDescription("content"); + todo->setSummary(QStringLiteral("summary")); + todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDate(2013, 11, 24))); todo->setDtDue(KDateTime(QDate(2014, 03, 01))); // ... as payload of an item... Akonadi::Item item; - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); item.addAttribute(new Akonadi::EntityDisplayAttribute); // WHEN auto storage = createStorage(); auto job = storage->createItem(item, calendar2()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(*notifiedItem.payload(), *todo); QVERIFY(notifiedItem.hasAttribute()); auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemRemoved() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); MonitorSpy monitorSpy(monitor.data()); - const Akonadi::Collection notesCol = fetchCollectionByRID("{f5e3f1be-b998-4c56-aa3d-e3a6e7e5493a}"); - Akonadi::Item item = fetchItemByRID("{d0159c99-0d23-41fa-bb5f-436570140f8b}", notesCol); + const Akonadi::Collection notesCol = fetchCollectionByRID(QStringLiteral("{f5e3f1be-b998-4c56-aa3d-e3a6e7e5493a}")); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{d0159c99-0d23-41fa-bb5f-436570140f8b}"), notesCol); QVERIFY(item.isValid()); // WHEN auto storage = createStorage(); auto job = storage->removeItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemChanged() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("summary"); - todo->setDescription("content"); + todo->setSummary(QStringLiteral("summary")); + todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDate(2013, 11, 24))); todo->setDtDue(KDateTime(QDate(2014, 03, 01))); // ... as payload of an existing item (if we trust the test data)... - Akonadi::Item item = fetchItemByRID("{1d33862f-f274-4c67-ab6c-362d56521ff6}", calendar2()); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff6}"), calendar2()); QVERIFY(item.isValid()); - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); item.addAttribute(new Akonadi::EntityDisplayAttribute); // WHEN auto storage = createStorage(); auto job = storage->updateItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); QCOMPARE(*notifiedItem.payload(), *todo); QVERIFY(notifiedItem.hasAttribute()); auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemTagAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data)... - Akonadi::Item item = fetchItemByRID("{1d33862f-f274-4c67-ab6c-362d56521ff5}", calendar2()); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff5}"), calendar2()); QVERIFY(item.isValid()); - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); // An existing tag (if we trust the test data) Akonadi::Tag tag(5); // WHEN item.setTag(tag); auto storage = createStorage(); auto job = storage->updateItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); QVERIFY(notifiedItem.hasPayload()); Akonadi::Tag::List notifiedTags = notifiedItem.tags(); QVERIFY(notifiedTags.contains(tag)); for (const auto &tag : notifiedTags) { QVERIFY(tag.isValid()); QVERIFY(!tag.name().isEmpty()); QVERIFY(!tag.type().isEmpty()); } auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemTagRemoved() // aka dissociate { // GIVEN auto storage = createStorage(); - Akonadi::Tag tag = fetchTagByGID("philosophy-tag"); - const QString expectedRemoteIds = {"{7824df00-2fd6-47a4-8319-52659dc82006}"}; + Akonadi::Tag tag = fetchTagByGID(QStringLiteral("philosophy-tag")); + const QString expectedRemoteIds = {QStringLiteral("{7824df00-2fd6-47a4-8319-52659dc82006}")}; auto job = storage->fetchTagItems(tag); AKVERIFYEXEC(job->kjob()); auto item = job->items().first(); QCOMPARE(item.remoteId(), expectedRemoteIds); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); QVERIFY(!item.tags().isEmpty()); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN item.clearTag(tag); auto jobUpdate = storage->updateItem(item); AKVERIFYEXEC(jobUpdate); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); QVERIFY(!notifiedItem.tags().contains(tag)); } void AkonadiStorageTestBase::shouldNotifyTagAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagAdded); MonitorSpy monitorSpy(monitor.data()); // A tag Akonadi::Tag tag; tag.setGid("gid"); - tag.setName("name"); + tag.setName(QStringLiteral("name")); tag.setType("type"); // WHEN auto storage = createStorage(); auto job = storage->createTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedTag = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedTag.gid(), tag.gid()); QCOMPARE(notifiedTag.name(), tag.name()); QCOMPARE(notifiedTag.type(), tag.type()); } void AkonadiStorageTestBase::shouldNotifyTagRemoved() { // GIVEN // An existing tag (if we trust the test data) connected to an existing item tagged to it auto storage = createStorage(); - Akonadi::Tag tag = fetchTagByGID("delete-me"); + Akonadi::Tag tag = fetchTagByGID(QStringLiteral("delete-me")); // NOTE : this item was linked to the delete-me tag during test time - const QString expectedRemoteIds = {"{1d33862f-f274-4c67-ab6c-362d56521ff5}"}; + const QString expectedRemoteIds = {QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff5}")}; auto job = storage->fetchTagItems(tag); AKVERIFYEXEC(job->kjob()); QCOMPARE(job->items().size(), 1); auto itemTagged = job->items().first(); QCOMPARE(itemTagged.remoteId(), expectedRemoteIds); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved); QSignalSpy spyItemChanged(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto jobDelete = storage->removeTag(tag); AKVERIFYEXEC(jobDelete); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); QTRY_VERIFY(!spyItemChanged.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedTag = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedTag.id(), tag.id()); QCOMPARE(spyItemChanged.size(), 1); auto notifiedItem = spyItemChanged.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), itemTagged.id()); } void AkonadiStorageTestBase::shouldNotifyTagChanged() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagChanged); MonitorSpy monitorSpy(monitor.data()); // An existing tag (if we trust the test data) Akonadi::Tag tag(6); - tag.setName("Oh it changed!"); + tag.setName(QStringLiteral("Oh it changed!")); // WHEN auto storage = createStorage(); auto job = storage->updateTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedTag = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedTag.id(), tag.id()); QCOMPARE(notifiedTag.name(), tag.name()); } void AkonadiStorageTestBase::shouldReadDefaultNoteCollectionFromSettings() { // GIVEN // A storage implementation auto storage = createStorage(); // WHEN Akonadi::StorageSettings::instance().setDefaultNoteCollection(Akonadi::Collection(24)); // THEN QCOMPARE(storage->defaultNoteCollection(), Akonadi::Collection(24)); } void AkonadiStorageTestBase::shouldReadDefaultTaskCollectionFromSettings() { // GIVEN // A storage implementation auto storage = createStorage(); // WHEN Akonadi::StorageSettings::instance().setDefaultTaskCollection(Akonadi::Collection(24)); // THEN QCOMPARE(storage->defaultTaskCollection(), Akonadi::Collection(24)); } void AkonadiStorageTestBase::shouldUpdateItem() { // GIVEN // A storage implementation auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("new summary"); - todo->setDescription("new content"); + todo->setSummary(QStringLiteral("new summary")); + todo->setDescription(QStringLiteral("new content")); // ... as payload of an existing item (if we trust the test data)... - Akonadi::Item item = fetchItemByRID("{1d33862f-f274-4c67-ab6c-362d56521ff4}", calendar2()); - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff4}"), calendar2()); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // WHEN auto job = storage->updateItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); // KCalCore 4.83 fixes this bug #if KCALCORE_VERSION < 0x045300 QCOMPARE(notifiedItem.payload()->uid(), todo->uid()); QCOMPARE(notifiedItem.payload()->summary(), todo->summary()); QCOMPARE(notifiedItem.payload()->description(), todo->description()); QEXPECT_FAIL("", "Bug introduced by 76c686bc1de3a5d16956a627744ce352bc28d12a in KCalCore", Continue); QCOMPARE(*notifiedItem.payload(), *todo); QEXPECT_FAIL("", "Bug introduced by 76c686bc1de3a5d16956a627744ce352bc28d12a in KCalCore", Continue); QCOMPARE(notifiedItem.payload()->status(), todo->status()); #else QCOMPARE(*notifiedItem.payload(), *todo); #endif } void AkonadiStorageTestBase::shouldUseTransaction() { // GIVEN auto storage = createStorage(); - Akonadi::Item item1 = fetchItemByRID("{0aa4dc30-a2c2-4e08-8241-033b3344debc}", calendar1()); + Akonadi::Item item1 = fetchItemByRID(QStringLiteral("{0aa4dc30-a2c2-4e08-8241-033b3344debc}"), calendar1()); QVERIFY(item1.isValid()); - Akonadi::Item item2 = fetchItemByRID("{5dc1aba7-eead-4254-ba7a-58e397de1179}", calendar1()); + Akonadi::Item item2 = fetchItemByRID(QStringLiteral("{5dc1aba7-eead-4254-ba7a-58e397de1179}"), calendar1()); QVERIFY(item2.isValid()); // create wrong item Akonadi::Item item3(10000); - item3.setRemoteId("wrongId"); + item3.setRemoteId(QStringLiteral("wrongId")); // A spied monitor auto monitor = createMonitor(); QSignalSpy spyUpdated(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto todo = item1.payload(); - todo->setSummary("Buy tomatoes"); + todo->setSummary(QStringLiteral("Buy tomatoes")); todo = item2.payload(); - todo->setSummary("Buy chocolate"); + todo->setSummary(QStringLiteral("Buy chocolate")); auto transaction = storage->createTransaction(); storage->updateItem(item1, transaction); storage->updateItem(item3, transaction); // this job should fail storage->updateItem(item2, transaction); QVERIFY(!transaction->exec()); monitorSpy.waitForStableState(); // THEN QCOMPARE(spyUpdated.size(), 0); auto job = storage->fetchItem(item1); AKVERIFYEXEC(job->kjob()); QCOMPARE(job->items().size(), 1); item1 = job->items()[0]; job = storage->fetchItem(item2); AKVERIFYEXEC(job->kjob()); QCOMPARE(job->items().size(), 1); item2 = job->items()[0]; - QCOMPARE(item1.payload()->summary(), QString("Buy kiwis")); - QCOMPARE(item2.payload()->summary(), QString("Buy cheese")); + QCOMPARE(item1.payload()->summary(), QStringLiteral("Buy kiwis")); + QCOMPARE(item2.payload()->summary(), QStringLiteral("Buy cheese")); } void AkonadiStorageTestBase::shouldCreateItem() { // GIVEN // A storage implementation auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemAdded); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("summary"); - todo->setDescription("content"); + todo->setSummary(QStringLiteral("summary")); + todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDate(2013, 11, 24))); todo->setDtDue(KDateTime(QDate(2014, 03, 01))); // ... as payload of a new item Akonadi::Item item; - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // WHEN auto job = storage->createItem(item, calendar2()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.parentCollection(), calendar2()); QCOMPARE(*notifiedItem.payload(), *todo); } void AkonadiStorageTestBase::shouldRetrieveItem() { // GIVEN auto storage = createStorage(); - Akonadi::Item findItem = fetchItemByRID("{7824df00-2fd6-47a4-8319-52659dc82005}", calendar2()); + Akonadi::Item findItem = fetchItemByRID(QStringLiteral("{7824df00-2fd6-47a4-8319-52659dc82005}"), calendar2()); QVERIFY(findItem.isValid()); // WHEN auto job = storage->fetchItem(findItem); AKVERIFYEXEC(job->kjob()); // THEN auto items = job->items(); QCOMPARE(items.size(), 1); const auto &item = items[0]; QCOMPARE(item.id(), findItem.id()); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); auto parent = item.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldMoveItem() { // GIVEN auto storage = createStorage(); - Akonadi::Item item = fetchItemByRID("{7824df00-2fd6-47a4-8319-52659dc82005}", calendar2()); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{7824df00-2fd6-47a4-8319-52659dc82005}"), calendar2()); QVERIFY(item.isValid()); // A spied monitor auto monitor = createMonitor(); QSignalSpy spyMoved(monitor.data(), &Akonadi::MonitorInterface::itemMoved); MonitorSpy monitorSpy(monitor.data()); auto job = storage->moveItem(item, calendar1()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spyMoved.isEmpty()); QCOMPARE(spyMoved.size(), 1); auto movedItem = spyMoved.takeFirst().takeFirst().value(); QCOMPARE(movedItem.id(), item.id()); } void AkonadiStorageTestBase::shouldMoveItems() { // GIVEN auto storage = createStorage(); - Akonadi::Item item = fetchItemByRID("{1d33862f-f274-4c67-ab6c-362d56521ff4}", calendar2()); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff4}"), calendar2()); QVERIFY(item.isValid()); Akonadi::Item::List list; list << item; // A spied monitor auto monitor = createMonitor(); QSignalSpy spyMoved(monitor.data(), &Akonadi::MonitorInterface::itemMoved); MonitorSpy monitorSpy(monitor.data()); auto job = storage->moveItems(list, calendar1()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spyMoved.isEmpty()); QCOMPARE(spyMoved.size(), 1); auto movedItem = spyMoved.takeFirst().takeFirst().value(); QCOMPARE(movedItem.id(), item.id()); } void AkonadiStorageTestBase::shouldDeleteItem() { //GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data) - Akonadi::Item item = fetchItemByRID("{0aa4dc30-a2c2-4e08-8241-033b3344debc}", calendar1()); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{0aa4dc30-a2c2-4e08-8241-033b3344debc}"), calendar1()); QVERIFY(item.isValid()); //When auto job = storage->removeItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); } void AkonadiStorageTestBase::shouldDeleteItems() { //GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data) - Akonadi::Item item = fetchItemByRID("{6c7bf5b9-4136-4203-9f45-54e32ea0eacb}", calendar1()); + Akonadi::Item item = fetchItemByRID(QStringLiteral("{6c7bf5b9-4136-4203-9f45-54e32ea0eacb}"), calendar1()); QVERIFY(item.isValid()); - Akonadi::Item item2 = fetchItemByRID("{83cf0b15-8d61-436b-97ae-4bd88fb2fef9}", calendar1()); + Akonadi::Item item2 = fetchItemByRID(QStringLiteral("{83cf0b15-8d61-436b-97ae-4bd88fb2fef9}"), calendar1()); QVERIFY(item2.isValid()); Akonadi::Item::List list; list << item << item2; //When auto job = storage->removeItems(list); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 2); auto notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item.id()); notifiedItem = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedItem.id(), item2.id()); } void AkonadiStorageTestBase::shouldCreateTag() { // GIVEN // A storage implementation auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagAdded); MonitorSpy monitorSpy(monitor.data()); // A tag Akonadi::Tag tag; - QString name = "Tag42"; + QString name = QStringLiteral("Tag42"); const QByteArray type = QByteArray("Zanshin-Context"); const QByteArray gid = QByteArray(name.toLatin1()); tag.setName(name); tag.setType(QByteArray("Zanshin-Context")); tag.setGid(gid); // WHEN auto job = storage->createTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedTag = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedTag.name(), name); QCOMPARE(notifiedTag.type(), type); QCOMPARE(notifiedTag.gid(), gid); } void AkonadiStorageTestBase::shouldRemoveTag() { // GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing tag - Akonadi::Tag tag = fetchTagByGID("errands-context"); + Akonadi::Tag tag = fetchTagByGID(QStringLiteral("errands-context")); // WHEN auto job = storage->removeTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedTag = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedTag.id(), tag.id()); } void AkonadiStorageTestBase::shouldUpdateTag() { // GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagChanged); MonitorSpy monitorSpy(monitor.data()); // An existing tag - Akonadi::Tag tag = fetchTagByGID("change-me"); + Akonadi::Tag tag = fetchTagByGID(QStringLiteral("change-me")); // WHEN auto job = storage->updateTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); auto notifiedTag = spy.takeFirst().takeFirst().value(); QCOMPARE(notifiedTag.id(), tag.id()); } void AkonadiStorageTestBase::shouldUpdateCollection() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = calendar2(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); QSignalSpy selectionSpy(monitor.data(), &Akonadi::MonitorInterface::collectionSelectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto attr = new Akonadi::EntityDisplayAttribute; - attr->setDisplayName("Foo"); + attr->setDisplayName(QStringLiteral("Foo")); collection.addAttribute(attr); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); QCOMPARE(selectionSpy.size(), 0); auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); QCOMPARE(notifiedCollection.attribute()->displayName(), attr->displayName()); } void AkonadiStorageTestBase::shouldNotifyCollectionTimestampChanges() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = calendar2(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN collection.attribute(Akonadi::Collection::AddIfMissing)->refreshTimestamp(); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); } void AkonadiStorageTestBase::shouldNotifyCollectionSelectionChanges() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = calendar2(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); QSignalSpy selectionSpy(monitor.data(), &Akonadi::MonitorInterface::collectionSelectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto attr = new Akonadi::ApplicationSelectedAttribute; attr->setSelected(false); collection.addAttribute(attr); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); QCOMPARE(selectionSpy.size(), 1); auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); QVERIFY(!notifiedCollection.attribute()->isSelected()); notifiedCollection = selectionSpy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); QVERIFY(!notifiedCollection.attribute()->isSelected()); } void AkonadiStorageTestBase::shouldNotNotifyCollectionSelectionChangesForIrrelevantCollections() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = emails(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); QSignalSpy selectionSpy(monitor.data(), &Akonadi::MonitorInterface::collectionSelectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto attr = new Akonadi::ApplicationSelectedAttribute; attr->setSelected(false); collection.addAttribute(attr); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); QVERIFY(selectionSpy.isEmpty()); } void AkonadiStorageTestBase::shouldNotifyCollectionSubscriptionChanges_data() { QTest::addColumn("isEnabled"); QTest::addColumn("isReferenced"); QTest::newRow("enabled and !referenced") << true << false; // Fails randomly due to an akonadi bug... //QTest::newRow("!enabled and referenced") << false << true; QTest::newRow("!enabled and !referenced") << false << false; QTest::newRow("!enabled and referenced (again)") << false << true; QTest::newRow("enabled and !referenced (again)") << true << false; } void AkonadiStorageTestBase::shouldNotifyCollectionSubscriptionChanges() { // GIVEN QFETCH(bool, isEnabled); QFETCH(bool, isReferenced); // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection(calendar2().id()); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN static int run = 1; collection.attribute(Akonadi::Collection::AddIfMissing) - ->setIconName(QString("folder-%1").arg(run++)); + ->setIconName(QStringLiteral("folder-%1").arg(run++)); collection.setEnabled(isEnabled); collection.setReferenced(isReferenced); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); QCOMPARE(notifiedCollection.id(), collection.id()); QCOMPARE(notifiedCollection.enabled(), isEnabled); QCOMPARE(notifiedCollection.referenced(), isReferenced); } void AkonadiStorageTestBase::shouldFindCollectionsByName_data() { QTest::addColumn("name"); QTest::addColumn("contentType"); QTest::addColumn("expectedResults"); QTest::addColumn("referenceCalendar1"); QTest::addColumn("enableCalendar1"); QStringList expectedResults; - expectedResults << "Calendar1"; + expectedResults << QStringLiteral("Calendar1"); QTest::newRow("get a collection") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults.clear(); QTest::newRow("try with wrong type") << "Calendar1" << int(Akonadi::StorageInterface::Notes) << expectedResults << false << true; - expectedResults << "Notes"; + expectedResults << QStringLiteral("Notes"); QTest::newRow("get a note collection") << "Not" << int(Akonadi::StorageInterface::Notes) << expectedResults << false << true; expectedResults.clear(); QTest::newRow("try with unknown name") << "toto" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; - expectedResults << "Calendar3" << "Calendar2" << "Calendar1"; + expectedResults << QStringLiteral("Calendar3") << QStringLiteral("Calendar2") << QStringLiteral("Calendar1"); QTest::newRow("try with a part of a name") << "Calendar" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults.clear(); - expectedResults << "Calendar2"; + expectedResults << QStringLiteral("Calendar2"); QTest::newRow("make sure it is case insensitive") << "calendar2" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults.clear(); - expectedResults << "Calendar1"; + expectedResults << QStringLiteral("Calendar1"); QTest::newRow("include referenced") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << true << false; QTest::newRow("include referenced + enabled") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << true << true; QTest::newRow("include !referenced + !enabled") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << false; } void AkonadiStorageTestBase::shouldFindCollectionsByName() { // GIVEN auto storage = createStorage(); QFETCH(QString, name); QFETCH(int, contentType); QFETCH(QStringList, expectedResults); QFETCH(bool, referenceCalendar1); QFETCH(bool, enableCalendar1); // A spied monitor auto monitor = createMonitor(); MonitorSpy monitorSpy(monitor.data()); // Default is not referenced and enabled // no need to feedle with the collection in that case if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(referenceCalendar1); cal1.setEnabled(enableCalendar1); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); monitorSpy.waitForStableState(); } // WHEN auto job = storage->searchCollections(name, Akonadi::StorageInterface::FetchContentType(contentType)); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); // Restore proper DB state if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(false); cal1.setEnabled(true); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); monitorSpy.waitForStableState(); } auto collectionNames = QStringList(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(collectionNames), Utils::mem_fn(&Akonadi::Collection::name)); QCOMPARE(collectionNames.toSet(), expectedResults.toSet()); } void AkonadiStorageTestBase::shouldFindCollectionsByNameIncludingTheirAncestors_data() { QTest::addColumn("searchTerm"); QTest::addColumn("contentType"); QTest::newRow("task search") << "Calendar3" << int(Akonadi::StorageInterface::Tasks); QTest::newRow("note search") << "Notes" << int(Akonadi::StorageInterface::Notes); } void AkonadiStorageTestBase::shouldFindCollectionsByNameIncludingTheirAncestors() { // GIVEN auto storage = createStorage(); // WHEN QFETCH(QString, searchTerm); QFETCH(int, contentType); auto job = storage->searchCollections(searchTerm, Akonadi::StorageInterface::FetchContentType(contentType)); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); for (const auto &collection : collections) { auto parent = collection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); QVERIFY(!parent.displayName().isEmpty()); parent = parent.parentCollection(); } } } Akonadi::Item AkonadiStorageTestBase::fetchItemByRID(const QString &remoteId, const Akonadi::Collection &collection) { Akonadi::Item item; item.setRemoteId(remoteId); auto job = createStorage()->fetchItem(item); job->setCollection(collection); if (!job->kjob()->exec()) { qWarning() << job->kjob()->errorString(); return Akonadi::Item(); } if (job->items().count() != 1) { qWarning() << "Received unexpected amount of items: " << job->items().count(); return Akonadi::Item(); } return job->items().first(); } Akonadi::Collection AkonadiStorageTestBase::fetchCollectionByRID(const QString &remoteId) { Akonadi::Collection collection; collection.setRemoteId(remoteId); auto job = createStorage()->fetchCollections(collection, Akonadi::StorageInterface::Base, Akonadi::StorageInterface::AllContent); - job->setResource("akonadi_knut_resource_0"); + job->setResource(QStringLiteral("akonadi_knut_resource_0")); job->setFiltered(false); if (!job->kjob()->exec()) { qWarning() << job->kjob()->errorString() << remoteId; return Akonadi::Collection(); } if (job->collections().count() != 1) { qWarning() << "Received unexpected amount of collections: " << job->collections().count(); return Akonadi::Collection(); } return job->collections().first(); } Akonadi::Tag AkonadiStorageTestBase::fetchTagByGID(const QString &gid) { auto job = createStorage()->fetchTags(); if (!job->kjob()->exec()) { qWarning() << job->kjob()->errorString(); return Akonadi::Tag(); } auto tags = job->tags(); for (const Akonadi::Tag &tag : tags) { if (tag.gid() == gid) return tag; } return Akonadi::Tag(); } Akonadi::Collection AkonadiStorageTestBase::calendar1() { - return fetchCollectionByRID("{cdc229c7-a9b5-4d37-989d-a28e372be2a9}"); + return fetchCollectionByRID(QStringLiteral("{cdc229c7-a9b5-4d37-989d-a28e372be2a9}")); } Akonadi::Collection AkonadiStorageTestBase::calendar2() { - return fetchCollectionByRID("{e682b8b5-b67c-4538-8689-6166f64177f0}"); + return fetchCollectionByRID(QStringLiteral("{e682b8b5-b67c-4538-8689-6166f64177f0}")); } Akonadi::Collection AkonadiStorageTestBase::emails() { - return fetchCollectionByRID("{14096930-7bfe-46ca-8fba-7c04d3b62ec8}"); + return fetchCollectionByRID(QStringLiteral("{14096930-7bfe-46ca-8fba-7c04d3b62ec8}")); } diff --git a/tests/testlib/gentodo.cpp b/tests/testlib/gentodo.cpp index ff302b46..c25ba8c6 100644 --- a/tests/testlib/gentodo.cpp +++ b/tests/testlib/gentodo.cpp @@ -1,157 +1,157 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "gentodo.h" #include #include using namespace Testlib; GenTodo::GenTodo(const Akonadi::Item &item) : m_item(item) { m_item.setMimeType(KCalCore::Todo::todoMimeType()); if (!m_item.hasPayload()) m_item.setPayload(KCalCore::Todo::Ptr::create()); } Testlib::GenTodo::operator Akonadi::Item() { return m_item; } GenTodo &GenTodo::withId(Akonadi::Item::Id id) { m_item.setId(id); return *this; } GenTodo &GenTodo::withParent(Akonadi::Collection::Id id) { m_item.setParentCollection(Akonadi::Collection(id)); return *this; } GenTodo &GenTodo::withTags(QList ids) { auto tags = Akonadi::Tag::List(); std::transform(ids.constBegin(), ids.constEnd(), std::back_inserter(tags), [] (Akonadi::Tag::Id id) { return Akonadi::Tag(id); }); m_item.setTags(tags); return *this; } GenTodo &GenTodo::asProject(bool value) { auto todo = m_item.payload(); if (value) - todo->setCustomProperty("Zanshin", "Project", "1"); + todo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); else todo->removeCustomProperty("Zanshin", "Project"); return *this; } GenTodo &GenTodo::withUid(const QString &uid) { m_item.payload()->setUid(uid); return *this; } GenTodo &GenTodo::withParentUid(const QString &uid) { m_item.payload()->setRelatedTo(uid); return *this; } GenTodo &GenTodo::withTitle(const QString &title) { m_item.payload()->setSummary(title); return *this; } GenTodo &GenTodo::withText(const QString &text) { m_item.payload()->setDescription(text); return *this; } GenTodo &GenTodo::done(bool value) { m_item.payload()->setCompleted(value); return *this; } GenTodo &GenTodo::withDoneDate(const QString &date) { m_item.payload()->setCompleted(KDateTime(QDate::fromString(date, Qt::ISODate))); return *this; } GenTodo &GenTodo::withDoneDate(const QDateTime &date) { m_item.payload()->setCompleted(KDateTime(date)); return *this; } GenTodo &GenTodo::withStartDate(const QString &date) { m_item.payload()->setDtStart(KDateTime(QDate::fromString(date, Qt::ISODate))); return *this; } GenTodo &GenTodo::withStartDate(const QDateTime &date) { m_item.payload()->setDtStart(KDateTime(date)); return *this; } GenTodo &GenTodo::withDueDate(const QString &date) { m_item.payload()->setDtDue(KDateTime(QDate::fromString(date, Qt::ISODate))); return *this; } GenTodo &GenTodo::withDueDate(const QDateTime &date) { m_item.payload()->setDtDue(KDateTime(date)); return *this; } GenTodo &GenTodo::withDelegate(const QString &name, const QString &email) { withNoDelegate(); KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(name, email, true, KCalCore::Attendee::Delegated)); m_item.payload()->addAttendee(attendee); return *this; } GenTodo &GenTodo::withNoDelegate() { m_item.payload()->clearAttendees(); return *this; } diff --git a/tests/units/akonadi/akonadicontextqueriestest.cpp b/tests/units/akonadi/akonadicontextqueriestest.cpp index aaaedfb7..98f08b0a 100644 --- a/tests/units/akonadi/akonadicontextqueriestest.cpp +++ b/tests/units/akonadi/akonadicontextqueriestest.cpp @@ -1,440 +1,440 @@ /* This file is part of Zanshin Copyright 2014 Franck Arrecot 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonadicontextqueries.h" #include "akonadi/akonadiserializer.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gentodo.h" #include "testlib/gentag.h" #include "testlib/testhelpers.h" using namespace Testlib; class AkonadiContextQueriesTest : public QObject { Q_OBJECT private slots: void shouldDealWithEmptyTagList() { // GIVEN AkonadiFakeData data; // WHEN QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); QCOMPARE(result->data().size(), 0); } void shouldLookInAllReportedForAllContexts() { // GIVEN AkonadiFakeData data; // Two context tags - data.createTag(GenTag().withId(42).withName("42").asContext()); - data.createTag(GenTag().withId(43).withName("43").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asContext()); // WHEN QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); result->data(); result = queries->findAll(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43")); } void shouldIgnoreWrongTagType() { // GIVEN AkonadiFakeData data; // One context tag and one plain tag - data.createTag(GenTag().withId(42).withName("42").asContext()); - data.createTag(GenTag().withId(43).withName("43").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asPlain()); // WHEN QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); result->data(); result = queries->findAll(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldReactToTagAdded() { // GIVEN AkonadiFakeData data; QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createTag(GenTag().withId(42).withName("42").asContext()); - data.createTag(GenTag().withId(43).withName("43").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asContext()); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43")); } void shouldReactToTagRemoved() { // GIVEN AkonadiFakeData data; // Two context tags - data.createTag(GenTag().withId(42).withName("42").asContext()); - data.createTag(GenTag().withId(43).withName("43").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asContext()); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeTag(Akonadi::Tag(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldReactToTagChanges() { // GIVEN AkonadiFakeData data; // Two context tags - data.createTag(GenTag().withId(42).withName("42").asContext()); - data.createTag(GenTag().withId(43).withName("43").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asContext()); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyTag(GenTag(data.tag(43)).withName("43bis")); + data.modifyTag(GenTag(data.tag(43)).withName(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43bis")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43bis")); } void shouldLookForAllContextTopLevelTasks() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); // Three tasks in the collection, two related to context, one not - data.createItem(GenTodo().withParent(42).withId(42).withTitle("42").withTags({42})); - data.createItem(GenTodo().withParent(42).withId(43).withTitle("43")); - data.createItem(GenTodo().withParent(42).withId(44).withTitle("44").withTags({42})); + data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); + data.createItem(GenTodo().withParent(42).withId(43).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withParent(42).withId(44).withTitle(QStringLiteral("44")).withTags({42})); // WHEN auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context = serializer->createContextFromTag(data.tag(42)); auto result = queries->findTopLevelTasks(context); result->data(); result = queries->findTopLevelTasks(context); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); // Should not change nothing result = queries->findTopLevelTasks(context); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldReactToItemAddsForTopLevelTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context = serializer->createContextFromTag(data.tag(42)); auto result = queries->findTopLevelTasks(context); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createItem(GenTodo().withParent(42).withId(42).withTitle("42").withTags({42})); + data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shoudlReactToItemChangesForTopLevelTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); // One task related to the context - data.createItem(GenTodo().withParent(42).withId(42).withTitle("42").withTags({42})); + data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context = serializer->createContextFromTag(data.tag(42)); auto result = queries->findTopLevelTasks(context); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42bis")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42bis"))); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42bis")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42bis")); QVERIFY(replaceHandlerCalled); } void shouldAddItemToCorrespondingResultWhenTagAddedToTopLevelTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); // One task not related to the context - data.createItem(GenTodo().withParent(42).withId(42).withTitle("42")); + data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42"))); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context = serializer->createContextFromTag(data.tag(42)); auto result = queries->findTopLevelTasks(context); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN data.modifyItem(GenTodo(data.item(42)).withTags({42})); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldRemoveItemFromCorrespondingResultWhenTagRemovedFromTopLevelTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); // One task related to the context - data.createItem(GenTodo().withParent(42).withId(42).withTitle("42").withTags({42})); + data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context = serializer->createContextFromTag(data.tag(42)); auto result = queries->findTopLevelTasks(context); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); // WHEN data.modifyItem(GenTodo(data.item(42)).withTags({})); // THEN QVERIFY(result->data().isEmpty()); } void shouldMoveItemToCorrespondingResultWhenTagChangedOnTopLevelTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Two context tags - data.createTag(GenTag().withId(42).withName("42").asContext()); - data.createTag(GenTag().withId(43).withName("43").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asContext()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asContext()); // One task related to the first context - data.createItem(GenTodo().withParent(42).withId(42).withTitle("42").withTags({42})); + data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context1 = serializer->createContextFromTag(data.tag(42)); auto result1 = queries->findTopLevelTasks(context1); auto context2 = serializer->createContextFromTag(data.tag(43)); auto result2 = queries->findTopLevelTasks(context2); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result1->data().size(), 1); - QCOMPARE(result1->data().at(0)->title(), QString("42")); + QCOMPARE(result1->data().at(0)->title(), QStringLiteral("42")); QVERIFY(result2->data().isEmpty()); // WHEN data.modifyItem(GenTodo(data.item(42)).withTags({43})); // THEN QVERIFY(result1->data().isEmpty()); QCOMPARE(result2->data().size(), 1); - QCOMPARE(result2->data().at(0)->title(), QString("42")); + QCOMPARE(result2->data().at(0)->title(), QStringLiteral("42")); } void shoudlReactToItemRemovesForTopLevelTask() { // GIVEN AkonadiFakeData data; // One context tag - data.createTag(GenTag().withId(42).withName("tag-42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asContext()); // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // A task related to the context - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").withTags({42})); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags({42})); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ContextQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto context = serializer->createContextFromTag(data.tag(42)); auto result = queries->findTopLevelTasks(context); bool removeHandlerCalled = false; result->addPostRemoveHandler([&removeHandlerCalled](const Domain::Artifact::Ptr &, int) { removeHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); // WHEN data.removeItem(Akonadi::Item(42)); // THEN QVERIFY(result->data().isEmpty()); QVERIFY(removeHandlerCalled); } }; ZANSHIN_TEST_MAIN(AkonadiContextQueriesTest) #include "akonadicontextqueriestest.moc" diff --git a/tests/units/akonadi/akonadicontextrepositorytest.cpp b/tests/units/akonadi/akonadicontextrepositorytest.cpp index 47579140..ae398613 100644 --- a/tests/units/akonadi/akonadicontextrepositorytest.cpp +++ b/tests/units/akonadi/akonadicontextrepositorytest.cpp @@ -1,334 +1,334 @@ /* This file is part of Zanshin Copyright 2014 Franck Arrecot Copyright 2014 Rémi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "testlib/akonadifakejobs.h" #include "testlib/akonadifakemonitor.h" #include "akonadi/akonadicontextrepository.h" #include "akonadi/akonadiserializerinterface.h" #include "akonadi/akonadistorageinterface.h" using namespace mockitopp; using namespace mockitopp::matcher; Q_DECLARE_METATYPE(Testlib::AkonadiFakeItemFetchJob*) Q_DECLARE_METATYPE(Testlib::AkonadiFakeTagFetchJob*) class AkonadiContextRepositoryTest : public QObject { Q_OBJECT private slots: void shouldCreateContext() { // GIVEN // A Context and its corresponding Tag not existing in akonadi Akonadi::Tag tag; auto context = Domain::Context::Ptr::create(); // A mock creating job auto tagCreateJob = new FakeJob(this); // Storage mock returning the tagCreatejob Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::createTag).when(tag) .thenReturn(tagCreateJob); // Serializer mock Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).thenReturn(tag); // WHEN QScopedPointer repository(new Akonadi::ContextRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->create(context)->exec(); //THEN QVERIFY(storageMock(&Akonadi::StorageInterface::createTag).when(tag).exactly(1)); } void shouldUpdateContext() { // GIVEN Akonadi::Tag tag; - tag.setName("tag42"); + tag.setName(QStringLiteral("tag42")); tag.setId(42); auto context = Domain::Context::Ptr::create(); // A mock creating job auto tagModifyJob = new FakeJob(this); // Storage mock returning the tagCreatejob Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::updateTag).when(tag) .thenReturn(tagModifyJob); // Serializer mock Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).thenReturn(tag); // WHEN QScopedPointer repository(new Akonadi::ContextRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->update(context)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateTag).when(tag).exactly(1)); } void shouldRemoveContext() { // GIVEN Akonadi::Tag tag; - tag.setName("tag42"); + tag.setName(QStringLiteral("tag42")); tag.setId(42); auto context = Domain::Context::Ptr::create(); // A mock creating job auto tagDeleteJob= new FakeJob(this); // Storage mock returning the tagCreatejob Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::removeTag).when(tag) .thenReturn(tagDeleteJob); // Serializer mock Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).thenReturn(tag); // WHEN QScopedPointer repository(new Akonadi::ContextRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->remove(context)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::removeTag).when(tag).exactly(1)); } void shouldAssociateATaskToAContext_data() { QTest::addColumn("associatedTag"); QTest::addColumn("item"); QTest::addColumn("context"); QTest::addColumn("task"); QTest::addColumn("itemFetchJob"); QTest::addColumn("execJob"); Akonadi::Collection col(40); Akonadi::Item item(42); item.setParentCollection(col); Domain::Task::Ptr task(new Domain::Task); Akonadi::Tag associatedTag(qint64(43)); auto associatedContext = Domain::Context::Ptr::create(); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << item); QTest::newRow("nominal case") << associatedTag << item << associatedContext << task << itemFetchJob << true; itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); QTest::newRow("task job error, cannot find task") << associatedTag << item << associatedContext << task << itemFetchJob << false; } void shouldAssociateATaskToAContext() { // GIVEN QFETCH(Akonadi::Tag,associatedTag); QFETCH(Akonadi::Item,item); QFETCH(Domain::Context::Ptr,context); QFETCH(Domain::Task::Ptr,task); QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob); QFETCH(bool,execJob); // A mock update job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob); storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task) .thenReturn(item); serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context) .thenReturn(associatedTag); // WHEN QScopedPointer repository(new Akonadi::ContextRepository(storageMock.getInstance(), serializerMock.getInstance())); auto associateJob = repository->associate(context, task); if (execJob) associateJob->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); if (execJob) { QVERIFY(serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } } void shoudDissociateTaskFromContext_data() { QTest::addColumn("associatedTag"); QTest::addColumn("item"); QTest::addColumn("context"); QTest::addColumn("task"); QTest::addColumn("itemFetchJob"); QTest::addColumn("execJob"); Akonadi::Item item(42); Domain::Task::Ptr task(new Domain::Task); Akonadi::Tag associatedTag(qint64(43)); auto associatedContext = Domain::Context::Ptr::create(); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << item); QTest::newRow("nominal case") << associatedTag << item << associatedContext << task << itemFetchJob << true; itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); QTest::newRow("task job error, cannot find task") << associatedTag << item << associatedContext << task << itemFetchJob << false; } void shoudDissociateTaskFromContext() { QFETCH(Akonadi::Tag,associatedTag); QFETCH(Akonadi::Item,item); QFETCH(Domain::Context::Ptr,context); QFETCH(Domain::Task::Ptr,task); QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob); QFETCH(bool,execJob); // A mock update job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob); storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task) .thenReturn(item); serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context) .thenReturn(associatedTag); // WHEN QScopedPointer repository(new Akonadi::ContextRepository(storageMock.getInstance(), serializerMock.getInstance())); auto dissociateJob = repository->dissociate(context, task); if (execJob) dissociateJob->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); if (execJob) { QVERIFY(serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } } void shouldDissociateTaskFromAllContext_data() { QTest::addColumn("item"); QTest::addColumn("task"); QTest::addColumn("itemFetchJob"); QTest::addColumn("execJob"); Akonadi::Item item(42); Domain::Task::Ptr task(new Domain::Task); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << item); QTest::newRow("nominal case") << item << task << itemFetchJob << true; itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); QTest::newRow("task job error, cannot find task") << item << task << itemFetchJob << false; } void shouldDissociateTaskFromAllContext() { QFETCH(Akonadi::Item,item); QFETCH(Domain::Task::Ptr,task); QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob); QFETCH(bool,execJob); // A mock update job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob); storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task) .thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::ContextRepository(storageMock.getInstance(), serializerMock.getInstance())); auto dissociateJob = repository->dissociateAll(task); if (execJob) dissociateJob->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); if (execJob) { QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } } }; ZANSHIN_TEST_MAIN(AkonadiContextRepositoryTest) #include "akonadicontextrepositorytest.moc" diff --git a/tests/units/akonadi/akonadidatasourcequeriestest.cpp b/tests/units/akonadi/akonadidatasourcequeriestest.cpp index 324a380c..fed7d3bb 100644 --- a/tests/units/akonadi/akonadidatasourcequeriestest.cpp +++ b/tests/units/akonadi/akonadidatasourcequeriestest.cpp @@ -1,1204 +1,1204 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonadidatasourcequeries.h" #include "akonadi/akonadiserializer.h" #include "akonadi/akonadistoragesettings.h" #include "utils/jobhandler.h" #include "utils/mem_fn.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/testhelpers.h" using namespace Testlib; typedef std::function::Ptr(Domain::DataSourceQueries*)> QueryFunction; Q_DECLARE_METATYPE(QueryFunction) typedef std::function SetDefaultCollectionFunction; Q_DECLARE_METATYPE(SetDefaultCollectionFunction) typedef std::function GetDefaultCollectionFunction; Q_DECLARE_METATYPE(GetDefaultCollectionFunction) Q_DECLARE_METATYPE(Akonadi::StorageInterface::FetchContentType) class AkonadiDataSourceQueriesTest : public QObject { Q_OBJECT public: explicit AkonadiDataSourceQueriesTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } private slots: void shouldCheckIfASourceIsDefaultFromSettings_data() { QTest::addColumn("contentType"); QTest::addColumn("setDefaultCollection"); QTest::addColumn("getDefaultCollection"); { SetDefaultCollectionFunction setFunction = Utils::mem_fn(&Akonadi::StorageSettings::setDefaultNoteCollection); GetDefaultCollectionFunction getFunction = Utils::mem_fn(&Akonadi::StorageSettings::defaultNoteCollection); QTest::newRow("notes") << Akonadi::StorageInterface::Notes << setFunction << getFunction; } { SetDefaultCollectionFunction setFunction = Utils::mem_fn(&Akonadi::StorageSettings::setDefaultTaskCollection); GetDefaultCollectionFunction getFunction = Utils::mem_fn(&Akonadi::StorageSettings::defaultTaskCollection); QTest::newRow("tasks") << Akonadi::StorageInterface::Tasks << setFunction << getFunction; } } void shouldCheckIfASourceIsDefaultFromSettings() { // GIVEN const auto minId = qint64(42); const auto maxId = qint64(44); const auto defaultId = qint64(43); QFETCH(Akonadi::StorageInterface::FetchContentType, contentType); QFETCH(SetDefaultCollectionFunction, setDefaultCollection); // A default collection for saving setDefaultCollection(&Akonadi::StorageSettings::instance(), Akonadi::Collection(defaultId)); // A few data sources AkonadiFakeData data; for (auto id = minId; id <= maxId; id++) { auto col = GenCollection().withId(id).withName(QString::number(id)).withRootAsParent(); if (contentType == Akonadi::StorageInterface::Tasks) data.createCollection(col.withTaskContent()); else data.createCollection(col.withTaskContent()); } // WHEN auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::DataSourceQueries(contentType, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); // THEN for (auto id = minId; id <= maxId; id++) { auto source = serializer->createDataSourceFromCollection(data.collection(id), Akonadi::SerializerInterface::BaseName); QCOMPARE(queries->isDefaultSource(source), id == defaultId); } } void shouldStoreDefaultSourceInTheSettingsAndNotify_data() { shouldCheckIfASourceIsDefaultFromSettings_data(); } void shouldStoreDefaultSourceInTheSettingsAndNotify() { // GIVEN const auto minId = qint64(42); const auto maxId = qint64(44); const auto defaultId = qint64(43); QFETCH(Akonadi::StorageInterface::FetchContentType, contentType); QFETCH(SetDefaultCollectionFunction, setDefaultCollection); // A default collection for saving setDefaultCollection(&Akonadi::StorageSettings::instance(), Akonadi::Collection(minId)); // A few data sources AkonadiFakeData data; for (auto id = minId; id <= maxId; id++) { auto col = GenCollection().withId(id).withName(QString::number(id)).withRootAsParent(); if (contentType == Akonadi::StorageInterface::Tasks) data.createCollection(col.withTaskContent()); else data.createCollection(col.withTaskContent()); } // WHEN auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::DataSourceQueries(contentType, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); QSignalSpy spy(queries->notifier(), &Domain::DataSourceQueriesNotifier::defaultSourceChanged); auto defaultSource = serializer->createDataSourceFromCollection(data.collection(defaultId), Akonadi::SerializerInterface::BaseName); queries->setDefaultSource(defaultSource); // THEN QFETCH(GetDefaultCollectionFunction, getDefaultCollection); QCOMPARE(getDefaultCollection(&Akonadi::StorageSettings::instance()).id(), defaultId); QCOMPARE(spy.count(), 1); } void shouldLookInAllReportedForTopLevelSources_data() { QTest::addColumn("contentTypes"); QTest::addColumn("expectedNames"); auto expectedNames = QStringList(); - expectedNames << "42Task" << "44Note"; + expectedNames << QStringLiteral("42Task") << QStringLiteral("44Note"); QTest::newRow("tasks and notes") << int(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes) << expectedNames; expectedNames.clear(); - expectedNames << "42Task"; + expectedNames << QStringLiteral("42Task"); QTest::newRow("tasks") << int(Akonadi::StorageInterface::Tasks) << expectedNames; expectedNames.clear(); - expectedNames << "44Note"; + expectedNames << QStringLiteral("44Note"); QTest::newRow("notes") << int(Akonadi::StorageInterface::Notes) << expectedNames; } void shouldLookInAllReportedForTopLevelSources() { // GIVEN AkonadiFakeData data; // Two top level collections, one with tasks, one with notes - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("44Note").withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44Note")).withRootAsParent().withNoteContent()); // One with a note child collection - data.createCollection(GenCollection().withId(43).withName("43TaskChild").withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskChild")).withParent(42).withTaskContent()); // One with a task child collection - data.createCollection(GenCollection().withId(45).withName("45NoteChild").withParent(44).withNoteContent()); + data.createCollection(GenCollection().withId(45).withName(QStringLiteral("45NoteChild")).withParent(44).withNoteContent()); // WHEN QFETCH(int, contentTypes); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::FetchContentTypes(contentTypes), Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findTopLevel(); result->data(); result = queries->findTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); auto actualNames = QStringList(); std::transform(result->data().constBegin(), result->data().constEnd(), std::back_inserter(actualNames), [] (const Domain::DataSource::Ptr &source) { return source->name(); }); actualNames.sort(); QFETCH(QStringList, expectedNames); expectedNames.sort(); QCOMPARE(actualNames, expectedNames); } void shouldReactToCollectionAddsForTopLevelSources() { // GIVEN AkonadiFakeData data; QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43Note").withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43Note")).withRootAsParent().withNoteContent()); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42Task")); - QCOMPARE(result->data().at(1)->name(), QString("43Note")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42Task")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43Note")); } void shouldReactToCollectionRemovesForTopLevelSources() { // GIVEN AkonadiFakeData data; // Two top level collections and two child collections - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43Note").withRootAsParent().withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("43TaskChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(45).withName("43NoteChild").withParent(43).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43Note")).withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("43TaskChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(45).withName(QStringLiteral("43NoteChild")).withParent(43).withNoteContent()); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeCollection(Akonadi::Collection(42)); data.removeCollection(Akonadi::Collection(43)); // THEN QCOMPARE(result->data().size(), 0); } void shouldReactToItemChangesForTopLevelTasks() { // GIVEN AkonadiFakeData data; // Two top level collections and one child collection - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43Note").withRootAsParent().withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("44NoteChild").withParent(43).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43Note")).withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44NoteChild")).withParent(43).withNoteContent()); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findTopLevel(); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::DataSource::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyCollection(GenCollection(data.collection(42)).withName("42TaskBis")); - data.modifyCollection(GenCollection(data.collection(43)).withName("43NoteBis")); + data.modifyCollection(GenCollection(data.collection(42)).withName(QStringLiteral("42TaskBis"))); + data.modifyCollection(GenCollection(data.collection(43)).withName(QStringLiteral("43NoteBis"))); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42TaskBis")); - QCOMPARE(result->data().at(1)->name(), QString("43NoteBis")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42TaskBis")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43NoteBis")); QVERIFY(replaceHandlerCalled); } void shouldRemoveUnlistedCollectionFromTopLevelTasks() { // GIVEN AkonadiFakeData data; // Two top level collections and one child collection - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43Note").withRootAsParent().withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("44NoteChild").withParent(43).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43Note")).withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44NoteChild")).withParent(43).withNoteContent()); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.modifyCollection(GenCollection(data.collection(43)).referenced(false).enabled(false)); // datasource unlisted now // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("42Task")); + QCOMPARE(result->data().first()->name(), QStringLiteral("42Task")); } void shouldNotCrashDuringFindTopLevelWhenFetchJobFailedOrEmpty_data() { QTest::addColumn("colErrorCode"); QTest::addColumn("colFetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("No error with empty collection list (+ query delete)") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; QTest::newRow("Error with collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; } void shouldNotCrashDuringFindTopLevelWhenFetchJobFailedOrEmpty() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); QFETCH(int, colErrorCode); QFETCH(int, colFetchBehavior); data.storageBehavior().setFetchCollectionsErrorCode(Akonadi::Collection::root().id(), colErrorCode); data.storageBehavior().setFetchCollectionsBehavior(Akonadi::Collection::root().id(), AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); QFETCH(bool, deleteQuery); // WHEN Domain::QueryResult::Ptr result = queries->findTopLevel(); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 0); } void shouldLookInAllReportedForChildSources_data() { QTest::addColumn("contentTypes"); QTest::addColumn("expectedNames"); auto expectedNames = QStringList(); - expectedNames << "43TaskFirstChild" << "45NoteSecondChild"; + expectedNames << QStringLiteral("43TaskFirstChild") << QStringLiteral("45NoteSecondChild"); QTest::newRow("tasks and notes") << int(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes) << expectedNames; expectedNames.clear(); - expectedNames << "43TaskFirstChild"; + expectedNames << QStringLiteral("43TaskFirstChild"); QTest::newRow("tasks") << int(Akonadi::StorageInterface::Tasks) << expectedNames; expectedNames.clear(); - expectedNames << "45NoteSecondChild"; + expectedNames << QStringLiteral("45NoteSecondChild"); QTest::newRow("notes") << int(Akonadi::StorageInterface::Notes) << expectedNames; } void shouldLookInAllReportedForChildSources() { // GIVEN AkonadiFakeData data; // One top level collection with two children (one of them also having a child) - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43TaskFirstChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("44TaskFirstChildChild").withParent(43).withTaskContent()); - data.createCollection(GenCollection().withId(45).withName("45NoteSecondChild").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskFirstChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44TaskFirstChildChild")).withParent(43).withTaskContent()); + data.createCollection(GenCollection().withId(45).withName(QStringLiteral("45NoteSecondChild")).withParent(42).withNoteContent()); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr topLevelDataSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); // WHEN QFETCH(int, contentTypes); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::FetchContentTypes(contentTypes), Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findChildren(topLevelDataSource); result->data(); result = queries->findChildren(topLevelDataSource); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); auto actualNames = QStringList(); std::transform(result->data().constBegin(), result->data().constEnd(), std::back_inserter(actualNames), [] (const Domain::DataSource::Ptr &source) { return source->name(); }); actualNames.sort(); QFETCH(QStringList, expectedNames); expectedNames.sort(); QCOMPARE(actualNames, expectedNames); } void shouldReactToCollectionAddsForChildSources() { // GIVEN AkonadiFakeData data; // One top level collection with no child yet - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr topLevelDataSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findChildren(topLevelDataSource); result->data(); result = queries->findChildren(topLevelDataSource); // Should not cause any problem or wrong data TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 0); // WHEN - data.createCollection(GenCollection().withId(43).withName("43TaskChild").withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskChild")).withParent(42).withTaskContent()); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("43TaskChild")); + QCOMPARE(result->data().first()->name(), QStringLiteral("43TaskChild")); } void shouldReactToCollectionRemovesForChildSources() { // GIVEN AkonadiFakeData data; // One top level collection with two children - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43TaskFirstChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("45NoteSecondChild").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskFirstChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("45NoteSecondChild")).withParent(42).withNoteContent()); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr topLevelDataSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findChildren(topLevelDataSource); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeCollection(Akonadi::Collection(44)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("43TaskFirstChild")); + QCOMPARE(result->data().first()->name(), QStringLiteral("43TaskFirstChild")); } void shouldReactToCollectionChangesForChildSources() { // GIVEN AkonadiFakeData data; // One top level collection with two children - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43TaskFirstChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("44NoteSecondChild").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskFirstChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44NoteSecondChild")).withParent(42).withNoteContent()); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr topLevelDataSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findChildren(topLevelDataSource); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::DataSource::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyCollection(GenCollection(data.collection(43)).withName("43TaskFirstChildBis")); + data.modifyCollection(GenCollection(data.collection(43)).withName(QStringLiteral("43TaskFirstChildBis"))); // THEN TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().first()->name(), QString("43TaskFirstChildBis")); - QCOMPARE(result->data().at(1)->name(), QString("44NoteSecondChild")); + QCOMPARE(result->data().first()->name(), QStringLiteral("43TaskFirstChildBis")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("44NoteSecondChild")); QVERIFY(replaceHandlerCalled); } void shouldRemoveUnlistedCollectionsFromChildSources() { // GIVEN AkonadiFakeData data; // One top level collection with two children - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43TaskFirstChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("44NoteSecondChild").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskFirstChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44NoteSecondChild")).withParent(42).withNoteContent()); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr topLevelDataSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findChildren(topLevelDataSource); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.modifyCollection(GenCollection(data.collection(43)).referenced(false).enabled(false)); // unlist the child collection // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("44NoteSecondChild")); + QCOMPARE(result->data().first()->name(), QStringLiteral("44NoteSecondChild")); } void shouldNotCrashDuringFindChildrenWhenFetchJobFailedOrEmpty_data() { QTest::addColumn("colErrorCode"); QTest::addColumn("colFetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("No error with empty collection list (+ query delete)") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; QTest::newRow("Error with collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; } void shouldNotCrashDuringFindChildrenWhenFetchJobFailedOrEmpty() { // GIVEN AkonadiFakeData data; // One top level collection with two children - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("43TaskFirstChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("44NoteSecondChild").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("43TaskFirstChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("44NoteSecondChild")).withParent(42).withNoteContent()); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr topLevelDataSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QFETCH(bool, deleteQuery); QFETCH(int, colErrorCode); QFETCH(int, colFetchBehavior); data.storageBehavior().setFetchCollectionsErrorCode(data.collection(42).id(), colErrorCode); data.storageBehavior().setFetchCollectionsBehavior(data.collection(42).id(), AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); // WHEN QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findChildren(topLevelDataSource); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 0); } void shouldLookInAllReportedForSearchTopLevelSources_data() { QTest::addColumn("contentTypes"); QTest::addColumn("expectedColNames"); QTest::addColumn("expectedTitiNames"); auto expectedColNames = QStringList(); auto expectedTitiNames = QStringList(); - expectedColNames << "TaskToto" << "NoteCol"; - expectedTitiNames << "NoteTiti" << "TaskTiti"; + expectedColNames << QStringLiteral("TaskToto") << QStringLiteral("NoteCol"); + expectedTitiNames << QStringLiteral("NoteTiti") << QStringLiteral("TaskTiti"); QTest::newRow("tasks and notes") << int(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes) << expectedColNames << expectedTitiNames; expectedColNames.clear(); expectedTitiNames.clear(); - expectedColNames << "TaskToto"; - expectedTitiNames << "TaskTiti"; + expectedColNames << QStringLiteral("TaskToto"); + expectedTitiNames << QStringLiteral("TaskTiti"); QTest::newRow("tasks") << int(Akonadi::StorageInterface::Tasks) << expectedColNames << expectedTitiNames; expectedColNames.clear(); expectedTitiNames.clear(); - expectedColNames << "NoteCol"; - expectedTitiNames << "NoteTiti"; + expectedColNames << QStringLiteral("NoteCol"); + expectedTitiNames << QStringLiteral("NoteTiti"); QTest::newRow("notes") << int(Akonadi::StorageInterface::Notes) << expectedColNames << expectedTitiNames; } void shouldLookInAllReportedForSearchTopLevelSources() { // GIVEN AkonadiFakeData data; // Four top level collections, two with tasks, two with notes - data.createCollection(GenCollection().withId(42).withName("TaskToto").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("NoteTiti").withRootAsParent().withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("TaskTiti").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(46).withName("NoteCol").withRootAsParent().withNoteContent()); - data.createCollection(GenCollection().withId(47).withName("NoCol").withRootAsParent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("TaskToto")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("NoteTiti")).withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("TaskTiti")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(46).withName(QStringLiteral("NoteCol")).withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(47).withName(QStringLiteral("NoCol")).withRootAsParent()); // One child collection with tasks - data.createCollection(GenCollection().withId(45).withName("TaskTotoCol").withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(45).withName(QStringLiteral("TaskTotoCol")).withParent(42).withTaskContent()); - QString searchTerm("Col"); + QString searchTerm(QStringLiteral("Col")); // WHEN QFETCH(int, contentTypes); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::FetchContentTypes(contentTypes), Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchTopLevel(); result->data(); result = queries->findSearchTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); auto actualNames = QStringList(); std::transform(result->data().constBegin(), result->data().constEnd(), std::back_inserter(actualNames), [] (const Domain::DataSource::Ptr &source) { return source->name(); }); actualNames.sort(); QFETCH(QStringList, expectedColNames); expectedColNames.sort(); QCOMPARE(actualNames, expectedColNames); // WHEN - QString searchTerm2("Titi"); + QString searchTerm2(QStringLiteral("Titi")); queries->setSearchTerm(searchTerm2); // THEN TestHelpers::waitForEmptyJobQueue(); actualNames.clear(); std::transform(result->data().constBegin(), result->data().constEnd(), std::back_inserter(actualNames), [] (const Domain::DataSource::Ptr &source) { return source->name(); }); actualNames.sort(); QFETCH(QStringList, expectedTitiNames); expectedTitiNames.sort(); QCOMPARE(actualNames, expectedTitiNames); } void shouldReactToCollectionAddsForSearchTopLevelSources() { // GIVEN AkonadiFakeData data; - QString searchTerm("col"); + QString searchTerm(QStringLiteral("col")); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchTopLevel(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createCollection(GenCollection().withId(42).withName("42Task").withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("42Task")).withRootAsParent().withTaskContent()); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("42Task")); + QCOMPARE(result->data().first()->name(), QStringLiteral("42Task")); } void shouldReactToCollectionRemovesForSearchTopLevelSources() { // GIVEN AkonadiFakeData data; // Two top level collections - data.createCollection(GenCollection().withId(42).withName("TaskToto").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("NoteToto").withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("TaskToto")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("NoteToto")).withRootAsParent().withNoteContent()); - QString searchTerm("Toto"); + QString searchTerm(QStringLiteral("Toto")); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeCollection(Akonadi::Collection(42)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("NoteToto")); + QCOMPARE(result->data().first()->name(), QStringLiteral("NoteToto")); } void shouldReactToItemChangesForSearchTopLevelTasks() { // GIVEN AkonadiFakeData data; // Two top level collections - data.createCollection(GenCollection().withId(42).withName("TaskCol1").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("NoteCol2").withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("TaskCol1")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("NoteCol2")).withRootAsParent().withNoteContent()); // One child collection - data.createCollection(GenCollection().withId(44).withName("NoteCol2Child").withParent(43).withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("NoteCol2Child")).withParent(43).withNoteContent()); - QString searchTerm("Col"); + QString searchTerm(QStringLiteral("Col")); // WHEN QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchTopLevel(); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::DataSource::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyCollection(GenCollection(data.collection(43)).withName("NoteCol2Bis")); - data.modifyCollection(GenCollection(data.collection(44)).withName("NoteCol2ChildBis")); + data.modifyCollection(GenCollection(data.collection(43)).withName(QStringLiteral("NoteCol2Bis"))); + data.modifyCollection(GenCollection(data.collection(44)).withName(QStringLiteral("NoteCol2ChildBis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("TaskCol1")); - QCOMPARE(result->data().at(1)->name(), QString("NoteCol2Bis")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("TaskCol1")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("NoteCol2Bis")); QVERIFY(replaceHandlerCalled); } void shouldNotCrashDuringFindSearchTopLevelWhenFetchJobFailedOrEmpty_data() { QTest::addColumn("colErrorCode"); QTest::addColumn("colFetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("No error with empty collection list (+ query delete)") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; QTest::newRow("Error with collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; } void shouldNotCrashDuringFindSearchTopLevelWhenFetchJobFailedOrEmpty() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, storage, serializer, monitor)); QFETCH(bool, deleteQuery); QFETCH(int, colErrorCode); QFETCH(int, colFetchBehavior); data.storageBehavior().setFetchCollectionsErrorCode(Akonadi::Collection::root().id(), colErrorCode); data.storageBehavior().setFetchCollectionsBehavior(Akonadi::Collection::root().id(), AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); // WHEN Domain::QueryResult::Ptr result = queries->findSearchTopLevel(); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 0); } void shouldNotStartJobDuringFindSearchTopLevelWhenSearchTermIsEmpty() { // GIVEN AkonadiFakeData data; // one top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("parent")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("parent"))); // WHEN QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findSearchTopLevel(); result->data(); result = queries->findSearchTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); QCOMPARE(Utils::JobHandler::jobCount(), 0); } void shouldLookInAllReportedForSearchChildSources_data() { QTest::addColumn("contentTypes"); QTest::addColumn("expectedColNames"); QTest::addColumn("expectedTotoNames"); auto expectedColNames = QStringList(); auto expectedTotoNames = QStringList(); - expectedColNames << "NoteCol1"; - expectedTotoNames << "TaskToto"; + expectedColNames << QStringLiteral("NoteCol1"); + expectedTotoNames << QStringLiteral("TaskToto"); QTest::newRow("tasks and notes") << int(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes) << expectedColNames << expectedTotoNames; expectedColNames.clear(); expectedTotoNames.clear(); - expectedColNames << "NoteCol1"; - expectedTotoNames << "TaskToto"; + expectedColNames << QStringLiteral("NoteCol1"); + expectedTotoNames << QStringLiteral("TaskToto"); QTest::newRow("tasks") << int(Akonadi::StorageInterface::Tasks) << expectedColNames << expectedTotoNames; expectedColNames.clear(); expectedTotoNames.clear(); - expectedColNames << "NoteCol1"; + expectedColNames << QStringLiteral("NoteCol1"); QTest::newRow("notes") << int(Akonadi::StorageInterface::Notes) << expectedColNames << expectedTotoNames; } void shouldLookInAllReportedForSearchChildSources() { // GIVEN AkonadiFakeData data; // Two top level collections - data.createCollection(GenCollection().withId(42).withName("parent").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(46).withName("Col46").withRootAsParent().withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("parent")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(46).withName(QStringLiteral("Col46")).withRootAsParent().withNoteContent()); // two child of parent - data.createCollection(GenCollection().withId(43).withName("NoteCol1").withParent(42).withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("TaskToto").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(47).withName("NoCol").withParent(42)); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("NoteCol1")).withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("TaskToto")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(47).withName(QStringLiteral("NoCol")).withParent(42)); // One child of the first child - data.createCollection(GenCollection().withId(45).withName("TaskCol43Child").withParent(43).withTaskContent()); + data.createCollection(GenCollection().withId(45).withName(QStringLiteral("TaskCol43Child")).withParent(43).withTaskContent()); - QString searchTerm("Col"); + QString searchTerm(QStringLiteral("Col")); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr parentSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); // WHEN QFETCH(int, contentTypes); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::FetchContentTypes(contentTypes), Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchChildren(parentSource); result->data(); result = queries->findSearchChildren(parentSource); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); auto actualNames = QStringList(); std::transform(result->data().constBegin(), result->data().constEnd(), std::back_inserter(actualNames), [] (const Domain::DataSource::Ptr &source) { return source->name(); }); actualNames.sort(); QFETCH(QStringList, expectedColNames); expectedColNames.sort(); QCOMPARE(actualNames, expectedColNames); // WHEN - QString searchTerm2("toto"); + QString searchTerm2(QStringLiteral("toto")); queries->setSearchTerm(searchTerm2); // THEN TestHelpers::waitForEmptyJobQueue(); actualNames.clear(); std::transform(result->data().constBegin(), result->data().constEnd(), std::back_inserter(actualNames), [] (const Domain::DataSource::Ptr &source) { return source->name(); }); actualNames.sort(); QFETCH(QStringList, expectedTotoNames); expectedTotoNames.sort(); QCOMPARE(actualNames, expectedTotoNames); } void shouldReactToCollectionAddsForSearchChildSources() { // GIVEN AkonadiFakeData data; // One top level collections - data.createCollection(GenCollection().withId(42).withName("Col1").withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("Col1")).withRootAsParent().withTaskContent()); - QString searchTerm("Col"); + QString searchTerm(QStringLiteral("Col")); // Serializer auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr parentSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchChildren(parentSource); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createCollection(GenCollection().withId(43).withName("Col2").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("Col2")).withParent(42).withNoteContent()); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("Col2")); + QCOMPARE(result->data().first()->name(), QStringLiteral("Col2")); } void shouldReactToCollectionRemovesForSearchChildSources() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withName("parent").withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("parent")).withRootAsParent().withTaskContent()); // two children of parent - data.createCollection(GenCollection().withId(43).withName("NoteCol1").withParent(42).withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("TaskCol2").withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("NoteCol1")).withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("TaskCol2")).withParent(42).withTaskContent()); - QString searchTerm("Col"); + QString searchTerm(QStringLiteral("Col")); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr parentSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchChildren(parentSource); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeCollection(Akonadi::Collection(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->name(), QString("TaskCol2")); + QCOMPARE(result->data().first()->name(), QStringLiteral("TaskCol2")); } void shouldReactToCollectionChangesForSearchChildSources() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withName("parent").withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("parent")).withRootAsParent().withTaskContent()); // two children - data.createCollection(GenCollection().withId(43).withName("NoteCol1").withParent(42).withNoteContent()); - data.createCollection(GenCollection().withId(44).withName("TaskCol2").withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("NoteCol1")).withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("TaskCol2")).withParent(42).withTaskContent()); - QString searchTerm("Col"); + QString searchTerm(QStringLiteral("Col")); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr parentSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); // WHEN QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); queries->setSearchTerm(searchTerm); Domain::QueryResult::Ptr result = queries->findSearchChildren(parentSource); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::DataSource::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyCollection(GenCollection(data.collection(43)).withName("NoteCol1Bis")); + data.modifyCollection(GenCollection(data.collection(43)).withName(QStringLiteral("NoteCol1Bis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("NoteCol1Bis")); - QCOMPARE(result->data().at(1)->name(), QString("TaskCol2")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("NoteCol1Bis")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("TaskCol2")); QVERIFY(replaceHandlerCalled); } void shouldNotCrashDuringFindSearchChildrenWhenFetchJobFailedOrEmpty_data() { QTest::addColumn("colErrorCode"); QTest::addColumn("colFetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("No error with empty collection list (+ query delete)") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; QTest::newRow("Error with collection list (+ query delete)") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; } void shouldNotCrashDuringFindSearchChildrenWhenFetchJobFailedOrEmpty() { // GIVEN AkonadiFakeData data; // One top level collection with two children - data.createCollection(GenCollection().withId(42).withName("parent").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("TaskChild").withParent(42).withTaskContent()); - data.createCollection(GenCollection().withId(44).withName("TaskChild").withParent(42).withNoteContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("parent")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("TaskChild")).withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(44).withName(QStringLiteral("TaskChild")).withParent(42).withNoteContent()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr parentSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); QFETCH(bool, deleteQuery); QFETCH(int, colErrorCode); QFETCH(int, colFetchBehavior); data.storageBehavior().setFetchCollectionsErrorCode(data.collection(42).id(), colErrorCode); data.storageBehavior().setFetchCollectionsBehavior(data.collection(42).id(), AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findSearchChildren(parentSource); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 0); } void shouldNotStartJobDuringFindSearchChildrenWhenSearchTermIsEmpty() { // GIVEN AkonadiFakeData data; // One top level collection and its child - data.createCollection(GenCollection().withId(42).withName("parent").withRootAsParent().withTaskContent()); - data.createCollection(GenCollection().withId(43).withName("child").withParent(42).withTaskContent()); + data.createCollection(GenCollection().withId(42).withName(QStringLiteral("parent")).withRootAsParent().withTaskContent()); + data.createCollection(GenCollection().withId(43).withName(QStringLiteral("child")).withParent(42).withTaskContent()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); Domain::DataSource::Ptr parentSource = serializer->createDataSourceFromCollection(data.collection(42), Akonadi::SerializerInterface::BaseName); // WHEN QScopedPointer queries(new Akonadi::DataSourceQueries(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes, Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findSearchChildren(parentSource); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } }; ZANSHIN_TEST_MAIN(AkonadiDataSourceQueriesTest) #include "akonadidatasourcequeriestest.moc" diff --git a/tests/units/akonadi/akonadilivequeryhelperstest.cpp b/tests/units/akonadi/akonadilivequeryhelperstest.cpp index d780136e..d08abc8f 100644 --- a/tests/units/akonadi/akonadilivequeryhelperstest.cpp +++ b/tests/units/akonadi/akonadilivequeryhelperstest.cpp @@ -1,822 +1,822 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonadilivequeryhelpers.h" #include #include #include #include #include "akonadi/akonadiserializer.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gennote.h" #include "testlib/gentag.h" #include "testlib/gentodo.h" #include "testlib/testhelpers.h" using namespace Testlib; using namespace std::placeholders; Q_DECLARE_METATYPE(Akonadi::StorageInterface::FetchContentTypes) static QString titleFromItem(const Akonadi::Item &item) { if (item.hasPayload()) { const auto todo = item.payload(); return todo->summary(); } else if (item.hasPayload()) { const auto message = item.payload(); const Akonadi::NoteUtils::NoteMessageWrapper note(message); return note.title(); } else { return QString(); } } class AkonadiLiveQueryHelpersTest : public QObject { Q_OBJECT private: Akonadi::LiveQueryHelpers::Ptr createHelpers(AkonadiFakeData &data) { return Akonadi::LiveQueryHelpers::Ptr(new Akonadi::LiveQueryHelpers(createSerializer(), createStorage(data))); } Akonadi::StorageInterface::Ptr createStorage(AkonadiFakeData &data) { return Akonadi::StorageInterface::Ptr(data.createStorage()); } Akonadi::SerializerInterface::Ptr createSerializer() { return Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); } private slots: void shouldFetchAllCollectionsForType_data() { QTest::addColumn("contentTypes"); QTest::newRow("task collections only") << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Tasks); QTest::newRow("note collections only") << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Notes); QTest::newRow("task and note collections only") << (Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); QTest::newRow("all collections") << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::AllContent); } void shouldFetchAllCollectionsForType() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Three top level collections (any content, tasks and notes) - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43").withTaskContent()); - data.createCollection(GenCollection().withId(44).withRootAsParent().withName("44").withNoteContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43")).withTaskContent()); + data.createCollection(GenCollection().withId(44).withRootAsParent().withName(QStringLiteral("44")).withNoteContent()); // Three children under each of the top level for each content type - data.createCollection(GenCollection().withId(45).withParent(42).withName("45")); - data.createCollection(GenCollection().withId(46).withParent(42).withName("46").withTaskContent()); - data.createCollection(GenCollection().withId(47).withParent(42).withName("47").withNoteContent()); - data.createCollection(GenCollection().withId(48).withParent(43).withName("48")); - data.createCollection(GenCollection().withId(49).withParent(43).withName("49").withTaskContent()); - data.createCollection(GenCollection().withId(50).withParent(43).withName("50").withNoteContent()); - data.createCollection(GenCollection().withId(51).withParent(44).withName("51")); - data.createCollection(GenCollection().withId(52).withParent(44).withName("52").withTaskContent()); - data.createCollection(GenCollection().withId(53).withParent(44).withName("53").withNoteContent()); + data.createCollection(GenCollection().withId(45).withParent(42).withName(QStringLiteral("45"))); + data.createCollection(GenCollection().withId(46).withParent(42).withName(QStringLiteral("46")).withTaskContent()); + data.createCollection(GenCollection().withId(47).withParent(42).withName(QStringLiteral("47")).withNoteContent()); + data.createCollection(GenCollection().withId(48).withParent(43).withName(QStringLiteral("48"))); + data.createCollection(GenCollection().withId(49).withParent(43).withName(QStringLiteral("49")).withTaskContent()); + data.createCollection(GenCollection().withId(50).withParent(43).withName(QStringLiteral("50")).withNoteContent()); + data.createCollection(GenCollection().withId(51).withParent(44).withName(QStringLiteral("51"))); + data.createCollection(GenCollection().withId(52).withParent(44).withName(QStringLiteral("52")).withTaskContent()); + data.createCollection(GenCollection().withId(53).withParent(44).withName(QStringLiteral("53")).withNoteContent()); // The list which will be filled by the fetch function auto collections = Akonadi::Collection::List(); auto add = [&collections] (const Akonadi::Collection &collection) { collections.append(collection); }; // WHEN QFETCH(Akonadi::StorageInterface::FetchContentTypes, contentTypes); auto fetch = helpers->fetchAllCollections(contentTypes); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN auto expected = QStringList(); if (contentTypes == Akonadi::StorageInterface::AllContent) { - expected << "42" << "45" << "48" << "51"; + expected << QStringLiteral("42") << QStringLiteral("45") << QStringLiteral("48") << QStringLiteral("51"); } if ((contentTypes & Akonadi::StorageInterface::Tasks) || contentTypes == Akonadi::StorageInterface::AllContent) { - expected << "43" << "46" << "49" << "52"; + expected << QStringLiteral("43") << QStringLiteral("46") << QStringLiteral("49") << QStringLiteral("52"); } if ((contentTypes & Akonadi::StorageInterface::Notes) || contentTypes == Akonadi::StorageInterface::AllContent) { - expected << "44" << "47" << "50" << "53"; + expected << QStringLiteral("44") << QStringLiteral("47") << QStringLiteral("50") << QStringLiteral("53"); } expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); collections.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); QCOMPARE(result, expected); } void shouldFetchCollectionsForRootAndType_data() { QTest::addColumn("root"); QTest::addColumn("contentTypes"); QTest::newRow("task collections only from root") << Akonadi::Collection::root() << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Tasks); QTest::newRow("note collections only from root") << Akonadi::Collection::root() << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Notes); QTest::newRow("task and note collections only from root") << Akonadi::Collection::root() << (Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); QTest::newRow("all collections from root") << Akonadi::Collection::root() << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::AllContent); QTest::newRow("task collections only from 'all branch'") << Akonadi::Collection(42) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Tasks); QTest::newRow("note collections only from 'all branch'") << Akonadi::Collection(42) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Notes); QTest::newRow("task and note collections only from 'all branch'") << Akonadi::Collection(42) << (Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); QTest::newRow("all collections from 'all branch'") << Akonadi::Collection(42) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::AllContent); QTest::newRow("task collections only from 'task branch'") << Akonadi::Collection(43) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Tasks); QTest::newRow("note collections only from 'task branch'") << Akonadi::Collection(43) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Notes); QTest::newRow("task and note collections only from 'task branch'") << Akonadi::Collection(43) << (Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); QTest::newRow("all collections from 'task branch'") << Akonadi::Collection(43) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::AllContent); QTest::newRow("task collections only from 'note branch'") << Akonadi::Collection(44) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Tasks); QTest::newRow("note collections only from 'note branch'") << Akonadi::Collection(44) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Notes); QTest::newRow("task and note collections only from 'note branch'") << Akonadi::Collection(44) << (Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); QTest::newRow("all collections from 'note branch'") << Akonadi::Collection(44) << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::AllContent); } void shouldFetchCollectionsForRootAndType() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Three top level collections (any content, tasks and notes) - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43").withTaskContent()); - data.createCollection(GenCollection().withId(44).withRootAsParent().withName("44").withNoteContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43")).withTaskContent()); + data.createCollection(GenCollection().withId(44).withRootAsParent().withName(QStringLiteral("44")).withNoteContent()); // Three children under each of the top level for each content type - data.createCollection(GenCollection().withId(45).withParent(42).withName("45")); - data.createCollection(GenCollection().withId(46).withParent(42).withName("46").withTaskContent()); - data.createCollection(GenCollection().withId(47).withParent(42).withName("47").withNoteContent()); - data.createCollection(GenCollection().withId(48).withParent(43).withName("48")); - data.createCollection(GenCollection().withId(49).withParent(43).withName("49").withTaskContent()); - data.createCollection(GenCollection().withId(50).withParent(43).withName("50").withNoteContent()); - data.createCollection(GenCollection().withId(51).withParent(44).withName("51")); - data.createCollection(GenCollection().withId(52).withParent(44).withName("52").withTaskContent()); - data.createCollection(GenCollection().withId(53).withParent(44).withName("53").withNoteContent()); + data.createCollection(GenCollection().withId(45).withParent(42).withName(QStringLiteral("45"))); + data.createCollection(GenCollection().withId(46).withParent(42).withName(QStringLiteral("46")).withTaskContent()); + data.createCollection(GenCollection().withId(47).withParent(42).withName(QStringLiteral("47")).withNoteContent()); + data.createCollection(GenCollection().withId(48).withParent(43).withName(QStringLiteral("48"))); + data.createCollection(GenCollection().withId(49).withParent(43).withName(QStringLiteral("49")).withTaskContent()); + data.createCollection(GenCollection().withId(50).withParent(43).withName(QStringLiteral("50")).withNoteContent()); + data.createCollection(GenCollection().withId(51).withParent(44).withName(QStringLiteral("51"))); + data.createCollection(GenCollection().withId(52).withParent(44).withName(QStringLiteral("52")).withTaskContent()); + data.createCollection(GenCollection().withId(53).withParent(44).withName(QStringLiteral("53")).withNoteContent()); // The list which will be filled by the fetch function auto collections = Akonadi::Collection::List(); auto add = [&collections] (const Akonadi::Collection &collection) { collections.append(collection); }; // WHEN QFETCH(Akonadi::Collection, root); QFETCH(Akonadi::StorageInterface::FetchContentTypes, contentTypes); auto fetch = helpers->fetchCollections(root, contentTypes); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN auto expected = QStringList(); if (root == Akonadi::Collection::root()) { - expected << "42" << "43" << "44"; + expected << QStringLiteral("42") << QStringLiteral("43") << QStringLiteral("44"); } else { const qint64 baseId = root.id() == 42 ? 45 : root.id() == 43 ? 48 : root.id() == 44 ? 51 : -1; QVERIFY(baseId > 0); if (contentTypes == Akonadi::StorageInterface::AllContent) { expected << QString::number(baseId); } if ((contentTypes & Akonadi::StorageInterface::Tasks) || contentTypes == Akonadi::StorageInterface::AllContent) { expected << QString::number(baseId + 1); } if ((contentTypes & Akonadi::StorageInterface::Notes) || contentTypes == Akonadi::StorageInterface::AllContent) { expected << QString::number(baseId + 2); } } expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); collections.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); QCOMPARE(result, expected); } void shouldSearchCollectionsForRootAndTerm_data() { QTest::addColumn("root"); QTest::newRow("search from root") << Akonadi::Collection::root(); QTest::newRow("search from no content branch") << Akonadi::Collection(42); QTest::newRow("search from in branch") << Akonadi::Collection(43); QTest::newRow("search from ex branch") << Akonadi::Collection(44); } void shouldSearchCollectionsForRootAndTerm() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Three top level collections (any content, tasks and notes) - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42in")); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43in").withTaskContent()); - data.createCollection(GenCollection().withId(44).withRootAsParent().withName("44ex").withNoteContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42in"))); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43in")).withTaskContent()); + data.createCollection(GenCollection().withId(44).withRootAsParent().withName(QStringLiteral("44ex")).withNoteContent()); // Three children under each of the top level for each content type - data.createCollection(GenCollection().withId(45).withParent(42).withName("45in")); - data.createCollection(GenCollection().withId(46).withParent(42).withName("46in").withNoteContent()); - data.createCollection(GenCollection().withId(47).withParent(42).withName("47ex").withTaskContent()); - data.createCollection(GenCollection().withId(48).withParent(43).withName("48in")); - data.createCollection(GenCollection().withId(49).withParent(43).withName("49in").withTaskContent()); - data.createCollection(GenCollection().withId(50).withParent(43).withName("50ex").withNoteContent()); - data.createCollection(GenCollection().withId(51).withParent(44).withName("51in")); - data.createCollection(GenCollection().withId(52).withParent(44).withName("52in").withTaskContent()); - data.createCollection(GenCollection().withId(53).withParent(44).withName("53ex").withNoteContent()); + data.createCollection(GenCollection().withId(45).withParent(42).withName(QStringLiteral("45in"))); + data.createCollection(GenCollection().withId(46).withParent(42).withName(QStringLiteral("46in")).withNoteContent()); + data.createCollection(GenCollection().withId(47).withParent(42).withName(QStringLiteral("47ex")).withTaskContent()); + data.createCollection(GenCollection().withId(48).withParent(43).withName(QStringLiteral("48in"))); + data.createCollection(GenCollection().withId(49).withParent(43).withName(QStringLiteral("49in")).withTaskContent()); + data.createCollection(GenCollection().withId(50).withParent(43).withName(QStringLiteral("50ex")).withNoteContent()); + data.createCollection(GenCollection().withId(51).withParent(44).withName(QStringLiteral("51in"))); + data.createCollection(GenCollection().withId(52).withParent(44).withName(QStringLiteral("52in")).withTaskContent()); + data.createCollection(GenCollection().withId(53).withParent(44).withName(QStringLiteral("53ex")).withNoteContent()); // The list which will be filled by the fetch function auto collections = Akonadi::Collection::List(); auto add = [&collections] (const Akonadi::Collection &collection) { collections.append(collection); }; // WHEN (no search term) QFETCH(Akonadi::Collection, root); auto term = QString(); auto fetch = helpers->searchCollections(root, &term, Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN auto expected = QStringList(); QCOMPARE(result, expected); // WHEN ("in" search term) collections.clear(); result.clear(); expected.clear(); - term = "in"; + term = QStringLiteral("in"); fetch(add); TestHelpers::waitForEmptyJobQueue(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN if (root == Akonadi::Collection::root()) { - expected << "42in" << "43in" << "44ex"; + expected << QStringLiteral("42in") << QStringLiteral("43in") << QStringLiteral("44ex"); } else { switch (root.id()) { case 42: - expected << "46in"; + expected << QStringLiteral("46in"); break; case 43: - expected << "49in"; + expected << QStringLiteral("49in"); break; case 44: - expected << "52in"; + expected << QStringLiteral("52in"); break; } QVERIFY(!expected.isEmpty()); } expected.sort(); QCOMPARE(result, expected); // WHEN ("ex" search term) collections.clear(); result.clear(); expected.clear(); - term = "ex"; + term = QStringLiteral("ex"); fetch(add); TestHelpers::waitForEmptyJobQueue(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN if (root == Akonadi::Collection::root()) { - expected << "42in" << "43in" << "44ex"; + expected << QStringLiteral("42in") << QStringLiteral("43in") << QStringLiteral("44ex"); } else { switch (root.id()) { case 42: - expected << "47ex"; + expected << QStringLiteral("47ex"); break; case 43: - expected << "50ex"; + expected << QStringLiteral("50ex"); break; case 44: - expected << "53ex"; + expected << QStringLiteral("53ex"); break; } QVERIFY(!expected.isEmpty()); } expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); collections.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); QCOMPARE(result, expected); } void shouldSearchCollectionsForContentTypes_data() { QTest::addColumn("contentTypes"); QTest::addColumn("expected"); auto expected = QStringList(); - expected << "42-foo-all" << "43-foo-task" << "44-foo-note"; + expected << QStringLiteral("42-foo-all") << QStringLiteral("43-foo-task") << QStringLiteral("44-foo-note"); QTest::newRow("all") << int(Akonadi::StorageInterface::AllContent) << expected; expected.clear(); - expected << "43-foo-task" << "44-foo-note"; + expected << QStringLiteral("43-foo-task") << QStringLiteral("44-foo-note"); QTest::newRow("task + note") << int(Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes) << expected; expected.clear(); - expected << "43-foo-task"; + expected << QStringLiteral("43-foo-task"); QTest::newRow("task") << int(Akonadi::StorageInterface::Tasks) << expected; expected.clear(); - expected << "44-foo-note"; + expected << QStringLiteral("44-foo-note"); QTest::newRow("note") << int(Akonadi::StorageInterface::Notes) << expected; } void shouldSearchCollectionsForContentTypes() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Three top level collections (any content, tasks and notes) - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42-foo-all")); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43-foo-task").withTaskContent()); - data.createCollection(GenCollection().withId(44).withRootAsParent().withName("44-foo-note").withNoteContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42-foo-all"))); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43-foo-task")).withTaskContent()); + data.createCollection(GenCollection().withId(44).withRootAsParent().withName(QStringLiteral("44-foo-note")).withNoteContent()); // The list which will be filled by the fetch function auto collections = Akonadi::Collection::List(); auto add = [&collections] (const Akonadi::Collection &collection) { collections.append(collection); }; // WHEN (no search term) QFETCH(int, contentTypes); auto term = QString(); auto fetch = helpers->searchCollections(Akonadi::Collection::root(), &term, Akonadi::StorageInterface::FetchContentTypes(contentTypes)); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN QCOMPARE(result, QStringList()); // WHEN ("foo" search term) collections.clear(); result.clear(); - term = "foo"; + term = QStringLiteral("foo"); fetch(add); TestHelpers::waitForEmptyJobQueue(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); // THEN QFETCH(QStringList, expected); expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); collections.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Collection::displayName, _1)); result.sort(); QCOMPARE(result, expected); } void shouldFetchItemsByContentTypes_data() { QTest::addColumn("contentTypes"); QTest::newRow("task collections only") << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Tasks); QTest::newRow("note collections only") << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::Notes); QTest::newRow("task and note collections only") << (Akonadi::StorageInterface::Tasks | Akonadi::StorageInterface::Notes); QTest::newRow("all collections") << Akonadi::StorageInterface::FetchContentTypes(Akonadi::StorageInterface::AllContent); } void shouldFetchItemsByContentTypes() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Two top level collections, one with no particular content, one with tasks - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43").withTaskContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43")).withTaskContent()); // One note collection as child of the first one - data.createCollection(GenCollection().withId(44).withParent(42).withName("44").withNoteContent()); + data.createCollection(GenCollection().withId(44).withParent(42).withName(QStringLiteral("44")).withNoteContent()); // One task collection as child of the note collection - data.createCollection(GenCollection().withId(45).withParent(44).withName("45").withTaskContent()); + data.createCollection(GenCollection().withId(45).withParent(44).withName(QStringLiteral("45")).withTaskContent()); // One task in the first collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // Two items (tasks or notes) in all the other collections - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(43).withTitle("44")); - data.createItem(GenNote().withId(45).withParent(44).withTitle("45")); - data.createItem(GenNote().withId(46).withParent(44).withTitle("46")); - data.createItem(GenTodo().withId(47).withParent(45).withTitle("47")); - data.createItem(GenTodo().withId(48).withParent(45).withTitle("48")); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44"))); + data.createItem(GenNote().withId(45).withParent(44).withTitle(QStringLiteral("45"))); + data.createItem(GenNote().withId(46).withParent(44).withTitle(QStringLiteral("46"))); + data.createItem(GenTodo().withId(47).withParent(45).withTitle(QStringLiteral("47"))); + data.createItem(GenTodo().withId(48).withParent(45).withTitle(QStringLiteral("48"))); // The list which will be filled by the fetch function auto items = Akonadi::Item::List(); auto add = [&items] (const Akonadi::Item &item) { items.append(item); }; // WHEN QFETCH(Akonadi::StorageInterface::FetchContentTypes, contentTypes); auto fetch = helpers->fetchItems(contentTypes); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(items.constBegin(), items.constEnd(), std::back_inserter(result), titleFromItem); result.sort(); // THEN auto expected = QStringList(); if ((contentTypes & Akonadi::StorageInterface::Tasks) || contentTypes == Akonadi::StorageInterface::AllContent) { - expected << "43" << "44" << "47" << "48"; + expected << QStringLiteral("43") << QStringLiteral("44") << QStringLiteral("47") << QStringLiteral("48"); } if ((contentTypes & Akonadi::StorageInterface::Notes) || contentTypes == Akonadi::StorageInterface::AllContent) { - expected << "45" << "46"; + expected << QStringLiteral("45") << QStringLiteral("46"); } expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); items.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(items.constBegin(), items.constEnd(), std::back_inserter(result), titleFromItem); result.sort(); QCOMPARE(result, expected); } void shouldFetchItemsByTag_data() { QTest::addColumn("tag"); QTest::newRow("first tag") << Akonadi::Tag(42); QTest::newRow("second tag") << Akonadi::Tag(43); } void shouldFetchItemsByTag() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Two top level collections with tasks - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42").withTaskContent()); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43").withTaskContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42")).withTaskContent()); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43")).withTaskContent()); // Two tags data.createTag(GenTag().withId(42)); data.createTag(GenTag().withId(43)); // Four items in each collection, one with no tag, one with the first tag, // one with the second tag, last one with both tags - data.createItem(GenTodo().withId(42).withParent(42).withTags({}).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(42).withTags({42}).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(42).withTags({43}).withTitle("44")); - data.createItem(GenTodo().withId(45).withParent(42).withTags({42, 43}).withTitle("45")); - data.createItem(GenTodo().withId(46).withParent(43).withTags({}).withTitle("46")); - data.createItem(GenTodo().withId(47).withParent(43).withTags({42}).withTitle("47")); - data.createItem(GenTodo().withId(48).withParent(43).withTags({43}).withTitle("48")); - data.createItem(GenTodo().withId(49).withParent(43).withTags({42, 43}).withTitle("49")); + data.createItem(GenTodo().withId(42).withParent(42).withTags({}).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(42).withTags({42}).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(42).withTags({43}).withTitle(QStringLiteral("44"))); + data.createItem(GenTodo().withId(45).withParent(42).withTags({42, 43}).withTitle(QStringLiteral("45"))); + data.createItem(GenTodo().withId(46).withParent(43).withTags({}).withTitle(QStringLiteral("46"))); + data.createItem(GenTodo().withId(47).withParent(43).withTags({42}).withTitle(QStringLiteral("47"))); + data.createItem(GenTodo().withId(48).withParent(43).withTags({43}).withTitle(QStringLiteral("48"))); + data.createItem(GenTodo().withId(49).withParent(43).withTags({42, 43}).withTitle(QStringLiteral("49"))); // The list which will be filled by the fetch function auto items = Akonadi::Item::List(); auto add = [&items] (const Akonadi::Item &item) { items.append(item); }; // WHEN QFETCH(Akonadi::Tag, tag); auto fetch = helpers->fetchItems(tag); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(items.constBegin(), items.constEnd(), std::back_inserter(result), titleFromItem); result.sort(); // THEN auto expected = QStringList(); switch (tag.id()) { case 42: - expected << "43" << "45" << "47" << "49"; + expected << QStringLiteral("43") << QStringLiteral("45") << QStringLiteral("47") << QStringLiteral("49"); break; case 43: - expected << "44" << "45" << "48" << "49"; + expected << QStringLiteral("44") << QStringLiteral("45") << QStringLiteral("48") << QStringLiteral("49"); break; } QVERIFY(!expected.isEmpty()); expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); items.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(items.constBegin(), items.constEnd(), std::back_inserter(result), titleFromItem); result.sort(); QCOMPARE(result, expected); } void shouldFetchSiblings_data() { QTest::addColumn("item"); QTest::newRow("item in first collection") << Akonadi::Item(43); QTest::newRow("item in second collection") << Akonadi::Item(48); } void shouldFetchSiblings() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Two top level collections (one with notes, one with tasks) - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42").withTaskContent()); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43").withNoteContent()); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42")).withTaskContent()); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43")).withNoteContent()); // Four items in each collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44")); - data.createItem(GenTodo().withId(45).withParent(42).withTitle("45")); - data.createItem(GenNote().withId(46).withParent(43).withTitle("46")); - data.createItem(GenNote().withId(47).withParent(43).withTitle("47")); - data.createItem(GenNote().withId(48).withParent(43).withTitle("48")); - data.createItem(GenNote().withId(49).withParent(43).withTitle("49")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44"))); + data.createItem(GenTodo().withId(45).withParent(42).withTitle(QStringLiteral("45"))); + data.createItem(GenNote().withId(46).withParent(43).withTitle(QStringLiteral("46"))); + data.createItem(GenNote().withId(47).withParent(43).withTitle(QStringLiteral("47"))); + data.createItem(GenNote().withId(48).withParent(43).withTitle(QStringLiteral("48"))); + data.createItem(GenNote().withId(49).withParent(43).withTitle(QStringLiteral("49"))); // The list which will be filled by the fetch function auto items = Akonadi::Item::List(); auto add = [&items] (const Akonadi::Item &item) { items.append(item); }; // WHEN QFETCH(Akonadi::Item, item); auto fetch = helpers->fetchSiblings(item); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(items.constBegin(), items.constEnd(), std::back_inserter(result), titleFromItem); result.sort(); // THEN auto expected = QStringList(); switch (item.id()) { case 43: - expected << "42" << "43" << "44" << "45"; + expected << QStringLiteral("42") << QStringLiteral("43") << QStringLiteral("44") << QStringLiteral("45"); break; case 48: - expected << "46" << "47" << "48" << "49"; + expected << QStringLiteral("46") << QStringLiteral("47") << QStringLiteral("48") << QStringLiteral("49"); break; } QVERIFY(!expected.isEmpty()); expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); items.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(items.constBegin(), items.constEnd(), std::back_inserter(result), titleFromItem); result.sort(); QCOMPARE(result, expected); } void shouldFetchTags() { // GIVEN auto data = AkonadiFakeData(); auto helpers = createHelpers(data); // Two tags (one plain, one context) - data.createTag(GenTag().withId(42).withName("42").asPlain()); - data.createTag(GenTag().withId(43).withName("43").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asPlain()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asContext()); // The list which will be filled by the fetch function auto tags = Akonadi::Tag::List(); auto add = [&tags] (const Akonadi::Tag &tag) { tags.append(tag); }; // WHEN auto fetch = helpers->fetchTags(); fetch(add); TestHelpers::waitForEmptyJobQueue(); auto result = QStringList(); std::transform(tags.constBegin(), tags.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Tag::name, _1)); result.sort(); // THEN auto expected = QStringList({"42", "43"}); expected.sort(); QCOMPARE(result, expected); // WHEN (should not crash when the helpers object is deleted) helpers.clear(); tags.clear(); fetch(add); TestHelpers::waitForEmptyJobQueue(); // THEN result.clear(); std::transform(tags.constBegin(), tags.constEnd(), std::back_inserter(result), std::bind(&Akonadi::Tag::name, _1)); result.sort(); QCOMPARE(result, expected); } }; ZANSHIN_TEST_MAIN(AkonadiLiveQueryHelpersTest) #include "akonadilivequeryhelperstest.moc" diff --git a/tests/units/akonadi/akonadilivequeryintegratortest.cpp b/tests/units/akonadi/akonadilivequeryintegratortest.cpp index db00fd40..de4c52cf 100644 --- a/tests/units/akonadi/akonadilivequeryintegratortest.cpp +++ b/tests/units/akonadi/akonadilivequeryintegratortest.cpp @@ -1,1620 +1,1620 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include "akonadi/akonadicollectionfetchjobinterface.h" #include "akonadi/akonadiitemfetchjobinterface.h" #include "akonadi/akonaditagfetchjobinterface.h" #include "akonadi/akonadilivequeryintegrator.h" #include "akonadi/akonadiserializer.h" #include "akonadi/akonadistorage.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gennote.h" #include "testlib/gentag.h" #include "testlib/gentodo.h" #include "testlib/testhelpers.h" #include "utils/jobhandler.h" using namespace Testlib; static QString titleFromItem(const Akonadi::Item &item) { if (item.hasPayload()) { const auto todo = item.payload(); return todo->summary(); } else if (item.hasPayload()) { const auto message = item.payload(); const Akonadi::NoteUtils::NoteMessageWrapper note(message); return note.title(); } else { return QString(); } } class AkonadiLiveQueryIntegratorTest : public QObject { Q_OBJECT private: Akonadi::LiveQueryIntegrator::Ptr createIntegrator(AkonadiFakeData &data) { return Akonadi::LiveQueryIntegrator::Ptr( new Akonadi::LiveQueryIntegrator(createSerializer(), Akonadi::MonitorInterface::Ptr(data.createMonitor()) ) ); } Akonadi::StorageInterface::Ptr createStorage(AkonadiFakeData &data) { return Akonadi::StorageInterface::Ptr(data.createStorage()); } Akonadi::SerializerInterface::Ptr createSerializer() { return Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); } private slots: void shouldBindArtifactQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // Three artifacts in the collection, one not matching the predicate - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42-in")); - data.createItem(GenNote().withId(43).withParent(42).withTitle("43-in")); - data.createItem(GenNote().withId(44).withParent(42).withTitle("44-ex")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42-in"))); + data.createItem(GenNote().withId(43).withParent(42).withTitle(QStringLiteral("43-in"))); + data.createItem(GenNote().withId(44).withParent(42).withTitle(QStringLiteral("44-ex"))); // Couple of projects in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(42).asProject().withTitle("41-in")); + data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(42).asProject().withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createItem(GenTodo().withId(45).withParent(42).withTitle("45-in")); + data.createItem(GenTodo().withId(45).withParent(42).withTitle(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); - QCOMPARE(result->data().at(2)->title(), QString("45-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeItem(Akonadi::Item(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42-bis-in")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyItem(GenNote(data.item(44)).withTitle("44-in")); + data.modifyItem(GenNote(data.item(44)).withTitle(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); - QCOMPARE(result->data().at(2)->title(), QString("44-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyItem(GenNote(data.item(44)).withTitle("44-ex")); + data.modifyItem(GenNote(data.item(44)).withTitle(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveArtifactsBetweenQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // One task and one note which show in one query and not the other - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42-in")); - data.createItem(GenNote().withId(43).withParent(42).withTitle("43-in")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42-in"))); + data.createItem(GenNote().withId(43).withParent(42).withTitle(QStringLiteral("43-in"))); // Couple of projects in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(39).withParent(42).asProject().withTitle("39")); - data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle("40-ex")); - data.createItem(GenTodo().withId(41).withParent(42).asProject().withTitle("41-in")); + data.createItem(GenTodo().withId(39).withParent(42).asProject().withTitle(QStringLiteral("39"))); + data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle(QStringLiteral("40-ex"))); + data.createItem(GenTodo().withId(41).withParent(42).asProject().withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto inPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-ex"); + return titleFromItem(item).endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 2); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42-ex")); - data.modifyItem(GenNote(data.item(43)).withTitle("43-ex")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42-ex"))); + data.modifyItem(GenNote(data.item(43)).withTitle(QStringLiteral("43-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 2); } void shouldReactToCollectionSelectionChangesForArtifactQueries() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in each collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); // Couple of projects in the collections which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(43).asProject().withTitle("41")); + data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(43).asProject().withTitle(QStringLiteral("41"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto serializer = createSerializer(); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage, serializer] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage, serializer] { foreach (const auto &col, job->collections()) { if (!serializer->isSelectedCollection(col)) continue; auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &) { return true; }; integrator->bind(query, fetch, predicate); auto result = query->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldBindContextQueries() { // GIVEN AkonadiFakeData data; // Three context tags, one not matching the predicate - data.createTag(GenTag().withId(42).asContext().withName("42-in")); - data.createTag(GenTag().withId(43).asContext().withName("43-in")); - data.createTag(GenTag().withId(44).asContext().withName("44-ex")); + data.createTag(GenTag().withId(42).asContext().withName(QStringLiteral("42-in"))); + data.createTag(GenTag().withId(43).asContext().withName(QStringLiteral("43-in"))); + data.createTag(GenTag().withId(44).asContext().withName(QStringLiteral("44-ex"))); // Couple of plain tags which should not appear or create trouble - data.createTag(GenTag().withId(40).asPlain().withName("40")); - data.createTag(GenTag().withId(41).asPlain().withName("41-in")); + data.createTag(GenTag().withId(40).asPlain().withName(QStringLiteral("40"))); + data.createTag(GenTag().withId(41).asPlain().withName(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchTags(); Utils::JobHandler::install(job->kjob(), [add, job] { foreach (const auto &tag, job->tags()) { add(tag); } }); }; auto predicate = [] (const Akonadi::Tag &tag) { - return tag.name().endsWith("-in"); + return tag.name().endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createTag(GenTag().withId(45).asContext().withName("45-in")); + data.createTag(GenTag().withId(45).asContext().withName(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("45-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeTag(Akonadi::Tag(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyTag(GenTag(data.tag(42)).withName("42-bis-in")); + data.modifyTag(GenTag(data.tag(42)).withName(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyTag(GenTag(data.tag(44)).withName("44-in")); + data.modifyTag(GenTag(data.tag(44)).withName(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("44-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyTag(GenTag(data.tag(44)).withName("44-ex")); + data.modifyTag(GenTag(data.tag(44)).withName(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveContextBetweenQueries() { // GIVEN AkonadiFakeData data; // One context tag which shows in one query not the other - data.createTag(GenTag().withId(42).asContext().withName("42-in")); + data.createTag(GenTag().withId(42).asContext().withName(QStringLiteral("42-in"))); // Couple of plain tags which should not appear or create trouble - data.createTag(GenTag().withId(39).asPlain().withName("39")); - data.createTag(GenTag().withId(40).asPlain().withName("40-ex")); - data.createTag(GenTag().withId(41).asPlain().withName("41-in")); + data.createTag(GenTag().withId(39).asPlain().withName(QStringLiteral("39"))); + data.createTag(GenTag().withId(40).asPlain().withName(QStringLiteral("40-ex"))); + data.createTag(GenTag().withId(41).asPlain().withName(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchTags(); Utils::JobHandler::install(job->kjob(), [add, job] { foreach (const auto &tag, job->tags()) { add(tag); } }); }; auto inPredicate = [] (const Akonadi::Tag &tag) { - return tag.name().endsWith("-in"); + return tag.name().endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Tag &tag) { - return tag.name().endsWith("-ex"); + return tag.name().endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 1); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyTag(GenTag(data.tag(42)).withName("42-ex")); + data.modifyTag(GenTag(data.tag(42)).withName(QStringLiteral("42-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 1); } void shouldBindDataSourceQueries() { // GIVEN AkonadiFakeData data; // Three top level collections, one not matching the predicate - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42-in")); - data.createCollection(GenCollection().withId(43).withRootAsParent().withName("43-in")); - data.createCollection(GenCollection().withId(44).withRootAsParent().withName("44-ex")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42-in"))); + data.createCollection(GenCollection().withId(43).withRootAsParent().withName(QStringLiteral("43-in"))); + data.createCollection(GenCollection().withId(44).withRootAsParent().withName(QStringLiteral("44-ex"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job] { foreach (const auto &col, job->collections()) { add(col); } }); }; auto predicate = [] (const Akonadi::Collection &collection) { - return collection.name().endsWith("-in"); + return collection.name().endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createCollection(GenCollection().withId(45).withRootAsParent().withName("45-in")); + data.createCollection(GenCollection().withId(45).withRootAsParent().withName(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("45-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeCollection(Akonadi::Collection(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyCollection(GenCollection(data.collection(42)).withName("42-bis-in")); + data.modifyCollection(GenCollection(data.collection(42)).withName(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyCollection(GenCollection(data.collection(44)).withName("44-in")); + data.modifyCollection(GenCollection(data.collection(44)).withName(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("44-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyCollection(GenCollection(data.collection(44)).withName("44-ex")); + data.modifyCollection(GenCollection(data.collection(44)).withName(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveDataSourceBetweenQueries() { // GIVEN AkonadiFakeData data; // One top level collection which shows in one query not the other - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42-in")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job] { foreach (const auto &col, job->collections()) { add(col); } }); }; auto inPredicate = [] (const Akonadi::Collection &collection) { - return collection.name().endsWith("-in"); + return collection.name().endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Collection &collection) { - return collection.name().endsWith("-ex"); + return collection.name().endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 1); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyCollection(GenCollection(data.collection(42)).withName("42-ex")); + data.modifyCollection(GenCollection(data.collection(42)).withName(QStringLiteral("42-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 1); } void shouldBindNoteQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // Three notes in the collection, one not matching the predicate - data.createItem(GenNote().withId(42).withParent(42).withTitle("42-in")); - data.createItem(GenNote().withId(43).withParent(42).withTitle("43-in")); - data.createItem(GenNote().withId(44).withParent(42).withTitle("44-ex")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42-in"))); + data.createItem(GenNote().withId(43).withParent(42).withTitle(QStringLiteral("43-in"))); + data.createItem(GenNote().withId(44).withParent(42).withTitle(QStringLiteral("44-ex"))); // Couple of tasks in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(42).withTitle("41-in")); + data.createItem(GenTodo().withId(40).withParent(42).withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(42).withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createItem(GenNote().withId(45).withParent(42).withTitle("45-in")); + data.createItem(GenNote().withId(45).withParent(42).withTitle(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); - QCOMPARE(result->data().at(2)->title(), QString("45-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeItem(Akonadi::Item(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyItem(GenNote(data.item(42)).withTitle("42-bis-in")); + data.modifyItem(GenNote(data.item(42)).withTitle(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyItem(GenNote(data.item(44)).withTitle("44-in")); + data.modifyItem(GenNote(data.item(44)).withTitle(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); - QCOMPARE(result->data().at(2)->title(), QString("44-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyItem(GenNote(data.item(44)).withTitle("44-ex")); + data.modifyItem(GenNote(data.item(44)).withTitle(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveNotesBetweenQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // One note which shows in one query and not the other - data.createItem(GenNote().withId(42).withParent(42).withTitle("42-in")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42-in"))); // Couple of tasks in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(39).withParent(42).withTitle("39")); - data.createItem(GenTodo().withId(40).withParent(42).withTitle("40-ex")); - data.createItem(GenTodo().withId(41).withParent(42).withTitle("41-in")); + data.createItem(GenTodo().withId(39).withParent(42).withTitle(QStringLiteral("39"))); + data.createItem(GenTodo().withId(40).withParent(42).withTitle(QStringLiteral("40-ex"))); + data.createItem(GenTodo().withId(41).withParent(42).withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto inPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-ex"); + return titleFromItem(item).endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 1); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyItem(GenNote(data.item(42)).withTitle("42-ex")); + data.modifyItem(GenNote(data.item(42)).withTitle(QStringLiteral("42-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 1); } void shouldReactToCollectionSelectionChangesForNoteQueries() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); // One note in each collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); - data.createItem(GenNote().withId(43).withParent(43).withTitle("43")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenNote().withId(43).withParent(43).withTitle(QStringLiteral("43"))); // Couple of tasks in the collections which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(43).withTitle("41")); + data.createItem(GenTodo().withId(40).withParent(42).withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(43).withTitle(QStringLiteral("41"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto serializer = createSerializer(); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage, serializer] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage, serializer] { foreach (const auto &col, job->collections()) { if (!serializer->isSelectedCollection(col)) continue; auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &) { return true; }; integrator->bind(query, fetch, predicate); auto result = query->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldBindProjectQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // Three projects in the collection, one not matching the predicate - data.createItem(GenTodo().withId(42).withParent(42).asProject().withTitle("42-in")); - data.createItem(GenTodo().withId(43).withParent(42).asProject().withTitle("43-in")); - data.createItem(GenTodo().withId(44).withParent(42).asProject().withTitle("44-ex")); + data.createItem(GenTodo().withId(42).withParent(42).asProject().withTitle(QStringLiteral("42-in"))); + data.createItem(GenTodo().withId(43).withParent(42).asProject().withTitle(QStringLiteral("43-in"))); + data.createItem(GenTodo().withId(44).withParent(42).asProject().withTitle(QStringLiteral("44-ex"))); // Couple of tasks in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(42).withTitle("41-in")); + data.createItem(GenTodo().withId(40).withParent(42).withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(42).withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createItem(GenTodo().withId(45).withParent(42).asProject().withTitle("45-in")); + data.createItem(GenTodo().withId(45).withParent(42).asProject().withTitle(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("45-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeItem(Akonadi::Item(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42-bis-in")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyItem(GenTodo(data.item(44)).withTitle("44-in")); + data.modifyItem(GenTodo(data.item(44)).withTitle(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("44-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyItem(GenTodo(data.item(44)).withTitle("44-ex")); + data.modifyItem(GenTodo(data.item(44)).withTitle(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveProjectsBetweenQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // One project which shows in one query and not the other - data.createItem(GenTodo().withId(42).withParent(42).asProject().withTitle("42-in")); + data.createItem(GenTodo().withId(42).withParent(42).asProject().withTitle(QStringLiteral("42-in"))); // Couple of tasks in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(39).withParent(42).withTitle("39")); - data.createItem(GenTodo().withId(40).withParent(42).withTitle("40-ex")); - data.createItem(GenTodo().withId(41).withParent(42).withTitle("41-in")); + data.createItem(GenTodo().withId(39).withParent(42).withTitle(QStringLiteral("39"))); + data.createItem(GenTodo().withId(40).withParent(42).withTitle(QStringLiteral("40-ex"))); + data.createItem(GenTodo().withId(41).withParent(42).withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto inPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-ex"); + return titleFromItem(item).endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 1); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42-ex")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 1); } void shouldReactToCollectionSelectionChangesForProjectQueries() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One project in each collection - data.createItem(GenTodo().withId(42).withParent(42).asProject().withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(43).asProject().withTitle("43")); + data.createItem(GenTodo().withId(42).withParent(42).asProject().withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(43).asProject().withTitle(QStringLiteral("43"))); // Couple of tasks in the collections which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(43).withTitle("41")); + data.createItem(GenTodo().withId(40).withParent(42).withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(43).withTitle(QStringLiteral("41"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto serializer = createSerializer(); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage, serializer] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage, serializer] { foreach (const auto &col, job->collections()) { if (!serializer->isSelectedCollection(col)) continue; auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &) { return true; }; integrator->bind(query, fetch, predicate); auto result = query->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldBindTagQueries() { // GIVEN AkonadiFakeData data; // Three plain tags, one not matching the predicate - data.createTag(GenTag().withId(42).asPlain().withName("42-in")); - data.createTag(GenTag().withId(43).asPlain().withName("43-in")); - data.createTag(GenTag().withId(44).asPlain().withName("44-ex")); + data.createTag(GenTag().withId(42).asPlain().withName(QStringLiteral("42-in"))); + data.createTag(GenTag().withId(43).asPlain().withName(QStringLiteral("43-in"))); + data.createTag(GenTag().withId(44).asPlain().withName(QStringLiteral("44-ex"))); // Couple of context tags which should not appear or create trouble - data.createTag(GenTag().withId(40).asContext().withName("40")); - data.createTag(GenTag().withId(41).asContext().withName("41-in")); + data.createTag(GenTag().withId(40).asContext().withName(QStringLiteral("40"))); + data.createTag(GenTag().withId(41).asContext().withName(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchTags(); Utils::JobHandler::install(job->kjob(), [add, job] { foreach (const auto &tag, job->tags()) { add(tag); } }); }; auto predicate = [] (const Akonadi::Tag &tag) { - return tag.name().endsWith("-in"); + return tag.name().endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createTag(GenTag().withId(45).asPlain().withName("45-in")); + data.createTag(GenTag().withId(45).asPlain().withName(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("45-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeTag(Akonadi::Tag(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyTag(GenTag(data.tag(42)).withName("42-bis-in")); + data.modifyTag(GenTag(data.tag(42)).withName(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyTag(GenTag(data.tag(44)).withName("44-in")); + data.modifyTag(GenTag(data.tag(44)).withName(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); - QCOMPARE(result->data().at(2)->name(), QString("44-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyTag(GenTag(data.tag(44)).withName("44-ex")); + data.modifyTag(GenTag(data.tag(44)).withName(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->name(), QString("43-in")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveTagBetweenQueries() { // GIVEN AkonadiFakeData data; // One plain tag which shows in one query not the other - data.createTag(GenTag().withId(42).asPlain().withName("42-in")); + data.createTag(GenTag().withId(42).asPlain().withName(QStringLiteral("42-in"))); // Couple of context tags which should not appear or create trouble - data.createTag(GenTag().withId(39).asContext().withName("39")); - data.createTag(GenTag().withId(40).asContext().withName("40-ex")); - data.createTag(GenTag().withId(41).asContext().withName("41-in")); + data.createTag(GenTag().withId(39).asContext().withName(QStringLiteral("39"))); + data.createTag(GenTag().withId(40).asContext().withName(QStringLiteral("40-ex"))); + data.createTag(GenTag().withId(41).asContext().withName(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchTags(); Utils::JobHandler::install(job->kjob(), [add, job] { foreach (const auto &tag, job->tags()) { add(tag); } }); }; auto inPredicate = [] (const Akonadi::Tag &tag) { - return tag.name().endsWith("-in"); + return tag.name().endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Tag &tag) { - return tag.name().endsWith("-ex"); + return tag.name().endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 1); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyTag(GenTag(data.tag(42)).withName("42-ex")); + data.modifyTag(GenTag(data.tag(42)).withName(QStringLiteral("42-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 1); } void shouldBindTaskQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // Three tasks in the collection, one not matching the predicate - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42-in")); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43-in")); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44-ex")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42-in"))); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43-in"))); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44-ex"))); // Couple of notes and projects in the collection which should not appear or create trouble - data.createItem(GenTodo().withId(38).withParent(42).asProject().withTitle("38")); - data.createItem(GenTodo().withId(39).withParent(42).asProject().withTitle("39-in")); - data.createItem(GenNote().withId(40).withParent(42).withTitle("40")); - data.createItem(GenNote().withId(41).withParent(42).withTitle("41-in")); + data.createItem(GenTodo().withId(38).withParent(42).asProject().withTitle(QStringLiteral("38"))); + data.createItem(GenTodo().withId(39).withParent(42).asProject().withTitle(QStringLiteral("39-in"))); + data.createItem(GenNote().withId(40).withParent(42).withTitle(QStringLiteral("40"))); + data.createItem(GenNote().withId(41).withParent(42).withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; // Initial listing // WHEN integrator->bind(query, fetch, predicate); auto result = query->result(); result->data(); integrator->bind(query, fetch, predicate); result = query->result(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to add // WHEN - data.createItem(GenTodo().withId(45).withParent(42).withTitle("45-in")); + data.createItem(GenTodo().withId(45).withParent(42).withTitle(QStringLiteral("45-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); - QCOMPARE(result->data().at(2)->title(), QString("45-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("45-in")); // Reacts to remove // WHEN data.removeItem(Akonadi::Item(45)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to change // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42-bis-in")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42-bis-in"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Reacts to change (which adds) // WHEN - data.modifyItem(GenTodo(data.item(44)).withTitle("44-in")); + data.modifyItem(GenTodo(data.item(44)).withTitle(QStringLiteral("44-in"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); - QCOMPARE(result->data().at(2)->title(), QString("44-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44-in")); // Reacts to change (which removes) // WHEN - data.modifyItem(GenTodo(data.item(44)).withTitle("44-ex")); + data.modifyItem(GenTodo(data.item(44)).withTitle(QStringLiteral("44-ex"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42-bis-in")); - QCOMPARE(result->data().at(1)->title(), QString("43-in")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42-bis-in")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43-in")); // Don't keep a reference on any result result.clear(); // The bug we're trying to hit here is the following: // - when bind is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when bind is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 integrator->bind(query, fetch, predicate); auto result = query->result(); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(!result->data().isEmpty()); } } void shouldMoveTasksBetweenQueries() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // One task which shows in one query and not the other - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42-in")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42-in"))); // Couple of notes in the collection which should not appear or create trouble - data.createItem(GenNote().withId(39).withParent(42).withTitle("39")); - data.createItem(GenNote().withId(40).withParent(42).withTitle("40-ex")); - data.createItem(GenNote().withId(41).withParent(42).withTitle("41-in")); + data.createItem(GenNote().withId(39).withParent(42).withTitle(QStringLiteral("39"))); + data.createItem(GenNote().withId(40).withParent(42).withTitle(QStringLiteral("40-ex"))); + data.createItem(GenNote().withId(41).withParent(42).withTitle(QStringLiteral("41-in"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto inQuery = Domain::LiveQueryOutput::Ptr(); auto exQuery = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage] { foreach (const auto &col, job->collections()) { auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto inPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-in"); + return titleFromItem(item).endsWith(QLatin1String("-in")); }; auto exPredicate = [] (const Akonadi::Item &item) { - return titleFromItem(item).endsWith("-ex"); + return titleFromItem(item).endsWith(QLatin1String("-ex")); }; integrator->bind(inQuery, fetch, inPredicate); auto inResult = inQuery->result(); integrator->bind(exQuery, fetch, exPredicate); auto exResult = exQuery->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(inResult->data().size(), 1); QCOMPARE(exResult->data().size(), 0); // WHEN - data.modifyItem(GenTodo(data.item(42)).withTitle("42-ex")); + data.modifyItem(GenTodo(data.item(42)).withTitle(QStringLiteral("42-ex"))); // THEN QCOMPARE(inResult->data().size(), 0); QCOMPARE(exResult->data().size(), 1); } void shouldReactToCollectionSelectionChangesForTaskQueries() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in each collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); // Couple of projects in the collections which should not appear or create trouble - data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle("40")); - data.createItem(GenTodo().withId(41).withParent(43).asProject().withTitle("41")); + data.createItem(GenTodo().withId(40).withParent(42).asProject().withTitle(QStringLiteral("40"))); + data.createItem(GenTodo().withId(41).withParent(43).asProject().withTitle(QStringLiteral("41"))); auto integrator = createIntegrator(data); auto storage = createStorage(data); auto serializer = createSerializer(); auto query = Domain::LiveQueryOutput::Ptr(); auto fetch = [storage, serializer] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::AllContent); Utils::JobHandler::install(job->kjob(), [add, job, storage, serializer] { foreach (const auto &col, job->collections()) { if (!serializer->isSelectedCollection(col)) continue; auto itemJob = storage->fetchItems(col); Utils::JobHandler::install(itemJob->kjob(), [add, itemJob] { foreach (const auto &item, itemJob->items()) add(item); }); } }); }; auto predicate = [] (const Akonadi::Item &) { return true; }; integrator->bind(query, fetch, predicate); auto result = query->result(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldCallCollectionRemoveHandlers() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); auto integrator = createIntegrator(data); qint64 removedId = -1; integrator->addRemoveHandler([&removedId] (const Akonadi::Collection &collection) { removedId = collection.id(); }); // WHEN data.removeCollection(Akonadi::Collection(42)); // THEN QCOMPARE(removedId, qint64(42)); } void shouldCallItemRemoveHandlers() { // GIVEN AkonadiFakeData data; // One top level collection - data.createCollection(GenCollection().withId(42).withRootAsParent().withName("42")); + data.createCollection(GenCollection().withId(42).withRootAsParent().withName(QStringLiteral("42"))); // One item in the collection data.createItem(GenTodo().withId(42).withParent(42)); auto integrator = createIntegrator(data); qint64 removedId = -1; integrator->addRemoveHandler([&removedId] (const Akonadi::Item &item) { removedId = item.id(); }); // WHEN data.removeItem(Akonadi::Item(42)); // THEN QCOMPARE(removedId, qint64(42)); } void shouldCallTagRemoveHandlers() { // GIVEN AkonadiFakeData data; // One tag - data.createTag(GenTag().withId(42).withName("42")); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42"))); auto integrator = createIntegrator(data); qint64 removedId = -1; integrator->addRemoveHandler([&removedId] (const Akonadi::Tag &tag) { removedId = tag.id(); }); // WHEN data.removeTag(Akonadi::Tag(42)); // THEN QCOMPARE(removedId, qint64(42)); } }; ZANSHIN_TEST_MAIN(AkonadiLiveQueryIntegratorTest) #include "akonadilivequeryintegratortest.moc" diff --git a/tests/units/akonadi/akonadinotequeriestest.cpp b/tests/units/akonadi/akonadinotequeriestest.cpp index 8badbe6e..d22f240d 100644 --- a/tests/units/akonadi/akonadinotequeriestest.cpp +++ b/tests/units/akonadi/akonadinotequeriestest.cpp @@ -1,487 +1,487 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Remi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonadinotequeries.h" #include "akonadi/akonadiserializer.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gennote.h" #include "testlib/gentag.h" #include "testlib/gentodo.h" #include "testlib/testhelpers.h" using namespace Testlib; class AkonadiNoteQueriesTest : public QObject { Q_OBJECT private slots: void shouldLookInAllReportedForAllNotes() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); // One note in the first collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // Two notes in the second collection - data.createItem(GenNote().withId(43).withParent(43).withTitle("43")); - data.createItem(GenNote().withId(44).withParent(43).withTitle("44")); + data.createItem(GenNote().withId(43).withParent(43).withTitle(QStringLiteral("43"))); + data.createItem(GenNote().withId(44).withParent(43).withTitle(QStringLiteral("44"))); // WHEN QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); result->data(); result = queries->findAll(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); - QCOMPARE(result->data().at(2)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); } void shouldIgnoreItemsWhichAreNotNotes() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // Two notes in the collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); auto item = Akonadi::Item(43); item.setPayloadFromData("FooBar"); item.setParentCollection(Akonadi::Collection(42)); data.createItem(item); // WHEN QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldReactToItemAddsForNotesOnly() { // GIVEN AkonadiFakeData data; // One empty collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); auto item = Akonadi::Item(43); item.setPayloadFromData("FooBar"); item.setParentCollection(Akonadi::Collection(42)); data.createItem(item); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->title(), QString("42")); + QCOMPARE(result->data().first()->title(), QStringLiteral("42")); } void shouldReactToItemRemovesForAllNotes() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // Three notes in the collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); - data.createItem(GenNote().withId(43).withParent(42).withTitle("43")); - data.createItem(GenNote().withId(44).withParent(42).withTitle("44")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenNote().withId(43).withParent(42).withTitle(QStringLiteral("43"))); + data.createItem(GenNote().withId(44).withParent(42).withTitle(QStringLiteral("44"))); QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldReactToItemChangesForAllNotes() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // Three Note in the collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); - data.createItem(GenNote().withId(43).withParent(42).withTitle("43")); - data.createItem(GenNote().withId(44).withParent(42).withTitle("44")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenNote().withId(43).withParent(42).withTitle(QStringLiteral("43"))); + data.createItem(GenNote().withId(44).withParent(42).withTitle(QStringLiteral("44"))); QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); Domain::QueryResult::Ptr result = queries->findAll(); // Even though the pointer didn't change it's convenient to user if we call // the replace handlers bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Note::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); // WHEN - data.modifyItem(GenNote(data.item(43)).withTitle("43bis")); + data.modifyItem(GenNote(data.item(43)).withTitle(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43bis")); - QCOMPARE(result->data().at(2)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43bis")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); QVERIFY(replaceHandlerCalled); } void shouldLookInAllSelectedCollectionsForInboxNotes() { // GIVEN AkonadiFakeData data; // Three top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(44).withRootAsParent().withNoteContent().enabled(false)); // One note in the first collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // Two notes in the second collection - data.createItem(GenNote().withId(43).withParent(43).withTitle("43")); - data.createItem(GenNote().withId(44).withParent(43).withTitle("44")); + data.createItem(GenNote().withId(43).withParent(43).withTitle(QStringLiteral("43"))); + data.createItem(GenNote().withId(44).withParent(43).withTitle(QStringLiteral("44"))); // One note in the third collection - data.createItem(GenNote().withId(45).withParent(44).withTitle("45")); + data.createItem(GenNote().withId(45).withParent(44).withTitle(QStringLiteral("45"))); // WHEN QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); result->data(); result = queries->findInbox(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); - QCOMPARE(result->data().at(2)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); } void shouldIgnoreItemsWhichAreNotNotesInInbox() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // Three items in the collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // One of them is a task - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43")); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); // One of them is not a task or a note auto item = Akonadi::Item(44); item.setPayloadFromData("FooBar"); item.setParentCollection(Akonadi::Collection(42)); data.createItem(item); // WHEN QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldNotHaveNotesWithTagsInInbox_data() { QTest::addColumn("hasTags"); QTest::addColumn("isExpectedInInbox"); QTest::newRow("note with no tags") << false << true; QTest::newRow("note with tags") << true << false; } void shouldNotHaveNotesWithTagsInInbox() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // One plain tag - data.createTag(GenTag().withId(42).withName("tag-42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asPlain()); // One item in the collection QFETCH(bool, hasTags); auto tagIds = QList(); if (hasTags) tagIds << 42; - data.createItem(GenNote().withId(42).withParent(42).withTitle("42").withTags(tagIds)); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds)); // WHEN QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QFETCH(bool, isExpectedInInbox); if (isExpectedInInbox) { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } else { QVERIFY(result->data().isEmpty()); } } void shouldReactToItemAddsForInbox_data() { QTest::addColumn("reactionExpected"); QTest::addColumn("isTodo"); QTest::addColumn("hasTags"); QTest::newRow("task with no tag") << false << true << false; QTest::newRow("task with tag") << false << true << true; QTest::newRow("note which should be in inbox") << true << false << false; QTest::newRow("note with tag") << false << false << true; } void shouldReactToItemAddsForInbox() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent().withNoteContent()); // One plain tag - data.createTag(GenTag().withId(42).withName("tag-42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asPlain()); QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN QFETCH(bool, hasTags); auto tagIds = QList(); if (hasTags) tagIds << 42; QFETCH(bool, isTodo); if (isTodo) { - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").withTags(tagIds)); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds)); } else { - data.createItem(GenNote().withId(42).withParent(42).withTitle("42").withTags(tagIds)); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds)); } // THEN QFETCH(bool, reactionExpected); if (reactionExpected) { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } else { QVERIFY(result->data().isEmpty()); } } void shouldReactToItemRemovesForInbox() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // One item in the collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // WHEN QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->title(), QString("42")); + QCOMPARE(result->data().first()->title(), QStringLiteral("42")); // WHEN data.removeItem(Akonadi::Item(42)); // THEN QVERIFY(result->data().isEmpty()); } void shouldReactToItemChangesForInbox_data() { QTest::addColumn("hasTagsBefore"); QTest::addColumn("hasTagsAfter"); QTest::addColumn("inListAfterChange"); QTest::newRow("note appears in inbox") << true << false << true; QTest::newRow("note disappears from inbox") << false << true << false; } void shouldReactToItemChangesForInbox() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // One plain tag - data.createTag(GenTag().withId(42).withName("tag-42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asPlain()); // Note data QFETCH(bool, hasTagsBefore); auto tagIds = QList(); if (hasTagsBefore) tagIds << 42; - data.createItem(GenNote().withId(42).withParent(42).withTitle("42").withTags(tagIds)); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds)); QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); TestHelpers::waitForEmptyJobQueue(); QFETCH(bool, inListAfterChange); if (inListAfterChange) { QVERIFY(result->data().isEmpty()); } else { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } // WHEN QFETCH(bool, hasTagsAfter); tagIds.clear(); if (hasTagsAfter) tagIds << 42; data.modifyItem(GenNote(data.item(42)).withTags(tagIds)); // THEN if (inListAfterChange) { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } else { QVERIFY(result->data().isEmpty()); } } void shouldReactToCollectionSelectionChangesForInbox() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); // One note in each collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); - data.createItem(GenNote().withId(43).withParent(43).withTitle("43")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenNote().withId(43).withParent(43).withTitle(QStringLiteral("43"))); QScopedPointer queries(new Akonadi::NoteQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInbox(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } }; ZANSHIN_TEST_MAIN(AkonadiNoteQueriesTest) #include "akonadinotequeriestest.moc" diff --git a/tests/units/akonadi/akonadinoterepositorytest.cpp b/tests/units/akonadi/akonadinoterepositorytest.cpp index 187210e0..f1f9bd30 100644 --- a/tests/units/akonadi/akonadinoterepositorytest.cpp +++ b/tests/units/akonadi/akonadinoterepositorytest.cpp @@ -1,284 +1,284 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "utils/mockobject.h" #include "testlib/akonadifakejobs.h" #include "testlib/akonadifakemonitor.h" #include "akonadi/akonadinoterepository.h" #include "akonadi/akonadiserializerinterface.h" #include "akonadi/akonadistorageinterface.h" using namespace mockitopp; Q_DECLARE_METATYPE(Testlib::AkonadiFakeItemFetchJob*) class AkonadiNoteRepositoryTest : public QObject { Q_OBJECT private slots: void shouldCreateNewItems() { // GIVEN // A default collection for saving auto col = Akonadi::Collection(42); // A note and its corresponding item not existing in storage yet auto item = Akonadi::Item(); auto note = Domain::Note::Ptr::create(); // A mock create job auto itemCreateJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().thenReturn(col); storageMock(&Akonadi::StorageInterface::createItem).when(item, col) .thenReturn(itemCreateJob); // Serializer mock returning the item for the note Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->create(note)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(item, col).exactly(1)); } void shouldCreateNewItemsInFirstWritableCollectionIfNothingInSettings() { // GIVEN // A few collections auto col1 = Akonadi::Collection(42); col1.setRights(Akonadi::Collection::ReadOnly); auto col2 = Akonadi::Collection(43); col2.setRights(Akonadi::Collection::CanCreateItem); auto col3 = Akonadi::Collection(44); col3.setRights(Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanDeleteItem); auto collectionFetchJob = new Testlib::AkonadiFakeCollectionFetchJob; collectionFetchJob->setCollections(Akonadi::Collection::List() << col1 << col2 << col3); // A note and its corresponding item not existing in storage yet auto item = Akonadi::Item(); auto note = Domain::Note::Ptr::create(); // A mock create job auto itemCreateJob = new FakeJob(this); // Storage mock returning the create job and with no default collection Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().thenReturn(Akonadi::Collection()); storageMock(&Akonadi::StorageInterface::fetchCollections).when(Akonadi::Collection::root(), Akonadi::StorageInterface::Recursive, Akonadi::StorageInterface::Notes) .thenReturn(collectionFetchJob); storageMock(&Akonadi::StorageInterface::createItem).when(item, col3) .thenReturn(itemCreateJob); // Serializer mock returning the item for the note Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->create(note)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(item, col3).exactly(1)); } void shouldEmitErrorIfNoFallbackCollectionIsFound() { // GIVEN // A few collections auto col1 = Akonadi::Collection(42); col1.setRights(Akonadi::Collection::ReadOnly); auto col2 = Akonadi::Collection(43); col2.setRights(Akonadi::Collection::ReadOnly); auto col3 = Akonadi::Collection(44); col3.setRights(Akonadi::Collection::ReadOnly); auto collectionFetchJob = new Testlib::AkonadiFakeCollectionFetchJob; collectionFetchJob->setCollections(Akonadi::Collection::List() << col1 << col2 << col3); // A task and its corresponding item not existing in storage yet Akonadi::Item item; Domain::Note::Ptr note(new Domain::Note); // Storage mock returning the create job and with no default collection Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().thenReturn(Akonadi::Collection()); storageMock(&Akonadi::StorageInterface::fetchCollections).when(Akonadi::Collection::root(), Akonadi::StorageInterface::Recursive, Akonadi::StorageInterface::Notes) .thenReturn(collectionFetchJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), serializerMock.getInstance())); auto job = repository->create(note); job->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().exactly(1)); QVERIFY(job->error()); QVERIFY(!job->errorText().isEmpty()); } void shouldCreateNewItemsInTag() { // GIVEN // a tag Akonadi::Tag akonadiTag; - akonadiTag.setName("akonadiTag42"); + akonadiTag.setName(QStringLiteral("akonadiTag42")); akonadiTag.setId(42); // the domain Tag related to the Akonadi Tag auto tag = Domain::Tag::Ptr::create(); // a default collection Akonadi::Collection defaultCollection(42); // A note and its corresponding item not existing in storage yet Akonadi::Item noteItem; auto note = Domain::Note::Ptr::create(); // A mock create job auto itemCreateJob = new FakeJob(this); // serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).thenReturn(akonadiTag); serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(noteItem); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().thenReturn(defaultCollection); storageMock(&Akonadi::StorageInterface::createItem).when(noteItem, defaultCollection).thenReturn(itemCreateJob); // WHEN QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->createInTag(note, tag)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(noteItem, defaultCollection).exactly(1)); } void shouldUpdateExistingItems() { // GIVEN // A default collection for saving auto col = Akonadi::Collection(42); // A note and its corresponding item already existing in storage auto item = Akonadi::Item(42); auto note = Domain::Note::Ptr::create(); // A mock create job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->update(note)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } void shouldRemoveANote() { // GIVEN Akonadi::Item item(42); Domain::Note::Ptr note(new Domain::Note); // A mock delete job auto itemDeleteJob = new FakeJob(this); // Storage mock returning the delete job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::removeItem).when(item) .thenReturn(itemDeleteJob); // Serializer mock returning the item for the note Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->remove(note)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::removeItem).when(item).exactly(1)); } }; ZANSHIN_TEST_MAIN(AkonadiNoteRepositoryTest) #include "akonadinoterepositorytest.moc" diff --git a/tests/units/akonadi/akonadiprojectqueriestest.cpp b/tests/units/akonadi/akonadiprojectqueriestest.cpp index 2d6bd02a..0109f71b 100644 --- a/tests/units/akonadi/akonadiprojectqueriestest.cpp +++ b/tests/units/akonadi/akonadiprojectqueriestest.cpp @@ -1,536 +1,536 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonadiprojectqueries.h" #include "akonadi/akonadiserializer.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gentodo.h" #include "testlib/testhelpers.h" using namespace Testlib; class AkonadiProjectQueriesTest : public QObject { Q_OBJECT private slots: void shouldLookInAllReportedForAllProjects() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One project in the first collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").asProject()); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject()); // Two projects in the second collection - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43").asProject()); - data.createItem(GenTodo().withId(44).withParent(43).withTitle("44").asProject()); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43")).asProject()); + data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44")).asProject()); // WHEN QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); result->data(); result = queries->findAll(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43")); - QCOMPARE(result->data().at(2)->name(), QString("44")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("44")); } void shouldIgnoreItemsWhichAreNotProjects() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project and one regular task in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").asProject()); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject()); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); // WHEN QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldReactToItemAddsForProjectsOnly() { // GIVEN AkonadiFakeData data; // One empty collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").asProject()); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject()); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldReactToItemRemovesForAllProjects() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three projects in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").asProject()); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43").asProject()); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44").asProject()); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject()); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).asProject()); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44")).asProject()); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("44")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("44")); } void shouldReactToItemChangesForAllProjects() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three projects in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").asProject()); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43").asProject()); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44").asProject()); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject()); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).asProject()); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44")).asProject()); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); // Even though the pointer didn't change it's convenient to user if we call // the replace handlers bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Project::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); // WHEN - data.modifyItem(GenTodo(data.item(43)).withTitle("43bis")); + data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43bis")); - QCOMPARE(result->data().at(2)->name(), QString("44")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43bis")); + QCOMPARE(result->data().at(2)->name(), QStringLiteral("44")); QVERIFY(replaceHandlerCalled); } void shouldReactToCollectionSelectionChangesForAllProjects() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // Two projects, one in each collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").asProject()); - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43").asProject()); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject()); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43")).asProject()); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43")); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldLookOnlyInParentCollectionForProjectTopLevel() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One project and two tasks in the first collection (one task being child of the project) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))); // Two tasks in the second collection (one having the project uid as parent) data.createItem(GenTodo().withId(45).withParent(43) - .withTitle("45").withParentUid("uid-42")); - data.createItem(GenTodo().withId(46).withParent(43).withTitle("46")); + .withTitle(QStringLiteral("45")).withParentUid(QStringLiteral("uid-42"))); + data.createItem(GenTodo().withId(46).withParent(43).withTitle(QStringLiteral("46"))); // WHEN auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); auto result = queries->findTopLevel(project); result->data(); result = queries->findTopLevel(project); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); // Should not change nothing result = queries->findTopLevel(project); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); } void shouldNotCrashWhenWeAskAgainTheSameTopLevelArtifacts() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project in the collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); // The bug we're trying to hit here is the following: // - when findChildren is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when findChildren is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 auto result = queries->findTopLevel(project); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } } void shouldReactToItemAddsForTopLevelArtifact() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project in the collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); auto result = queries->findTopLevel(project); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldReactToItemChangesForTopLevelArtifacts() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project and two tasks in the collection (tasks being children of the project) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); auto result = queries->findTopLevel(project); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Artifact::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyItem(GenTodo(data.item(43)).withTitle("43bis")); + data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43bis")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43bis")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); QVERIFY(replaceHandlerCalled); } void shouldRemoveItemFromCorrespondingResultWhenRelatedItemChangesForTopLevelArtifact() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project and two tasks in the collection (tasks being children of the project) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); auto result = queries->findTopLevel(project); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyItem(GenTodo(data.item(43)).withParentUid("")); + data.modifyItem(GenTodo(data.item(43)).withParentUid(QLatin1String(""))); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); } void shouldAddItemToCorrespondingResultWhenRelatedItemChangeForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project and two tasks in the collection (one being child of the project) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); auto result = queries->findTopLevel(project); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Artifact::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); // WHEN - data.modifyItem(GenTodo(data.item(43)).withParentUid("uid-42")); + data.modifyItem(GenTodo(data.item(43)).withParentUid(QStringLiteral("uid-42"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("44")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); QVERIFY(!replaceHandlerCalled); } void shouldMoveItemToCorrespondingResultWhenRelatedItemChangeForTopLevelArtifacts() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Two project and one task in the collection (task being child of the first project) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43").asProject()); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")).asProject()); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project1 = serializer->createProjectFromItem(data.item(42)); auto project2 = serializer->createProjectFromItem(data.item(43)); auto result1 = queries->findTopLevel(project1); auto result2 = queries->findTopLevel(project2); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result1->data().size(), 1); - QCOMPARE(result1->data().at(0)->title(), QString("44")); + QCOMPARE(result1->data().at(0)->title(), QStringLiteral("44")); QCOMPARE(result2->data().size(), 0); // WHEN - data.modifyItem(GenTodo(data.item(44)).withParentUid("uid-43")); + data.modifyItem(GenTodo(data.item(44)).withParentUid(QStringLiteral("uid-43"))); // THEN QCOMPARE(result1->data().size(), 0); QCOMPARE(result2->data().size(), 1); - QCOMPARE(result2->data().at(0)->title(), QString("44")); + QCOMPARE(result2->data().at(0)->title(), QStringLiteral("44")); } void shouldReactToItemRemovesForTopLevelArtifacts() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One project and two tasks in the collection (tasks being children of the project) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42").asProject()); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject()); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto project = serializer->createProjectFromItem(data.item(42)); auto result = queries->findTopLevel(project); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); } }; ZANSHIN_TEST_MAIN(AkonadiProjectQueriesTest) #include "akonadiprojectqueriestest.moc" diff --git a/tests/units/akonadi/akonadiserializertest.cpp b/tests/units/akonadi/akonadiserializertest.cpp index 22d0bea9..87a6820f 100644 --- a/tests/units/akonadi/akonadiserializertest.cpp +++ b/tests/units/akonadi/akonadiserializertest.cpp @@ -1,2433 +1,2433 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Rémi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonadiserializer.h" #include "akonadi/akonadiapplicationselectedattribute.h" #include "akonadi/akonaditimestampattribute.h" #include #include #include #include #include #include #include Q_DECLARE_METATYPE(Akonadi::Item*) class AkonadiSerializerTest : public QObject { Q_OBJECT private slots: void shouldKnowWhenAnObjectRepresentsACollection() { // GIVEN Akonadi::Serializer serializer; auto object = Akonadi::Serializer::QObjectPtr::create(); Akonadi::Collection collection(42); // WHEN // Nothing yet // THEN QVERIFY(!serializer.representsCollection(object, collection)); // WHEN object->setProperty("collectionId", 42); // THEN QVERIFY(serializer.representsCollection(object, collection)); // WHEN object->setProperty("collectionId", 43); // THEN QVERIFY(!serializer.representsCollection(object, collection)); } void shouldKnowWhenAnObjectRepresentsAnItem() { // GIVEN Akonadi::Serializer serializer; auto object = Akonadi::Serializer::QObjectPtr::create(); Akonadi::Item item(42); // WHEN // Nothing yet // THEN QVERIFY(!serializer.representsItem(object, item)); // WHEN object->setProperty("itemId", 42); // THEN QVERIFY(serializer.representsItem(object, item)); // WHEN object->setProperty("itemId", 43); // THEN QVERIFY(!serializer.representsItem(object, item)); } void shouldKnowWhenAnAkonadiTagRepresentsATag() { // GIVEN Akonadi::Serializer serializer; Akonadi::Tag akondiTag(42); auto tag = Domain::Tag::Ptr::create(); // WHEN // Nothing yet // THEN QVERIFY(!serializer.representsAkonadiTag(tag, akondiTag)); // WHEN tag->setProperty("tagId", 42); // THEN QVERIFY(serializer.representsAkonadiTag(tag, akondiTag)); // WHEN tag->setProperty("tagId", 43); // THEN QVERIFY(!serializer.representsAkonadiTag(tag, akondiTag)); } void shouldKnowObjectUid() { // GIVEN Akonadi::Serializer serializer; auto object = Akonadi::Serializer::QObjectPtr::create(); // WHEN object->setProperty("todoUid", "my-uid"); // THEN - QCOMPARE(serializer.objectUid(object), QString("my-uid")); + QCOMPARE(serializer.objectUid(object), QStringLiteral("my-uid")); } void shouldCreateDataSourceFromCollection_data() { QTest::addColumn("name"); QTest::addColumn("iconName"); QTest::addColumn("mimeTypes"); QTest::addColumn("hasSelectedAttribute"); QTest::addColumn("isSelected"); QTest::addColumn("isReferenced"); QTest::addColumn("isEnabled"); - const auto noteMimeTypes = QStringList() << "text/x-vnd.akonadi.note"; - const auto taskMimeTypes = QStringList() << "application/x-vnd.akonadi.calendar.todo"; - const auto bogusMimeTypes = QStringList() << "foo/bar"; + const auto noteMimeTypes = QStringList() << QStringLiteral("text/x-vnd.akonadi.note"); + const auto taskMimeTypes = QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.todo"); + const auto bogusMimeTypes = QStringList() << QStringLiteral("foo/bar"); const auto allMimeTypes = noteMimeTypes + taskMimeTypes + bogusMimeTypes; QTest::newRow("nominal case") << "name" << "icon" << allMimeTypes << true << false << false << true; QTest::newRow("only notes") << "name" << "icon" << noteMimeTypes << true << false << false << true; QTest::newRow("only tasks") << "name" << "icon" << taskMimeTypes << true << false << false << true; QTest::newRow("only bogus") << "name" << "icon" << bogusMimeTypes << true << false << false << true; QTest::newRow("no selected attribute") << "name" << "icon" << allMimeTypes << false << false << false << true; QTest::newRow("selected attribute (false)") << "name" << "icon" << allMimeTypes << true << false << false << true; QTest::newRow("selected attribute (true)") << "name" << "icon" << allMimeTypes << true << true << false << true; QTest::newRow("enabled and referenced") << "name" << "icon" << allMimeTypes << true << false << true << true; QTest::newRow("enabled and !referenced") << "name" << "icon" << allMimeTypes << true << false << true << false; QTest::newRow("!enabled and referenced") << "name" << "icon" << allMimeTypes << true << false << false << true; QTest::newRow("!enabled and !referenced") << "name" << "icon" << allMimeTypes << true << false << false << false; QTest::newRow("empty case") << QString() << QString() << QStringList() << false << false << false << true; } void shouldCreateDataSourceFromCollection() { // GIVEN // Data... QFETCH(QString, name); QFETCH(QString, iconName); QFETCH(QStringList, mimeTypes); QFETCH(bool, hasSelectedAttribute); QFETCH(bool, isSelected); QFETCH(bool, isReferenced); QFETCH(bool, isEnabled); Domain::DataSource::ContentTypes expectedContentTypes; - if (mimeTypes.contains("text/x-vnd.akonadi.note")) { + if (mimeTypes.contains(QStringLiteral("text/x-vnd.akonadi.note"))) { expectedContentTypes |= Domain::DataSource::Notes; } - if (mimeTypes.contains("application/x-vnd.akonadi.calendar.todo")) { + if (mimeTypes.contains(QStringLiteral("application/x-vnd.akonadi.calendar.todo"))) { expectedContentTypes |= Domain::DataSource::Tasks; } // ... stored in a collection Akonadi::Collection collection(42); collection.setContentMimeTypes(mimeTypes); collection.setName(name); collection.setReferenced(isReferenced); collection.setEnabled(isEnabled); auto displayAttribute = new Akonadi::EntityDisplayAttribute; displayAttribute->setIconName(iconName); collection.addAttribute(displayAttribute); if (hasSelectedAttribute) { auto selectedAttribute = new Akonadi::ApplicationSelectedAttribute; selectedAttribute->setSelected(isSelected); collection.addAttribute(selectedAttribute); } // WHEN Akonadi::Serializer serializer; auto dataSource = serializer.createDataSourceFromCollection(collection, Akonadi::SerializerInterface::BaseName); // THEN QCOMPARE(dataSource->name(), name); QCOMPARE(dataSource->iconName(), iconName); QCOMPARE(dataSource->contentTypes(), expectedContentTypes); QCOMPARE(dataSource->isSelected(), !hasSelectedAttribute || isSelected); QCOMPARE(dataSource->property("collectionId").value(), collection.id()); QCOMPARE((dataSource->listStatus() & Domain::DataSource::Listed) != 0, isReferenced || isEnabled); QCOMPARE((dataSource->listStatus() == Domain::DataSource::Bookmarked), isEnabled); } void shouldCreateNullDataSourceFromInvalidCollection() { // GIVEN Akonadi::Collection collection; // WHEN Akonadi::Serializer serializer; auto dataSource = serializer.createDataSourceFromCollection(collection, Akonadi::SerializerInterface::BaseName); // THEN QVERIFY(dataSource.isNull()); } void shouldUpdateDataSourceFromCollection_data() { QTest::addColumn("updatedName"); QTest::newRow("no change") << "name"; QTest::newRow("changed") << "new name"; } void shouldUpdateDataSourceFromCollection() { // GIVEN // A collection... Akonadi::Collection originalCollection(42); - originalCollection.setName("name"); + originalCollection.setName(QStringLiteral("name")); // ... deserialized as a data source Akonadi::Serializer serializer; auto dataSource = serializer.createDataSourceFromCollection(originalCollection, Akonadi::SerializerInterface::BaseName); // WHEN // Data... QFETCH(QString, updatedName); // ... in a new collection Akonadi::Collection updatedCollection(42); updatedCollection.setName(updatedName); serializer.updateDataSourceFromCollection(dataSource, updatedCollection, Akonadi::SerializerInterface::BaseName); // THEN QCOMPARE(dataSource->name(), updatedName); } void shouldNotUpdateDataSourceFromInvalidCollection() { // GIVEN // Data... - const QString name = "name"; + const QString name = QStringLiteral("name"); // ... stored in a collection... Akonadi::Collection originalCollection(42); originalCollection.setName(name); // ... deserialized as a data source Akonadi::Serializer serializer; auto dataSource = serializer.createDataSourceFromCollection(originalCollection, Akonadi::SerializerInterface::BaseName); // WHEN Akonadi::Collection invalidCollection; - invalidCollection.setName("foo"); + invalidCollection.setName(QStringLiteral("foo")); serializer.updateDataSourceFromCollection(dataSource, invalidCollection, Akonadi::SerializerInterface::BaseName); // THEN QCOMPARE(dataSource->name(), name); } void shouldNameDataSourceFromCollectionPathIfRequested() { // GIVEN // Data... - const QString name = "name"; - const QString parentName = "parent"; + const QString name = QStringLiteral("name"); + const QString parentName = QStringLiteral("parent"); // ... stored in a collection with a parent Akonadi::Collection collection(42); collection.setName(name); Akonadi::Collection parentCollection(41); - parentCollection.setName("Foo"); + parentCollection.setName(QStringLiteral("Foo")); auto attribute = new Akonadi::EntityDisplayAttribute; attribute->setDisplayName(parentName); parentCollection.addAttribute(attribute); collection.setParentCollection(parentCollection); // WHEN Akonadi::Serializer serializer; auto dataSource1 = serializer.createDataSourceFromCollection(collection, Akonadi::SerializerInterface::FullPath); auto dataSource2 = serializer.createDataSourceFromCollection(collection, Akonadi::SerializerInterface::BaseName); // Give it another try with the root parentCollection.setParentCollection(Akonadi::Collection::root()); collection.setParentCollection(parentCollection); auto dataSource3 = serializer.createDataSourceFromCollection(collection, Akonadi::SerializerInterface::FullPath); auto dataSource4 = serializer.createDataSourceFromCollection(collection, Akonadi::SerializerInterface::BaseName); // THEN QCOMPARE(dataSource1->name(), QString(parentName + "/" + name)); QCOMPARE(dataSource2->name(), name); QCOMPARE(dataSource3->name(), QString(parentName + "/" + name)); QCOMPARE(dataSource4->name(), name); } void shouldCreateCollectionFromDataSource_data() { QTest::addColumn("name"); QTest::addColumn("iconName"); QTest::addColumn("contentTypes"); QTest::addColumn("isSelected"); QTest::addColumn("listStatus"); const auto noType = Domain::DataSource::ContentTypes(Domain::DataSource::NoContent); const auto taskType = Domain::DataSource::ContentTypes(Domain::DataSource::Tasks); const auto noteType = Domain::DataSource::ContentTypes(Domain::DataSource::Notes); const auto allTypes = taskType | noteType; const auto unlisted = Domain::DataSource::Unlisted; const auto listed = Domain::DataSource::Listed; const auto bookmarked = Domain::DataSource::Bookmarked; QTest::newRow("nominal case") << "name" << "icon-name" << allTypes << true << unlisted; QTest::newRow("only notes") << "name" << "icon-name" << noteType << true << unlisted; QTest::newRow("only tasks") << "name" << "icon-name" << taskType << true << unlisted; QTest::newRow("only nothing ;)") << "name" << "icon-name" << noType << true << unlisted; QTest::newRow("not selected") << "name" << "icon-name" << allTypes << false << unlisted; QTest::newRow("selected") << "name" << "icon-name" << allTypes << true << unlisted; QTest::newRow("unlisted") << "name" << "icon-name" << allTypes << true << unlisted; QTest::newRow("listed") << "name" << "icon-name" << allTypes << true << listed; QTest::newRow("bookmarked") << "name" << "icon-name" << allTypes << true << bookmarked; QTest::newRow("empty case") << QString() << QString() << noType << true << unlisted; } void shouldCreateCollectionFromDataSource() { // GIVEN const auto timestamp = QDateTime::currentMSecsSinceEpoch(); // Data... QFETCH(QString, name); QFETCH(QString, iconName); QFETCH(Domain::DataSource::ContentTypes, contentTypes); QFETCH(bool, isSelected); QFETCH(Domain::DataSource::ListStatus, listStatus); QStringList mimeTypes; if (contentTypes & Domain::DataSource::Tasks) - mimeTypes << "application/x-vnd.akonadi.calendar.todo"; + mimeTypes << QStringLiteral("application/x-vnd.akonadi.calendar.todo"); if (contentTypes & Domain::DataSource::Notes) - mimeTypes << "text/x-vnd.akonadi.note"; + mimeTypes << QStringLiteral("text/x-vnd.akonadi.note"); // ... stored in a data source auto source = Domain::DataSource::Ptr::create(); source->setName(name); source->setIconName(iconName); source->setContentTypes(contentTypes); source->setListStatus(listStatus); source->setSelected(isSelected); source->setProperty("collectionId", 42); // WHEN Akonadi::Serializer serializer; auto collection = serializer.createCollectionFromDataSource(source); // THEN QCOMPARE(collection.id(), source->property("collectionId").value()); QVERIFY(collection.hasAttribute()); QCOMPARE(collection.attribute()->isSelected(), isSelected); QVERIFY(collection.hasAttribute()); QVERIFY(collection.attribute()->timestamp() >= timestamp); switch (listStatus) { case Domain::DataSource::Unlisted: QVERIFY(!collection.referenced()); QVERIFY(!collection.enabled()); break; case Domain::DataSource::Listed: QVERIFY(collection.referenced()); QVERIFY(!collection.enabled()); break; case Domain::DataSource::Bookmarked: QVERIFY(collection.enabled()); break; default: qFatal("Shouldn't happen"); break; } } void shouldVerifyIfCollectionIsListed_data() { QTest::addColumn("isEnabled"); QTest::addColumn("isReferenced"); QTest::addColumn("expectedListed"); QTest::newRow("enabled and referenced") << true << true << true; QTest::newRow("enabled and !referenced") << true << false << true; QTest::newRow("!enabled and referenced") << false << true << true; QTest::newRow("!enabled and !referenced") << false << false << false; } void shouldVerifyIfCollectionIsListed() { // GIVEN QFETCH(bool, isEnabled); QFETCH(bool, isReferenced); // ... stored in a collection Akonadi::Collection collection(42); collection.setReferenced(isReferenced); collection.setEnabled(isEnabled); // WHEN Akonadi::Serializer serializer; // THEN QFETCH(bool, expectedListed); QCOMPARE(serializer.isListedCollection(collection), expectedListed); } void shouldVerifyIfCollectionIsSelected_data() { QTest::addColumn("mimeTypes"); QTest::addColumn("hasSelectedAttribute"); QTest::addColumn("isSelected"); QTest::addColumn("isReferenced"); QTest::addColumn("isEnabled"); QTest::addColumn("expectedSelected"); - const auto noteMimeTypes = QStringList() << "text/x-vnd.akonadi.note"; - const auto taskMimeTypes = QStringList() << "application/x-vnd.akonadi.calendar.todo"; - const auto bogusMimeTypes = QStringList() << "foo/bar"; + const auto noteMimeTypes = QStringList() << QStringLiteral("text/x-vnd.akonadi.note"); + const auto taskMimeTypes = QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.todo"); + const auto bogusMimeTypes = QStringList() << QStringLiteral("foo/bar"); const auto allMimeTypes = noteMimeTypes + taskMimeTypes + bogusMimeTypes; QTest::newRow("nominal case") << allMimeTypes << true << false << false << true << false; QTest::newRow("only notes") << noteMimeTypes << true << false << false << true << false; QTest::newRow("only tasks") << taskMimeTypes << true << false << false << true << false; QTest::newRow("only bogus") << bogusMimeTypes << true << false << false << true << false; QTest::newRow("selected, only notes") << noteMimeTypes << true << true << false << true << true; QTest::newRow("selected, only tasks") << taskMimeTypes << true << true << false << true << true; QTest::newRow("selected, only bogus") << bogusMimeTypes << true << true << false << true << false; QTest::newRow("no selected attribute") << allMimeTypes << false << false << false << true << true; QTest::newRow("selected attribute (false)") << allMimeTypes << true << false << false << true << false; QTest::newRow("selected attribute (true)") << allMimeTypes << true << true << false << true << true; QTest::newRow("enabled and referenced") << allMimeTypes << true << false << true << true << false; QTest::newRow("enabled and !referenced") << allMimeTypes << true << false << true << false << false; QTest::newRow("!enabled and referenced") << allMimeTypes << true << false << false << true << false; QTest::newRow("!enabled and !referenced") << allMimeTypes << true << false << false << false << false; QTest::newRow("selected, enabled and referenced") << allMimeTypes << true << true << true << true << true; QTest::newRow("selected, enabled and !referenced") << allMimeTypes << true << true << true << false << true; QTest::newRow("selected, !enabled and referenced") << allMimeTypes << true << true << false << true << true; QTest::newRow("selected, !enabled and !referenced") << allMimeTypes << true << true << false << false << false; QTest::newRow("empty case") << QStringList() << false << false << false << true << false; } void shouldVerifyIfCollectionIsSelected() { // GIVEN QFETCH(QStringList, mimeTypes); QFETCH(bool, hasSelectedAttribute); QFETCH(bool, isSelected); QFETCH(bool, isReferenced); QFETCH(bool, isEnabled); Domain::DataSource::ContentTypes expectedContentTypes; - if (mimeTypes.contains("text/x-vnd.akonadi.note")) { + if (mimeTypes.contains(QStringLiteral("text/x-vnd.akonadi.note"))) { expectedContentTypes |= Domain::DataSource::Notes; } - if (mimeTypes.contains("application/x-vnd.akonadi.calendar.todo")) { + if (mimeTypes.contains(QStringLiteral("application/x-vnd.akonadi.calendar.todo"))) { expectedContentTypes |= Domain::DataSource::Tasks; } // ... stored in a collection Akonadi::Collection collection(42); collection.setContentMimeTypes(mimeTypes); collection.setReferenced(isReferenced); collection.setEnabled(isEnabled); if (hasSelectedAttribute) { auto selectedAttribute = new Akonadi::ApplicationSelectedAttribute; selectedAttribute->setSelected(isSelected); collection.addAttribute(selectedAttribute); } // WHEN Akonadi::Serializer serializer; // THEN QFETCH(bool, expectedSelected); QCOMPARE(serializer.isSelectedCollection(collection), expectedSelected); } void shouldVerifyCollectionContents_data() { QTest::addColumn("mimeType"); QTest::addColumn("expectedNotes"); QTest::addColumn("expectedTasks"); QTest::newRow("task collection") << "application/x-vnd.akonadi.calendar.todo" << false << true; QTest::newRow("note collection") << "text/x-vnd.akonadi.note" << true << false; } void shouldVerifyCollectionContents() { // GIVEN // Data... QFETCH(QString, mimeType); // ... stored in a collection Akonadi::Collection collection(42); collection.setContentMimeTypes(QStringList() << mimeType); // WHEN Akonadi::Serializer serializer; QFETCH(bool, expectedNotes); QFETCH(bool, expectedTasks); // THEN QCOMPARE(serializer.isNoteCollection(collection), expectedNotes); QCOMPARE(serializer.isTaskCollection(collection), expectedTasks); } void shouldCreateTaskFromItem_data() { QTest::addColumn("summary"); QTest::addColumn("content"); QTest::addColumn("isDone"); QTest::addColumn("doneDate"); QTest::addColumn("startDate"); QTest::addColumn("dueDate"); QTest::addColumn("delegateName"); QTest::addColumn("delegateEmail"); QTest::newRow("nominal case") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "John Doe" << "j@d.com"; QTest::newRow("done case") << "summary" << "content" << true << QDateTime(QDate(2013, 11, 30)) << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "John Doe" << "j@d.com"; QTest::newRow("done without doneDate case") << "summary" << "content" << true << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "John Doe" << "j@d.com"; QTest::newRow("empty case") << QString() << QString() << false << QDateTime() << QDateTime() << QDateTime() << QString() << QString(); } void shouldCreateTaskFromItem() { // GIVEN // Data... QFETCH(QString, summary); QFETCH(QString, content); QFETCH(bool, isDone); QFETCH(QDateTime, doneDate); QFETCH(QDateTime, startDate); QFETCH(QDateTime, dueDate); QFETCH(QString, delegateName); QFETCH(QString, delegateEmail); // Switch to UTC doneDate.setTimeSpec(Qt::UTC); startDate.setTimeSpec(Qt::UTC); dueDate.setTimeSpec(Qt::UTC); // ... stored in a todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(summary); todo->setDescription(content); if (isDone) todo->setCompleted(KDateTime(doneDate)); else todo->setCompleted(isDone); todo->setDtStart(KDateTime(startDate)); todo->setDtDue(KDateTime(dueDate)); - todo->setRelatedTo("my-uid"); + todo->setRelatedTo(QStringLiteral("my-uid")); if (!delegateName.isEmpty() || !delegateEmail.isEmpty()) { KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(delegateName, delegateEmail, true, KCalCore::Attendee::Accepted)); todo->addAttendee(attendee); } // ... as payload of an item Akonadi::Item item; - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // which has a parent collection Akonadi::Collection collection(43); item.setParentCollection(collection); // WHEN Akonadi::Serializer serializer; Domain::Task::Ptr task = serializer.createTaskFromItem(item); auto artifact = serializer.createArtifactFromItem(item).dynamicCast(); // THEN QCOMPARE(task->title(), summary); QCOMPARE(task->text(), content); QCOMPARE(task->isDone(), isDone); QCOMPARE(task->doneDate(), doneDate); QCOMPARE(task->startDate(), startDate); QCOMPARE(task->dueDate(), dueDate); QCOMPARE(task->property("todoUid").toString(), todo->uid()); QCOMPARE(task->property("relatedUid").toString(), todo->relatedTo()); QCOMPARE(task->property("itemId").toLongLong(), item.id()); QCOMPARE(task->property("parentCollectionId").toLongLong(), collection.id()); QCOMPARE(task->delegate().name(), delegateName); QCOMPARE(task->delegate().email(), delegateEmail); QVERIFY(!artifact.isNull()); QCOMPARE(artifact->title(), summary); QCOMPARE(artifact->text(), content); QCOMPARE(artifact->isDone(), isDone); QCOMPARE(artifact->doneDate(), doneDate); QCOMPARE(artifact->startDate(), startDate); QCOMPARE(artifact->dueDate(), dueDate); QCOMPARE(artifact->property("todoUid").toString(), todo->uid()); QCOMPARE(artifact->property("relatedUid").toString(), todo->relatedTo()); QCOMPARE(artifact->property("itemId").toLongLong(), item.id()); QCOMPARE(artifact->property("parentCollectionId").toLongLong(), collection.id()); QCOMPARE(artifact->delegate().name(), delegateName); QCOMPARE(artifact->delegate().email(), delegateEmail); } void shouldCreateNullTaskFromInvalidItem() { // GIVEN Akonadi::Item item; // WHEN Akonadi::Serializer serializer; Domain::Task::Ptr task = serializer.createTaskFromItem(item); auto artifact = serializer.createArtifactFromItem(item); // THEN QVERIFY(task.isNull()); QVERIFY(artifact.isNull()); } void shouldCreateNullTaskFromProjectItem() { // GIVEN // A todo with the project flag KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("foo"); - todo->setCustomProperty("Zanshin", "Project", "1"); + todo->setSummary(QStringLiteral("foo")); + todo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); // ... as payload of an item Akonadi::Item item; - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // WHEN Akonadi::Serializer serializer; Domain::Task::Ptr task = serializer.createTaskFromItem(item); auto artifact = serializer.createArtifactFromItem(item); // THEN QVERIFY(task.isNull()); QVERIFY(artifact.isNull()); } void shouldUpdateTaskFromItem_data() { QTest::addColumn("updatedSummary"); QTest::addColumn("updatedContent"); QTest::addColumn("updatedDone"); QTest::addColumn("updatedDoneDate"); QTest::addColumn("updatedStartDate"); QTest::addColumn("updatedDueDate"); QTest::addColumn("updatedRelated"); QTest::addColumn("updatedDelegateName"); QTest::addColumn("updatedDelegateEmail"); QTest::newRow("no change") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << "my-uid" << "John Doe" << "j@d.com"; QTest::newRow("changed") << "new summary" << "new content" << true << QDateTime(QDate(2013, 11, 28)) << QDateTime(QDate(2013, 11, 25)) << QDateTime(QDate(2014, 03, 02)) << "my-new-uid" << "John Smith" << "j@s.com"; } void shouldUpdateTaskFromItem() { // GIVEN // A todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); - originalTodo->setSummary("summary"); - originalTodo->setDescription("content"); + originalTodo->setSummary(QStringLiteral("summary")); + originalTodo->setDescription(QStringLiteral("content")); originalTodo->setCompleted(false); originalTodo->setDtStart(KDateTime(QDate(2013, 11, 24))); originalTodo->setDtDue(KDateTime(QDate(2014, 03, 01))); - originalTodo->setRelatedTo("my-uid"); - KCalCore::Attendee::Ptr originalAttendee(new KCalCore::Attendee("John Doe", - "j@d.com", + originalTodo->setRelatedTo(QStringLiteral("my-uid")); + KCalCore::Attendee::Ptr originalAttendee(new KCalCore::Attendee(QStringLiteral("John Doe"), + QStringLiteral("j@d.com"), true, KCalCore::Attendee::Accepted)); originalTodo->addAttendee(originalAttendee); // ... as payload of an item... Akonadi::Item originalItem; - originalItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + originalItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); originalItem.setPayload(originalTodo); // ... which has a parent collection... Akonadi::Collection originalCollection(43); originalItem.setParentCollection(originalCollection); // ... deserialized as a task Akonadi::Serializer serializer; auto task = serializer.createTaskFromItem(originalItem); auto artifact = serializer.createArtifactFromItem(originalItem); // WHEN // Data... QFETCH(QString, updatedSummary); QFETCH(QString, updatedContent); QFETCH(bool, updatedDone); QFETCH(QDateTime, updatedDoneDate); QFETCH(QDateTime, updatedStartDate); QFETCH(QDateTime, updatedDueDate); QFETCH(QString, updatedRelated); QFETCH(QString, updatedDelegateName); QFETCH(QString, updatedDelegateEmail); // Switch to UTC updatedDoneDate.setTimeSpec(Qt::UTC); updatedStartDate.setTimeSpec(Qt::UTC); updatedDueDate.setTimeSpec(Qt::UTC); // ... in a new todo... KCalCore::Todo::Ptr updatedTodo(new KCalCore::Todo); updatedTodo->setSummary(updatedSummary); updatedTodo->setDescription(updatedContent); if (updatedDone) updatedTodo->setCompleted(KDateTime(updatedDoneDate)); else updatedTodo->setCompleted(updatedDone); updatedTodo->setDtStart(KDateTime(updatedStartDate)); updatedTodo->setDtDue(KDateTime(updatedDueDate)); updatedTodo->setRelatedTo(updatedRelated); if (!updatedDelegateName.isEmpty() || !updatedDelegateEmail.isEmpty()) { KCalCore::Attendee::Ptr updatedAttendee(new KCalCore::Attendee(updatedDelegateName, updatedDelegateEmail, true, KCalCore::Attendee::Accepted)); updatedTodo->addAttendee(updatedAttendee); } // ... as payload of a new item Akonadi::Item updatedItem; - updatedItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + updatedItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); updatedItem.setPayload(updatedTodo); // ... which has a new parent collection Akonadi::Collection updatedCollection(45); updatedItem.setParentCollection(updatedCollection); serializer.updateTaskFromItem(task, updatedItem); serializer.updateArtifactFromItem(artifact, updatedItem); // THEN QCOMPARE(task->title(), updatedSummary); QCOMPARE(task->text(), updatedContent); QCOMPARE(task->isDone(), updatedDone); QCOMPARE(task->doneDate(), updatedDoneDate.toUTC()); QCOMPARE(task->startDate(), updatedStartDate.toUTC()); QCOMPARE(task->dueDate(), updatedDueDate.toUTC()); QCOMPARE(task->property("todoUid").toString(), updatedTodo->uid()); QCOMPARE(task->property("relatedUid").toString(), updatedTodo->relatedTo()); QCOMPARE(task->property("itemId").toLongLong(), updatedItem.id()); QCOMPARE(task->property("parentCollectionId").toLongLong(), updatedCollection.id()); QCOMPARE(task->delegate().name(), updatedDelegateName); QCOMPARE(task->delegate().email(), updatedDelegateEmail); task = artifact.dynamicCast(); QCOMPARE(task->title(), updatedSummary); QCOMPARE(task->text(), updatedContent); QCOMPARE(task->isDone(), updatedDone); QCOMPARE(task->doneDate(), updatedDoneDate.toUTC()); QCOMPARE(task->startDate(), updatedStartDate.toUTC()); QCOMPARE(task->dueDate(), updatedDueDate.toUTC()); QCOMPARE(task->property("todoUid").toString(), updatedTodo->uid()); QCOMPARE(task->property("relatedUid").toString(), updatedTodo->relatedTo()); QCOMPARE(task->property("itemId").toLongLong(), updatedItem.id()); QCOMPARE(task->property("parentCollectionId").toLongLong(), updatedCollection.id()); QCOMPARE(task->delegate().name(), updatedDelegateName); QCOMPARE(task->delegate().email(), updatedDelegateEmail); } void shouldNotUpdateTaskFromInvalidItem() { // GIVEN // Data... - const QString summary = "summary"; - const QString content = "content"; + const QString summary = QStringLiteral("summary"); + const QString content = QStringLiteral("content"); const bool isDone = true; const QDateTime doneDate(QDate(2013, 11, 30), QTime(0, 0), Qt::UTC); const QDateTime startDate(QDate(2013, 11, 24), QTime(0, 0), Qt::UTC); const QDateTime dueDate(QDate(2014, 03, 01), QTime(0, 0), Qt::UTC); // ... stored in a todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); originalTodo->setSummary(summary); originalTodo->setDescription(content); if (originalTodo) originalTodo->setCompleted(KDateTime(doneDate)); else originalTodo->setCompleted(isDone); originalTodo->setDtStart(KDateTime(startDate)); originalTodo->setDtDue(KDateTime(dueDate)); // ... as payload of an item... Akonadi::Item originalItem; - originalItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + originalItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); originalItem.setPayload(originalTodo); // ... deserialized as a task Akonadi::Serializer serializer; auto task = serializer.createTaskFromItem(originalItem); auto artifact = serializer.createArtifactFromItem(originalItem); // WHEN Akonadi::Item invalidItem; serializer.updateTaskFromItem(task, invalidItem); serializer.updateArtifactFromItem(artifact, invalidItem); // THEN QCOMPARE(task->title(), summary); QCOMPARE(task->text(), content); QCOMPARE(task->isDone(), isDone); QCOMPARE(task->doneDate(), doneDate); QCOMPARE(task->startDate(), startDate); QCOMPARE(task->dueDate(), dueDate); QCOMPARE(task->property("itemId").toLongLong(), originalItem.id()); task = artifact.dynamicCast(); QCOMPARE(task->title(), summary); QCOMPARE(task->text(), content); QCOMPARE(task->isDone(), isDone); QCOMPARE(task->doneDate(), doneDate); QCOMPARE(task->startDate(), startDate); QCOMPARE(task->dueDate(), dueDate); QCOMPARE(task->property("itemId").toLongLong(), originalItem.id()); } void shouldNotUpdateTaskFromProjectItem() { // GIVEN // Data... - const QString summary = "summary"; - const QString content = "content"; + const QString summary = QStringLiteral("summary"); + const QString content = QStringLiteral("content"); const bool isDone = true; const QDateTime doneDate(QDate(2013, 11, 30), QTime(0, 0), Qt::UTC); const QDateTime startDate(QDate(2013, 11, 24), QTime(0, 0), Qt::UTC); const QDateTime dueDate(QDate(2014, 03, 01), QTime(0, 0), Qt::UTC); // ... stored in a todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); originalTodo->setSummary(summary); originalTodo->setDescription(content); if (originalTodo) originalTodo->setCompleted(KDateTime(doneDate)); else originalTodo->setCompleted(isDone); originalTodo->setDtStart(KDateTime(startDate)); originalTodo->setDtDue(KDateTime(dueDate)); // ... as payload of an item... Akonadi::Item originalItem; - originalItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + originalItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); originalItem.setPayload(originalTodo); // ... deserialized as a task Akonadi::Serializer serializer; auto task = serializer.createTaskFromItem(originalItem); auto artifact = serializer.createArtifactFromItem(originalItem); // WHEN // A todo with the project flag KCalCore::Todo::Ptr projectTodo(new KCalCore::Todo); - projectTodo->setSummary("foo"); - projectTodo->setCustomProperty("Zanshin", "Project", "1"); + projectTodo->setSummary(QStringLiteral("foo")); + projectTodo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); // ... as payload of an item Akonadi::Item projectItem; - projectItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + projectItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); projectItem.setPayload(projectTodo); serializer.updateTaskFromItem(task, projectItem); serializer.updateArtifactFromItem(artifact, projectItem); // THEN QCOMPARE(task->title(), summary); QCOMPARE(task->text(), content); QCOMPARE(task->isDone(), isDone); QCOMPARE(task->doneDate(), doneDate); QCOMPARE(task->startDate(), startDate); QCOMPARE(task->dueDate(), dueDate); QCOMPARE(task->property("itemId").toLongLong(), originalItem.id()); task = artifact.dynamicCast(); QCOMPARE(task->title(), summary); QCOMPARE(task->text(), content); QCOMPARE(task->isDone(), isDone); QCOMPARE(task->doneDate(), doneDate); QCOMPARE(task->startDate(), startDate); QCOMPARE(task->dueDate(), dueDate); QCOMPARE(task->property("itemId").toLongLong(), originalItem.id()); } void shouldCreateItemFromTask_data() { QTest::addColumn("summary"); QTest::addColumn("content"); QTest::addColumn("isDone"); QTest::addColumn("doneDate"); QTest::addColumn("startDate"); QTest::addColumn("dueDate"); QTest::addColumn("itemId"); QTest::addColumn("parentCollectionId"); QTest::addColumn("todoUid"); QTest::addColumn("delegate"); QTest::newRow("nominal case (no id)") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << qint64(-1) << qint64(-1) << QString() - << Domain::Task::Delegate("John Doe", "j@d.com"); + << Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("j@d.com")); QTest::newRow("done case (no id)") << "summary" << "content" << true << QDateTime(QDate(2013, 11, 30)) << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << qint64(-1) << qint64(-1) << QString() - << Domain::Task::Delegate("John Doe", "j@d.com"); + << Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("j@d.com")); QTest::newRow("empty case (no id)") << QString() << QString() << false << QDateTime() << QDateTime() << QDateTime() << qint64(-1) << qint64(-1) << QString() << Domain::Task::Delegate(); QTest::newRow("nominal case (with id)") << "summary" << "content" << false << QDateTime() << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << qint64(42) << qint64(43) << "my-uid" - << Domain::Task::Delegate("John Doe", "j@d.com"); + << Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("j@d.com")); QTest::newRow("done case (with id)") << "summary" << "content" << true << QDateTime(QDate(2013, 11, 30)) << QDateTime(QDate(2013, 11, 24)) << QDateTime(QDate(2014, 03, 01)) << qint64(42) << qint64(43) << "my-uid" - << Domain::Task::Delegate("John Doe", "j@d.com"); + << Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("j@d.com")); QTest::newRow("empty case (with id)") << QString() << QString() << false << QDateTime() << QDateTime() << QDateTime() << qint64(42) << qint64(43) << "my-uid" << Domain::Task::Delegate(); } void shouldCreateItemFromTask() { // GIVEN // Data... QFETCH(QString, summary); QFETCH(QString, content); QFETCH(bool, isDone); QFETCH(QDateTime, doneDate); QFETCH(QDateTime, startDate); QFETCH(QDateTime, dueDate); QFETCH(qint64, itemId); QFETCH(qint64, parentCollectionId); QFETCH(QString, todoUid); QFETCH(Domain::Task::Delegate, delegate); // Switch to UTC doneDate.setTimeSpec(Qt::UTC); startDate.setTimeSpec(Qt::UTC); dueDate.setTimeSpec(Qt::UTC); // ... stored in a task auto task = Domain::Task::Ptr::create(); task->setTitle(summary); task->setText(content); task->setDone(isDone); task->setDoneDate(doneDate); task->setStartDate(startDate); task->setDueDate(dueDate); task->setDelegate(delegate); if (itemId > 0) task->setProperty("itemId", itemId); if (parentCollectionId > 0) task->setProperty("parentCollectionId", parentCollectionId); if (!todoUid.isEmpty()) task->setProperty("todoUid", todoUid); task->setProperty("relatedUid", "parent-uid"); // WHEN Akonadi::Serializer serializer; auto item = serializer.createItemFromTask(task); // THEN QCOMPARE(item.mimeType(), KCalCore::Todo::todoMimeType()); QCOMPARE(item.isValid(), itemId > 0); if (itemId > 0) { QCOMPARE(item.id(), itemId); } QCOMPARE(item.parentCollection().isValid(), parentCollectionId > 0); if (parentCollectionId > 0) { QCOMPARE(item.parentCollection().id(), parentCollectionId); } auto todo = item.payload(); QCOMPARE(todo->summary(), summary); QCOMPARE(todo->description(), content); QCOMPARE(todo->isCompleted(), isDone); QCOMPARE(todo->completed().dateTime().toUTC(), doneDate); QCOMPARE(todo->dtStart().dateTime().toUTC(), startDate); QCOMPARE(todo->dtDue().dateTime().toUTC(), dueDate); if (delegate.isValid()) { auto attendee = todo->attendeeByMail(delegate.email()); QVERIFY(attendee); QCOMPARE(attendee->name(), delegate.name()); QCOMPARE(attendee->email(), delegate.email()); } if (!todoUid.isEmpty()) { QCOMPARE(todo->uid(), todoUid); } - QCOMPARE(todo->relatedTo(), QString("parent-uid")); + QCOMPARE(todo->relatedTo(), QStringLiteral("parent-uid")); } void shouldVerifyIfAnItemIsATaskChild_data() { QTest::addColumn("task"); QTest::addColumn("item"); QTest::addColumn("isParent"); // Create task - const QString summary = "summary"; - const QString content = "content"; + const QString summary = QStringLiteral("summary"); + const QString content = QStringLiteral("content"); const bool isDone = true; const QDateTime doneDate(QDate(2013, 11, 30), QTime(0, 0), Qt::UTC); const QDateTime startDate(QDate(2013, 11, 24), QTime(0, 0), Qt::UTC); const QDateTime dueDate(QDate(2014, 03, 01), QTime(0, 0), Qt::UTC); // ... create a task Domain::Task::Ptr task(new Domain::Task); task->setTitle(summary); task->setText(content); task->setDone(isDone); task->setDoneDate(doneDate); task->setStartDate(startDate); task->setDueDate(dueDate); task->setProperty("todoUid", "1"); // Create Child item KCalCore::Todo::Ptr childTodo(new KCalCore::Todo); childTodo->setSummary(summary); childTodo->setDescription(content); if (isDone) childTodo->setCompleted(KDateTime(doneDate)); else childTodo->setCompleted(isDone); childTodo->setDtStart(KDateTime(startDate)); childTodo->setDtDue(KDateTime(dueDate)); Akonadi::Item childItem; - childItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + childItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); childItem.setPayload(childTodo); QTest::newRow("without parent") << task << childItem << false; // Create Child Item with parent KCalCore::Todo::Ptr childTodo2(new KCalCore::Todo); childTodo2->setSummary(summary); childTodo2->setDescription(content); if (isDone) childTodo2->setCompleted(KDateTime(doneDate)); else childTodo2->setCompleted(isDone); childTodo2->setDtStart(KDateTime(startDate)); childTodo2->setDtDue(KDateTime(dueDate)); - childTodo2->setRelatedTo("1"); + childTodo2->setRelatedTo(QStringLiteral("1")); Akonadi::Item childItem2; - childItem2.setMimeType("application/x-vnd.akonadi.calendar.todo"); + childItem2.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); childItem2.setPayload(childTodo2); QTest::newRow("with parent") << task << childItem2 << true; Domain::Task::Ptr invalidTask(new Domain::Task); QTest::newRow("with invalid task") << invalidTask << childItem << false; Akonadi::Item invalidItem; QTest::newRow("with invalid item") << task << invalidItem << false; } void shouldVerifyIfAnItemIsATaskChild() { // GIVEN QFETCH(Domain::Task::Ptr, task); QFETCH(Akonadi::Item, item); QFETCH(bool, isParent); // WHEN Akonadi::Serializer serializer; bool value = serializer.isTaskChild(task, item); // THEN QCOMPARE(value, isParent); } void shouldRetrieveRelatedUidFromItem_data() { QTest::addColumn("item"); QTest::addColumn("expectedUid"); Akonadi::Item item1; KCalCore::Todo::Ptr todo1(new KCalCore::Todo); item1.setPayload(todo1); Akonadi::Item item2; KCalCore::Todo::Ptr todo2(new KCalCore::Todo); - todo2->setRelatedTo("1"); + todo2->setRelatedTo(QStringLiteral("1")); item2.setPayload(todo2); Akonadi::Item item3; KMime::Message::Ptr message1(new KMime::Message); - message1->subject(true)->fromUnicodeString("foo", "utf-8"); - message1->mainBodyPart()->fromUnicodeString("bar"); + message1->subject(true)->fromUnicodeString(QStringLiteral("foo"), "utf-8"); + message1->mainBodyPart()->fromUnicodeString(QStringLiteral("bar")); item3.setMimeType(Akonadi::NoteUtils::noteMimeType()); item3.setPayload(message1); Akonadi::Item item4; KMime::Message::Ptr message2(new KMime::Message); - message2->subject(true)->fromUnicodeString("foo", "utf-8"); - message2->mainBodyPart()->fromUnicodeString("bar"); + message2->subject(true)->fromUnicodeString(QStringLiteral("foo"), "utf-8"); + message2->mainBodyPart()->fromUnicodeString(QStringLiteral("bar")); auto relatedHeader1 = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader1->from7BitString("1"); message2->appendHeader(relatedHeader1); item4.setMimeType(Akonadi::NoteUtils::noteMimeType()); item4.setPayload(message2); Akonadi::Item item5; KMime::Message::Ptr message3(new KMime::Message); - message3->subject(true)->fromUnicodeString("foo", "utf-8"); - message3->mainBodyPart()->fromUnicodeString("bar"); + message3->subject(true)->fromUnicodeString(QStringLiteral("foo"), "utf-8"); + message3->mainBodyPart()->fromUnicodeString(QStringLiteral("bar")); auto relatedHeader2 = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); message3->appendHeader(relatedHeader2); item5.setMimeType(Akonadi::NoteUtils::noteMimeType()); item5.setPayload(message3); QTest::newRow("task without related") << item1 << QString(); QTest::newRow("task with related") << item2 << "1"; QTest::newRow("note without related") << item3 << QString(); QTest::newRow("note with related") << item4 << "1"; QTest::newRow("note with empty related") << item5 << QString(); } void shouldRetrieveRelatedUidFromItem() { // GIVEN QFETCH(Akonadi::Item, item); QFETCH(QString, expectedUid); // WHEN Akonadi::Serializer serializer; QString uid = serializer.relatedUidFromItem(item); // THEN QCOMPARE(uid, expectedUid); } void shouldCreateNoteFromItem_data() { QTest::addColumn("title"); QTest::addColumn("text"); QTest::addColumn("relatedUid"); QTest::newRow("nominal case (no related)") << "A note title" << "A note content.\nWith two lines." << QString(); QTest::newRow("nominal case (with related)") << "A note title" << "A note content.\nWith two lines." << "parent-uid"; QTest::newRow("trailing new lines") << "A note title" << "Empty lines at the end.\n\n\n" << QString(); QTest::newRow("empty case") << QString() << QString() << QString(); } void shouldCreateNoteFromItem() { // GIVEN // Data... QFETCH(QString, title); QFETCH(QString, text); QFETCH(QString, relatedUid); // ... stored in a message... KMime::Message::Ptr message(new KMime::Message); message->subject(true)->fromUnicodeString(title, "utf-8"); message->mainBodyPart()->fromUnicodeString(text); if (!relatedUid.isEmpty()) { auto relatedHeader = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader->from7BitString(relatedUid.toUtf8()); message->appendHeader(relatedHeader); } // ... as payload of an item. Akonadi::Item item; item.setMimeType(Akonadi::NoteUtils::noteMimeType()); item.setPayload(message); // WHEN Akonadi::Serializer serializer; Domain::Note::Ptr note = serializer.createNoteFromItem(item); auto artifact = serializer.createArtifactFromItem(item).dynamicCast(); // THEN const auto expectedText = text.endsWith('\n') ? (text.chop(1), text) : text; QCOMPARE(note->title(), title); QCOMPARE(note->text(), expectedText); QCOMPARE(note->property("itemId").toLongLong(), item.id()); QCOMPARE(note->property("relatedUid").toString(), relatedUid); QVERIFY(!artifact.isNull()); QCOMPARE(artifact->title(), title); QCOMPARE(artifact->text(), expectedText); QCOMPARE(artifact->property("itemId").toLongLong(), item.id()); QCOMPARE(artifact->property("relatedUid").toString(), relatedUid); } void shouldCreateNullNoteFromInvalidItem() { // GIVEN Akonadi::Item item; // WHEN Akonadi::Serializer serializer; Domain::Note::Ptr note = serializer.createNoteFromItem(item); auto artifact = serializer.createArtifactFromItem(item); // THEN QVERIFY(note.isNull()); QVERIFY(artifact.isNull()); } void shouldUpdateNoteFromItem_data() { QTest::addColumn("updatedTitle"); QTest::addColumn("updatedText"); QTest::addColumn("updatedRelatedUid"); QTest::newRow("no change") << "title" << "content" << "parent-uid"; QTest::newRow("data changed (with related)") << "A new title" << "A new content" << "new-parent-uid"; QTest::newRow("data changed (with no related)") << "A new title" << "A new content" << QString(); } void shouldUpdateNoteFromItem() { // GIVEN // A message... KMime::Message::Ptr message(new KMime::Message); - message->subject(true)->fromUnicodeString("title", "utf-8"); - message->mainBodyPart()->fromUnicodeString("text"); + message->subject(true)->fromUnicodeString(QStringLiteral("title"), "utf-8"); + message->mainBodyPart()->fromUnicodeString(QStringLiteral("text")); auto relatedHeader = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader->from7BitString("parent-uid"); message->appendHeader(relatedHeader); //... as the payload of an item... Akonadi::Item item; item.setMimeType(Akonadi::NoteUtils::noteMimeType()); item.setPayload(message); //... deserialized as a note Akonadi::Serializer serializer; auto note = serializer.createNoteFromItem(item); auto artifact = serializer.createNoteFromItem(item); // WHEN // Data... QFETCH(QString, updatedTitle); QFETCH(QString, updatedText); QFETCH(QString, updatedRelatedUid); //... stored in a new message... KMime::Message::Ptr updatedMessage(new KMime::Message); updatedMessage->subject(true)->fromUnicodeString(updatedTitle, "utf-8"); updatedMessage->mainBodyPart()->fromUnicodeString(updatedText); if (!updatedRelatedUid.isEmpty()) { relatedHeader = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader->from7BitString(updatedRelatedUid.toUtf8()); updatedMessage->appendHeader(relatedHeader); } //... as the payload of a new item... Akonadi::Item updatedItem; updatedItem.setMimeType(Akonadi::NoteUtils::noteMimeType()); updatedItem.setPayload(updatedMessage); serializer.updateNoteFromItem(note, updatedItem); serializer.updateArtifactFromItem(artifact, updatedItem); // THEN QCOMPARE(note->title(), updatedTitle); QCOMPARE(note->text(), updatedText); QCOMPARE(note->property("itemId").toLongLong(), updatedItem.id()); QCOMPARE(note->property("relatedUid").toString(), updatedRelatedUid); note = artifact.dynamicCast(); QCOMPARE(note->title(), updatedTitle); QCOMPARE(note->text(), updatedText); QCOMPARE(note->property("itemId").toLongLong(), updatedItem.id()); QCOMPARE(note->property("relatedUid").toString(), updatedRelatedUid); } void shouldNotUpdateNoteFromInvalidItem() { // GIVEN // Data... - QString title = "A title"; - QString text = "A note content"; + QString title = QStringLiteral("A title"); + QString text = QStringLiteral("A note content"); // ... stored in a message... KMime::Message::Ptr message(new KMime::Message); message->subject(true)->fromUnicodeString(title, "utf-8"); message->mainBodyPart()->fromUnicodeString(text); //... as the payload of an item... Akonadi::Item item; item.setMimeType(Akonadi::NoteUtils::noteMimeType()); item.setPayload(message); //... deserialized as a note Akonadi::Serializer serializer; auto note = serializer.createNoteFromItem(item); auto artifact = serializer.createArtifactFromItem(item); // WHEN Akonadi::Item invalidItem; serializer.updateNoteFromItem(note, invalidItem); serializer.updateArtifactFromItem(artifact, invalidItem); //THEN QCOMPARE(note->title(), title); QCOMPARE(note->text(), text); QCOMPARE(note->property("itemId").toLongLong(), item.id()); note = artifact.dynamicCast(); QCOMPARE(note->title(), title); QCOMPARE(note->text(), text); QCOMPARE(note->property("itemId").toLongLong(), item.id()); } void shouldCreateItemFromNote_data() { QTest::addColumn("title"); QTest::addColumn("content"); QTest::addColumn("expectedTitle"); QTest::addColumn("expectedContent"); QTest::addColumn("itemId"); QTest::addColumn("relatedUid"); QTest::newRow("nominal case (no id)") << "title" << "content" << "title" << "content" << qint64(-1) << QString(); QTest::newRow("empty case (no id)") << QString() << QString() << "New Note" << QString() << qint64(-1) << QString(); QTest::newRow("nominal case (with id)") << "title" << "content" << "title" << "content" << qint64(42) << "parent-uid"; QTest::newRow("empty case (with id)") << QString() << QString() << "New Note" << QString() << qint64(42) << "parent-uid"; QTest::newRow("empty line at the end") << "title" << "content\n\n\n" << "title" << "content\n\n\n" << qint64(-1) << QString(); } void shouldCreateItemFromNote() { // GIVEN // Data... QFETCH(QString, title); QFETCH(QString, content); QFETCH(qint64, itemId); QFETCH(QString, relatedUid); // ... stored in a note auto note = Domain::Note::Ptr::create(); note->setTitle(title); note->setText(content); if (itemId > 0) note->setProperty("itemId", itemId); if (!relatedUid.isEmpty()) note->setProperty("relatedUid", relatedUid); // WHEN Akonadi::Serializer serializer; auto item = serializer.createItemFromNote(note); // THEN QCOMPARE(item.mimeType(), Akonadi::NoteUtils::noteMimeType()); QCOMPARE(item.isValid(), itemId > 0); if (itemId > 0) { QCOMPARE(item.id(), itemId); } QFETCH(QString, expectedTitle); QFETCH(QString, expectedContent); auto message = item.payload(); QCOMPARE(message->subject(false)->asUnicodeString(), expectedTitle); QCOMPARE(message->mainBodyPart()->decodedText(), expectedContent); if (relatedUid.isEmpty()) { QVERIFY(!message->headerByType("X-Zanshin-RelatedProjectUid")); } else { QVERIFY(message->headerByType("X-Zanshin-RelatedProjectUid")); QCOMPARE(message->headerByType("X-Zanshin-RelatedProjectUid")->asUnicodeString(), relatedUid); } } void shouldCreateProjectFromItem_data() { QTest::addColumn("summary"); QTest::newRow("nominal case") << "summary"; QTest::newRow("empty case") << QString(); } void shouldCreateProjectFromItem() { // GIVEN // Data... QFETCH(QString, summary); // ... stored in a todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(summary); - todo->setCustomProperty("Zanshin", "Project", "1"); + todo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); QVERIFY(!todo->uid().isEmpty()); // ... as payload of an item Akonadi::Item item(42); - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // which has a prent collection Akonadi::Collection collection(43); item.setParentCollection(collection); // WHEN Akonadi::Serializer serializer; Domain::Project::Ptr project = serializer.createProjectFromItem(item); // THEN QCOMPARE(project->name(), summary); QCOMPARE(project->property("itemId").toLongLong(), item.id()); QCOMPARE(project->property("parentCollectionId").toLongLong(), collection.id()); QCOMPARE(project->property("todoUid").toString(), todo->uid()); } void shouldCreateNullProjectFromInvalidItem() { // GIVEN Akonadi::Item item; // WHEN Akonadi::Serializer serializer; Domain::Project::Ptr project = serializer.createProjectFromItem(item); // THEN QVERIFY(project.isNull()); } void shouldCreateNullProjectFromTaskItem() { // GIVEN // A todo without the project flag KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setSummary("foo"); + todo->setSummary(QStringLiteral("foo")); // ... as payload of an item Akonadi::Item item; - item.setMimeType("application/x-vnd.akonadi.calendar.todo"); + item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // WHEN Akonadi::Serializer serializer; Domain::Project::Ptr project = serializer.createProjectFromItem(item); // THEN QVERIFY(project.isNull()); } void shouldUpdateProjectFromItem_data() { QTest::addColumn("updatedSummary"); QTest::newRow("no change") << "summary"; QTest::newRow("changed") << "new summary"; } void shouldUpdateProjectFromItem() { // GIVEN // A todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); - originalTodo->setSummary("summary"); - originalTodo->setCustomProperty("Zanshin", "Project", "1"); + originalTodo->setSummary(QStringLiteral("summary")); + originalTodo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); // ... as payload of an item... Akonadi::Item originalItem(42); - originalItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + originalItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); originalItem.setPayload(originalTodo); // ... which has a parent collection... Akonadi::Collection originalCollection(43); originalItem.setParentCollection(originalCollection); // ... deserialized as a project Akonadi::Serializer serializer; auto project = serializer.createProjectFromItem(originalItem); // WHEN // Data... QFETCH(QString, updatedSummary); // ... in a new todo... KCalCore::Todo::Ptr updatedTodo(new KCalCore::Todo); updatedTodo->setSummary(updatedSummary); - updatedTodo->setCustomProperty("Zanshin", "Project", "1"); + updatedTodo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); QVERIFY(!updatedTodo->uid().isEmpty()); // ... as payload of a new item Akonadi::Item updatedItem(44); - updatedItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + updatedItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); updatedItem.setPayload(updatedTodo); // ... which has a new parent collection Akonadi::Collection updatedCollection(45); updatedItem.setParentCollection(updatedCollection); serializer.updateProjectFromItem(project, updatedItem); // THEN QCOMPARE(project->name(), updatedSummary); QCOMPARE(project->property("itemId").toLongLong(), updatedItem.id()); QCOMPARE(project->property("parentCollectionId").toLongLong(), updatedCollection.id()); QCOMPARE(project->property("todoUid").toString(), updatedTodo->uid()); } void shouldNotUpdateProjectFromInvalidItem() { // GIVEN // Data... - const QString summary = "summary"; + const QString summary = QStringLiteral("summary"); // ... stored in a todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); originalTodo->setSummary(summary); - originalTodo->setCustomProperty("Zanshin", "Project", "1"); + originalTodo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); // ... as payload of an item... Akonadi::Item originalItem; - originalItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + originalItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); originalItem.setPayload(originalTodo); // ... deserialized as a project Akonadi::Serializer serializer; auto project = serializer.createProjectFromItem(originalItem); // WHEN Akonadi::Item invalidItem; serializer.updateProjectFromItem(project, invalidItem); // THEN QCOMPARE(project->name(), summary); } void shouldNotUpdateProjectFromTaskItem() { // GIVEN // Data... - const QString summary = "summary"; + const QString summary = QStringLiteral("summary"); // ... stored in a todo... KCalCore::Todo::Ptr originalTodo(new KCalCore::Todo); originalTodo->setSummary(summary); - originalTodo->setCustomProperty("Zanshin", "Project", "1"); + originalTodo->setCustomProperty("Zanshin", "Project", QStringLiteral("1")); // ... as payload of an item... Akonadi::Item originalItem; - originalItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + originalItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); originalItem.setPayload(originalTodo); // ... deserialized as a project Akonadi::Serializer serializer; auto project = serializer.createProjectFromItem(originalItem); // WHEN // A todo without the project flag KCalCore::Todo::Ptr projectTodo(new KCalCore::Todo); - projectTodo->setSummary("foo"); + projectTodo->setSummary(QStringLiteral("foo")); // ... as payload of an item Akonadi::Item projectItem; - projectItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + projectItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); projectItem.setPayload(projectTodo); serializer.updateProjectFromItem(project, projectItem); // THEN QCOMPARE(project->name(), summary); } void shouldCreateItemFromProject_data() { QTest::addColumn("summary"); QTest::addColumn("itemId"); QTest::addColumn("parentCollectionId"); QTest::newRow("nominal case (no id)") << "summary" << qint64(-1) << qint64(-1); QTest::newRow("empty case (no id)") << QString() << qint64(-1) << qint64(-1); QTest::newRow("nominal case (with id)") << "summary" << qint64(42) << qint64(43); QTest::newRow("empty case (with id)") << QString() << qint64(42) << qint64(43); } void shouldCreateItemFromProject() { // GIVEN // Data... QFETCH(QString, summary); QFETCH(qint64, itemId); QFETCH(qint64, parentCollectionId); - const QString todoUid = "test-uid"; + const QString todoUid = QStringLiteral("test-uid"); // ... stored in a project auto project = Domain::Project::Ptr::create(); project->setName(summary); project->setProperty("todoUid", todoUid); if (itemId > 0) project->setProperty("itemId", itemId); if (parentCollectionId > 0) project->setProperty("parentCollectionId", parentCollectionId); // WHEN Akonadi::Serializer serializer; auto item = serializer.createItemFromProject(project); // THEN QCOMPARE(item.mimeType(), KCalCore::Todo::todoMimeType()); QCOMPARE(item.isValid(), itemId > 0); if (itemId > 0) { QCOMPARE(item.id(), itemId); } QCOMPARE(item.parentCollection().isValid(), parentCollectionId > 0); if (parentCollectionId > 0) { QCOMPARE(item.parentCollection().id(), parentCollectionId); } auto todo = item.payload(); QCOMPARE(todo->summary(), summary); QCOMPARE(todo->uid(), todoUid); QVERIFY(!todo->customProperty("Zanshin", "Project").isEmpty()); } void shouldVerifyIfAnItemIsAProjectChild_data() { QTest::addColumn("project"); QTest::addColumn("item"); QTest::addColumn("isParent"); // Create project auto project = Domain::Project::Ptr::create(); - project->setName("project"); + project->setName(QStringLiteral("project")); project->setProperty("todoUid", "1"); // Create unrelated todo auto unrelatedTodo = KCalCore::Todo::Ptr::create(); - unrelatedTodo->setSummary("summary"); + unrelatedTodo->setSummary(QStringLiteral("summary")); Akonadi::Item unrelatedTodoItem; - unrelatedTodoItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + unrelatedTodoItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); unrelatedTodoItem.setPayload(unrelatedTodo); QTest::newRow("unrelated todo") << project << unrelatedTodoItem << false; // Create child todo auto childTodo = KCalCore::Todo::Ptr::create(); - childTodo->setSummary("summary"); - childTodo->setRelatedTo("1"); + childTodo->setSummary(QStringLiteral("summary")); + childTodo->setRelatedTo(QStringLiteral("1")); Akonadi::Item childTodoItem; - childTodoItem.setMimeType("application/x-vnd.akonadi.calendar.todo"); + childTodoItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); childTodoItem.setPayload(childTodo); QTest::newRow("child todo") << project << childTodoItem << true; // Create unrelated note KMime::Message::Ptr unrelatedNote(new KMime::Message); - unrelatedNote->subject(true)->fromUnicodeString("subject", "utf-8"); + unrelatedNote->subject(true)->fromUnicodeString(QStringLiteral("subject"), "utf-8"); Akonadi::Item unrelatedNoteItem; unrelatedNoteItem.setMimeType(Akonadi::NoteUtils::noteMimeType()); unrelatedNoteItem.setPayload(unrelatedNote); QTest::newRow("unrelated note") << project << unrelatedNoteItem << false; // Create child note KMime::Message::Ptr childNote(new KMime::Message); - childNote->subject(true)->fromUnicodeString("subject", "utf-8"); + childNote->subject(true)->fromUnicodeString(QStringLiteral("subject"), "utf-8"); auto relatedHeader = new KMime::Headers::Generic("X-Zanshin-RelatedProjectUid"); relatedHeader->from7BitString("1"); childNote->appendHeader(relatedHeader); Akonadi::Item childNoteItem; childNoteItem.setMimeType(Akonadi::NoteUtils::noteMimeType()); childNoteItem.setPayload(childNote); QTest::newRow("child todo") << project << childNoteItem << true; auto invalidProject = Domain::Project::Ptr::create(); QTest::newRow("invalid project") << invalidProject << unrelatedNoteItem << false; Akonadi::Item invalidItem; QTest::newRow("invalid item") << project << invalidItem << false; } void shouldVerifyIfAnItemIsAProjectChild() { // GIVEN QFETCH(Domain::Project::Ptr, project); QFETCH(Akonadi::Item, item); QFETCH(bool, isParent); // WHEN Akonadi::Serializer serializer; bool value = serializer.isProjectChild(project, item); // THEN QCOMPARE(value, isParent); } void shouldUpdateItemParent_data() { QTest::addColumn("item"); QTest::addColumn("parent"); QTest::addColumn("expectedRelatedToUid"); Akonadi::Item item1; KCalCore::Todo::Ptr todo1(new KCalCore::Todo); item1.setPayload(todo1); Domain::Task::Ptr parent(new Domain::Task); parent->setProperty("todoUid", "1"); QTest::newRow("nominal case") << item1 << parent << "1"; Akonadi::Item item2; QTest::newRow("update item without payload") << item2 << parent << QString(); Domain::Task::Ptr parent2(new Domain::Task); QTest::newRow("update item with a empty parent uid") << item1 << parent2 << QString(); } void shouldUpdateItemParent() { // GIVEN QFETCH(Akonadi::Item, item); QFETCH(Domain::Task::Ptr, parent); QFETCH(QString, expectedRelatedToUid); // WHEN Akonadi::Serializer serializer; serializer.updateItemParent(item, parent); // THEN if (item.hasPayload()) { auto todo = item.payload(); QString relatedUid = todo->relatedTo(); QCOMPARE(relatedUid, expectedRelatedToUid); } } void shouldUpdateItemProject_data() { QTest::addColumn("item"); QTest::addColumn("parent"); QTest::addColumn("expectedRelatedToUid"); Akonadi::Item todoItem; KCalCore::Todo::Ptr todo(new KCalCore::Todo); todoItem.setPayload(todo); auto parent = Domain::Project::Ptr::create(); parent->setProperty("todoUid", "1"); QTest::newRow("nominal todo case") << todoItem << parent << "1"; auto invalidParent = Domain::Project::Ptr::create(); QTest::newRow("update todo item with a empty parent uid") << todoItem << invalidParent << QString(); Akonadi::Item noteItem; KMime::Message::Ptr note(new KMime::Message); noteItem.setPayload(note); QTest::newRow("nominal note case") << noteItem << parent << "1"; QTest::newRow("update note item with a empty parent uid") << noteItem << invalidParent << QString(); Akonadi::Item invalidItem; QTest::newRow("update item without payload") << invalidItem << parent << QString(); } void shouldUpdateItemProject() { // GIVEN QFETCH(Akonadi::Item, item); QFETCH(Domain::Project::Ptr, parent); QFETCH(QString, expectedRelatedToUid); // WHEN Akonadi::Serializer serializer; serializer.updateItemProject(item, parent); // THEN if (item.hasPayload()) { auto todo = item.payload(); const QString relatedUid = todo->relatedTo(); QCOMPARE(relatedUid, expectedRelatedToUid); } else if (item.hasPayload()) { auto note = item.payload(); const auto relatedHeader = note->headerByType("X-Zanshin-RelatedProjectUid"); const QString relatedUid = relatedHeader ? relatedHeader->asUnicodeString() : QString(); QCOMPARE(relatedUid, expectedRelatedToUid); if (!expectedRelatedToUid.isEmpty()) - QVERIFY(note->encodedContent().contains(QString("X-Zanshin-RelatedProjectUid: %1").arg(expectedRelatedToUid).toUtf8())); + QVERIFY(note->encodedContent().contains(QStringLiteral("X-Zanshin-RelatedProjectUid: %1").arg(expectedRelatedToUid).toUtf8())); else QVERIFY(!note->encodedContent().contains("X-Zanshin-RelatedProjectUid:")); } } void shouldFilterChildrenItem_data() { QTest::addColumn("item"); QTest::addColumn("items"); QTest::addColumn("size"); Akonadi::Item item(12); KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setUid("1"); + todo->setUid(QStringLiteral("1")); item.setPayload(todo); Akonadi::Item::List items; QTest::newRow("empty list") << item << items << 0; Akonadi::Item item2(13); KCalCore::Todo::Ptr todo2(new KCalCore::Todo); item2.setPayload(todo2); Akonadi::Item::List items2; items2 << item2; QTest::newRow("list without child") << item << items2 << 0; Akonadi::Item item3(14); KCalCore::Todo::Ptr todo3(new KCalCore::Todo); - todo3->setUid("3"); - todo3->setRelatedTo("1"); + todo3->setUid(QStringLiteral("3")); + todo3->setRelatedTo(QStringLiteral("1")); item3.setPayload(todo3); Akonadi::Item::List items3; items3 << item2 << item3; QTest::newRow("list with child") << item << items3 << 1; Akonadi::Item item4(15); KCalCore::Todo::Ptr todo4(new KCalCore::Todo); - todo4->setRelatedTo("3"); + todo4->setRelatedTo(QStringLiteral("3")); item4.setPayload(todo4); Akonadi::Item::List items4; items4 << item2 << item3 << item4; QTest::newRow("list with child with a child") << item << items4 << 2; Akonadi::Item::List items5; items5 << item << item2 << item3 << item4; QTest::newRow("list with filter in list") << item << items5 << 2; } void shouldFilterChildrenItem() { // GIVEN QFETCH(Akonadi::Item, item); QFETCH(Akonadi::Item::List, items); QFETCH(int, size); // WHEN Akonadi::Serializer serializer; Akonadi::Item::List list = serializer.filterDescendantItems(items, item); // THEN QCOMPARE(list.size(), size); } void shouldRemoveItemParent_data() { QTest::addColumn("item"); Akonadi::Item item(15); KCalCore::Todo::Ptr todo(new KCalCore::Todo); - todo->setRelatedTo("3"); + todo->setRelatedTo(QStringLiteral("3")); item.setPayload(todo); QTest::newRow("nominal case") << item; Akonadi::Item item2(16); QTest::newRow("parent invalid") << item2; } void shouldRemoveItemParent() { // GIVEN QFETCH(Akonadi::Item, item); // WHEN Akonadi::Serializer serializer; serializer.removeItemParent(item); // THEN if (item.hasPayload()) QCOMPARE(item.payload()->relatedTo(), QString()); } void shouldPromoteItemToProject_data() { QTest::addColumn("item"); auto item = Akonadi::Item(15); auto todo = KCalCore::Todo::Ptr::create(); - todo->setRelatedTo("3"); + todo->setRelatedTo(QStringLiteral("3")); item.setPayload(todo); QTest::newRow("nominal case") << item; QTest::newRow("invalid item") << Akonadi::Item(16); } void shouldPromoteItemToProject() { // GIVEN QFETCH(Akonadi::Item, item); // WHEN Akonadi::Serializer serializer; serializer.promoteItemToProject(item); // THEN if (item.hasPayload()) { auto todo = item.payload(); QCOMPARE(todo->relatedTo(), QString()); QVERIFY(!todo->customProperty("Zanshin", "Project").isEmpty()); } } void shouldClearItem_data() { QTest::addColumn("item"); Akonadi::Item *itemWithContent = new Akonadi::Item(15); KCalCore::Todo::Ptr todo(new KCalCore::Todo); // context - Akonadi::Tag context("42"); + Akonadi::Tag context(QStringLiteral("42")); context.setType( Akonadi::SerializerInterface::contextTagType() ); // tag - Akonadi::Tag tag("43"); + Akonadi::Tag tag(QStringLiteral("43")); tag.setType( Akonadi::Tag::PLAIN ); Akonadi::Tag::List tagsList = Akonadi::Tag::List() << tag << context; itemWithContent->setTags(tagsList); itemWithContent->setPayload(todo); QTest::newRow("nominal case") << itemWithContent; Akonadi::Item *item2 = new Akonadi::Item(16); QTest::newRow("parent invalid") << item2; } void shouldClearItem() { // GIVEN QFETCH(Akonadi::Item*, item); // WHEN Akonadi::Serializer serializer; serializer.clearItem(item); // THEN QCOMPARE(item->tags().size(), 0); delete item; } void shouldCreateContextFromTag_data() { QTest::addColumn("type"); QTest::addColumn("name"); QTest::addColumn("tagId"); const QByteArray rightTagType = Akonadi::Serializer::contextTagType() ; QTest::newRow("nominal case") << rightTagType << "Context42" << Akonadi::Tag::Id(42); QTest::newRow("empty name case") << rightTagType << "" << Akonadi::Tag::Id(43); } void shouldCreateContextFromTag() { // GIVEN // Data... QFETCH(QByteArray, type); QFETCH(QString, name); QFETCH(Akonadi::Tag::Id, tagId); // ... stored as an Akonadi Tag Akonadi::Tag tag(name); tag.setType(type); tag.setId(tagId); // WHEN Akonadi::Serializer serializer; Domain::Context::Ptr context = serializer.createContextFromTag(tag); // THEN QCOMPARE(context->name(), tag.name()); QCOMPARE(context->property("tagId").toLongLong(), tag.id()); } void shouldNotCreateContextFromWrongTagType() { // GIVEN // Data stored as an Akonadi Tag - Akonadi::Tag tag("context42"); + Akonadi::Tag tag(QStringLiteral("context42")); tag.setType(QByteArray("wrongTagType")); // WHEN Akonadi::Serializer serializer; Domain::Context::Ptr context = serializer.createContextFromTag(tag); // THEN QVERIFY(!context); } void shouldUpdateContextFromTag_data() { shouldCreateContextFromTag_data(); } void shouldUpdateContextFromTag() { // GIVEN // Data... QFETCH(QByteArray, type); QFETCH(QString, name); QFETCH(Akonadi::Tag::Id, tagId); // ... stored as an Akonadi Tag Akonadi::Tag tag(name); tag.setType(type); tag.setId(tagId); // WHEN Akonadi::Serializer serializer; Domain::Context::Ptr context(new Domain::Context); serializer.updateContextFromTag(context, tag); // THEN QCOMPARE(context->name(), tag.name()); QCOMPARE(context->property("tagId").toLongLong(), tag.id()); } void shouldNotUpdateContextFromWrongTagType() { // GIVEN - Akonadi::Tag originalTag("Context42"); + Akonadi::Tag originalTag(QStringLiteral("Context42")); originalTag.setType(Akonadi::Serializer::contextTagType()); originalTag.setId(42); Akonadi::Serializer serializer; Domain::Context::Ptr context = serializer.createContextFromTag(originalTag); // WHEN - Akonadi::Tag wrongTag("WrongContext42"); + Akonadi::Tag wrongTag(QStringLiteral("WrongContext42")); wrongTag.setType(QByteArray("wrongTypeTag")); serializer.updateContextFromTag(context, wrongTag); // THEN QCOMPARE(context->name(), originalTag.name()); QCOMPARE(context->property("tagId").toLongLong(), originalTag.id()); } void shouldVerifyIfAnItemIsAContextChild_data() { QTest::addColumn("context"); QTest::addColumn("item"); QTest::addColumn("isChild"); // Create a context auto context = Domain::Context::Ptr::create(); context->setProperty("tagId", qint64(43)); Akonadi::Tag tag(Akonadi::Tag::Id(43)); Akonadi::Item unrelatedItem; QTest::newRow("Unrelated item") << context << unrelatedItem << false; Akonadi::Item relatedItem; relatedItem.setTag(tag); QTest::newRow("Related item") << context << relatedItem << true; auto invalidContext = Domain::Context::Ptr::create(); QTest::newRow("Invalid context") << invalidContext << relatedItem << false; Akonadi::Item invalidItem; QTest::newRow("Invalid Item") << context << invalidItem << false; } void shouldVerifyIfAnItemIsAContextChild() { // GIVEN QFETCH(Domain::Context::Ptr, context); QFETCH(Akonadi::Item, item); QFETCH(bool, isChild); // WHEN Akonadi::Serializer serializer; bool value = serializer.isContextChild(context, item); // THEN QCOMPARE(value, isChild); } void shouldCheckIfAnItemHasContextsOrTags_data() { QTest::addColumn("item"); QTest::addColumn("contextsExpected"); QTest::addColumn("tagsExpected"); - Akonadi::Tag unrelatedTag("Foo"); + Akonadi::Tag unrelatedTag(QStringLiteral("Foo")); unrelatedTag.setType("unrelated"); - Akonadi::Tag contextTag("Bar"); + Akonadi::Tag contextTag(QStringLiteral("Bar")); contextTag.setType(Akonadi::Serializer::contextTagType()); - Akonadi::Tag akonadiTag("Baz"); + Akonadi::Tag akonadiTag(QStringLiteral("Baz")); akonadiTag.setType(Akonadi::Tag::PLAIN); Akonadi::Item item; QTest::newRow("no tags") << item << false << false; item.setTags({ unrelatedTag }); QTest::newRow("unrelated tags") << item << false << false; item.setTags({ unrelatedTag, contextTag }); QTest::newRow("has contexts") << item << true << false; item.setTags({ unrelatedTag, akonadiTag }); QTest::newRow("has tags") << item << false << true; item.setTags({ unrelatedTag, contextTag, akonadiTag }); QTest::newRow("has both") << item << true << true; } void shouldCheckIfAnItemHasContextsOrTags() { // GIVEN QFETCH(Akonadi::Item, item); QFETCH(bool, contextsExpected); QFETCH(bool, tagsExpected); Akonadi::Serializer serializer; // WHEN const bool hasContexts = serializer.hasContextTags(item); const bool hasTags = serializer.hasAkonadiTags(item); // THEN QCOMPARE(hasContexts, contextsExpected); QCOMPARE(hasTags, tagsExpected); } void shouldCreateTagFromContext_data() { QTest::addColumn("name"); QTest::addColumn("tagId"); QTest::addColumn("tagGid"); - QString nameInternet = "Internet"; + QString nameInternet = QStringLiteral("Internet"); QTest::newRow("nominal case") << QString(nameInternet) << qint64(42) << nameInternet.toLatin1(); QTest::newRow("null name case") << QString() << qint64(42) << QByteArray(); QTest::newRow("null tagId case") << QString(nameInternet)<< qint64(-1) << nameInternet.toLatin1(); QTest::newRow("totally null context case") << QString() << qint64(-1) << QByteArray(); } void shouldCreateTagFromContext() { // GIVEN QFETCH(QString, name); QFETCH(qint64, tagId); QFETCH(QByteArray, tagGid); // WHEN auto context = Domain::Context::Ptr::create(); context->setProperty("tagId", tagId); context->setName(name); Akonadi::Serializer serializer; Akonadi::Tag tag = serializer.createTagFromContext(context); // THEN QCOMPARE(tag.name(), name); QCOMPARE(tag.isValid(), tagId > 0); if (tagId > 0) { QCOMPARE(tag.id(), tagId); QCOMPARE(tag.gid(), tagGid); QCOMPARE(tag.type(), Akonadi::SerializerInterface::contextTagType()); } } void shouldCreateTagFromAkonadiTag_data() { QTest::addColumn("name"); QTest::addColumn("tagId"); QTest::addColumn("type"); - QString tagName = "Optional"; + QString tagName = QStringLiteral("Optional"); QByteArray plainType = Akonadi::Tag::PLAIN; QTest::newRow("nominal case") << tagName << qint64(42) << plainType; QTest::newRow("null name case") << QString() << qint64(42) << plainType; QTest::newRow("null tagId case") << tagName << qint64(-1) << plainType; QTest::newRow("totally null tag case") << QString() << qint64(-1) << plainType; } void shouldCreateTagFromAkonadiTag() { // GIVEN QFETCH(QString, name); QFETCH(qint64, tagId); QFETCH(QByteArray, type); auto akonadiTag = Akonadi::Tag(); akonadiTag.setName(name); akonadiTag.setId(tagId); akonadiTag.setType(type); // WHEN Akonadi::Serializer serializer; Domain::Tag::Ptr resultTag = serializer.createTagFromAkonadiTag(akonadiTag); // THEN QCOMPARE(resultTag->name(), akonadiTag.name()); QCOMPARE(resultTag->property("tagId").toLongLong(), akonadiTag.id()); } void shouldUpdateTagFromAkonadiTag_data() { shouldCreateTagFromAkonadiTag_data(); } void shouldUpdateTagFromAkonadiTag() { // GIVEN QFETCH(QString, name); QFETCH(qint64, tagId); QFETCH(QByteArray, type); // ... stored as an Akonadi Tag Akonadi::Tag akonadiTag(name); akonadiTag.setId(tagId); akonadiTag.setType(type); // WHEN Akonadi::Serializer serializer; auto tag = Domain::Tag::Ptr::create(); - tag->setName("tag42"); + tag->setName(QStringLiteral("tag42")); serializer.updateTagFromAkonadiTag(tag, akonadiTag); // THEN QCOMPARE(tag->name(), akonadiTag.name()); QCOMPARE(tag->property("tagId").toLongLong(), akonadiTag.id()); } void shouldCreateAkonadiTagFromTag_data() { // GIVEN QTest::addColumn("name"); QTest::addColumn("tagId"); QTest::addColumn("tagGid"); const QByteArray namePhilo = "Philosophy"; QTest::newRow("nominal case") << QString(namePhilo) << qint64(42) << namePhilo; QTest::newRow("null name case") << QString() << qint64(42) << QByteArray(); QTest::newRow("null tagId case") << QString(namePhilo) << qint64(-1) << namePhilo; QTest::newRow("totally null tag case") << QString() << qint64(-1) << QByteArray(); } void shouldCreateAkonadiTagFromTag() { // GIVEN QFETCH(QString, name); QFETCH(qint64, tagId); QFETCH(QByteArray, tagGid); // WHEN auto tag = Domain::Tag::Ptr::create(); tag->setProperty("tagId", tagId); tag->setName(name); Akonadi::Serializer serializer; Akonadi::Tag akonadiTag = serializer.createAkonadiTagFromTag(tag); // THEN QCOMPARE(akonadiTag.name(), name); QCOMPARE(akonadiTag.isValid(), tagId > 0); if (tagId > 0) { QCOMPARE(akonadiTag.id(), tagId); QCOMPARE(akonadiTag.gid(), tagGid); QCOMPARE(akonadiTag.type(), QByteArray(Akonadi::Tag::PLAIN)); } } void shouldVerifyIfAnItemIsATagChild_data() { QTest::addColumn("tag"); QTest::addColumn("item"); QTest::addColumn("isChild"); // Create a Tag auto tag = Domain::Tag::Ptr::create(); tag->setProperty("tagId", qint64(43)); Akonadi::Tag akonadiTag(Akonadi::Tag::Id(43)); Akonadi::Item unrelatedItem; QTest::newRow("Unrelated item") << tag << unrelatedItem << false; Akonadi::Item relatedItem; relatedItem.setTag(akonadiTag); QTest::newRow("Related item") << tag << relatedItem << true; auto invalidTag = Domain::Tag::Ptr::create(); QTest::newRow("Invalid Tag") << invalidTag << relatedItem << false; Akonadi::Item invalidItem; QTest::newRow("Invalid Item") << tag << invalidItem << false; QTest::newRow("both invalid") << invalidTag << invalidItem << false; } void shouldVerifyIfAnItemIsATagChild() { // GIVEN QFETCH(Domain::Tag::Ptr, tag); QFETCH(Akonadi::Item, item); QFETCH(bool, isChild); // WHEN Akonadi::Serializer serializer; bool value = serializer.isTagChild(tag, item); // THEN QCOMPARE(value, isChild); } }; ZANSHIN_TEST_MAIN(AkonadiSerializerTest) #include "akonadiserializertest.moc" diff --git a/tests/units/akonadi/akonaditagqueriestest.cpp b/tests/units/akonadi/akonaditagqueriestest.cpp index f19716aa..5820e93a 100644 --- a/tests/units/akonadi/akonaditagqueriestest.cpp +++ b/tests/units/akonadi/akonaditagqueriestest.cpp @@ -1,302 +1,302 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonaditagqueries.h" #include "akonadi/akonadiserializer.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gennote.h" #include "testlib/gentag.h" #include "testlib/testhelpers.h" using namespace Testlib; class AkonadiTagQueriesTest : public QObject { Q_OBJECT private slots: void shouldLookInAllReportedForAllTag() { // GIVEN AkonadiFakeData data; // Two plain tags - data.createTag(GenTag().withId(42).withName("42").asPlain()); - data.createTag(GenTag().withId(43).withName("43").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asPlain()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asPlain()); // WHEN QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); result->data(); result = queries->findAll(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43")); } void shouldReactToTagAdded() { // GIVEN AkonadiFakeData data; QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createTag(GenTag().withId(42).withName("42").asPlain()); - data.createTag(GenTag().withId(43).withName("43").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asPlain()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asPlain()); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43")); } void shouldReactToTagRemoved() { // GIVEN AkonadiFakeData data; // Two plain tags - data.createTag(GenTag().withId(42).withName("42").asPlain()); - data.createTag(GenTag().withId(43).withName("43").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asPlain()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asPlain()); QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeTag(Akonadi::Tag(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->name(), QString("42")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); } void shouldReactToTagChanges() { // GIVEN AkonadiFakeData data; // Two plain tags - data.createTag(GenTag().withId(42).withName("42").asPlain()); - data.createTag(GenTag().withId(43).withName("43").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asPlain()); + data.createTag(GenTag().withId(43).withName(QStringLiteral("43")).asPlain()); QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyTag(GenTag(data.tag(43)).withName("43bis")); + data.modifyTag(GenTag(data.tag(43)).withName(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->name(), QString("42")); - QCOMPARE(result->data().at(1)->name(), QString("43bis")); + QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->name(), QStringLiteral("43bis")); } void shouldLookInAllCollectionsForTagTopLevelArtifacts() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withNoteContent()); // One plain tag - data.createTag(GenTag().withId(42).withName("42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("42")).asPlain()); // Two notes in the first collection - data.createItem(GenNote().withParent(42).withId(42).withTitle("42").withTags({42})); - data.createItem(GenNote().withParent(42).withId(43).withTitle("43")); + data.createItem(GenNote().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); + data.createItem(GenNote().withParent(42).withId(43).withTitle(QStringLiteral("43"))); // Two notes in the second collection - data.createItem(GenNote().withParent(43).withId(44).withTitle("44").withTags({42})); - data.createItem(GenNote().withParent(43).withId(45).withTitle("45")); + data.createItem(GenNote().withParent(43).withId(44).withTitle(QStringLiteral("44")).withTags({42})); + data.createItem(GenNote().withParent(43).withId(45).withTitle(QStringLiteral("45"))); // WHEN auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto tag = serializer->createTagFromAkonadiTag(data.tag(42)); auto result = queries->findNotes(tag); result->data(); result = queries->findNotes(tag); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); // Should not change nothing result = queries->findNotes(tag); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldReactToItemAddedForTag() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // One plain tag - data.createTag(GenTag().withId(42).withName("tag-42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asPlain()); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto tag = serializer->createTagFromAkonadiTag(data.tag(42)); auto result = queries->findNotes(tag); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createItem(GenNote().withParent(42).withId(42).withTitle("42").withTags({42})); + data.createItem(GenNote().withParent(42).withId(42).withTitle(QStringLiteral("42")).withTags({42})); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldReactToItemNewlyAssociatedToTag() { // GIVEN AkonadiFakeData data; // One plain tag - data.createTag(GenTag().withId(42).withName("tag-42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asPlain()); // One top level collection with a note data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto tag = serializer->createTagFromAkonadiTag(data.tag(42)); auto result = queries->findNotes(tag); bool insertHandlerCalled = false; result->addPostInsertHandler([&insertHandlerCalled](const Domain::Artifact::Ptr &, int) { insertHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN data.modifyItem(GenNote(data.item(42)).withTags({42})); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); QVERIFY(insertHandlerCalled); } void shouldReactWhenAnItemTaggedIsRemoved() { // GIVEN AkonadiFakeData data; // One plain tag - data.createTag(GenTag().withId(42).withName("tag-42").asPlain()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asPlain()); // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); // Two notes related to the tag - data.createItem(GenNote().withId(42).withParent(42).withTitle("42").withTags({42})); - data.createItem(GenNote().withId(43).withParent(42).withTitle("43").withTags({42})); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags({42})); + data.createItem(GenNote().withId(43).withParent(42).withTitle(QStringLiteral("43")).withTags({42})); auto serializer = Akonadi::SerializerInterface::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TagQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto tag = serializer->createTagFromAkonadiTag(data.tag(42)); auto result = queries->findNotes(tag); bool removeHandlerCalled = false; result->addPostRemoveHandler([&removeHandlerCalled](const Domain::Artifact::Ptr &, int) { removeHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); QVERIFY(removeHandlerCalled); } }; ZANSHIN_TEST_MAIN(AkonadiTagQueriesTest) #include "akonaditagqueriestest.moc" diff --git a/tests/units/akonadi/akonaditagrepositorytest.cpp b/tests/units/akonadi/akonaditagrepositorytest.cpp index 63c30d3c..244ed4eb 100644 --- a/tests/units/akonadi/akonaditagrepositorytest.cpp +++ b/tests/units/akonadi/akonaditagrepositorytest.cpp @@ -1,254 +1,254 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Franck Arrecot 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "testlib/akonadifakejobs.h" #include "testlib/akonadifakemonitor.h" #include "akonadi/akonaditagrepository.h" #include "akonadi/akonadiserializerinterface.h" #include "akonadi/akonadistorageinterface.h" using namespace mockitopp; using namespace mockitopp::matcher; Q_DECLARE_METATYPE(Testlib::AkonadiFakeItemFetchJob*) Q_DECLARE_METATYPE(Testlib::AkonadiFakeTagFetchJob*) class AkonadiTagRepositoryTest : public QObject { Q_OBJECT private slots: void shouldCreateTag() { // GIVEN // A Tag and its corresponding Akonadi Tag Akonadi::Tag akonadiTag; // not existing yet auto tag = Domain::Tag::Ptr::create(); // A mock creating job auto tagCreateJob = new FakeJob(this); // Storage mock returning the tagCreatejob Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::createTag).when(akonadiTag) .thenReturn(tagCreateJob); // Serializer mock Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).thenReturn(akonadiTag); // WHEN QScopedPointer repository(new Akonadi::TagRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->create(tag)->exec(); //THEN QVERIFY(storageMock(&Akonadi::StorageInterface::createTag).when(akonadiTag).exactly(1)); } void shouldRemoveTag() { // GIVEN Akonadi::Tag akonadiTag(42); auto tag = Domain::Tag::Ptr::create(); tag->setProperty("tagId", qint64(42)); // must be set - tag->setName("42"); + tag->setName(QStringLiteral("42")); // A mock of removal job auto tagRemoveJob = new FakeJob(this); // Storage mock returning the tagCreatejob Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::removeTag).when(akonadiTag) .thenReturn(tagRemoveJob); // Serializer mock Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).thenReturn(akonadiTag); // WHEN QScopedPointer repository(new Akonadi::TagRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->remove(tag)->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::removeTag).when(akonadiTag).exactly(1)); } void shouldAssociateNoteToTag() { // GIVEN auto tag = Domain::Tag::Ptr::create(); Akonadi::Tag akonadiTag(42); auto note = Domain::Note::Ptr::create(); Akonadi::Item noteItem(42); // A mock of update job auto itemModifyJob = new FakeJob(this); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << noteItem); // Storage mock returning the tagCreatejob Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::updateItem).when(noteItem, Q_NULLPTR) .thenReturn(itemModifyJob); storageMock(&Akonadi::StorageInterface::fetchItem).when(noteItem) .thenReturn(itemFetchJob); // Serializer mock Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).thenReturn(akonadiTag); serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(noteItem); // WHEN QScopedPointer repository(new Akonadi::TagRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->associate(tag, note)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(noteItem, Q_NULLPTR).exactly(1)); } void shouldDissociateNoteFromTag() { // GIVEN Akonadi::Item item(42); Domain::Note::Ptr note(new Domain::Note); Akonadi::Tag akonadiTag(qint64(42)); auto tag = Domain::Tag::Ptr::create(); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); auto itemFetchJobFilled = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJobFilled->setItems(Akonadi::Item::List() << item); // A mock update job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob) .thenReturn(itemFetchJobFilled); storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the note Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note) .thenReturn(item); serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag) .thenReturn(akonadiTag); // WHEN QScopedPointer repository(new Akonadi::TagRepository(storageMock.getInstance(), serializerMock.getInstance())); repository->dissociate(tag, note)->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).exactly(0)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(0)); // WHEN repository->dissociate(tag, note)->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(2)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createAkonadiTagFromTag).when(tag).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } void shouldDissociateNoteFromAllTags_data() { QTest::addColumn("item"); QTest::addColumn("note"); QTest::addColumn("itemFetchJob"); QTest::addColumn("execJob"); Akonadi::Item item(42); auto note = Domain::Note::Ptr::create(); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << item); QTest::newRow("nominal case") << item << note << itemFetchJob << true; itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); QTest::newRow("task job error, cannot find task") << item << note << itemFetchJob << false; } void shouldDissociateNoteFromAllTags() { QFETCH(Akonadi::Item,item); QFETCH(Domain::Note::Ptr, note); QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob); QFETCH(bool,execJob); // A mock update job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob); storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note) .thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::TagRepository(storageMock.getInstance(), serializerMock.getInstance())); auto dissociateJob = repository->dissociateAll(note); if (execJob) dissociateJob->exec(); // THEN QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); if (execJob) { QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } } }; ZANSHIN_TEST_MAIN(AkonadiTagRepositoryTest) #include "akonaditagrepositorytest.moc" diff --git a/tests/units/akonadi/akonaditaskqueriestest.cpp b/tests/units/akonadi/akonaditaskqueriestest.cpp index 834a2330..5a25101c 100644 --- a/tests/units/akonadi/akonaditaskqueriestest.cpp +++ b/tests/units/akonadi/akonaditaskqueriestest.cpp @@ -1,1541 +1,1541 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "akonadi/akonaditaskqueries.h" #include "akonadi/akonadiserializer.h" #include "testlib/akonadifakedata.h" #include "testlib/gencollection.h" #include "testlib/gennote.h" #include "testlib/gentag.h" #include "testlib/gentodo.h" #include "testlib/testhelpers.h" #include "utils/datetime.h" using namespace Testlib; class AkonadiTaskQueriesTest : public QObject { Q_OBJECT private slots: void shouldLookInAllReportedForAllTasks() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in the first collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // Two tasks in the second collection - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(43).withTitle("44")); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44"))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); result->data(); result = queries->findAll(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); - QCOMPARE(result->data().at(2)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); } void shouldIgnoreItemsWhichAreNotTasks() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Two items in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // One of them is not a task auto item = Akonadi::Item(43); item.setPayloadFromData("FooBar"); item.setParentCollection(Akonadi::Collection(42)); data.createItem(item); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldReactToItemAddsForTasksOnly() { // GIVEN AkonadiFakeData data; // One empty collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); auto item = Akonadi::Item(43); item.setPayloadFromData("FooBar"); item.setParentCollection(Akonadi::Collection(42)); data.createItem(item); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->title(), QString("42")); + QCOMPARE(result->data().first()->title(), QStringLiteral("42")); } void shouldReactToItemRemovesForAllTasks() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three task in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldReactToItemChangesForAllTasks() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three task in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findAll(); // Even though the pointer didn't change it's convenient to user if we call // the replace handlers bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 3); // WHEN - data.modifyItem(GenTodo(data.item(43)).withTitle("43bis")); + data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 3); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43bis")); - QCOMPARE(result->data().at(2)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43bis")); + QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); QVERIFY(replaceHandlerCalled); } void shouldLookInAllChildrenReportedForAllChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being children of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); // WHEN auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task); result->data(); result = queries->findChildren(task); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); // Should not change nothing result = queries->findChildren(task); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldNotCrashWhenWeAskAgainTheSameChildrenList() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One task in the collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); // The bug we're trying to hit here is the following: // - when findChildren is called the first time a provider is created internally // - result is deleted at the end of the loop, no one holds the provider with // a strong reference anymore so it is deleted as well // - when findChildren is called the second time, there's a risk of a dangling // pointer if the recycling of providers is wrongly implemented which can lead // to a crash, if it is properly done no crash will occur for (int i = 0; i < 2; i++) { // WHEN * 2 auto result = queries->findChildren(task); // THEN * 2 QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } } void shouldReactToItemAddsForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One task in the collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldReactToItemChangesForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being children of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyItem(GenTodo(data.item(43)).withTitle("43bis")); + data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43bis")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43bis")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); QVERIFY(replaceHandlerCalled); } void shouldRemoveItemFromCorrespondingResultWhenRelatedItemChangeForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being children of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyItem(GenTodo(data.item(43)).withParentUid("")); + data.modifyItem(GenTodo(data.item(43)).withParentUid(QLatin1String(""))); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); } void shouldAddItemToCorrespondingResultWhenRelatedItemChangeForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being top level) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); // WHEN - data.modifyItem(GenTodo(data.item(43)).withParentUid("uid-42")); + data.modifyItem(GenTodo(data.item(43)).withParentUid(QStringLiteral("uid-42"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("44")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); QVERIFY(!replaceHandlerCalled); } void shouldMoveItemToCorrespondingResultWhenRelatedItemChangeForChildTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being top level) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task1 = serializer->createTaskFromItem(data.item(42)); auto task2 = serializer->createTaskFromItem(data.item(43)); auto result1 = queries->findChildren(task1); auto result2 = queries->findChildren(task2); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result1->data().size(), 1); - QCOMPARE(result1->data().at(0)->title(), QString("44")); + QCOMPARE(result1->data().at(0)->title(), QStringLiteral("44")); QCOMPARE(result2->data().size(), 0); // WHEN - data.modifyItem(GenTodo(data.item(44)).withParentUid("uid-43")); + data.modifyItem(GenTodo(data.item(44)).withParentUid(QStringLiteral("uid-43"))); // THEN QCOMPARE(result1->data().size(), 0); QCOMPARE(result2->data().size(), 1); - QCOMPARE(result2->data().at(0)->title(), QString("44")); + QCOMPARE(result2->data().at(0)->title(), QStringLiteral("44")); } void shouldReactToItemRemovesForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being children of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto task = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); } void shouldLookInAllReportedForTopLevelTasks() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in the first collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // Two tasks in the second collection - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(43).withTitle("44").withParentUid("2")); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44")).withParentUid(QStringLiteral("2"))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); result->data(); result = queries->findTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); } void shouldReactToItemAddsForTopLevelTasks() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43").withParentUid("2")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).withParentUid(QStringLiteral("2"))); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->title(), QString("42")); + QCOMPARE(result->data().first()->title(), QStringLiteral("42")); } void shouldReactToItemRemovesForTopLevelTasks() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (one being child of the second one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldReactToItemChangesForTopLevelTasks() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (one being child of the second one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); // Even though the pointer didn't change it's convenient to user if we call // the replace handlers bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { replaceHandlerCalled = true; }); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyItem(GenTodo(data.item(43)).withTitle("43bis")); + data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43bis")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43bis")); QVERIFY(replaceHandlerCalled); } void shouldRemoveItemFromTopLevelResultWhenRelatedItemChangeForTopLevelTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (one being child of the second one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); // WHEN - data.modifyItem(GenTodo(data.item(43)).withParentUid("uid-42")); + data.modifyItem(GenTodo(data.item(43)).withParentUid(QStringLiteral("uid-42"))); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldAddItemToTopLevelResultWhenRelatedItemChangeForChildrenTask() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (one being child of the second one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); // WHEN data.modifyItem(GenTodo(data.item(43)).withParentUid(QString())); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); } void shouldRemoveParentNodeAndMoveChildrenInTopLevelResult() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (one being child of the second one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); auto resultChild = queries->findChildren(result->data().at(1)); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(resultChild->data().size(), 1); // WHEN data.removeItem(Akonadi::Item(43)); // THEN QCOMPARE(resultChild->data().size(), 0); QCOMPARE(result->data().size(), 1); // FIXME: Should become 2 once we got a proper cache in place } void shouldNotCrashDuringFindChildrenWhenJobIsKilled() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being children of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor()))); data.storageBehavior().setFetchItemErrorCode(42, KJob::KilledJobError); // WHEN auto task1 = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task1); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } void shouldNotCrashDuringFindChildrenWhenItemsJobReceiveResult_data() { QTest::addColumn("errorCode"); QTest::addColumn("fetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; QTest::newRow("Error with list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; } void shouldNotCrashDuringFindChildrenWhenItemsJobReceiveResult() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (two being children of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); QScopedPointer queries(new Akonadi::TaskQueries(storage, serializer, monitor)); QFETCH(int, errorCode); QFETCH(int, fetchBehavior); QFETCH(bool, deleteQuery); data.storageBehavior().setFetchItemsErrorCode(42, errorCode); data.storageBehavior().setFetchItemsBehavior(42, AkonadiFakeStorageBehavior::FetchBehavior(fetchBehavior)); // WHEN auto task1 = serializer->createTaskFromItem(data.item(42)); auto result = queries->findChildren(task1); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } void shouldNotCrashDuringFindAllWhenFetchJobFailedOrEmpty_data() { QTest::addColumn("colErrorCode"); QTest::addColumn("colFetchBehavior"); QTest::addColumn("itemsErrorCode"); QTest::addColumn("itemsFetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; QTest::newRow("No error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; } void shouldNotCrashDuringFindAllWhenFetchJobFailedOrEmpty() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))); auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); QScopedPointer queries(new Akonadi::TaskQueries(storage, serializer, monitor)); QFETCH(int, colErrorCode); QFETCH(int, colFetchBehavior); data.storageBehavior().setFetchCollectionsErrorCode(Akonadi::Collection::root().id(), colErrorCode); data.storageBehavior().setFetchCollectionsBehavior(Akonadi::Collection::root().id(), AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); QFETCH(int, itemsErrorCode); QFETCH(int, itemsFetchBehavior); data.storageBehavior().setFetchItemsErrorCode(42, itemsErrorCode); data.storageBehavior().setFetchItemsBehavior(42, AkonadiFakeStorageBehavior::FetchBehavior(itemsFetchBehavior)); QFETCH(bool, deleteQuery); // WHEN auto result = queries->findAll(); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } void shouldNotCrashDuringFindTopLevelWhenFetchJobFailedOrEmpty_data() { QTest::addColumn("colErrorCode"); QTest::addColumn("colFetchBehavior"); QTest::addColumn("itemsErrorCode"); QTest::addColumn("itemsFetchBehavior"); QTest::addColumn("deleteQuery"); QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; QTest::newRow("No error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; QTest::newRow("Error with item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << false; } void shouldNotCrashDuringFindTopLevelWhenFetchJobFailedOrEmpty() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (third one being child of the first one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-42"))); auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); QScopedPointer queries(new Akonadi::TaskQueries(storage, serializer, monitor)); QFETCH(int, colErrorCode); QFETCH(int, colFetchBehavior); data.storageBehavior().setFetchCollectionsErrorCode(Akonadi::Collection::root().id(), colErrorCode); data.storageBehavior().setFetchCollectionsBehavior(Akonadi::Collection::root().id(), AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); QFETCH(int, itemsErrorCode); QFETCH(int, itemsFetchBehavior); data.storageBehavior().setFetchItemsErrorCode(42, itemsErrorCode); data.storageBehavior().setFetchItemsBehavior(42, AkonadiFakeStorageBehavior::FetchBehavior(itemsFetchBehavior)); QFETCH(bool, deleteQuery); // WHEN auto result = queries->findTopLevel(); if (deleteQuery) delete queries.take(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); } void shouldIgnoreProjectsWhenReportingTopLevelTasks() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in the first collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); // Two tasks and one project in the second collection data.createItem(GenTodo().withId(43).withParent(43) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(44).withParent(43) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); data.createItem(GenTodo().withId(45).withParent(43) - .withTitle("45").withUid("uid-45") + .withTitle(QStringLiteral("45")).withUid(QStringLiteral("uid-45")) .asProject()); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findTopLevel(); result->data(); result = queries->findTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); } void shouldLookInAllSelectedCollectionsForInboxTopLevel() { // GIVEN AkonadiFakeData data; // Three top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(44).withRootAsParent().withTaskContent().enabled(false)); // One note in the first collection - data.createItem(GenNote().withId(42).withParent(42).withTitle("42")); + data.createItem(GenNote().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // Two tasks in the second collection - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); - data.createItem(GenTodo().withId(44).withParent(43).withTitle("44")); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); + data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44"))); // One task in the third collection - data.createItem(GenTodo().withId(45).withParent(44).withTitle("45")); + data.createItem(GenTodo().withId(45).withParent(44).withTitle(QStringLiteral("45"))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); result->data(); result = queries->findInboxTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("43")); - QCOMPARE(result->data().at(1)->title(), QString("44")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); } void shouldIgnoreItemsWhichAreNotTasksInInboxTopLevel() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Two items in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // One of them is not a task auto item = Akonadi::Item(43); item.setPayloadFromData("FooBar"); item.setParentCollection(Akonadi::Collection(42)); data.createItem(item); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldNotHaveTasksWithParentsInInboxTopLevel() { // TODO: Note that this specification is kind of an over simplification which // assumes that all the underlying data is correct. Ideally it should be checked // that the uid refered to actually points to a todo which exists in a proper // collection. We will need a cache to be able to implement that properly though. // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three items in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").withUid("uid-42")); - data.createItem(GenTodo().withId(43).withParent(42).withTitle("43").withUid("uid-43").withParentUid("uid-42")); - data.createItem(GenTodo().withId(44).withParent(42).withTitle("44").withUid("uid-44").withParentUid("foo")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); + data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")).withParentUid(QStringLiteral("uid-42"))); + data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")).withParentUid(QStringLiteral("foo"))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldNotHaveTasksWithContextsInInboxTopLevel_data() { QTest::addColumn("hasContexts"); QTest::addColumn("isExpectedInInbox"); QTest::newRow("task with no context") << false << true; QTest::newRow("task with contexts") << true << false; } void shouldNotHaveTasksWithContextsInInboxTopLevel() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("tag-42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asContext()); // One item in the collection QFETCH(bool, hasContexts); auto tagIds = QList(); if (hasContexts) tagIds << 42; - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").withTags(tagIds)); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds)); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QFETCH(bool, isExpectedInInbox); if (isExpectedInInbox) { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } else { QVERIFY(result->data().isEmpty()); } } void shouldReactToItemAddsForInboxTopLevel_data() { QTest::addColumn("reactionExpected"); QTest::addColumn("relatedUid"); QTest::addColumn("hasContexts"); QTest::newRow("task which should be in inbox") << true << QString() << false; QTest::newRow("task with related uid") << false << "foo" << false; QTest::newRow("task with context") << false << QString() << true; } void shouldReactToItemAddsForInboxTopLevel() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("tag-42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asContext()); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); TestHelpers::waitForEmptyJobQueue(); QVERIFY(result->data().isEmpty()); // WHEN QFETCH(QString, relatedUid); QFETCH(bool, hasContexts); auto tagIds = QList(); if (hasContexts) tagIds << 42; - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").withTags(tagIds).withParentUid(relatedUid)); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds).withParentUid(relatedUid)); // THEN QFETCH(bool, reactionExpected); if (reactionExpected) { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } else { QVERIFY(result->data().isEmpty()); } } void shouldReactToItemRemovesForInboxTopLevel() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One item in the collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().first()->title(), QString("42")); + QCOMPARE(result->data().first()->title(), QStringLiteral("42")); // WHEN data.removeItem(Akonadi::Item(42)); // THEN QVERIFY(result->data().isEmpty()); } void shouldReactToItemChangesForInboxTopLevel_data() { QTest::addColumn("inListAfterChange"); QTest::addColumn("relatedUidBefore"); QTest::addColumn("relatedUidAfter"); QTest::addColumn("hasContextsBefore"); QTest::addColumn("hasContextsAfter"); QTest::newRow("task appears in inbox (related uid)") << true << "foo" << QString() << false << false; QTest::newRow("task disappears from inbox (related uid)") << false << QString() << "foo" << false << false; QTest::newRow("task appears in inbox (context)") << true << QString() << QString() << true << false; QTest::newRow("task disappears from inbox (context)") << false << QString() << QString() << false << true; } void shouldReactToItemChangesForInboxTopLevel() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // One context tag - data.createTag(GenTag().withId(42).withName("tag-42").asContext()); + data.createTag(GenTag().withId(42).withName(QStringLiteral("tag-42")).asContext()); // Artifact data QFETCH(QString, relatedUidBefore); QFETCH(bool, hasContextsBefore); auto tagIds = QList(); if (hasContextsBefore) tagIds << 42; - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42").withTags(tagIds).withParentUid(relatedUidBefore)); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withTags(tagIds).withParentUid(relatedUidBefore)); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); TestHelpers::waitForEmptyJobQueue(); QFETCH(bool, inListAfterChange); if (inListAfterChange) { QVERIFY(result->data().isEmpty()); } else { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } // WHEN QFETCH(QString, relatedUidAfter); QFETCH(bool, hasContextsAfter); tagIds.clear(); if (hasContextsAfter) tagIds << 42; data.modifyItem(GenTodo(data.item(42)).withTags(tagIds).withParentUid(relatedUidAfter)); // THEN if (inListAfterChange) { QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } else { QVERIFY(result->data().isEmpty()); } } void shouldReactToCollectionSelectionChangesForInboxTopLevel() { // GIVEN AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in each collection - data.createItem(GenTodo().withId(42).withParent(42).withTitle("42")); - data.createItem(GenTodo().withId(43).withParent(43).withTitle("43")); + data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); + data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findInboxTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); // WHEN data.modifyCollection(GenCollection(data.collection(43)).selected(false)); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); } void shouldLookInAllWorkdayReportedForAllTasks_data() { QTest::addColumn("isExpectedInWorkday"); QTest::addColumn("item2"); const auto today = Utils::DateTime::currentDateTime(); QTest::newRow("todayTask") << true << Akonadi::Item(GenTodo() .withStartDate(today) .withDueDate(today)); QTest::newRow("pastTask") << true << Akonadi::Item(GenTodo() .withStartDate(today.addDays(-42)) .withDueDate(today.addDays(-41))); QTest::newRow("startTodayTask") << true << Akonadi::Item(GenTodo() .withStartDate(today)); QTest::newRow("endTodayTask") << true << Akonadi::Item(GenTodo() .withStartDate(today)); QTest::newRow("futureTask") << false << Akonadi::Item(GenTodo() .withStartDate(today.addDays(41)) .withDueDate(today.addDays(42))); QTest::newRow("pastDoneTask") << false << Akonadi::Item(GenTodo() .withStartDate(today.addDays(-42)) .withDueDate(today.addDays(-41)) .done() .withDoneDate(today.addDays(-30))); QTest::newRow("todayDoneTask") << true << Akonadi::Item(GenTodo() .withStartDate(today) .withDueDate(today) .done() .withDoneDate(QDateTime(today.date(), QTime(12, 00)))); QTest::newRow("startTodayDoneTask") << true << Akonadi::Item(GenTodo() .withStartDate(today) .done() .withDoneDate(QDateTime(today.date(), QTime(12, 00)))); QTest::newRow("endTodayDoneTask") << true << Akonadi::Item(GenTodo() .withDueDate(today) .done() .withDoneDate(QDateTime(today.date(), QTime(12, 00)))); } void shouldLookInAllWorkdayReportedForAllTasks() { // GIVEN const auto today = Utils::DateTime::currentDateTime(); AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in the first collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42") + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) .withStartDate(today.addSecs(300))); // One task in the second collection (from data driven set) QFETCH(Akonadi::Item, item2); data.createItem(GenTodo(item2).withId(43).withParent(43) - .withTitle("43").withUid("uid-43")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findWorkdayTopLevel(); result->data(); result = queries->findWorkdayTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QFETCH(bool, isExpectedInWorkday); const int sizeExpected = (isExpectedInWorkday) ? 2 : 1; QCOMPARE(result->data().size(), sizeExpected); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); if (isExpectedInWorkday) - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); } void shouldLookInAllWorkdayReportedForAllTasksWhenOverrideDate() { // GIVEN qputenv("ZANSHIN_OVERRIDE_DATETIME", "2015-03-10"); const auto today = Utils::DateTime::currentDateTime(); AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in the first collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42") + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) .withStartDate(today)); // One task in the second collection data.createItem(GenTodo().withId(43).withParent(43) - .withTitle("43").withUid("uid-43") + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) .withStartDate(today.addSecs(3600))); // WHEN QScopedPointer queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor()))); auto result = queries->findWorkdayTopLevel(); result->data(); result = queries->findWorkdayTopLevel(); // Should not cause any problem or wrong data // THEN QVERIFY(result->data().isEmpty()); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); } void shouldPollForCurrentDayToListWorkday() { // GIVEN qputenv("ZANSHIN_OVERRIDE_DATETIME", "2015-03-10T23:59:59UTC"); const auto today = Utils::DateTime::currentDateTime(); AkonadiFakeData data; // Two top level collections data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); // One task in the first collection data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42") + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) .withStartDate(today)); // One task in the second collection data.createItem(GenTodo().withId(43).withParent(43) - .withTitle("43").withUid("uid-43") + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) .withStartDate(today.addDays(1))); QScopedPointer queries; { auto akqueries = new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), Akonadi::Serializer::Ptr(new Akonadi::Serializer), Akonadi::MonitorInterface::Ptr(data.createMonitor())); QCOMPARE(akqueries->workdayPollInterval(), 30000); akqueries->setWorkdayPollInterval(500); queries.reset(akqueries); } auto result = queries->findWorkdayTopLevel(); TestHelpers::waitForEmptyJobQueue(); QCOMPARE(result->data().size(), 1); - QCOMPARE(result->data().at(0)->title(), QString("42")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); // WHEN qputenv("ZANSHIN_OVERRIDE_DATETIME", "2015-03-11T00:01:00UTC"); QTest::qWait(1000); TestHelpers::waitForEmptyJobQueue(); // THEN QCOMPARE(result->data().size(), 2); - QCOMPARE(result->data().at(0)->title(), QString("42")); - QCOMPARE(result->data().at(1)->title(), QString("43")); + QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); + QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); } }; ZANSHIN_TEST_MAIN(AkonadiTaskQueriesTest) #include "akonaditaskqueriestest.moc" diff --git a/tests/units/akonadi/akonaditaskrepositorytest.cpp b/tests/units/akonadi/akonaditaskrepositorytest.cpp index 19e53559..d9c11e8f 100644 --- a/tests/units/akonadi/akonaditaskrepositorytest.cpp +++ b/tests/units/akonadi/akonaditaskrepositorytest.cpp @@ -1,834 +1,834 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "utils/mockobject.h" #include "testlib/akonadifakedata.h" #include "testlib/akonadifakejobs.h" #include "testlib/akonadifakemonitor.h" #include "testlib/akonadifakestorage.h" #include "testlib/gencollection.h" #include "testlib/gentodo.h" #include "akonadi/akonadimessaginginterface.h" #include "akonadi/akonaditaskrepository.h" #include "akonadi/akonadiserializer.h" #include "akonadi/akonadistorageinterface.h" using namespace mockitopp; using namespace mockitopp::matcher; using namespace Testlib; Q_DECLARE_METATYPE(Testlib::AkonadiFakeItemFetchJob*) class AkonadiTaskRepositoryTest : public QObject { Q_OBJECT public: explicit AkonadiTaskRepositoryTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } private slots: void shouldCreateNewItems() { // GIVEN // A default collection for saving Akonadi::Collection col(42); // A task and its corresponding item not existing in storage yet Akonadi::Item item; Domain::Task::Ptr task(new Domain::Task); // A mock create job auto itemCreateJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().thenReturn(col); storageMock(&Akonadi::StorageInterface::createItem).when(item, col) .thenReturn(itemCreateJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->create(task)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(item, col).exactly(1)); } void shouldCreateNewItemsInFirstWritableCollectionIsNothingInSettings() { // GIVEN // A few collections auto col1 = Akonadi::Collection(42); col1.setRights(Akonadi::Collection::ReadOnly); auto col2 = Akonadi::Collection(43); col2.setRights(Akonadi::Collection::CanCreateItem); auto col3 = Akonadi::Collection(44); col3.setRights(Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanChangeItem | Akonadi::Collection::CanDeleteItem); auto collectionFetchJob = new Testlib::AkonadiFakeCollectionFetchJob; collectionFetchJob->setCollections(Akonadi::Collection::List() << col1 << col2 << col3); // A task and its corresponding item not existing in storage yet Akonadi::Item item; Domain::Task::Ptr task(new Domain::Task); // A mock create job auto itemCreateJob = new FakeJob(this); // Storage mock returning the create job and with no default collection Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().thenReturn(Akonadi::Collection()); storageMock(&Akonadi::StorageInterface::fetchCollections).when(Akonadi::Collection::root(), Akonadi::StorageInterface::Recursive, Akonadi::StorageInterface::Tasks) .thenReturn(collectionFetchJob); storageMock(&Akonadi::StorageInterface::createItem).when(item, col3) .thenReturn(itemCreateJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->create(task)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(item, col3).exactly(1)); } void shouldEmitErrorIfNoFallbackCollectionIsFound() { // GIVEN // A few collections auto col1 = Akonadi::Collection(42); col1.setRights(Akonadi::Collection::ReadOnly); auto col2 = Akonadi::Collection(43); col2.setRights(Akonadi::Collection::ReadOnly); auto col3 = Akonadi::Collection(44); col3.setRights(Akonadi::Collection::ReadOnly); auto collectionFetchJob = new Testlib::AkonadiFakeCollectionFetchJob; collectionFetchJob->setCollections(Akonadi::Collection::List() << col1 << col2 << col3); // A task and its corresponding item not existing in storage yet Akonadi::Item item; Domain::Task::Ptr task(new Domain::Task); // Storage mock returning the create job and with no default collection Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().thenReturn(Akonadi::Collection()); storageMock(&Akonadi::StorageInterface::fetchCollections).when(Akonadi::Collection::root(), Akonadi::StorageInterface::Recursive, Akonadi::StorageInterface::Tasks) .thenReturn(collectionFetchJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); auto job = repository->create(task); job->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().exactly(1)); QVERIFY(job->error()); QVERIFY(!job->errorText().isEmpty()); } void shouldCreateNewChildrenInParentCollection() { // GIVEN // A parent item with a collection Akonadi::Collection col(42); Akonadi::Item parentItem(43); parentItem.setParentCollection(col); auto parent = Domain::Task::Ptr::create(); // A task and its corresponding item not existing in storage yet Akonadi::Item childItem; auto child = Domain::Task::Ptr::create(); // A mock create job auto itemCreateJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::createItem).when(childItem, col) .thenReturn(itemCreateJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(parent).thenReturn(parentItem); serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).thenReturn(childItem); serializerMock(&Akonadi::SerializerInterface::updateItemParent).when(childItem, parent).thenReturn(); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->createChild(child, parent)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(parent).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::updateItemParent).when(childItem, parent).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(childItem, col).exactly(1)); } void shouldCreateNewItemsInProjectCollection() { // GIVEN // A project item with a collection Akonadi::Collection col(42); Akonadi::Item projectItem(43); projectItem.setParentCollection(col); auto project = Domain::Project::Ptr::create(); // A task and its corresponding item not existing in storage yet Akonadi::Item taskItem; auto task = Domain::Task::Ptr::create(); // A mock create job auto itemCreateJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::createItem).when(taskItem, col) .thenReturn(itemCreateJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromProject).when(project).thenReturn(projectItem); serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(taskItem); serializerMock(&Akonadi::SerializerInterface::updateItemProject).when(taskItem, project).thenReturn(); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->createInProject(task, project)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromProject).when(project).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::updateItemProject).when(taskItem, project).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(taskItem, col).exactly(1)); } void shouldCreateNewItemsInContext() { // GIVEN // a tag Akonadi::Tag tag; - tag.setName("tag42"); + tag.setName(QStringLiteral("tag42")); tag.setId(42); // the context related to the tag auto context = Domain::Context::Ptr::create(); // a default collection Akonadi::Collection defaultCollection(42); // A task and its corresponding item not existing in storage yet Akonadi::Item taskItem; auto task = Domain::Task::Ptr::create(); // A mock create job auto itemCreateJob = new FakeJob(this); // serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).thenReturn(tag); serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(taskItem); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().thenReturn(defaultCollection); storageMock(&Akonadi::StorageInterface::createItem).when(taskItem, defaultCollection).thenReturn(itemCreateJob); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->createInContext(task, context)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createTagFromContext).when(context).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(taskItem, defaultCollection).exactly(1)); } void shouldUpdateExistingItems() { // GIVEN // A default collection for saving Akonadi::Collection col(42); // A task and its corresponding item already existing in storage Akonadi::Item item(42); Domain::Task::Ptr task(new Domain::Task); // A mock create job auto itemModifyJob = new FakeJob(this); // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->update(task)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } void shouldRemoveATask_data() { QTest::addColumn("item"); QTest::addColumn("itemFetchJob1"); QTest::addColumn("itemFetchJob2"); QTest::addColumn("list"); QTest::addColumn("itemFetchJobSucceeded"); QTest::addColumn("collectionItemsFetchJobSucceeded"); Akonadi::Collection col(40); Akonadi::Item item(42); item.setParentCollection(col); Akonadi::Item item2(43); auto itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << item); auto itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); Akonadi::Item::List list; QTest::newRow("nominal case") << item << itemFetchJob1 << itemFetchJob2 << list << true << true; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setExpectedError(KJob::KilledJobError); QTest::newRow("item job error with empty list") << item << itemFetchJob1 << itemFetchJob2 << list << false << false; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setExpectedError(KJob::KilledJobError); itemFetchJob1->setItems(Akonadi::Item::List() << item); QTest::newRow("item job error with item") << item << itemFetchJob1 << itemFetchJob2 << list << false << false; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << item); itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob2->setExpectedError(KJob::KilledJobError); QTest::newRow("items job error with empty list") << item << itemFetchJob1 << itemFetchJob2 << list << true << false; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << item); itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); list << item2; itemFetchJob2->setItems(list); QTest::newRow("remove item and his child") << item << itemFetchJob1 << itemFetchJob2 << list << true << true; } void shouldRemoveATask() { // GIVEN QFETCH(Akonadi::Item, item); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob1); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob2); QFETCH(Akonadi::Item::List, list); QFETCH(bool, itemFetchJobSucceeded); QFETCH(bool, collectionItemsFetchJobSucceeded); Domain::Task::Ptr task(new Domain::Task); Akonadi::Item::List removedList; removedList << list << item; // A mock delete job auto itemDeleteJob = new FakeJob(this); // Storage mock returning the delete job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob1); storageMock(&Akonadi::StorageInterface::fetchItems).when(item.parentCollection()) .thenReturn(itemFetchJob2); storageMock(&Akonadi::StorageInterface::removeItems).when(removedList, Q_NULLPTR) .thenReturn(itemDeleteJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); serializerMock(&Akonadi::SerializerInterface::filterDescendantItems).when(list, item).thenReturn(list); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->remove(task)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); if (itemFetchJobSucceeded) { QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItems).when(item.parentCollection()).exactly(1)); if (collectionItemsFetchJobSucceeded) { QVERIFY(storageMock(&Akonadi::StorageInterface::removeItems).when(removedList, Q_NULLPTR).exactly(1)); } } } void shouldPromoteTaskToProject() { // GIVEN // A default collection for saving Akonadi::Collection col(42); // A task and its corresponding item already existing in storage Akonadi::Item item(42); Domain::Task::Ptr task(new Domain::Task); // A mock fetch job auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << item); // A mock modify job auto itemModifyJob = new FakeJob(this); // Serializer mock returning the item for the task and transforming it into a project Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); serializerMock(&Akonadi::SerializerInterface::promoteItemToProject).when(item).thenReturn(); // Storage mock returning the modify job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(item) .thenReturn(itemFetchJob); storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR) .thenReturn(itemModifyJob); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->promoteToProject(task)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::promoteItemToProject).when(item).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, Q_NULLPTR).exactly(1)); } void shouldAssociateATaskToAnother_data() { QTest::addColumn("childItem"); QTest::addColumn("parentItem"); QTest::addColumn("child"); QTest::addColumn("parent"); QTest::addColumn("itemFetchJob1"); QTest::addColumn("itemFetchJob2"); QTest::addColumn("itemFetchJob3"); QTest::addColumn("execJob"); QTest::addColumn("execParentJob"); QTest::addColumn("list"); Akonadi::Collection col(40); Akonadi::Item childItem(42); childItem.setParentCollection(col); Domain::Task::Ptr child(new Domain::Task); Akonadi::Item parentItem(41); parentItem.setParentCollection(col); Domain::Task::Ptr parent(new Domain::Task); auto itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << childItem); auto itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob2->setItems(Akonadi::Item::List() << childItem << parentItem); auto itemFetchJob3 = new Testlib::AkonadiFakeItemFetchJob(this); Akonadi::Item::List list; QTest::newRow("nominal case") << childItem << parentItem << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << true << true << list; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setExpectedError(KJob::KilledJobError); QTest::newRow("child job error with empty list") << childItem << parentItem << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << false << false << list; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setExpectedError(KJob::KilledJobError); itemFetchJob1->setItems(Akonadi::Item::List() << childItem); QTest::newRow("child job error with item") << childItem << parentItem << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << false << false << list; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << childItem); itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob2->setExpectedError(KJob::KilledJobError); QTest::newRow("parent job error with empty list") << childItem << parentItem << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << true << false << list; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << childItem); itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob2->setExpectedError(KJob::KilledJobError); itemFetchJob2->setItems(Akonadi::Item::List() << childItem << parentItem); QTest::newRow("parent job error with item") << childItem << parentItem << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << true << false << list; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << childItem); itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); Akonadi::Collection col2(39); Akonadi::Item parentItem2(41); parentItem2.setParentCollection(col2); itemFetchJob2->setItems(Akonadi::Item::List() << parentItem2); itemFetchJob3 = new Testlib::AkonadiFakeItemFetchJob(this); QTest::newRow("update and move item") << childItem << parentItem2 << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << true << true << list; itemFetchJob1 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob1->setItems(Akonadi::Item::List() << childItem); itemFetchJob2 = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob2->setItems(Akonadi::Item::List() << parentItem2); itemFetchJob3 = new Testlib::AkonadiFakeItemFetchJob(this); Akonadi::Item childItem2(43); Akonadi::Item::List list2; list2 << childItem2; itemFetchJob3->setItems(list2); QTest::newRow("update and move item and his child") << childItem << parentItem2 << child << parent << itemFetchJob1 << itemFetchJob2 << itemFetchJob3 << true << true << list2; } void shouldAssociateATaskToAnother() { // GIVEN QFETCH(Akonadi::Item, childItem); QFETCH(Akonadi::Item, parentItem); QFETCH(Domain::Task::Ptr, child); QFETCH(Domain::Task::Ptr, parent); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob1); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob2); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob3); QFETCH(bool, execJob); QFETCH(bool, execParentJob); QFETCH(Akonadi::Item::List, list); // A mock create job auto itemModifyJob = new FakeJob(this); auto transactionJob = new FakeJob(this); auto itemsMoveJob = new FakeJob(this); Akonadi::Item::List movedList; movedList << childItem << list; // Storage mock returning the create job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::fetchItem).when(childItem) .thenReturn(itemFetchJob1); storageMock(&Akonadi::StorageInterface::fetchItems).when(parentItem.parentCollection()) .thenReturn(itemFetchJob2); if (parentItem.parentCollection().id() != childItem.parentCollection().id()) { storageMock(&Akonadi::StorageInterface::fetchItems).when(childItem.parentCollection()) .thenReturn(itemFetchJob3); storageMock(&Akonadi::StorageInterface::createTransaction).when().thenReturn(transactionJob); storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, transactionJob) .thenReturn(itemModifyJob); storageMock(&Akonadi::StorageInterface::moveItems).when(movedList, parentItem.parentCollection(), transactionJob) .thenReturn(itemsMoveJob); } else { storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, Q_NULLPTR) .thenReturn(itemModifyJob); } // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).thenReturn(childItem); serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(parent).thenReturn(parentItem); serializerMock(&Akonadi::SerializerInterface::createTaskFromItem).when(childItem).thenReturn(child); serializerMock(&Akonadi::SerializerInterface::createTaskFromItem).when(parentItem).thenReturn(parent); serializerMock(&Akonadi::SerializerInterface::updateItemParent).when(childItem, parent).thenReturn(); - serializerMock(&Akonadi::SerializerInterface::objectUid).when(parent).thenReturn(QString("parent")); - serializerMock(&Akonadi::SerializerInterface::objectUid).when(child).thenReturn(QString("child")); + serializerMock(&Akonadi::SerializerInterface::objectUid).when(parent).thenReturn(QStringLiteral("parent")); + serializerMock(&Akonadi::SerializerInterface::objectUid).when(child).thenReturn(QStringLiteral("child")); serializerMock(&Akonadi::SerializerInterface::relatedUidFromItem).when(parentItem).thenReturn(QString()); serializerMock(&Akonadi::SerializerInterface::relatedUidFromItem).when(childItem).thenReturn(QString()); if (execParentJob) serializerMock(&Akonadi::SerializerInterface::filterDescendantItems).when(list, childItem).thenReturn(list); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); auto associateJob = repository->associate(parent, child); if (execJob) associateJob->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(childItem).exactly(1)); if (execJob) { QVERIFY(serializerMock(&Akonadi::SerializerInterface::updateItemParent).when(childItem, parent).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(parent).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItems).when(parentItem.parentCollection()).exactly(1)); if (execParentJob) { if (parentItem.parentCollection().id() == childItem.parentCollection().id()) QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, Q_NULLPTR).exactly(1)); else { //QVERIFY(serializerMock(&Akonadi::SerializerInterface::filterDescendantItems).when(list, childItem).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItems).when(childItem.parentCollection()).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::createTransaction).when().thenReturn(transactionJob).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, transactionJob).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::moveItems).when(movedList, parentItem.parentCollection(), transactionJob).exactly(1)); } } } } void shouldPreventCyclesDuringAssociation() { // GIVEN AkonadiFakeData data; // One top level collection data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); // Three tasks in the collection (one being child of the second one) data.createItem(GenTodo().withId(42).withParent(42) - .withTitle("42").withUid("uid-42")); + .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(43).withParent(42) - .withTitle("43").withUid("uid-43") - .withParentUid("uid-42")); + .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) + .withParentUid(QStringLiteral("uid-42"))); data.createItem(GenTodo().withId(44).withParent(42) - .withTitle("44").withUid("uid-44") - .withParentUid("uid-43")); + .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) + .withParentUid(QStringLiteral("uid-43"))); auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); auto task42 = serializer->createTaskFromItem(data.item(42)); auto task44 = serializer->createTaskFromItem(data.item(44)); auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); QScopedPointer repository(new Akonadi::TaskRepository(Akonadi::StorageInterface::Ptr(data.createStorage()), serializer, Akonadi::MessagingInterface::Ptr())); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); // WHEN auto job = repository->associate(task44, task42); QVERIFY(!job->exec()); // THEN QVERIFY(spy.isEmpty()); QVERIFY(job->error() != KJob::NoError); QVERIFY(!job->errorText().isEmpty()); } void shouldDissociateATaskFromItsParent_data() { QTest::addColumn("child"); QTest::addColumn("childItem"); QTest::addColumn("itemFetchJob"); QTest::addColumn("childJobFailed"); Domain::Task::Ptr child(new Domain::Task); Akonadi::Item childItem(42); auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setItems(Akonadi::Item::List() << childItem); QTest::newRow("nominal case") << child << childItem << itemFetchJob << false; itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); QTest::newRow("child job error with empty list") << child << childItem << itemFetchJob << true; itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this); itemFetchJob->setExpectedError(KJob::KilledJobError); itemFetchJob->setItems(Akonadi::Item::List() << childItem); QTest::newRow("child job error with item") << child << childItem << itemFetchJob << true; } void shouldDissociateATaskFromItsParent() { // GIVEN QFETCH(Domain::Task::Ptr, child); QFETCH(Akonadi::Item, childItem); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob); QFETCH(bool, childJobFailed); auto itemModifyJob = new FakeJob(this); // Storage mock returning the delete job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, Q_NULLPTR) .thenReturn(itemModifyJob); storageMock(&Akonadi::StorageInterface::fetchItem).when(childItem) .thenReturn(itemFetchJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).thenReturn(childItem); serializerMock(&Akonadi::SerializerInterface::removeItemParent).when(childItem).thenReturn(); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->dissociate(child)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(childItem).exactly(1)); if (!childJobFailed) { QVERIFY(serializerMock(&Akonadi::SerializerInterface::removeItemParent).when(childItem).exactly(1));; QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, Q_NULLPTR).exactly(1)); } } void shouldDissociateAllLinksOfTask_data() { shouldDissociateATaskFromItsParent_data(); } void shouldDissociateAllLinksOfTask() { // GIVEN QFETCH(Domain::Task::Ptr, child); QFETCH(Akonadi::Item, childItem); QFETCH(Testlib::AkonadiFakeItemFetchJob*, itemFetchJob); QFETCH(bool, childJobFailed); auto itemModifyJob = new FakeJob(this); // Storage mock returning the delete job Utils::MockObject storageMock; storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, Q_NULLPTR) .thenReturn(itemModifyJob); storageMock(&Akonadi::StorageInterface::fetchItem).when(childItem) .thenReturn(itemFetchJob); // Serializer mock returning the item for the task Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).thenReturn(childItem); serializerMock(&Akonadi::SerializerInterface::removeItemParent).when(childItem).thenReturn(); serializerMock(&Akonadi::SerializerInterface::clearItem).when(any()).thenReturn(); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), serializerMock.getInstance(), Akonadi::MessagingInterface::Ptr())); repository->dissociateAll(child)->exec(); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(child).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(childItem).exactly(1)); if (!childJobFailed) { QVERIFY(serializerMock(&Akonadi::SerializerInterface::removeItemParent).when(childItem).exactly(1)); QVERIFY(serializerMock(&Akonadi::SerializerInterface::clearItem).when(any()).exactly(1)); QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(childItem, Q_NULLPTR).exactly(1)); } } void shouldSendDelegationMessage() { // GIVEN - auto oldDelegate = Domain::Task::Delegate("John Smith", "john@smith.com"); - auto newDelegate = Domain::Task::Delegate("John Doe", "john@doe.com"); + auto oldDelegate = Domain::Task::Delegate(QStringLiteral("John Smith"), QStringLiteral("john@smith.com")); + auto newDelegate = Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com")); auto task = Domain::Task::Ptr::create(); task->setDelegate(oldDelegate); QSignalSpy spy(task.data(), &Domain::Task::delegateChanged); auto item = Akonadi::Item(42); Utils::MockObject serializerMock; serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); Utils::MockObject messagingMock; messagingMock(&Akonadi::MessagingInterface::sendDelegationMessage).when(item).thenReturn(); // WHEN QScopedPointer repository(new Akonadi::TaskRepository(Akonadi::StorageInterface::Ptr(), serializerMock.getInstance(), messagingMock.getInstance())); repository->delegate(task, newDelegate); // THEN QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); QVERIFY(messagingMock(&Akonadi::MessagingInterface::sendDelegationMessage).when(item).exactly(1)); QCOMPARE(task->delegate(), oldDelegate); QVERIFY(spy.isEmpty()); } }; ZANSHIN_TEST_MAIN(AkonadiTaskRepositoryTest) #include "akonaditaskrepositorytest.moc" diff --git a/tests/units/domain/artifacttest.cpp b/tests/units/domain/artifacttest.cpp index 7dbd3c3c..4fa3a0b1 100644 --- a/tests/units/domain/artifacttest.cpp +++ b/tests/units/domain/artifacttest.cpp @@ -1,80 +1,80 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/artifact.h" using namespace Domain; class ArtifactTest : public QObject { Q_OBJECT private slots: void shouldHaveEmptyPropertiesByDefault() { Artifact a; QCOMPARE(a.text(), QString()); QCOMPARE(a.title(), QString()); } void shouldNotifyTextChanges() { Artifact a; QSignalSpy spy(&a, &Artifact::textChanged); - a.setText("foo"); + a.setText(QStringLiteral("foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("foo")); } void shouldNotNotifyIdenticalTextChanges() { Artifact a; - a.setText("foo"); + a.setText(QStringLiteral("foo")); QSignalSpy spy(&a, &Artifact::textChanged); - a.setText("foo"); + a.setText(QStringLiteral("foo")); QCOMPARE(spy.count(), 0); } void shouldNotifyTitleChanges() { Artifact a; QSignalSpy spy(&a, &Artifact::titleChanged); - a.setTitle("foo"); + a.setTitle(QStringLiteral("foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("foo")); } void shouldNotNotifyIdenticalTitleChanges() { Artifact a; - a.setTitle("foo"); + a.setTitle(QStringLiteral("foo")); QSignalSpy spy(&a, &Artifact::titleChanged); - a.setTitle("foo"); + a.setTitle(QStringLiteral("foo")); QCOMPARE(spy.count(), 0); } }; ZANSHIN_TEST_MAIN(ArtifactTest) #include "artifacttest.moc" diff --git a/tests/units/domain/contexttest.cpp b/tests/units/domain/contexttest.cpp index c3c90ee8..078486df 100644 --- a/tests/units/domain/contexttest.cpp +++ b/tests/units/domain/contexttest.cpp @@ -1,61 +1,61 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/context.h" using namespace Domain; class ContextTest : public QObject { Q_OBJECT private slots: void shouldHaveEmptyPropertiesByDefault() { Context c; QCOMPARE(c.name(), QString()); } void shouldNotifyNameChanges() { Context c; QSignalSpy spy(&c, &Context::nameChanged); - c.setName("foo"); + c.setName(QStringLiteral("foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("foo")); } void shouldNotNotifyIdenticalNameChanges() { Context c; - c.setName("foo"); + c.setName(QStringLiteral("foo")); QSignalSpy spy(&c, &Context::nameChanged); - c.setName("foo"); + c.setName(QStringLiteral("foo")); QCOMPARE(spy.count(), 0); } }; ZANSHIN_TEST_MAIN(ContextTest) #include "contexttest.moc" diff --git a/tests/units/domain/datasourcetest.cpp b/tests/units/domain/datasourcetest.cpp index 082bf502..a635fe7a 100644 --- a/tests/units/domain/datasourcetest.cpp +++ b/tests/units/domain/datasourcetest.cpp @@ -1,146 +1,146 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/datasource.h" using namespace Domain; class DataSourceTest : public QObject { Q_OBJECT public: explicit DataSourceTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); qRegisterMetaType(); } private slots: void shouldHaveEmptyPropertiesByDefault() { DataSource ds; QCOMPARE(ds.name(), QString()); QCOMPARE(ds.iconName(), QString()); QCOMPARE(ds.contentTypes(), DataSource::NoContent); QCOMPARE(ds.listStatus(), DataSource::Unlisted); QVERIFY(!ds.isSelected()); } void shouldNotifyNameChanges() { DataSource ds; QSignalSpy spy(&ds, &DataSource::nameChanged); - ds.setName("Foo"); + ds.setName(QStringLiteral("Foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("Foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("Foo")); } void shouldNotNotifyIdenticalNameChanges() { DataSource ds; - ds.setName("Foo"); + ds.setName(QStringLiteral("Foo")); QSignalSpy spy(&ds, &DataSource::nameChanged); - ds.setName("Foo"); + ds.setName(QStringLiteral("Foo")); QCOMPARE(spy.count(), 0); } void shouldNotifyIconNameChanges() { DataSource ds; QSignalSpy spy(&ds, &DataSource::iconNameChanged); - ds.setIconName("Foo"); + ds.setIconName(QStringLiteral("Foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("Foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("Foo")); } void shouldNotNotifyIdenticalIconNameChanges() { DataSource ds; - ds.setIconName("Foo"); + ds.setIconName(QStringLiteral("Foo")); QSignalSpy spy(&ds, &DataSource::iconNameChanged); - ds.setIconName("Foo"); + ds.setIconName(QStringLiteral("Foo")); QCOMPARE(spy.count(), 0); } void shouldNotifyContentTypesChanges() { DataSource ds; QSignalSpy spy(&ds, &DataSource::contentTypesChanged); ds.setContentTypes(Domain::DataSource::Notes); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().value(), Domain::DataSource::Notes); } void shouldNotNotifyIdenticalContentTypesChanges() { DataSource ds; ds.setContentTypes(Domain::DataSource::Notes); QSignalSpy spy(&ds, &DataSource::contentTypesChanged); ds.setContentTypes(Domain::DataSource::Notes); QCOMPARE(spy.count(), 0); } void shouldNotifySelectedChanges() { DataSource ds; QSignalSpy spy(&ds, &DataSource::selectedChanged); ds.setSelected(true); QCOMPARE(spy.count(), 1); QVERIFY(spy.first().first().toBool()); } void shouldNotNotifyIdenticalSelectedChanges() { DataSource ds; ds.setSelected(true); QSignalSpy spy(&ds, &DataSource::selectedChanged); ds.setSelected(true); QCOMPARE(spy.count(), 0); } void shouldNotifyListStatusChanges() { DataSource ds; QSignalSpy spy(&ds, &DataSource::listStatusChanged); ds.setListStatus(DataSource::Bookmarked); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().value(), DataSource::Bookmarked); } void shouldNotNotifyIdenticalListStatusChanges() { DataSource ds; ds.setListStatus(DataSource::Bookmarked); QSignalSpy spy(&ds, &DataSource::listStatusChanged); ds.setListStatus(DataSource::Bookmarked); QCOMPARE(spy.count(), 0); } }; ZANSHIN_TEST_MAIN(DataSourceTest) #include "datasourcetest.moc" diff --git a/tests/units/domain/livequerytest.cpp b/tests/units/domain/livequerytest.cpp index 006c6782..99185bea 100644 --- a/tests/units/domain/livequerytest.cpp +++ b/tests/units/domain/livequerytest.cpp @@ -1,532 +1,532 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/livequery.h" #include "utils/jobhandler.h" #include "testlib/fakejob.h" using namespace Domain; typedef QSharedPointer QObjectPtr; class LiveQueryTest : public QObject { Q_OBJECT private: QObject *createObject(int id, const QString &name) { QObject *obj = new QObject(this); obj->setObjectName(name); obj->setProperty("objectId", id); return obj; } private slots: void shouldHaveInitialFetchFunctionAndPredicate() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQueryInput::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); // WHEN Domain::QueryResult>::Ptr result = query.result(); result->data(); result = query.result(); // Should not cause any problem or wrong data QVERIFY(result->data().isEmpty()); QTest::qWait(150); // THEN QList> expected; - expected << QPair(0, "0A") - << QPair(3, "0B") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0B")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); } void shouldFilterOutNullRawPointers() { // GIVEN auto query = Domain::LiveQuery(); query.setFetchFunction([this] (const Domain::LiveQueryInput::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add("0"); - add("1"); + add(QStringLiteral("0")); + add(QStringLiteral("1")); add(QString()); - add("a"); - add("2"); + add(QStringLiteral("a")); + add(QStringLiteral("2")); }); }); query.setConvertFunction([this] (const QString &s) -> QObject* { bool ok = false; const int id = s.toInt(&ok); if (ok) { auto object = new QObject(this); object->setProperty("id", id); return object; } else { return Q_NULLPTR; } }); query.setPredicateFunction([] (const QString &s) { return !s.isEmpty(); }); // WHEN auto result = query.result(); result->data(); result = query.result(); // Should not cause any problem or wrong data QVERIFY(result->data().isEmpty()); QTest::qWait(150); // THEN QCOMPARE(result->data().size(), 3); QCOMPARE(result->data().at(0)->property("id").toInt(), 0); QCOMPARE(result->data().at(1)->property("id").toInt(), 1); QCOMPARE(result->data().at(2)->property("id").toInt(), 2); } void shouldFilterOutNullSharedPointers() { // GIVEN auto query = Domain::LiveQuery(); query.setFetchFunction([this] (const Domain::LiveQueryInput::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add("0"); - add("1"); + add(QStringLiteral("0")); + add(QStringLiteral("1")); add(QString()); - add("a"); - add("2"); + add(QStringLiteral("a")); + add(QStringLiteral("2")); }); }); query.setConvertFunction([this] (const QString &s) { bool ok = false; const int id = s.toInt(&ok); if (ok) { auto object = QObjectPtr::create(); object->setProperty("id", id); return object; } else { return QObjectPtr(); } }); query.setPredicateFunction([] (const QString &s) { return !s.isEmpty(); }); // WHEN auto result = query.result(); result->data(); result = query.result(); // Should not cause any problem or wrong data QVERIFY(result->data().isEmpty()); QTest::qWait(150); // THEN QCOMPARE(result->data().size(), 3); QCOMPARE(result->data().at(0)->property("id").toInt(), 0); QCOMPARE(result->data().at(1)->property("id").toInt(), 1); QCOMPARE(result->data().at(2)->property("id").toInt(), 2); } void shouldDealWithSeveralFetchesProperly() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); for (int i = 0; i < 2; i++) { // WHEN * 2 Domain::QueryResult>::Ptr result = query.result(); // THEN * 2 QVERIFY(result->data().isEmpty()); QTest::qWait(150); QList> expected; - expected << QPair(0, "0A") - << QPair(3, "0B") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0B")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); } } void shouldClearProviderWhenDeleted() { // GIVEN auto query = new Domain::LiveQuery>; query->setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); }); }); query->setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query->setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); Domain::QueryResult>::Ptr result = query->result(); QTest::qWait(150); QCOMPARE(result->data().count(), 1); // WHEN delete query; // THEN QVERIFY(result->data().isEmpty()); } void shouldReactToAdds() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); Domain::QueryResult>::Ptr result = query.result(); QTest::qWait(150); QList> expected; - expected << QPair(0, "0A"); + expected << QPair(0, QStringLiteral("0A")); QCOMPARE(result->data(), expected); // WHEN - query.onAdded(createObject(3, "0B")); - query.onAdded(createObject(4, "1B")); - query.onAdded(createObject(5, "2B")); + query.onAdded(createObject(3, QStringLiteral("0B"))); + query.onAdded(createObject(4, QStringLiteral("1B"))); + query.onAdded(createObject(5, QStringLiteral("2B"))); // THEN - expected << QPair(3, "0B"); + expected << QPair(3, QStringLiteral("0B")); QCOMPARE(result->data(), expected); } void shouldReactToRemoves() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); query.setRepresentsFunction([] (QObject *object, const QPair &output) { return object->property("objectId").toInt() == output.first; }); Domain::QueryResult>::Ptr result = query.result(); QTest::qWait(150); QList> expected; - expected << QPair(0, "0A") - << QPair(3, "0B") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0B")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); // WHEN - query.onRemoved(createObject(3, "0B")); - query.onRemoved(createObject(4, "1B")); - query.onRemoved(createObject(5, "2B")); + query.onRemoved(createObject(3, QStringLiteral("0B"))); + query.onRemoved(createObject(4, QStringLiteral("1B"))); + query.onRemoved(createObject(5, QStringLiteral("2B"))); // THEN expected.removeAt(1); QCOMPARE(result->data(), expected); } void shouldReactToChanges() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setUpdateFunction([] (QObject *object, QPair &output) { output.second = object->objectName(); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); query.setRepresentsFunction([] (QObject *object, const QPair &output) { return object->property("objectId").toInt() == output.first; }); Domain::QueryResult>::Ptr result = query.result(); QTest::qWait(150); QList> expected; - expected << QPair(0, "0A") - << QPair(3, "0B") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0B")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const QPair &, int) { replaceHandlerCalled = true; }); // WHEN - query.onChanged(createObject(3, "0BB")); + query.onChanged(createObject(3, QStringLiteral("0BB"))); // Then expected.clear(); - expected << QPair(0, "0A") - << QPair(3, "0BB") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0BB")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); QVERIFY(replaceHandlerCalled); } void shouldRemoveWhenChangesMakeInputUnsuitableForQuery() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); query.setRepresentsFunction([] (QObject *object, const QPair &output) { return object->property("objectId").toInt() == output.first; }); Domain::QueryResult>::Ptr result = query.result(); QTest::qWait(150); QList> expected; - expected << QPair(0, "0A") - << QPair(3, "0B") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0B")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const QPair &, int) { replaceHandlerCalled = true; }); // WHEN - query.onChanged(createObject(3, "1B")); + query.onChanged(createObject(3, QStringLiteral("1B"))); // Then expected.removeAt(1); QCOMPARE(result->data(), expected); QVERIFY(!replaceHandlerCalled); } void shouldAddWhenChangesMakeInputSuitableForQuery() { // GIVEN Domain::LiveQuery> query; query.setFetchFunction([this] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([] (QObject *object) { return object->objectName().startsWith('0'); }); query.setRepresentsFunction([] (QObject *object, const QPair &output) { return object->property("objectId").toInt() == output.first; }); Domain::QueryResult>::Ptr result = query.result(); QTest::qWait(150); QList> expected; - expected << QPair(0, "0A") - << QPair(3, "0B") - << QPair(6, "0C"); + expected << QPair(0, QStringLiteral("0A")) + << QPair(3, QStringLiteral("0B")) + << QPair(6, QStringLiteral("0C")); QCOMPARE(result->data(), expected); bool replaceHandlerCalled = false; result->addPostReplaceHandler([&replaceHandlerCalled](const QPair &, int) { replaceHandlerCalled = true; }); // WHEN - query.onChanged(createObject(4, "0BB")); + query.onChanged(createObject(4, QStringLiteral("0BB"))); // Then - expected << QPair(4, "0BB"); + expected << QPair(4, QStringLiteral("0BB")); QCOMPARE(result->data(), expected); QVERIFY(!replaceHandlerCalled); } void shouldEmptyAndFetchAgainOnReset() { // GIVEN bool afterReset = false; Domain::LiveQuery> query; query.setFetchFunction([this, &afterReset] (const Domain::LiveQuery::AddFunction &add) { Utils::JobHandler::install(new FakeJob, [this, &afterReset, add] { - add(createObject(0, "0A")); - add(createObject(1, "1A")); - add(createObject(2, "2A")); - add(createObject(3, "0B")); - add(createObject(4, "1B")); - add(createObject(5, "2B")); + add(createObject(0, QStringLiteral("0A"))); + add(createObject(1, QStringLiteral("1A"))); + add(createObject(2, QStringLiteral("2A"))); + add(createObject(3, QStringLiteral("0B"))); + add(createObject(4, QStringLiteral("1B"))); + add(createObject(5, QStringLiteral("2B"))); if (afterReset) { - add(createObject(6, "0C")); - add(createObject(7, "1C")); - add(createObject(8, "2C")); + add(createObject(6, QStringLiteral("0C"))); + add(createObject(7, QStringLiteral("1C"))); + add(createObject(8, QStringLiteral("2C"))); } }); }); query.setConvertFunction([] (QObject *object) { return QPair(object->property("objectId").toInt(), object->objectName()); }); query.setPredicateFunction([&afterReset] (QObject *object) { if (afterReset) return object->objectName().startsWith('1'); else return object->objectName().startsWith('0'); }); Domain::QueryResult>::Ptr result = query.result(); int removeHandlerCallCount = 0; result->addPostRemoveHandler([&removeHandlerCallCount](const QPair &, int) { removeHandlerCallCount++; }); QTest::qWait(150); QVERIFY(!result->data().isEmpty()); QCOMPARE(removeHandlerCallCount, 0); // WHEN query.reset(); afterReset = true; QTest::qWait(150); // THEN QList> expected; - expected << QPair(1, "1A") - << QPair(4, "1B") - << QPair(7, "1C"); + expected << QPair(1, QStringLiteral("1A")) + << QPair(4, QStringLiteral("1B")) + << QPair(7, QStringLiteral("1C")); QVERIFY(afterReset); QCOMPARE(result->data(), expected); QCOMPARE(removeHandlerCallCount, 2); } }; ZANSHIN_TEST_MAIN(LiveQueryTest) #include "livequerytest.moc" diff --git a/tests/units/domain/mockitotest.cpp b/tests/units/domain/mockitotest.cpp index 5e4d7681..35adaf7e 100644 --- a/tests/units/domain/mockitotest.cpp +++ b/tests/units/domain/mockitotest.cpp @@ -1,78 +1,78 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include class FakeInterface { public: virtual ~FakeInterface(); virtual void doSomething() = 0; virtual int computeMe(QString input) = 0; }; using namespace mockitopp; using mockitopp::matcher::any; class MockitoTest : public QObject { Q_OBJECT private slots: void testBasics() { mock_object mock; mock(&FakeInterface::doSomething).when().thenReturn(); mock(&FakeInterface::doSomething).when().thenThrow("exception"); for (int i = 0; i < 10; i++) { - mock(&FakeInterface::computeMe).when("A").thenReturn(0); - mock(&FakeInterface::computeMe).when("B").thenReturn(1); - mock(&FakeInterface::computeMe).when("C").thenReturn(-1); - mock(&FakeInterface::computeMe).when("Foo").thenReturn(-1); + mock(&FakeInterface::computeMe).when(QStringLiteral("A")).thenReturn(0); + mock(&FakeInterface::computeMe).when(QStringLiteral("B")).thenReturn(1); + mock(&FakeInterface::computeMe).when(QStringLiteral("C")).thenReturn(-1); + mock(&FakeInterface::computeMe).when(QStringLiteral("Foo")).thenReturn(-1); } FakeInterface &iface = mock.getInstance(); iface.doSomething(); try { iface.doSomething(); QFAIL("No exception thrown"); } catch (...) { // We expect to catch something } for (int i = 0; i < 10; i++) { - QCOMPARE(iface.computeMe("A"), 0); - QCOMPARE(iface.computeMe("B"), 1); - QCOMPARE(iface.computeMe("C"), -1); - QCOMPARE(iface.computeMe("Foo"), -1); + QCOMPARE(iface.computeMe(QStringLiteral("A")), 0); + QCOMPARE(iface.computeMe(QStringLiteral("B")), 1); + QCOMPARE(iface.computeMe(QStringLiteral("C")), -1); + QCOMPARE(iface.computeMe(QStringLiteral("Foo")), -1); } QVERIFY(mock(&FakeInterface::doSomething).when().exactly(2)); QVERIFY(mock(&FakeInterface::computeMe).when(any()).exactly(40)); } }; ZANSHIN_TEST_MAIN(MockitoTest) #include "mockitotest.moc" diff --git a/tests/units/domain/projecttest.cpp b/tests/units/domain/projecttest.cpp index b8c03054..4bf615dc 100644 --- a/tests/units/domain/projecttest.cpp +++ b/tests/units/domain/projecttest.cpp @@ -1,61 +1,61 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/project.h" using namespace Domain; class ProjectTest : public QObject { Q_OBJECT private slots: void shouldHaveEmptyPropertiesByDefault() { Project p; QCOMPARE(p.name(), QString()); } void shouldNotifyNameChanges() { Project p; QSignalSpy spy(&p, &Project::nameChanged); - p.setName("foo"); + p.setName(QStringLiteral("foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("foo")); } void shouldNotNotifyIdenticalNameChanges() { Project p; - p.setName("foo"); + p.setName(QStringLiteral("foo")); QSignalSpy spy(&p, &Project::nameChanged); - p.setName("foo"); + p.setName(QStringLiteral("foo")); QCOMPARE(spy.count(), 0); } }; ZANSHIN_TEST_MAIN(ProjectTest) #include "projecttest.moc" diff --git a/tests/units/domain/queryresulttest.cpp b/tests/units/domain/queryresulttest.cpp index 3b3f7b52..65d168f8 100644 --- a/tests/units/domain/queryresulttest.cpp +++ b/tests/units/domain/queryresulttest.cpp @@ -1,346 +1,346 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/queryresult.h" using namespace Domain; class Base { public: typedef QSharedPointer Ptr; virtual ~Base() {} - virtual QString whoAmI() { return "I'm Base"; } + virtual QString whoAmI() { return QStringLiteral("I'm Base"); } }; class Derived : public Base { public: typedef QSharedPointer Ptr; - QString whoAmI() { return "I'm Derived"; } + QString whoAmI() { return QStringLiteral("I'm Derived"); } }; class QueryResultTest : public QObject { Q_OBJECT private slots: void shouldBeCreatedEmpty() { QueryResultProvider::Ptr provider(new QueryResultProvider); QVERIFY(provider->data().isEmpty()); QueryResult::Ptr result = QueryResult::create(provider); QVERIFY(result->data().isEmpty()); } void shouldHaveSameContent() { QueryResultProvider::Ptr provider(new QueryResultProvider); QueryResult::Ptr result = QueryResult::create(provider); - provider->append("Bar"); + provider->append(QStringLiteral("Bar")); QVERIFY(!provider->data().isEmpty()); QVERIFY(!result->data().isEmpty()); QCOMPARE(provider->data().size(), 1); QCOMPARE(result->data().size(), 1); - QCOMPARE(provider->data().first(), QString("Bar")); - QCOMPARE(result->data().first(), QString("Bar")); + QCOMPARE(provider->data().first(), QStringLiteral("Bar")); + QCOMPARE(result->data().first(), QStringLiteral("Bar")); - provider->prepend("Foo"); - *provider << "Baz"; + provider->prepend(QStringLiteral("Foo")); + *provider << QStringLiteral("Baz"); QCOMPARE(provider->data().size(), 3); QCOMPARE(result->data().size(), 3); - QCOMPARE(provider->data().first(), QString("Foo")); - QCOMPARE(result->data().first(), QString("Foo")); - QCOMPARE(provider->data().at(1), QString("Bar")); - QCOMPARE(result->data().at(1), QString("Bar")); - QCOMPARE(provider->data().last(), QString("Baz")); - QCOMPARE(result->data().last(), QString("Baz")); + QCOMPARE(provider->data().first(), QStringLiteral("Foo")); + QCOMPARE(result->data().first(), QStringLiteral("Foo")); + QCOMPARE(provider->data().at(1), QStringLiteral("Bar")); + QCOMPARE(result->data().at(1), QStringLiteral("Bar")); + QCOMPARE(provider->data().last(), QStringLiteral("Baz")); + QCOMPARE(result->data().last(), QStringLiteral("Baz")); } void shouldCreateResultFromAnotherResultOfSameType() { auto provider = QueryResultProvider::Ptr::create(); auto result = QueryResult::create(provider); - provider->append("Foo"); - provider->append("Bar"); - provider->append("Baz"); + provider->append(QStringLiteral("Foo")); + provider->append(QStringLiteral("Bar")); + provider->append(QStringLiteral("Baz")); QVERIFY(!provider->data().isEmpty()); QVERIFY(!result->data().isEmpty()); QCOMPARE(result->data(), provider->data()); auto otherResult = QueryResult::copy(result); QCOMPARE(otherResult->data(), result->data()); } void shouldCreateResultFromAnotherResultOfCompatibleType() { auto provider = QueryResultProvider::Ptr::create(); auto result = QueryResult::create(provider); provider->append(Derived::Ptr::create()); QList baseList; baseList << provider->data().first(); QVERIFY(!provider->data().isEmpty()); QVERIFY(!result->data().isEmpty()); QCOMPARE(result->data(), provider->data()); auto otherResult = QueryResult::copy(result); QCOMPARE(otherResult->data(), baseList); } void shouldProperlyCopyNullPointers() { QueryResult::Ptr result; QVERIFY(QueryResult::copy(result).isNull()); } void shouldResultsKeepProviderAlive() { QueryResultProvider::WeakPtr provider; QVERIFY(provider.isNull()); { QueryResult::Ptr result1; { QueryResultProvider::Ptr strongProvider(new QueryResultProvider); provider = strongProvider; QVERIFY(!provider.isNull()); result1 = QueryResult::create(provider.toStrongRef()); } QVERIFY(!provider.isNull()); { QueryResult::Ptr result2 = QueryResult::create(provider.toStrongRef()); Q_UNUSED(result2); QVERIFY(!provider.isNull()); } QVERIFY(!provider.isNull()); } QVERIFY(provider.isNull()); } void shouldNotifyInserts() { QList preInserts, postInserts; QList preInsertsPos, postInsertsPos; QueryResultProvider::Ptr provider(new QueryResultProvider); QueryResult::Ptr result = QueryResult::create(provider); result->addPreInsertHandler( [&](const QString &value, int pos) { preInserts << value; preInsertsPos << pos; } ); result->addPostInsertHandler( [&](const QString &value, int pos) { postInserts << value; postInsertsPos << pos; } ); - provider->append("Bar"); - provider->prepend("Foo"); - *provider << "Baz"; - provider->insert(1, "Bazz"); + provider->append(QStringLiteral("Bar")); + provider->prepend(QStringLiteral("Foo")); + *provider << QStringLiteral("Baz"); + provider->insert(1, QStringLiteral("Bazz")); const QList expectedInserts = {"Bar", "Foo", "Baz", "Bazz"}; const QList expectedInsertsPos = {0, 0, 2, 1}; QCOMPARE(preInserts, expectedInserts); QCOMPARE(preInsertsPos, expectedInsertsPos); QCOMPARE(postInserts, expectedInserts); QCOMPARE(postInsertsPos, expectedInsertsPos); } void shouldNotifyInsertsForCompatibleTypes() { QList preInserts, postInserts; QList preInsertsPos, postInsertsPos; auto provider = QueryResultProvider::Ptr::create(); auto derivedResult = QueryResult::create(provider); auto baseResult = QueryResult::copy(derivedResult); baseResult->addPreInsertHandler( [&](const Base::Ptr &value, int pos) { preInserts << value; preInsertsPos << pos; } ); baseResult->addPostInsertHandler( [&](const Base::Ptr &value, int pos) { postInserts << value; postInsertsPos << pos; } ); provider->append(Derived::Ptr::create()); provider->append(Derived::Ptr::create()); const QList expectedInserts = { provider->data().first(), provider->data().last() }; const QList expectedInsertsPos = {0, 1}; QCOMPARE(preInserts, expectedInserts); QCOMPARE(preInsertsPos, expectedInsertsPos); QCOMPARE(postInserts, expectedInserts); QCOMPARE(postInsertsPos, expectedInsertsPos); } void shouldNotifyRemoves() { QList preRemoves, postRemoves; QList preRemovesPos, postRemovesPos; QueryResultProvider::Ptr provider(new QueryResultProvider); - *provider << "Foo" << "Bar" << "Baz" << "Bazz"; + *provider << QStringLiteral("Foo") << QStringLiteral("Bar") << QStringLiteral("Baz") << QStringLiteral("Bazz"); QueryResult::Ptr result = QueryResult::create(provider); result->addPreRemoveHandler( [&](const QString &value, int pos) { preRemoves << value; preRemovesPos << pos; } ); result->addPostRemoveHandler( [&](const QString &value, int pos) { postRemoves << value; postRemovesPos << pos; } ); provider->removeAt(1); provider->removeFirst(); provider->removeLast(); const QList expectedRemoves = {"Bar", "Foo", "Bazz"}; const QList expectedRemovesPos = {1, 0, 1}; QCOMPARE(preRemoves, expectedRemoves); QCOMPARE(preRemovesPos, expectedRemovesPos); QCOMPARE(postRemoves, expectedRemoves); QCOMPARE(postRemovesPos, expectedRemovesPos); } void shouldNotifyTakes() { QList preRemoves, postRemoves, taken; QList preRemovesPos, postRemovesPos; QueryResultProvider::Ptr provider(new QueryResultProvider); - *provider << "Foo" << "Bar" << "Baz" << "Bazz"; + *provider << QStringLiteral("Foo") << QStringLiteral("Bar") << QStringLiteral("Baz") << QStringLiteral("Bazz"); QueryResult::Ptr result = QueryResult::create(provider); result->addPreRemoveHandler( [&](const QString &value, int pos) { preRemoves << value; preRemovesPos << pos; } ); result->addPostRemoveHandler( [&](const QString &value, int pos) { postRemoves << value; postRemovesPos << pos; } ); taken << provider->takeAt(1); taken << provider->takeFirst(); taken << provider->takeLast(); const QList expectedRemoves = {"Bar", "Foo", "Bazz"}; const QList expectedRemovesPos = {1, 0, 1}; QCOMPARE(preRemoves, expectedRemoves); QCOMPARE(preRemovesPos, expectedRemovesPos); QCOMPARE(postRemoves, expectedRemoves); QCOMPARE(postRemovesPos, expectedRemovesPos); QCOMPARE(taken, expectedRemoves); } void shouldNotifyReplaces() { QList preReplaces, postReplaces; QList preReplacesPos, postReplacesPos; QueryResultProvider::Ptr provider(new QueryResultProvider); - *provider << "Foo" << "Foo" << "Foo" << "Foo"; + *provider << QStringLiteral("Foo") << QStringLiteral("Foo") << QStringLiteral("Foo") << QStringLiteral("Foo"); QueryResult::Ptr result = QueryResult::create(provider); result->addPreReplaceHandler( [&](const QString &value, int pos) { preReplaces << value; preReplacesPos << pos; } ); result->addPostReplaceHandler( [&](const QString &value, int pos) { postReplaces << value; postReplacesPos << pos; } ); - provider->replace(1, "Bar"); - provider->replace(2, "Baz"); + provider->replace(1, QStringLiteral("Bar")); + provider->replace(2, QStringLiteral("Baz")); const QList expectedPreReplaces = {"Foo", "Foo"}; const QList expectedPostReplaces = {"Bar", "Baz"}; const QList expectedReplacesPos = {1, 2}; QCOMPARE(preReplaces, expectedPreReplaces); QCOMPARE(preReplacesPos, expectedReplacesPos); QCOMPARE(postReplaces, expectedPostReplaces); QCOMPARE(postReplacesPos, expectedReplacesPos); } }; ZANSHIN_TEST_MAIN(QueryResultTest) #include "queryresulttest.moc" diff --git a/tests/units/domain/tagtest.cpp b/tests/units/domain/tagtest.cpp index d9ab7c69..be24d87e 100644 --- a/tests/units/domain/tagtest.cpp +++ b/tests/units/domain/tagtest.cpp @@ -1,61 +1,61 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/tag.h" using namespace Domain; class TagTest : public QObject { Q_OBJECT private slots: void shouldHaveEmptyPropertiesByDefault() { Tag t; QCOMPARE(t.name(), QString()); } void shouldNotifyNameChanges() { Tag t; QSignalSpy spy(&t, &Tag::nameChanged); - t.setName("foo"); + t.setName(QStringLiteral("foo")); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.first().first().toString(), QString("foo")); + QCOMPARE(spy.first().first().toString(), QStringLiteral("foo")); } void shouldNotNotifyIdenticalNameChanges() { Tag t; - t.setName("foo"); + t.setName(QStringLiteral("foo")); QSignalSpy spy(&t, &Tag::nameChanged); - t.setName("foo"); + t.setName(QStringLiteral("foo")); QCOMPARE(spy.count(), 0); } }; ZANSHIN_TEST_MAIN(TagTest) #include "tagtest.moc" diff --git a/tests/units/domain/tasktest.cpp b/tests/units/domain/tasktest.cpp index 28a3ba25..3275c680 100644 --- a/tests/units/domain/tasktest.cpp +++ b/tests/units/domain/tasktest.cpp @@ -1,196 +1,196 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "domain/task.h" #include "utils/datetime.h" using namespace Domain; class TaskTest : public QObject { Q_OBJECT public: explicit TaskTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } private slots: void shouldHaveEmptyPropertiesByDefault() { Task t; QCOMPARE(t.text(), QString()); QCOMPARE(t.title(), QString()); QCOMPARE(t.isDone(), false); QCOMPARE(t.startDate(), QDateTime()); QCOMPARE(t.dueDate(), QDateTime()); QCOMPARE(t.doneDate(), QDateTime()); QVERIFY(!t.delegate().isValid()); } void shouldHaveValueBasedDelegate() { Task::Delegate d; QVERIFY(!d.isValid()); QCOMPARE(d.name(), QString()); QCOMPARE(d.email(), QString()); QCOMPARE(d.display(), QString()); - d.setName("John Doe"); + d.setName(QStringLiteral("John Doe")); QVERIFY(!d.isValid()); - QCOMPARE(d.name(), QString("John Doe")); + QCOMPARE(d.name(), QStringLiteral("John Doe")); QCOMPARE(d.email(), QString()); QCOMPARE(d.display(), QString()); - d.setEmail("doe@somewhere.com"); + d.setEmail(QStringLiteral("doe@somewhere.com")); QVERIFY(d.isValid()); - QCOMPARE(d.name(), QString("John Doe")); - QCOMPARE(d.email(), QString("doe@somewhere.com")); - QCOMPARE(d.display(), QString("John Doe")); + QCOMPARE(d.name(), QStringLiteral("John Doe")); + QCOMPARE(d.email(), QStringLiteral("doe@somewhere.com")); + QCOMPARE(d.display(), QStringLiteral("John Doe")); d.setName(QString()); QVERIFY(d.isValid()); QCOMPARE(d.name(), QString()); - QCOMPARE(d.email(), QString("doe@somewhere.com")); - QCOMPARE(d.display(), QString("doe@somewhere.com")); + QCOMPARE(d.email(), QStringLiteral("doe@somewhere.com")); + QCOMPARE(d.display(), QStringLiteral("doe@somewhere.com")); } void shouldNotifyStatusChanges() { Task t; QSignalSpy spy(&t, &Task::doneChanged); t.setDone(true); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().toBool(), true); } void shouldNotNotifyIdenticalStatusChanges() { Task t; t.setDone(true); QSignalSpy spy(&t, &Task::doneChanged); t.setDone(true); QCOMPARE(spy.count(), 0); } void shouldNotifyStartDateChanges() { Task t; QSignalSpy spy(&t, &Task::startDateChanged); t.setStartDate(QDateTime(QDate(2014, 1, 13))); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().toDateTime(), QDateTime(QDate(2014, 1, 13))); } void shouldNotNotifyIdenticalStartDateChanges() { Task t; t.setStartDate(QDateTime(QDate(2014, 1, 13))); QSignalSpy spy(&t, &Task::startDateChanged); t.setStartDate(QDateTime(QDate(2014, 1, 13))); QCOMPARE(spy.count(), 0); } void shouldNotifyDueDateChanges() { Task t; QSignalSpy spy(&t, &Task::dueDateChanged); t.setDueDate(QDateTime(QDate(2014, 1, 13))); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().toDateTime(), QDateTime(QDate(2014, 1, 13))); } void shouldNotNotifyIdenticalDueDateChanges() { Task t; t.setDueDate(QDateTime(QDate(2014, 1, 13))); QSignalSpy spy(&t, &Task::dueDateChanged); t.setDueDate(QDateTime(QDate(2014, 1, 13))); QCOMPARE(spy.count(), 0); } void shouldNotifyDelegateChanges() { Task t; QSignalSpy spy(&t, &Task::delegateChanged); - t.setDelegate(Task::Delegate("John Doe", "doe@somewhere.com")); + t.setDelegate(Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("doe@somewhere.com"))); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().value(), - Task::Delegate("John Doe", "doe@somewhere.com")); + Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("doe@somewhere.com"))); } void shouldNotNotifyIdenticalDelegateChanges() { Task t; - t.setDelegate(Task::Delegate("John Doe", "doe@somewhere.com")); + t.setDelegate(Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("doe@somewhere.com"))); QSignalSpy spy(&t, &Task::delegateChanged); - t.setDelegate(Task::Delegate("John Doe", "doe@somewhere.com")); + t.setDelegate(Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("doe@somewhere.com"))); QCOMPARE(spy.count(), 0); } void shouldNotifyDoneDateChanges() { Task t; QSignalSpy spy(&t, &Task::doneDateChanged); t.setDoneDate(QDateTime(QDate(2014, 1, 13))); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().toDateTime(), QDateTime(QDate(2014, 1, 13))); } void shouldNotNotifyIdenticalDoneDateChanges() { Task t; t.setDoneDate(QDateTime(QDate(2014, 1, 13))); QSignalSpy spy(&t, &Task::doneDateChanged); t.setDoneDate(QDateTime(QDate(2014, 1, 13))); QCOMPARE(spy.count(), 0); } void shouldNotifyDoneDateSet() { Task t; QSignalSpy spy(&t, &Task::doneDateChanged); t.setDone(true); QCOMPARE(spy.count(), 1); QCOMPARE(spy.takeFirst().at(0).toDateTime().date(), Utils::DateTime::currentDateTime().date()); } void shouldNotifyDoneDateUnset() { Task t; t.setDone(true); QSignalSpy spy(&t, &Task::doneDateChanged); t.setDone(false); QCOMPARE(spy.count(), 1); QCOMPARE(spy.takeFirst().at(0).toDateTime(), QDateTime()); } }; ZANSHIN_TEST_MAIN(TaskTest) #include "tasktest.moc" diff --git a/tests/units/migrator/zanshin021migrationtest.cpp b/tests/units/migrator/zanshin021migrationtest.cpp index 70b8bdd9..73b70571 100644 --- a/tests/units/migrator/zanshin021migrationtest.cpp +++ b/tests/units/migrator/zanshin021migrationtest.cpp @@ -1,177 +1,177 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 David Faure 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "zanshin021migrator.h" #include #include #include #include #include #include #include #include #include "akonadi/akonadicollectionfetchjobinterface.h" #include "akonadi/akonadiitemfetchjobinterface.h" #include "akonadi/akonadistorage.h" #include #include #include #include class Zanshin021MigrationTest : public QObject { Q_OBJECT public: explicit Zanshin021MigrationTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } private slots: void initTestCase() { QVERIFY(TestLib::TestSafety::checkTestIsIsolated()); auto storage = Akonadi::StorageInterface::Ptr(new Akonadi::Storage); TestLib::AkonadiDebug::dumpTree(storage); //QProcess proc; //proc.execute("akonadiconsole"); //qApp->exec(); } void shouldFetchAllItems() { // GIVEN Zanshin021Migrator migrator; // WHEN Zanshin021Migrator::SeenItemHash hash = migrator.fetchAllItems(); // THEN // the migrator gathered all items and the initial state of "is a project" for each one is correct - m_expectedUids.insert("child-of-project", false); - m_expectedUids.insert("new-project-with-property", true); - m_expectedUids.insert("old-project-with-comment", false); // not yet - m_expectedUids.insert("project-with-comment-and-property", true); - m_expectedUids.insert("project-with-children", false); // not yet - m_expectedUids.insert("standalone-task", false); + m_expectedUids.insert(QStringLiteral("child-of-project"), false); + m_expectedUids.insert(QStringLiteral("new-project-with-property"), true); + m_expectedUids.insert(QStringLiteral("old-project-with-comment"), false); // not yet + m_expectedUids.insert(QStringLiteral("project-with-comment-and-property"), true); + m_expectedUids.insert(QStringLiteral("project-with-children"), false); // not yet + m_expectedUids.insert(QStringLiteral("standalone-task"), false); checkExpectedIsProject(hash, m_expectedUids); } void shouldMigrateCommentToProperty() { // GIVEN Zanshin021Migrator migrator; Zanshin021Migrator::SeenItemHash hash = migrator.fetchAllItems(); // WHEN Akonadi::TransactionSequence *sequence = new Akonadi::TransactionSequence(); migrator.migrateProjectComments(hash, sequence); // THEN // the project with an old-style comment was modified to have the property - SeenItem item = hash.value("old-project-with-comment"); + SeenItem item = hash.value(QStringLiteral("old-project-with-comment")); QVERIFY(item.isDirty()); - m_expectedUids["old-project-with-comment"] = true; // migrated! + m_expectedUids[QStringLiteral("old-project-with-comment")] = true; // migrated! checkExpectedIsProject(hash, m_expectedUids); - m_expectedUids["old-project-with-comment"] = false; // revert for now + m_expectedUids[QStringLiteral("old-project-with-comment")] = false; // revert for now sequence->rollback(); sequence->exec(); } void shouldMigrateTaskWithChildrenToProject() { // GIVEN Zanshin021Migrator migrator; Zanshin021Migrator::SeenItemHash hash = migrator.fetchAllItems(); // WHEN Akonadi::TransactionSequence *sequence = new Akonadi::TransactionSequence(); migrator.migrateProjectWithChildren(hash, sequence); // THEN // the project with children was modified to have the property - SeenItem item = hash.value("project-with-children"); + SeenItem item = hash.value(QStringLiteral("project-with-children")); QVERIFY(item.isDirty()); - m_expectedUids["project-with-children"] = true; // migrated! + m_expectedUids[QStringLiteral("project-with-children")] = true; // migrated! checkExpectedIsProject(hash, m_expectedUids); - m_expectedUids["project-with-children"] = false; // revert for now + m_expectedUids[QStringLiteral("project-with-children")] = false; // revert for now sequence->rollback(); sequence->exec(); } void shouldMigrateProjects() { // GIVEN Zanshin021Migrator migrator; // WHEN const bool ret = migrator.migrateProjects(); // THEN QVERIFY(ret); // success - m_expectedUids["old-project-with-comment"] = true; // migrated! - m_expectedUids["project-with-children"] = true; // migrated! + m_expectedUids[QStringLiteral("old-project-with-comment")] = true; // migrated! + m_expectedUids[QStringLiteral("project-with-children")] = true; // migrated! Zanshin021Migrator::SeenItemHash hash = migrator.fetchAllItems(); checkExpectedIsProject(hash, m_expectedUids); } private: void checkExpectedIsProject(const Zanshin021Migrator::SeenItemHash &hash, const QMap &expectedItems) { QStringList uids = hash.keys(); uids.sort(); if (uids.count() != expectedItems.count()) // QCOMPARE for QStringList isn't verbose enough qWarning() << "Got" << uids << "expected" << expectedItems.keys(); QCOMPARE(uids, QStringList(expectedItems.keys())); for (auto it = expectedItems.constBegin(); it != expectedItems.constEnd(); ++it) { //qDebug() << it.key(); QCOMPARE(Zanshin021Migrator::isProject(hash.value(it.key()).item()), it.value()); } } QMap m_expectedUids; }; ZANSHIN_TEST_MAIN(Zanshin021MigrationTest) #include "zanshin021migrationtest.moc" diff --git a/tests/units/presentation/artifacteditormodeltest.cpp b/tests/units/presentation/artifacteditormodeltest.cpp index 863c597d..bce25ffb 100644 --- a/tests/units/presentation/artifacteditormodeltest.cpp +++ b/tests/units/presentation/artifacteditormodeltest.cpp @@ -1,459 +1,459 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include #include "testlib/fakejob.h" #include "domain/task.h" #include "domain/note.h" #include "presentation/artifacteditormodel.h" #include "presentation/errorhandler.h" using namespace mockitopp; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class ArtifactEditorModelTest : public QObject { Q_OBJECT private slots: void shouldHaveEmptyDefaultState() { // GIVEN Presentation::ArtifactEditorModel model; // WHEN // Nothing // THEN QVERIFY(model.artifact().isNull()); QVERIFY(!model.hasTaskProperties()); QVERIFY(model.text().isEmpty()); QVERIFY(model.title().isEmpty()); QVERIFY(!model.isDone()); QVERIFY(model.startDate().isNull()); QVERIFY(model.dueDate().isNull()); QVERIFY(model.delegateText().isNull()); QVERIFY(!model.hasSaveFunction()); QVERIFY(!model.hasDelegateFunction()); } void shouldHaveTaskProperties() { // GIVEN Presentation::ArtifactEditorModel model; QSignalSpy textSpy(&model, &Presentation::ArtifactEditorModel::textChanged); QSignalSpy titleSpy(&model, &Presentation::ArtifactEditorModel::titleChanged); QSignalSpy doneSpy(&model, &Presentation::ArtifactEditorModel::doneChanged); QSignalSpy startSpy(&model, &Presentation::ArtifactEditorModel::startDateChanged); QSignalSpy dueSpy(&model, &Presentation::ArtifactEditorModel::dueDateChanged); QSignalSpy delegateSpy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); auto task = Domain::Task::Ptr::create(); - task->setText("description"); - task->setTitle("title"); + task->setText(QStringLiteral("description")); + task->setTitle(QStringLiteral("title")); task->setDone(true); task->setStartDate(QDateTime::currentDateTime()); task->setDueDate(QDateTime::currentDateTime().addDays(2)); - task->setDelegate(Domain::Task::Delegate("John Doe", "john@doe.com")); + task->setDelegate(Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com"))); // WHEN model.setArtifact(task); // To make sure we don't signal too much model.setText(task->text()); model.setTitle(task->title()); model.setDone(task->isDone()); model.setStartDate(task->startDate()); model.setDueDate(task->dueDate()); // THEN QVERIFY(model.hasTaskProperties()); QCOMPARE(textSpy.size(), 1); QCOMPARE(textSpy.takeFirst().takeFirst().toString(), task->text()); QCOMPARE(model.property("text").toString(), task->text()); QCOMPARE(titleSpy.size(), 1); QCOMPARE(titleSpy.takeFirst().takeFirst().toString(), task->title()); QCOMPARE(model.property("title").toString(), task->title()); QCOMPARE(doneSpy.size(), 1); QCOMPARE(doneSpy.takeFirst().takeFirst().toBool(), task->isDone()); QCOMPARE(model.property("done").toBool(), task->isDone()); QCOMPARE(startSpy.size(), 1); QCOMPARE(startSpy.takeFirst().takeFirst().toDateTime(), task->startDate()); QCOMPARE(model.property("startDate").toDateTime(), task->startDate()); QCOMPARE(dueSpy.size(), 1); QCOMPARE(dueSpy.takeFirst().takeFirst().toDateTime(), task->dueDate()); QCOMPARE(model.property("dueDate").toDateTime(), task->dueDate()); QCOMPARE(delegateSpy.size(), 1); QCOMPARE(delegateSpy.takeFirst().takeFirst().toString(), task->delegate().display()); QCOMPARE(model.property("delegateText").toString(), task->delegate().display()); } void shouldHaveNoteProperties() { // GIVEN Presentation::ArtifactEditorModel model; QSignalSpy textSpy(&model, &Presentation::ArtifactEditorModel::textChanged); QSignalSpy titleSpy(&model, &Presentation::ArtifactEditorModel::titleChanged); QSignalSpy doneSpy(&model, &Presentation::ArtifactEditorModel::doneChanged); QSignalSpy startSpy(&model, &Presentation::ArtifactEditorModel::startDateChanged); QSignalSpy dueSpy(&model, &Presentation::ArtifactEditorModel::dueDateChanged); QSignalSpy delegateSpy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); auto note = Domain::Note::Ptr::create(); - note->setText("description"); - note->setTitle("title"); + note->setText(QStringLiteral("description")); + note->setTitle(QStringLiteral("title")); // WHEN model.setArtifact(note); // To make sure we don't signal too much model.setText(note->text()); model.setTitle(note->title()); // THEN QVERIFY(!model.hasTaskProperties()); QCOMPARE(textSpy.size(), 1); QCOMPARE(textSpy.takeFirst().takeFirst().toString(), note->text()); QCOMPARE(model.property("text").toString(), note->text()); QCOMPARE(titleSpy.size(), 1); QCOMPARE(titleSpy.takeFirst().takeFirst().toString(), note->title()); QCOMPARE(model.property("title").toString(), note->title()); QCOMPARE(doneSpy.size(), 1); QCOMPARE(doneSpy.takeFirst().takeFirst().toBool(), false); QCOMPARE(model.property("done").toBool(), false); QCOMPARE(startSpy.size(), 1); QVERIFY(startSpy.takeFirst().takeFirst().toDateTime().isNull()); QVERIFY(model.property("startDate").toDateTime().isNull()); QCOMPARE(dueSpy.size(), 1); QVERIFY(dueSpy.takeFirst().takeFirst().toDateTime().isNull()); QVERIFY(model.property("dueDate").toDateTime().isNull()); QCOMPARE(delegateSpy.size(), 1); QVERIFY(delegateSpy.takeFirst().takeFirst().toString().isEmpty()); QVERIFY(model.property("delegateText").toString().isEmpty()); } void shouldReactToArtifactPropertyChanges_data() { QTest::addColumn("artifact"); QTest::addColumn("propertyName"); QTest::addColumn("propertyValue"); QTest::addColumn("signal"); QTest::newRow("note text") << Domain::Artifact::Ptr(Domain::Note::Ptr::create()) << QByteArray("text") << QVariant("new text") << QByteArray(SIGNAL(textChanged(QString))); QTest::newRow("note title") << Domain::Artifact::Ptr(Domain::Note::Ptr::create()) << QByteArray("title") << QVariant("new title") << QByteArray(SIGNAL(titleChanged(QString))); QTest::newRow("task text") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("text") << QVariant("new text") << QByteArray(SIGNAL(textChanged(QString))); QTest::newRow("task title") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("title") << QVariant("new title") << QByteArray(SIGNAL(titleChanged(QString))); QTest::newRow("task done") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("done") << QVariant(true) << QByteArray(SIGNAL(doneChanged(bool))); QTest::newRow("task start") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("startDate") << QVariant(QDateTime::currentDateTime()) << QByteArray(SIGNAL(startDateChanged(QDateTime))); QTest::newRow("task due") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("dueDate") << QVariant(QDateTime::currentDateTime().addDays(2)) << QByteArray(SIGNAL(dueDateChanged(QDateTime))); } void shouldReactToArtifactPropertyChanges() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); Presentation::ArtifactEditorModel model; model.setArtifact(artifact); QSignalSpy spy(&model, signal.constData()); // WHEN artifact->setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); QCOMPARE(model.property(propertyName), propertyValue); } void shouldReactToTaskDelegateChanges() { // GIVEN auto task = Domain::Task::Ptr::create(); Presentation::ArtifactEditorModel model; model.setArtifact(task); QSignalSpy spy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); // WHEN - task->setDelegate(Domain::Task::Delegate("John Doe", "john@doe.com")); + task->setDelegate(Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com"))); // THEN QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().toString(), task->delegate().display()); QCOMPARE(model.property("delegateText").toString(), task->delegate().display()); } void shouldApplyChangesBackToArtifactAfterADelay_data() { shouldReactToArtifactPropertyChanges_data(); } void shouldApplyChangesBackToArtifactAfterADelay() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; return new FakeJob(this); }; Presentation::ArtifactEditorModel model; model.setSaveFunction(save); model.setArtifact(artifact); QSignalSpy spy(&model, signal.constData()); // WHEN model.setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); QCOMPARE(model.property(propertyName), propertyValue); QVERIFY(artifact->property(propertyName) != propertyValue); QVERIFY(!savedArtifact); // WHEN (apply after delay) QTest::qWait(model.autoSaveDelay() + 50); // THEN QCOMPARE(savedArtifact, artifact); QCOMPARE(artifact->property(propertyName), propertyValue); } void shouldApplyChangesImmediatelyIfANewArtifactIsSet_data() { shouldReactToArtifactPropertyChanges_data(); } void shouldApplyChangesImmediatelyIfANewArtifactIsSet() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; return new FakeJob(this); }; Presentation::ArtifactEditorModel model; model.setSaveFunction(save); QVERIFY(model.hasSaveFunction()); model.setArtifact(artifact); QSignalSpy spy(&model, signal.constData()); // WHEN model.setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); QCOMPARE(model.property(propertyName), propertyValue); QVERIFY(artifact->property(propertyName) != propertyValue); QVERIFY(!savedArtifact); // WHEN (apply immediately) model.setArtifact(Domain::Task::Ptr::create()); // THEN QCOMPARE(savedArtifact, artifact); QCOMPARE(artifact->property(propertyName), propertyValue); savedArtifact.clear(); // WHEN (nothing else happens after a delay) QTest::qWait(model.autoSaveDelay() + 50); // THEN QVERIFY(!savedArtifact); QCOMPARE(artifact->property(propertyName), propertyValue); } void shouldApplyChangesImmediatelyIfDeleted_data() { shouldReactToArtifactPropertyChanges_data(); } void shouldApplyChangesImmediatelyIfDeleted() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; return new FakeJob(this); }; auto model = new Presentation::ArtifactEditorModel; model->setSaveFunction(save); QVERIFY(model->hasSaveFunction()); model->setArtifact(artifact); QSignalSpy spy(model, signal.constData()); // WHEN model->setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); QCOMPARE(model->property(propertyName), propertyValue); QVERIFY(artifact->property(propertyName) != propertyValue); QVERIFY(!savedArtifact); // WHEN (apply immediately) delete model; // THEN QCOMPARE(savedArtifact, artifact); QCOMPARE(artifact->property(propertyName), propertyValue); } void shouldLaunchDelegation() { // GIVEN auto task = Domain::Task::Ptr::create(); - auto expectedDelegate = Domain::Task::Delegate("John Doe", "john@doe.com"); + auto expectedDelegate = Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com")); auto delegatedTask = Domain::Task::Ptr(); auto delegate = Domain::Task::Delegate(); auto delegateFunction = [this, &delegatedTask, &delegate] (const Domain::Task::Ptr &task, const Domain::Task::Delegate &d) { delegatedTask = task; delegate = d; return new FakeJob(this); }; Presentation::ArtifactEditorModel model; model.setDelegateFunction(delegateFunction); QVERIFY(model.hasDelegateFunction()); model.setArtifact(task); // WHEN - model.delegate("John Doe", "john@doe.com"); + model.delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com")); // THEN QCOMPARE(delegatedTask, task); QCOMPARE(delegate, expectedDelegate); QVERIFY(!task->delegate().isValid()); } void shouldGetAnErrorMessageWhenSaveFailed() { // GIVEN auto task = Domain::Task::Ptr::create(); - task->setTitle("Task 1"); + task->setTitle(QStringLiteral("Task 1")); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); return job; }; auto model = new Presentation::ArtifactEditorModel; model->setSaveFunction(save); QVERIFY(model->hasSaveFunction()); FakeErrorHandler errorHandler; model->setErrorHandler(&errorHandler); model->setArtifact(task); // WHEN model->setProperty("title", "Foo"); delete model; // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify task Task 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task Task 1: Foo")); } }; ZANSHIN_TEST_MAIN(ArtifactEditorModelTest) #include "artifacteditormodeltest.moc" diff --git a/tests/units/presentation/artifactfilterproxymodeltest.cpp b/tests/units/presentation/artifactfilterproxymodeltest.cpp index eadde4db..f0ab94b4 100644 --- a/tests/units/presentation/artifactfilterproxymodeltest.cpp +++ b/tests/units/presentation/artifactfilterproxymodeltest.cpp @@ -1,255 +1,255 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "domain/note.h" #include "domain/task.h" #include "presentation/artifactfilterproxymodel.h" #include "presentation/querytreemodelbase.h" Q_DECLARE_METATYPE(QList) class ArtifactFilterProxyModelTest : public QObject { Q_OBJECT private: QStandardItem *createTaskItem(const QString &title, const QString &text, const QDate &start = QDate(), const QDate &due = QDate()) const { auto task = Domain::Task::Ptr::create(); task->setTitle(title); task->setText(text); task->setStartDate(QDateTime(start)); task->setDueDate(QDateTime(due)); auto item = new QStandardItem; item->setData(task->title(), Qt::DisplayRole); item->setData(QVariant::fromValue(Domain::Artifact::Ptr(task)), Presentation::QueryTreeModelBase::ObjectRole); return item; } QStandardItem *createNoteItem(const QString &title, const QString &text) const { auto note = Domain::Note::Ptr::create(); note->setTitle(title); note->setText(text); auto item = new QStandardItem; item->setData(note->title(), Qt::DisplayRole); item->setData(QVariant::fromValue(Domain::Artifact::Ptr(note)), Presentation::QueryTreeModelBase::ObjectRole); return item; } private slots: void shouldHaveDefaultState() { Presentation::ArtifactFilterProxyModel proxy; QVERIFY(!proxy.sourceModel()); QCOMPARE(proxy.sortColumn(), 0); QCOMPARE(proxy.sortOrder(), Qt::AscendingOrder); QCOMPARE(proxy.sortType(), Presentation::ArtifactFilterProxyModel::TitleSort); QCOMPARE(proxy.sortCaseSensitivity(), Qt::CaseInsensitive); } void shouldFilterByTextAndTitle() { // GIVEN QStandardItemModel input; - input.appendRow(createTaskItem("1. foo", "find me")); - input.appendRow(createTaskItem("2. Find Me", "bar")); - input.appendRow(createTaskItem("3. baz", "baz")); - input.appendRow(createNoteItem("4. foo", "find me")); - input.appendRow(createNoteItem("5. find me", "bar")); - input.appendRow(createNoteItem("6. baz", "baz")); + input.appendRow(createTaskItem(QStringLiteral("1. foo"), QStringLiteral("find me"))); + input.appendRow(createTaskItem(QStringLiteral("2. Find Me"), QStringLiteral("bar"))); + input.appendRow(createTaskItem(QStringLiteral("3. baz"), QStringLiteral("baz"))); + input.appendRow(createNoteItem(QStringLiteral("4. foo"), QStringLiteral("find me"))); + input.appendRow(createNoteItem(QStringLiteral("5. find me"), QStringLiteral("bar"))); + input.appendRow(createNoteItem(QStringLiteral("6. baz"), QStringLiteral("baz"))); Presentation::ArtifactFilterProxyModel output; output.setSourceModel(&input); // WHEN - output.setFilterFixedString("find me"); + output.setFilterFixedString(QStringLiteral("find me")); // THEN QCOMPARE(output.rowCount(), 4); - QCOMPARE(output.index(0, 0).data().toString(), QString("1. foo")); - QCOMPARE(output.index(1, 0).data().toString(), QString("2. Find Me")); - QCOMPARE(output.index(2, 0).data().toString(), QString("4. foo")); - QCOMPARE(output.index(3, 0).data().toString(), QString("5. find me")); + QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. foo")); + QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. Find Me")); + QCOMPARE(output.index(2, 0).data().toString(), QStringLiteral("4. foo")); + QCOMPARE(output.index(3, 0).data().toString(), QStringLiteral("5. find me")); } void shouldKeepRowIfItHasAcceptableChildren() { // GIVEN QStandardItemModel input; - input.appendRow(createTaskItem("1. foo", "find me")); - QStandardItem *item = createTaskItem("2. baz", "baz"); - item->appendRow(createTaskItem("21. bar", "bar")); - item->appendRow(createNoteItem("22. foo", "Find Me")); - item->appendRow(createTaskItem("23. find me", "foo")); + input.appendRow(createTaskItem(QStringLiteral("1. foo"), QStringLiteral("find me"))); + QStandardItem *item = createTaskItem(QStringLiteral("2. baz"), QStringLiteral("baz")); + item->appendRow(createTaskItem(QStringLiteral("21. bar"), QStringLiteral("bar"))); + item->appendRow(createNoteItem(QStringLiteral("22. foo"), QStringLiteral("Find Me"))); + item->appendRow(createTaskItem(QStringLiteral("23. find me"), QStringLiteral("foo"))); input.appendRow(item); - input.appendRow(createTaskItem("3. baz", "baz")); + input.appendRow(createTaskItem(QStringLiteral("3. baz"), QStringLiteral("baz"))); Presentation::ArtifactFilterProxyModel output; output.setSourceModel(&input); // WHEN - output.setFilterFixedString("find me"); + output.setFilterFixedString(QStringLiteral("find me")); // THEN QCOMPARE(output.rowCount(), 2); - QCOMPARE(output.index(0, 0).data().toString(), QString("1. foo")); - QCOMPARE(output.index(1, 0).data().toString(), QString("2. baz")); + QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. foo")); + QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. baz")); const QModelIndex parent = output.index(1, 0); QCOMPARE(output.rowCount(parent), 2); - QCOMPARE(output.index(0, 0, parent).data().toString(), QString("22. foo")); - QCOMPARE(output.index(1, 0, parent).data().toString(), QString("23. find me")); + QCOMPARE(output.index(0, 0, parent).data().toString(), QStringLiteral("22. foo")); + QCOMPARE(output.index(1, 0, parent).data().toString(), QStringLiteral("23. find me")); } void shouldSortFollowingType_data() { QTest::addColumn("sortType"); QTest::addColumn("sortOrder"); QTest::addColumn>("inputItems"); QTest::addColumn("expectedOutputTitles"); QList inputItems; QStringList expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("B", "foo") << createNoteItem("A", "foo") << createTaskItem("C", "foo"); - expectedOutputTitles << "A" << "B" << "C"; + inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo")) << createNoteItem(QStringLiteral("A"), QStringLiteral("foo")) << createTaskItem(QStringLiteral("C"), QStringLiteral("foo")); + expectedOutputTitles << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C"); QTest::newRow("title ascending") << int(Presentation::ArtifactFilterProxyModel::TitleSort) << int(Qt::AscendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("B", "foo") << createNoteItem("A", "foo") << createTaskItem("C", "foo"); - expectedOutputTitles << "C" << "B" << "A"; + inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo")) << createNoteItem(QStringLiteral("A"), QStringLiteral("foo")) << createTaskItem(QStringLiteral("C"), QStringLiteral("foo")); + expectedOutputTitles << QStringLiteral("C") << QStringLiteral("B") << QStringLiteral("A"); QTest::newRow("title descending") << int(Presentation::ArtifactFilterProxyModel::TitleSort) << int(Qt::DescendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("B", "foo", QDate(2014, 03, 10)) - << createNoteItem("A", "foo") - << createTaskItem("C", "foo", QDate(2014, 03, 01)) - << createTaskItem("D", "foo"); - expectedOutputTitles << "C" << "B" << "D" << "A"; + inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 10)) + << createNoteItem(QStringLiteral("A"), QStringLiteral("foo")) + << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(2014, 03, 01)) + << createTaskItem(QStringLiteral("D"), QStringLiteral("foo")); + expectedOutputTitles << QStringLiteral("C") << QStringLiteral("B") << QStringLiteral("D") << QStringLiteral("A"); QTest::newRow("start date ascending") << int(Presentation::ArtifactFilterProxyModel::DateSort) << int(Qt::AscendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("B", "foo", QDate(2014, 03, 10)) - << createNoteItem("A", "foo") - << createTaskItem("C", "foo", QDate(2014, 03, 01)) - << createTaskItem("D", "foo"); - expectedOutputTitles << "A" << "D" << "B" << "C"; + inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 10)) + << createNoteItem(QStringLiteral("A"), QStringLiteral("foo")) + << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(2014, 03, 01)) + << createTaskItem(QStringLiteral("D"), QStringLiteral("foo")); + expectedOutputTitles << QStringLiteral("A") << QStringLiteral("D") << QStringLiteral("B") << QStringLiteral("C"); QTest::newRow("start date descending") << int(Presentation::ArtifactFilterProxyModel::DateSort) << int(Qt::DescendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("B", "foo", QDate(), QDate(2014, 03, 10)) - << createNoteItem("A", "foo") - << createTaskItem("C", "foo", QDate(), QDate(2014, 03, 01)) - << createTaskItem("D", "foo"); - expectedOutputTitles << "C" << "B" << "D" << "A"; + inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 10)) + << createNoteItem(QStringLiteral("A"), QStringLiteral("foo")) + << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 01)) + << createTaskItem(QStringLiteral("D"), QStringLiteral("foo")); + expectedOutputTitles << QStringLiteral("C") << QStringLiteral("B") << QStringLiteral("D") << QStringLiteral("A"); QTest::newRow("due date ascending") << int(Presentation::ArtifactFilterProxyModel::DateSort) << int(Qt::AscendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("B", "foo", QDate(), QDate(2014, 03, 10)) - << createNoteItem("A", "foo") - << createTaskItem("C", "foo", QDate(), QDate(2014, 03, 01)) - << createTaskItem("D", "foo"); - expectedOutputTitles << "A" << "D" << "B" << "C"; + inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 10)) + << createNoteItem(QStringLiteral("A"), QStringLiteral("foo")) + << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 01)) + << createTaskItem(QStringLiteral("D"), QStringLiteral("foo")); + expectedOutputTitles << QStringLiteral("A") << QStringLiteral("D") << QStringLiteral("B") << QStringLiteral("C"); QTest::newRow("due date descending") << int(Presentation::ArtifactFilterProxyModel::DateSort) << int(Qt::DescendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("A", "foo", QDate(2014, 03, 01), QDate(2014, 03, 10)) - << createTaskItem("B", "foo", QDate(2014, 03, 10), QDate(2014, 03, 01)); - expectedOutputTitles << "B" << "A"; + inputItems << createTaskItem(QStringLiteral("A"), QStringLiteral("foo"), QDate(2014, 03, 01), QDate(2014, 03, 10)) + << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 10), QDate(2014, 03, 01)); + expectedOutputTitles << QStringLiteral("B") << QStringLiteral("A"); QTest::newRow("due date over start date") << int(Presentation::ArtifactFilterProxyModel::DateSort) << int(Qt::AscendingOrder) << inputItems << expectedOutputTitles; inputItems.clear(); expectedOutputTitles.clear(); - inputItems << createTaskItem("A", "foo", QDate(), QDate(2014, 03, 10)) - << createTaskItem("B", "foo", QDate(2014, 03, 01), QDate()); - expectedOutputTitles << "B" << "A"; + inputItems << createTaskItem(QStringLiteral("A"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 10)) + << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 01), QDate()); + expectedOutputTitles << QStringLiteral("B") << QStringLiteral("A"); QTest::newRow("due date over start date") << int(Presentation::ArtifactFilterProxyModel::DateSort) << int(Qt::AscendingOrder) << inputItems << expectedOutputTitles; } void shouldSortFollowingType() { // GIVEN QFETCH(int, sortType); QFETCH(int, sortOrder); QFETCH(QList, inputItems); QFETCH(QStringList, expectedOutputTitles); QStandardItemModel input; foreach (QStandardItem *item, inputItems) { input.appendRow(item); } // WHEN Presentation::ArtifactFilterProxyModel output; output.setSourceModel(&input); output.setSortType(Presentation::ArtifactFilterProxyModel::SortType(sortType)); output.setSortOrder(Qt::SortOrder(sortOrder)); QStringList outputTitles; for (int row = 0; row < output.rowCount(); row++) { outputTitles << output.index(row, 0).data().toString(); } // THEN QCOMPARE(outputTitles, expectedOutputTitles); } }; ZANSHIN_TEST_MAIN(ArtifactFilterProxyModelTest) #include "artifactfilterproxymodeltest.moc" diff --git a/tests/units/presentation/availablenotepagesmodeltest.cpp b/tests/units/presentation/availablenotepagesmodeltest.cpp index 2228b11f..341bb262 100644 --- a/tests/units/presentation/availablenotepagesmodeltest.cpp +++ b/tests/units/presentation/availablenotepagesmodeltest.cpp @@ -1,464 +1,464 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "presentation/availablenotepagesmodel.h" #include "presentation/errorhandler.h" #include "presentation/noteinboxpagemodel.h" #include "presentation/querytreemodelbase.h" #include "presentation/tagpagemodel.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class AvailableNotePagesModelTest : public QObject { Q_OBJECT private slots: void shouldDeclareOnlyProjectAndContextPages() { // GIVEN Presentation::AvailableNotePagesModel pages({}, {}, {}, {}); // THEN QVERIFY(!pages.hasProjectPages()); QVERIFY(!pages.hasContextPages()); QVERIFY(pages.hasTagPages()); } void shouldListAvailablePages() { // GIVEN // Two tags auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("Tag 1"); + tag1->setName(QStringLiteral("Tag 1")); auto tag2 = Domain::Tag::Ptr::create(); - tag2->setName("Tag 2"); + tag2->setName(QStringLiteral("Tag 2")); auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); tagProvider->append(tag1); tagProvider->append(tag2); // One note (used for dropping later on) auto noteToDrop = Domain::Note::Ptr::create(); Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Utils::MockObject tagRepositoryMock; Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), tagRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex inboxIndex = model->index(0, 0); const QModelIndex tagsIndex = model->index(1, 0); const QModelIndex tag1Index = model->index(0, 0, tagsIndex); const QModelIndex tag2Index = model->index(1, 0, tagsIndex); QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(inboxIndex), 0); QCOMPARE(model->rowCount(tagsIndex), 2); QCOMPARE(model->rowCount(tag1Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; QCOMPARE(model->flags(inboxIndex), (defaultFlags & ~(Qt::ItemIsEditable)) | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(tagsIndex), Qt::NoItemFlags); QCOMPARE(model->flags(tag1Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(tag2Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->data(inboxIndex).toString(), tr("Inbox")); QCOMPARE(model->data(tagsIndex).toString(), tr("Tags")); QCOMPARE(model->data(tag1Index).toString(), tag1->name()); QCOMPARE(model->data(tag2Index).toString(), tag2->name()); QVERIFY(!model->data(inboxIndex, Qt::EditRole).isValid()); QVERIFY(!model->data(tagsIndex, Qt::EditRole).isValid()); QCOMPARE(model->data(tag1Index, Qt::EditRole).toString(), tag1->name()); QCOMPARE(model->data(tag2Index, Qt::EditRole).toString(), tag2->name()); - QCOMPARE(model->data(inboxIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("mail-folder-inbox")); - QCOMPARE(model->data(tagsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(tag1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("view-pim-tasks")); - QCOMPARE(model->data(tag2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("view-pim-tasks")); + QCOMPARE(model->data(inboxIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("mail-folder-inbox")); + QCOMPARE(model->data(tagsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(tag1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); + QCOMPARE(model->data(tag2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); QVERIFY(!model->data(inboxIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(tagsIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(tag1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(tag2Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->setData(inboxIndex, "foo", Qt::EditRole)); QVERIFY(!model->setData(tagsIndex, "foo", Qt::EditRole)); QVERIFY(!model->setData(tag1Index, "foo", Qt::EditRole)); QVERIFY(!model->setData(tag2Index, "foo", Qt::EditRole)); // WHEN tagRepositoryMock(&Domain::TagRepository::associate).when(tag1, noteToDrop).thenReturn(new FakeJob(this)); QMimeData *data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << noteToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, tag1Index); // THEN QVERIFY(tagRepositoryMock(&Domain::TagRepository::associate).when(tag1, noteToDrop).exactly(1)); // WHEN tagRepositoryMock(&Domain::TagRepository::dissociateAll).when(noteToDrop).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << noteToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, inboxIndex); QTest::qWait(150); // THEN QVERIFY(tagRepositoryMock(&Domain::TagRepository::dissociateAll).when(noteToDrop).exactly(1)); } void shouldCreateInboxPage() { // GIVEN // Empty tag provider auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), Domain::TagRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex inboxIndex = model->index(0, 0); QObject *inboxPage = pages.createPageForIndex(inboxIndex); QVERIFY(qobject_cast(inboxPage)); } void shouldCreateTagsPage() { // GIVEN // Two tags auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("tag 1"); + tag1->setName(QStringLiteral("tag 1")); auto tag2 = Domain::Tag::Ptr::create(); - tag2->setName("tag 2"); + tag2->setName(QStringLiteral("tag 2")); auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); tagProvider->append(tag1); tagProvider->append(tag2); // tags mocking Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), Domain::TagRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex tagsIndex = model->index(1, 0); const QModelIndex tag1Index = model->index(0, 0, tagsIndex); const QModelIndex tag2Index = model->index(1, 0, tagsIndex); QObject *tagsPage = pages.createPageForIndex(tagsIndex); QObject *tag1Page = pages.createPageForIndex(tag1Index); QObject *tag2Page = pages.createPageForIndex(tag2Index); QVERIFY(!tagsPage); QVERIFY(qobject_cast(tag1Page)); QCOMPARE(qobject_cast(tag1Page)->tag(), tag1); QVERIFY(qobject_cast(tag2Page)); QCOMPARE(qobject_cast(tag2Page)->tag(), tag2); } void shouldAddTags() { // GIVEN Utils::MockObject tagRepositoryMock; tagRepositoryMock(&Domain::TagRepository::create).when(any()) .thenReturn(new FakeJob(this)); Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), Domain::TagQueries::Ptr(), tagRepositoryMock.getInstance()); // WHEN - pages.addTag("Foo"); + pages.addTag(QStringLiteral("Foo")); // THEN QVERIFY(tagRepositoryMock(&Domain::TagRepository::create).when(any()) .exactly(1)); } void shouldGetAnErrorMessageWhenAddTagFailed() { // GIVEN Utils::MockObject tagRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); tagRepositoryMock(&Domain::TagRepository::create).when(any()) .thenReturn(job); Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), Domain::TagQueries::Ptr(), tagRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); // WHEN - pages.addTag("Foo"); + pages.addTag(QStringLiteral("Foo")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add tag Foo: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add tag Foo: Foo")); } void shouldRemoveTag() { // GIVEN // Two tags auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("tag 1"); + tag1->setName(QStringLiteral("tag 1")); auto tag2 = Domain::Tag::Ptr::create(); - tag2->setName("tag 2"); + tag2->setName(QStringLiteral("tag 2")); auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); tagProvider->append(tag1); tagProvider->append(tag2); // tags mocking Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Utils::MockObject tagRepositoryMock; Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), tagRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex tagsIndex = model->index(1, 0); const QModelIndex tag1Index = model->index(0, 0, tagsIndex); auto job = new FakeJob(this); tagRepositoryMock(&Domain::TagRepository::remove).when(tag1).thenReturn(job); // WHEN pages.removeItem(tag1Index); // THEN QTest::qWait(150); QVERIFY(errorHandler.m_message.isEmpty()); QVERIFY(tagRepositoryMock(&Domain::TagRepository::remove).when(tag1).exactly(1)); } void shouldGetAnErrorMessageWhenRemoveTagFailed() { // GIVEN // Two tags auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("tag 1"); + tag1->setName(QStringLiteral("tag 1")); auto tag2 = Domain::Tag::Ptr::create(); - tag2->setName("tag 2"); + tag2->setName(QStringLiteral("tag 2")); auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); tagProvider->append(tag1); tagProvider->append(tag2); // tags mocking Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Utils::MockObject tagRepositoryMock; Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), tagRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex tagsIndex = model->index(1, 0); const QModelIndex tag1Index = model->index(0, 0, tagsIndex); auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); tagRepositoryMock(&Domain::TagRepository::remove).when(tag1).thenReturn(job); // WHEN pages.removeItem(tag1Index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove tag tag 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove tag tag 1: Foo")); } void shouldGetAnErrorMessageWhenAssociateTagFailed() { // GIVEN // Two tags auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("Tag 1"); + tag1->setName(QStringLiteral("Tag 1")); auto tag2 = Domain::Tag::Ptr::create(); - tag2->setName("Tag 2"); + tag2->setName(QStringLiteral("Tag 2")); auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); tagProvider->append(tag1); tagProvider->append(tag2); // One note (used for dropping later on) auto noteToDrop = Domain::Note::Ptr::create(); - noteToDrop->setTitle("noteDropped"); + noteToDrop->setTitle(QStringLiteral("noteDropped")); // tags mocking Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Utils::MockObject tagRepositoryMock; Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), tagRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex tagsIndex = model->index(1, 0); const QModelIndex tag1Index = model->index(0, 0, tagsIndex); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); tagRepositoryMock(&Domain::TagRepository::associate).when(tag1, noteToDrop).thenReturn(job); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << noteToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, tag1Index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot tag noteDropped with Tag 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot tag noteDropped with Tag 1: Foo")); } void shouldGetAnErrorMessageWhenDissociateTaskFailed() { // GIVEN // Two tags auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("tag 1"); + tag1->setName(QStringLiteral("tag 1")); auto tag2 = Domain::Tag::Ptr::create(); - tag2->setName("tag 2"); + tag2->setName(QStringLiteral("tag 2")); auto tagProvider = Domain::QueryResultProvider::Ptr::create(); auto tagResult = Domain::QueryResult::create(tagProvider); tagProvider->append(tag1); tagProvider->append(tag2); // One note (used for dropping later on) auto noteToDrop = Domain::Note::Ptr::create(); - noteToDrop->setTitle("noteDropped"); + noteToDrop->setTitle(QStringLiteral("noteDropped")); // tags mocking Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findAll).when().thenReturn(tagResult); Utils::MockObject tagRepositoryMock; Presentation::AvailableNotePagesModel pages(Domain::NoteQueries::Ptr(), Domain::NoteRepository::Ptr(), tagQueriesMock.getInstance(), tagRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex inboxIndex = model->index(0, 0); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); tagRepositoryMock(&Domain::TagRepository::dissociateAll).when(noteToDrop).thenReturn(job); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << noteToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, inboxIndex); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot move noteDropped to Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move noteDropped to Inbox: Foo")); } }; ZANSHIN_TEST_MAIN(AvailableNotePagesModelTest) #include "availablenotepagesmodeltest.moc" diff --git a/tests/units/presentation/availablepagessortfilterproxymodeltest.cpp b/tests/units/presentation/availablepagessortfilterproxymodeltest.cpp index 3536bac4..7f1b94da 100644 --- a/tests/units/presentation/availablepagessortfilterproxymodeltest.cpp +++ b/tests/units/presentation/availablepagessortfilterproxymodeltest.cpp @@ -1,110 +1,110 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2015 David Faure 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "utils/mockobject.h" #include "domain/contextqueries.h" #include "domain/contextrepository.h" #include "domain/projectqueries.h" #include "domain/projectrepository.h" #include "domain/note.h" #include "domain/tag.h" #include "domain/tagqueries.h" #include "domain/tagrepository.h" #include "domain/task.h" #include "domain/taskrepository.h" #include "presentation/availablepagessortfilterproxymodel.h" #include "presentation/availabletaskpagesmodel.h" #include "presentation/contextpagemodel.h" #include "presentation/projectpagemodel.h" #include "presentation/querytreemodelbase.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; static QString extractChildRowsTexts( QAbstractItemModel *model, int row, const QModelIndex &parent = QModelIndex() ) { QString result; const QModelIndex index = model->index(row, 0, parent); const int children = model->rowCount(index); for (int row = 0; row < children; ++row) { const QString txt = model->index(row, 0, index).data().toString(); - result += txt.isEmpty() ? QString(" ") : txt; + result += txt.isEmpty() ? QStringLiteral(" ") : txt; if ( row + 1 < children ) result += ';'; } return result; } class AvailablePagesSortFilterProxyModelTest : public QObject { Q_OBJECT private slots: void shouldSortSecondLevel() { // GIVEN a tree model as source QStandardItemModel sourceModel; - sourceModel.appendRow(new QStandardItem("Projects")); - sourceModel.item(0, 0)->appendRow(new QStandardItem("D")); - sourceModel.item(0, 0)->appendRow(new QStandardItem("A")); - sourceModel.item(0, 0)->appendRow(new QStandardItem("F")); - sourceModel.appendRow(new QStandardItem("Contexts")); - sourceModel.item(1, 0)->appendRow(new QStandardItem("K")); - sourceModel.item(1, 0)->appendRow(new QStandardItem("D")); - sourceModel.item(1, 0)->appendRow(new QStandardItem("E")); - sourceModel.appendRow(new QStandardItem("Tags")); - - QCOMPARE(sourceModel.index(0, 0).data().toString(), QString("Projects")); - QCOMPARE(extractChildRowsTexts(&sourceModel, 0), QString("D;A;F")); - QCOMPARE(sourceModel.index(1, 0).data().toString(), QString("Contexts")); - QCOMPARE(extractChildRowsTexts(&sourceModel, 1), QString("K;D;E")); - QCOMPARE(sourceModel.index(2, 0).data().toString(), QString("Tags")); + sourceModel.appendRow(new QStandardItem(QStringLiteral("Projects"))); + sourceModel.item(0, 0)->appendRow(new QStandardItem(QStringLiteral("D"))); + sourceModel.item(0, 0)->appendRow(new QStandardItem(QStringLiteral("A"))); + sourceModel.item(0, 0)->appendRow(new QStandardItem(QStringLiteral("F"))); + sourceModel.appendRow(new QStandardItem(QStringLiteral("Contexts"))); + sourceModel.item(1, 0)->appendRow(new QStandardItem(QStringLiteral("K"))); + sourceModel.item(1, 0)->appendRow(new QStandardItem(QStringLiteral("D"))); + sourceModel.item(1, 0)->appendRow(new QStandardItem(QStringLiteral("E"))); + sourceModel.appendRow(new QStandardItem(QStringLiteral("Tags"))); + + QCOMPARE(sourceModel.index(0, 0).data().toString(), QStringLiteral("Projects")); + QCOMPARE(extractChildRowsTexts(&sourceModel, 0), QStringLiteral("D;A;F")); + QCOMPARE(sourceModel.index(1, 0).data().toString(), QStringLiteral("Contexts")); + QCOMPARE(extractChildRowsTexts(&sourceModel, 1), QStringLiteral("K;D;E")); + QCOMPARE(sourceModel.index(2, 0).data().toString(), QStringLiteral("Tags")); // WHEN putting an AvailablePagesSortFilterProxyModel on top Presentation::AvailablePagesSortFilterProxyModel proxy; proxy.setSourceModel(&sourceModel); // THEN the projects and contexts should be sorted (but not the toplevel items) - QCOMPARE(proxy.index(0, 0).data().toString(), QString("Projects")); - QCOMPARE(extractChildRowsTexts(&proxy, 0), QString("A;D;F")); - QCOMPARE(proxy.index(1, 0).data().toString(), QString("Contexts")); - QCOMPARE(extractChildRowsTexts(&proxy, 1), QString("D;E;K")); - QCOMPARE(proxy.index(2, 0).data().toString(), QString("Tags")); + QCOMPARE(proxy.index(0, 0).data().toString(), QStringLiteral("Projects")); + QCOMPARE(extractChildRowsTexts(&proxy, 0), QStringLiteral("A;D;F")); + QCOMPARE(proxy.index(1, 0).data().toString(), QStringLiteral("Contexts")); + QCOMPARE(extractChildRowsTexts(&proxy, 1), QStringLiteral("D;E;K")); + QCOMPARE(proxy.index(2, 0).data().toString(), QStringLiteral("Tags")); } private: }; ZANSHIN_TEST_MAIN(AvailablePagesSortFilterProxyModelTest) #include "availablepagessortfilterproxymodeltest.moc" diff --git a/tests/units/presentation/availablesourcesmodeltest.cpp b/tests/units/presentation/availablesourcesmodeltest.cpp index 8b61efd5..fcfc6ad5 100644 --- a/tests/units/presentation/availablesourcesmodeltest.cpp +++ b/tests/units/presentation/availablesourcesmodeltest.cpp @@ -1,586 +1,586 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #define ZANSHIN_I_SWEAR_I_AM_IN_A_PRESENTATION_TEST #include "domain/datasourcequeries.h" #include "domain/datasourcerepository.h" #include "presentation/availablesourcesmodel.h" #include "presentation/querytreemodelbase.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" Q_DECLARE_METATYPE(QModelIndex); using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class AvailableSourcesModelTest : public QObject { Q_OBJECT public: explicit AvailableSourcesModelTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } private slots: void shouldListAvailableSources() { // GIVEN // Two top level sources auto source1 = Domain::DataSource::Ptr::create(); - source1->setName("Source 1"); - source1->setIconName("foo-icon"); + source1->setName(QStringLiteral("Source 1")); + source1->setIconName(QStringLiteral("foo-icon")); source1->setSelected(true); auto source2 = Domain::DataSource::Ptr::create(); - source2->setName("Source 2"); + source2->setName(QStringLiteral("Source 2")); source2->setSelected(false); source2->setContentTypes(Domain::DataSource::Tasks); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(source1); topLevelProvider->append(source2); // Two other sources under source1 auto source3 = Domain::DataSource::Ptr::create(); - source3->setName("Source 3"); + source3->setName(QStringLiteral("Source 3")); source3->setSelected(false); source3->setContentTypes(Domain::DataSource::Notes); auto source4 = Domain::DataSource::Ptr::create(); source4->setSelected(true); - source4->setName("Source 4"); + source4->setName(QStringLiteral("Source 4")); source4->setContentTypes(Domain::DataSource::Notes | Domain::DataSource::Tasks); auto source1Provider = Domain::QueryResultProvider::Ptr::create(); auto source1Result = Domain::QueryResult::create(source1Provider); source1Provider->append(source3); source1Provider->append(source4); // Nothing under source2, source3 or source4 auto source2Provider = Domain::QueryResultProvider::Ptr::create(); auto source2Result = Domain::QueryResult::create(source2Provider); auto source3Provider = Domain::QueryResultProvider::Ptr::create(); auto source3Result = Domain::QueryResult::create(source3Provider); auto source4Provider = Domain::QueryResultProvider::Ptr::create(); auto source4Result = Domain::QueryResult::create(source4Provider); Utils::MockObject sourceQueriesMock; sourceQueriesMock(&Domain::DataSourceQueries::findTopLevel).when().thenReturn(topLevelResult); sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source1).thenReturn(source1Result); sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source2).thenReturn(source2Result); sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source3).thenReturn(source3Result); sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source4).thenReturn(source4Result); // We'll simulate a default source change later on sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source1).thenReturn(false); sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source2).thenReturn(true) .thenReturn(false); sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source3).thenReturn(false); sourceQueriesMock(&Domain::DataSourceQueries::isDefaultSource).when(source4).thenReturn(false) .thenReturn(false) .thenReturn(true); Utils::MockObject sourceRepositoryMock; Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance(), Q_NULLPTR); // WHEN QAbstractItemModel *model = sources.sourceListModel(); // THEN const QModelIndex source1Index = model->index(0, 0); const QModelIndex source2Index = model->index(1, 0); const QModelIndex source3Index = model->index(0, 0, source1Index); const QModelIndex source4Index = model->index(1, 0, source1Index); QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(source1Index), 2); QCOMPARE(model->rowCount(source2Index), 0); QCOMPARE(model->rowCount(source3Index), 0); QCOMPARE(model->rowCount(source4Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; QCOMPARE(model->flags(source1Index), defaultFlags); QCOMPARE(model->flags(source2Index), defaultFlags | Qt::ItemIsUserCheckable); QCOMPARE(model->flags(source3Index), defaultFlags | Qt::ItemIsUserCheckable); QCOMPARE(model->flags(source4Index), defaultFlags | Qt::ItemIsUserCheckable); QCOMPARE(model->data(source1Index).toString(), source1->name()); QCOMPARE(model->data(source2Index).toString(), source2->name()); QCOMPARE(model->data(source3Index).toString(), source3->name()); QCOMPARE(model->data(source4Index).toString(), source4->name()); QCOMPARE(model->data(source1Index, Qt::EditRole).toString(), source1->name()); QCOMPARE(model->data(source2Index, Qt::EditRole).toString(), source2->name()); QCOMPARE(model->data(source3Index, Qt::EditRole).toString(), source3->name()); QCOMPARE(model->data(source4Index, Qt::EditRole).toString(), source4->name()); QVERIFY(!model->data(source1Index, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(source2Index, Qt::CheckStateRole).toBool(), source2->isSelected()); QCOMPARE(model->data(source3Index, Qt::CheckStateRole).toBool(), source3->isSelected()); QCOMPARE(model->data(source4Index, Qt::CheckStateRole).toBool(), source4->isSelected()); QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), source1->iconName()); - QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); + QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), true); QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); // WHEN sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source2).thenReturn(new FakeJob(this)); sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source4).thenReturn(new FakeJob(this)); QVERIFY(!model->setData(source1Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(source2Index, Qt::Checked, Qt::CheckStateRole)); QVERIFY(model->setData(source4Index, Qt::Unchecked, Qt::CheckStateRole)); // THEN QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source2).exactly(1)); QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source4).exactly(1)); QVERIFY(source2->isSelected()); QVERIFY(!source4->isSelected()); // WHEN QSignalSpy spy(model, &QAbstractItemModel::dataChanged); sourceQueriesMock(&Domain::DataSourceQueries::changeDefaultSource).when(source4).thenReturn(); sources.setDefaultItem(source4Index); // THEN QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), false); QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IsDefaultRole).toBool(), true); // Not overly efficient way of signaling the change, but doesn't happen often QCOMPARE(spy.count(), 4); QCOMPARE(spy.at(0).at(0).value(), source1Index); QCOMPARE(spy.at(0).at(1).value(), source1Index); QCOMPARE(spy.at(1).at(0).value(), source3Index); QCOMPARE(spy.at(1).at(1).value(), source3Index); QCOMPARE(spy.at(2).at(0).value(), source4Index); QCOMPARE(spy.at(2).at(1).value(), source4Index); QCOMPARE(spy.at(3).at(0).value(), source2Index); QCOMPARE(spy.at(3).at(1).value(), source2Index); QVERIFY(sourceQueriesMock(&Domain::DataSourceQueries::changeDefaultSource).when(source4).exactly(1)); } void shouldListAvailableSearchSources() { // GIVEN // Two top level sources auto source1 = Domain::DataSource::Ptr::create(); - source1->setName("Source 1"); - source1->setIconName("foo-icon"); + source1->setName(QStringLiteral("Source 1")); + source1->setIconName(QStringLiteral("foo-icon")); source1->setSelected(true); auto source2 = Domain::DataSource::Ptr::create(); - source2->setName("Source 2"); + source2->setName(QStringLiteral("Source 2")); source2->setSelected(false); source2->setContentTypes(Domain::DataSource::Tasks); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(source1); topLevelProvider->append(source2); // Two other sources under source1 auto source3 = Domain::DataSource::Ptr::create(); - source3->setName("Source 3"); + source3->setName(QStringLiteral("Source 3")); source3->setSelected(false); source3->setContentTypes(Domain::DataSource::Notes); auto source4 = Domain::DataSource::Ptr::create(); source4->setSelected(true); - source4->setName("Source 4"); + source4->setName(QStringLiteral("Source 4")); source4->setContentTypes(Domain::DataSource::Notes | Domain::DataSource::Tasks); auto source1Provider = Domain::QueryResultProvider::Ptr::create(); auto source1Result = Domain::QueryResult::create(source1Provider); source1Provider->append(source3); source1Provider->append(source4); // Nothing under source2, source3 or source4 auto source2Provider = Domain::QueryResultProvider::Ptr::create(); auto source2Result = Domain::QueryResult::create(source2Provider); auto source3Provider = Domain::QueryResultProvider::Ptr::create(); auto source3Result = Domain::QueryResult::create(source3Provider); auto source4Provider = Domain::QueryResultProvider::Ptr::create(); auto source4Result = Domain::QueryResult::create(source4Provider); Utils::MockObject sourceQueriesMock; sourceQueriesMock(&Domain::DataSourceQueries::findSearchTopLevel).when().thenReturn(topLevelResult); sourceQueriesMock(&Domain::DataSourceQueries::findSearchChildren).when(source1).thenReturn(source1Result); sourceQueriesMock(&Domain::DataSourceQueries::findSearchChildren).when(source2).thenReturn(source2Result); sourceQueriesMock(&Domain::DataSourceQueries::findSearchChildren).when(source3).thenReturn(source3Result); sourceQueriesMock(&Domain::DataSourceQueries::findSearchChildren).when(source4).thenReturn(source4Result); Utils::MockObject sourceRepositoryMock; Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance(), Q_NULLPTR); // WHEN QAbstractItemModel *model = sources.searchListModel(); // THEN const QModelIndex source1Index = model->index(0, 0); const QModelIndex source2Index = model->index(1, 0); const QModelIndex source3Index = model->index(0, 0, source1Index); const QModelIndex source4Index = model->index(1, 0, source1Index); QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(source1Index), 2); QCOMPARE(model->rowCount(source2Index), 0); QCOMPARE(model->rowCount(source3Index), 0); QCOMPARE(model->rowCount(source4Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; QCOMPARE(model->flags(source1Index), defaultFlags); QCOMPARE(model->flags(source2Index), defaultFlags); QCOMPARE(model->flags(source3Index), defaultFlags); QCOMPARE(model->flags(source4Index), defaultFlags); QCOMPARE(model->data(source1Index).toString(), source1->name()); QCOMPARE(model->data(source2Index).toString(), source2->name()); QCOMPARE(model->data(source3Index).toString(), source3->name()); QCOMPARE(model->data(source4Index).toString(), source4->name()); QCOMPARE(model->data(source1Index, Qt::EditRole).toString(), source1->name()); QCOMPARE(model->data(source2Index, Qt::EditRole).toString(), source2->name()); QCOMPARE(model->data(source3Index, Qt::EditRole).toString(), source3->name()); QCOMPARE(model->data(source4Index, Qt::EditRole).toString(), source4->name()); QVERIFY(!model->data(source1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(source2Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(source3Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(source4Index, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), source1->iconName()); - QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); + QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(source3Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(source4Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); QVERIFY(!model->setData(source1Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(!model->setData(source2Index, Qt::Checked, Qt::CheckStateRole)); QVERIFY(!model->setData(source4Index, Qt::Unchecked, Qt::CheckStateRole)); } void shouldChangeSourceToListed() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - source->setName("Source"); - source->setIconName("folder"); + source->setName(QStringLiteral("Source")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setSelected(false); source->setListStatus(Domain::DataSource::Unlisted); Utils::MockObject sourceQueriesMock; Utils::MockObject sourceRepositoryMock; sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).thenReturn(new FakeJob(this)); Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance()); // WHEN sources.listSource(source); // THEN QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).exactly(1)); QVERIFY(source->isSelected()); QCOMPARE(source->listStatus(), Domain::DataSource::Listed); } void shouldChangeSourceToUnlisted() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - source->setName("Source"); - source->setIconName("folder"); + source->setName(QStringLiteral("Source")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setSelected(true); source->setListStatus(Domain::DataSource::Bookmarked); Utils::MockObject sourceQueriesMock; Utils::MockObject sourceRepositoryMock; sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).thenReturn(new FakeJob(this)); Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance()); // WHEN sources.unlistSource(source); // THEN QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).exactly(1)); QVERIFY(!source->isSelected()); QCOMPARE(source->listStatus(), Domain::DataSource::Unlisted); } void shouldToggleSourceToBookmarkStatus_data() { QTest::addColumn("wasSelected"); QTest::addColumn("wasBookmarked"); QTest::newRow("unselected, not bookmarked") << false << false; QTest::newRow("selected, not bookmarked") << true << false; QTest::newRow("unselected, bookmarked") << false << true; QTest::newRow("selected, bookmarked") << true << true; } void shouldToggleSourceToBookmarkStatus() { // GIVEN QFETCH(bool, wasSelected); QFETCH(bool, wasBookmarked); auto source = Domain::DataSource::Ptr::create(); - source->setName("Source"); - source->setIconName("folder"); + source->setName(QStringLiteral("Source")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setSelected(wasSelected); if (wasBookmarked) source->setListStatus(Domain::DataSource::Bookmarked); else source->setListStatus(Domain::DataSource::Listed); Utils::MockObject sourceQueriesMock; Utils::MockObject sourceRepositoryMock; sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).thenReturn(new FakeJob(this)); Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance()); // WHEN sources.bookmarkSource(source); // THEN QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).exactly(1)); QCOMPARE(source->isSelected(), wasSelected); if (wasBookmarked) QCOMPARE(source->listStatus(), Domain::DataSource::Listed); else QCOMPARE(source->listStatus(), Domain::DataSource::Bookmarked); } void shouldGetAnErrorMessageWhenListSourceFailed() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - source->setName("Source"); - source->setIconName("folder"); + source->setName(QStringLiteral("Source")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setSelected(false); source->setListStatus(Domain::DataSource::Unlisted); Utils::MockObject sourceQueriesMock; Utils::MockObject sourceRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).thenReturn(job); Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance()); FakeErrorHandler errorHandler; sources.setErrorHandler(&errorHandler); // WHEN sources.listSource(source); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify source Source: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify source Source: Foo")); } void shouldGetAnErrorMessageWhenUnlistSourceFailed() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - source->setName("Source"); - source->setIconName("folder"); + source->setName(QStringLiteral("Source")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setSelected(false); source->setListStatus(Domain::DataSource::Unlisted); Utils::MockObject sourceQueriesMock; Utils::MockObject sourceRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).thenReturn(job); Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance()); FakeErrorHandler errorHandler; sources.setErrorHandler(&errorHandler); // WHEN sources.unlistSource(source); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify source Source: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify source Source: Foo")); } void shouldGetAnErrorMessageWhenBookmarkSourceFailed() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - source->setName("Source"); - source->setIconName("folder"); + source->setName(QStringLiteral("Source")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setSelected(false); source->setListStatus(Domain::DataSource::Unlisted); Utils::MockObject sourceQueriesMock; Utils::MockObject sourceRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source).thenReturn(job); Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance()); FakeErrorHandler errorHandler; sources.setErrorHandler(&errorHandler); // WHEN sources.bookmarkSource(source); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify source Source: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify source Source: Foo")); } void shouldGetAnErrorMessageWhenSetDataSourceFailed() { // GIVEN // Two top level sources auto source1 = Domain::DataSource::Ptr::create(); - source1->setName("Source 1"); - source1->setIconName("foo-icon"); + source1->setName(QStringLiteral("Source 1")); + source1->setIconName(QStringLiteral("foo-icon")); source1->setSelected(false); source1->setContentTypes(Domain::DataSource::Tasks); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(source1); // Nothing under source1 auto source1Provider = Domain::QueryResultProvider::Ptr::create(); auto source1Result = Domain::QueryResult::create(source1Provider); Utils::MockObject sourceQueriesMock; sourceQueriesMock(&Domain::DataSourceQueries::findTopLevel).when().thenReturn(topLevelResult); sourceQueriesMock(&Domain::DataSourceQueries::findChildren).when(source1).thenReturn(source1Result); Utils::MockObject sourceRepositoryMock; Presentation::AvailableSourcesModel sources(sourceQueriesMock.getInstance(), sourceRepositoryMock.getInstance(), Q_NULLPTR); FakeErrorHandler errorHandler; sources.setErrorHandler(&errorHandler); // WHEN QAbstractItemModel *model = sources.sourceListModel(); // THEN const QModelIndex source1Index = model->index(0, 0); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); sourceRepositoryMock(&Domain::DataSourceRepository::update).when(source1).thenReturn(job); QVERIFY(model->setData(source1Index, Qt::Unchecked, Qt::CheckStateRole)); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify source Source 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify source Source 1: Foo")); } void shouldExecBackendSettingsDialog() { // GIVEN Utils::MockObject sourceRepositoryMock; sourceRepositoryMock(&Domain::DataSourceRepository::showConfigDialog).when().thenReturn(); Presentation::AvailableSourcesModel sources(Domain::DataSourceQueries::Ptr(), sourceRepositoryMock.getInstance()); // WHEN sources.showConfigDialog(); // THEN QVERIFY(sourceRepositoryMock(&Domain::DataSourceRepository::showConfigDialog).when().exactly(1)); } }; ZANSHIN_TEST_MAIN(AvailableSourcesModelTest) #include "availablesourcesmodeltest.moc" diff --git a/tests/units/presentation/availabletaskpagesmodeltest.cpp b/tests/units/presentation/availabletaskpagesmodeltest.cpp index fa065485..c41693f3 100644 --- a/tests/units/presentation/availabletaskpagesmodeltest.cpp +++ b/tests/units/presentation/availabletaskpagesmodeltest.cpp @@ -1,1133 +1,1133 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "utils/datetime.h" #include "domain/note.h" #include "presentation/availabletaskpagesmodel.h" #include "presentation/contextpagemodel.h" #include "presentation/errorhandler.h" #include "presentation/projectpagemodel.h" #include "presentation/querytreemodelbase.h" #include "presentation/taskinboxpagemodel.h" #include "presentation/workdaypagemodel.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class AvailableTaskPagesModelTest : public QObject { Q_OBJECT private slots: void shouldDeclareOnlyProjectAndContextPages() { // GIVEN Presentation::AvailableTaskPagesModel pages({}, {}, {}, {}, {}, {}); // THEN QVERIFY(pages.hasProjectPages()); QVERIFY(pages.hasContextPages()); QVERIFY(!pages.hasTagPages()); } void shouldListAvailablePages() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project2); projectProvider->append(project1); // note: reversed order, to test sorting // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); - context2->setName("context 2"); + context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Two artifacts (used for dropping later on) Domain::Artifact::Ptr taskToDrop(new Domain::Task); Domain::Artifact::Ptr noteToDrop(new Domain::Note); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex inboxIndex = model->index(0, 0); const QModelIndex workdayIndex = model->index(1, 0); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex project1Index = model->index(0, 0, projectsIndex); const QModelIndex project2Index = model->index(1, 0, projectsIndex); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); const QModelIndex context2Index = model->index(1, 0, contextsIndex); QCOMPARE(model->rowCount(), 4); QCOMPARE(model->rowCount(inboxIndex), 0); QCOMPARE(model->rowCount(workdayIndex), 0); QCOMPARE(model->rowCount(projectsIndex), 2); QCOMPARE(model->rowCount(project1Index), 0); QCOMPARE(model->rowCount(project2Index), 0); QCOMPARE(model->rowCount(contextsIndex), 2); QCOMPARE(model->rowCount(context1Index), 0); QCOMPARE(model->rowCount(context2Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; QCOMPARE(model->flags(inboxIndex), (defaultFlags & ~(Qt::ItemIsEditable)) | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(workdayIndex), (defaultFlags & ~(Qt::ItemIsEditable)) | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(projectsIndex), Qt::NoItemFlags); QCOMPARE(model->flags(project1Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(project2Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(contextsIndex), Qt::NoItemFlags); QCOMPARE(model->flags(context1Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(context2Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->data(inboxIndex).toString(), tr("Inbox")); QCOMPARE(model->data(workdayIndex).toString(), tr("Workday")); QCOMPARE(model->data(projectsIndex).toString(), tr("Projects")); QCOMPARE(model->data(project1Index).toString(), project1->name()); QCOMPARE(model->data(project2Index).toString(), project2->name()); QCOMPARE(model->data(contextsIndex).toString(), tr("Contexts")); QCOMPARE(model->data(context1Index).toString(), context1->name()); QCOMPARE(model->data(context2Index).toString(), context2->name()); QVERIFY(!model->data(inboxIndex, Qt::EditRole).isValid()); QVERIFY(!model->data(workdayIndex, Qt::EditRole).isValid()); QVERIFY(!model->data(projectsIndex, Qt::EditRole).isValid()); QCOMPARE(model->data(project1Index, Qt::EditRole).toString(), project1->name()); QCOMPARE(model->data(project2Index, Qt::EditRole).toString(), project2->name()); QVERIFY(!model->data(contextsIndex, Qt::EditRole).isValid()); QCOMPARE(model->data(context1Index, Qt::EditRole).toString(), context1->name()); QCOMPARE(model->data(context2Index, Qt::EditRole).toString(), context2->name()); - QCOMPARE(model->data(inboxIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("mail-folder-inbox")); - QCOMPARE(model->data(workdayIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("go-jump-today")); - QCOMPARE(model->data(projectsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(project1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("view-pim-tasks")); - QCOMPARE(model->data(project2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("view-pim-tasks")); - QCOMPARE(model->data(contextsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("folder")); - QCOMPARE(model->data(context1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("view-pim-notes")); - QCOMPARE(model->data(context2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QString("view-pim-notes")); + QCOMPARE(model->data(inboxIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("mail-folder-inbox")); + QCOMPARE(model->data(workdayIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("go-jump-today")); + QCOMPARE(model->data(projectsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(project1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); + QCOMPARE(model->data(project2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); + QCOMPARE(model->data(contextsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); + QCOMPARE(model->data(context1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-notes")); + QCOMPARE(model->data(context2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-notes")); QVERIFY(!model->data(inboxIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(workdayIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(projectsIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(project1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(project2Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(contextsIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(context1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(context2Index, Qt::CheckStateRole).isValid()); // WHEN projectRepositoryMock(&Domain::ProjectRepository::update).when(project1).thenReturn(new FakeJob(this)); projectRepositoryMock(&Domain::ProjectRepository::update).when(project2).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::update).when(context1).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::update).when(context2).thenReturn(new FakeJob(this)); QVERIFY(!model->setData(inboxIndex, "Foo")); QVERIFY(!model->setData(projectsIndex, "Foo")); QVERIFY(model->setData(project1Index, "New Project 1")); QVERIFY(model->setData(project2Index, "New Project 2")); QVERIFY(!model->setData(contextsIndex, "Foo")); QVERIFY(model->setData(context1Index, "New Context 1")); QVERIFY(model->setData(context2Index, "New Context 2")); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::update).when(project1).exactly(1)); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::update).when(project2).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::update).when(context1).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::update).when(context2).exactly(1)); - QCOMPARE(project1->name(), QString("New Project 1")); - QCOMPARE(project2->name(), QString("New Project 2")); - QCOMPARE(context1->name(), QString("New Context 1")); - QCOMPARE(context2->name(), QString("New Context 2")); + QCOMPARE(project1->name(), QStringLiteral("New Project 1")); + QCOMPARE(project2->name(), QStringLiteral("New Project 2")); + QCOMPARE(context1->name(), QStringLiteral("New Context 1")); + QCOMPARE(context2->name(), QStringLiteral("New Context 2")); // WHEN projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, taskToDrop).thenReturn(new FakeJob(this)); QMimeData *data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, project1Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, taskToDrop).exactly(1)); // WHEN a task is dropped on a context contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop.objectCast()).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop.objectCast()).exactly(1)); // WHEN projectRepositoryMock(&Domain::ProjectRepository::dissociate).when(taskToDrop).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::dissociateAll).when(taskToDrop.objectCast()).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, inboxIndex); QTest::qWait(150); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::dissociate).when(taskToDrop).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociateAll).when(taskToDrop.objectCast()).exactly(1)); // WHEN projectRepositoryMock(&Domain::ProjectRepository::associate).when(project2, noteToDrop).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << noteToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, project2Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project2, noteToDrop).exactly(1)); // WHEN Domain::Artifact::Ptr taskToDrop2(new Domain::Task); Domain::Artifact::Ptr noteToDrop2(new Domain::Note); projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, taskToDrop2).thenReturn(new FakeJob(this)); projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, noteToDrop2).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop2 << noteToDrop2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, project1Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, taskToDrop2).exactly(1)); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, noteToDrop2).exactly(1)); // WHEN a task and a note are dropped on a context data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop2 << noteToDrop2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop2.objectCast()).exactly(0)); // WHEN two tasks are dropped on a context Domain::Task::Ptr taskToDrop3(new Domain::Task); Domain::Task::Ptr taskToDrop4(new Domain::Task); contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop3).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop4).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop3 << taskToDrop4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop3).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop4).exactly(1)); // WHEN a task is drop on the workday Domain::Task::Ptr taskToDrop5(new Domain::Task); taskRepositoryMock(&Domain::TaskRepository::update).when(taskToDrop5).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop5)); model->dropMimeData(data, Qt::MoveAction, -1, -1, workdayIndex); // THEN QCOMPARE(taskToDrop5->startDate().date(), Utils::DateTime::currentDateTime().date()); // WHEN two task are drop on the workday Domain::Task::Ptr taskToDrop6(new Domain::Task); Domain::Task::Ptr taskToDrop7(new Domain::Task); taskRepositoryMock(&Domain::TaskRepository::update).when(taskToDrop6).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(taskToDrop7).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop6 << taskToDrop7)); model->dropMimeData(data, Qt::MoveAction, -1, -1, workdayIndex); // THEN QCOMPARE(taskToDrop6->startDate().date(), Utils::DateTime::currentDateTime().date()); QCOMPARE(taskToDrop7->startDate().date(), Utils::DateTime::currentDateTime().date()); } void shouldCreateInboxPage() { // GIVEN // Empty project provider auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); // Empty context provider auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // context mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // projects mocking Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex inboxIndex = model->index(0, 0); QObject *inboxPage = pages.createPageForIndex(inboxIndex); QVERIFY(qobject_cast(inboxPage)); } void shouldCreateWorkdayPage() { // GIVEN // Empty project provider auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); // Empty context provider auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // context mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // projects mocking Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex workdayIndex = model->index(1, 0); QObject *workdayPage = pages.createPageForIndex(workdayIndex); QVERIFY(qobject_cast(workdayPage)); } void shouldCreateProjectsPage() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // No contexts auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // projects mocking Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex project1Index = model->index(0, 0, projectsIndex); const QModelIndex project2Index = model->index(1, 0, projectsIndex); QObject *projectsPage = pages.createPageForIndex(projectsIndex); QObject *project1Page = pages.createPageForIndex(project1Index); QObject *project2Page = pages.createPageForIndex(project2Index); QVERIFY(!projectsPage); QVERIFY(qobject_cast(project1Page)); QCOMPARE(qobject_cast(project1Page)->project(), project1); QVERIFY(qobject_cast(project2Page)); QCOMPARE(qobject_cast(project2Page)->project(), project2); } void shouldCreateContextsPage() { // GIVEN // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); - context2->setName("context 2"); + context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Empty Project provider auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // projects mocking Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); const QModelIndex context2Index = model->index(1, 0, contextsIndex); QObject *contextsPage = pages.createPageForIndex(contextsIndex); QObject *context1Page = pages.createPageForIndex(context1Index); QObject *context2Page = pages.createPageForIndex(context2Index); QVERIFY(!contextsPage); QVERIFY(qobject_cast(context1Page)); QCOMPARE(qobject_cast(context1Page)->context(), context1); QVERIFY(qobject_cast(context2Page)); QCOMPARE(qobject_cast(context2Page)->context(), context2); } void shouldAddProjects() { // GIVEN auto source = Domain::DataSource::Ptr::create(); Utils::MockObject projectRepositoryMock; projectRepositoryMock(&Domain::ProjectRepository::create).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::AvailableTaskPagesModel pages(Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), Domain::ContextQueries::Ptr(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN - pages.addProject("Foo", source); + pages.addProject(QStringLiteral("Foo"), source); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::create).when(any(), any()) .exactly(1)); } void shouldGetAnErrorMessageWhenAddProjectFailed() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - source->setName("Source1"); + source->setName(QStringLiteral("Source1")); Utils::MockObject projectRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::create).when(any(), any()) .thenReturn(job); Presentation::AvailableTaskPagesModel pages(Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), Domain::ContextQueries::Ptr(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); // WHEN - pages.addProject("Foo", source); + pages.addProject(QStringLiteral("Foo"), source); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add project Foo in dataSource Source1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add project Foo in dataSource Source1: Foo")); } void shouldAddContexts() { // GIVEN Utils::MockObject contextRepositoryMock; contextRepositoryMock(&Domain::ContextRepository::create).when(any()) .thenReturn(new FakeJob(this)); Presentation::AvailableTaskPagesModel pages(Domain::ProjectQueries::Ptr(), Domain::ProjectRepository::Ptr(), Domain::ContextQueries::Ptr(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN - pages.addContext("Foo"); + pages.addContext(QStringLiteral("Foo")); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::create).when(any()) .exactly(1)); } void shouldGetAnErrorMessageWhenAddContextFailed() { // GIVEN Utils::MockObject contextRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::create).when(any()) .thenReturn(job); Presentation::AvailableTaskPagesModel pages(Domain::ProjectQueries::Ptr(), Domain::ProjectRepository::Ptr(), Domain::ContextQueries::Ptr(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); // WHEN - pages.addContext("Foo"); + pages.addContext(QStringLiteral("Foo")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add context Foo: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add context Foo: Foo")); } void shouldRemoveProject() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // No contexts auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject projectRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex project1Index = model->index(0, 0, projectsIndex); projectRepositoryMock(&Domain::ProjectRepository::remove).when(project1).thenReturn(new FakeJob(this)); // WHEN pages.removeItem(project1Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::remove).when(project1).exactly(1)); } void shouldGetAnErrorMessageWhenRemoveProjectFailed() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // No contexts auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject projectRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex project1Index = model->index(0, 0, projectsIndex); auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::remove).when(project1).thenReturn(job); // WHEN pages.removeItem(project1Index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove project Project 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove project Project 1: Foo")); } void shouldRemoveContext() { // GIVEN // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); // empty projects auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // projects mocking Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), Domain::ProjectRepository::Ptr(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); contextRepositoryMock(&Domain::ContextRepository::remove).when(context1).thenReturn(new FakeJob(this)); // WHEN pages.removeItem(context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::remove).when(context1).exactly(1)); } void shouldGetAnErrorMessageWhenRemoveContextFailed() { // GIVEN // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); // empty projects auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // projects mocking Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), Domain::ProjectRepository::Ptr(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::remove).when(context1).thenReturn(job); // WHEN pages.removeItem(context1Index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove context context 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove context context 1: Foo")); } void shouldGetAnErrorMessageWhenUpdateProjectFailed() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); - context2->setName("context 2"); + context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Two artifacts (used for dropping later on) Domain::Artifact::Ptr taskToDrop(new Domain::Task); Domain::Artifact::Ptr noteToDrop(new Domain::Note); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex project1Index = model->index(0, 0, projectsIndex); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::update).when(project1).thenReturn(job); QVERIFY(model->setData(project1Index, "New Project 1")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify project Project 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify project Project 1: Foo")); } void shouldGetAnErrorMessageWhenUpdateContextFailed() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); - context2->setName("context 2"); + context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Two artifacts (used for dropping later on) Domain::Artifact::Ptr taskToDrop(new Domain::Task); Domain::Artifact::Ptr noteToDrop(new Domain::Note); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::update).when(context1).thenReturn(job); QVERIFY(model->setData(context1Index, "New Context 1")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify context context 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify context context 1: Foo")); } void shouldGetAnErrorMessageWhenAssociateProjectFailed() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); - context2->setName("context 2"); + context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Two artifacts (used for dropping later on) Domain::Artifact::Ptr taskToDrop(new Domain::Task); - taskToDrop->setTitle("taskDropped"); + taskToDrop->setTitle(QStringLiteral("taskDropped")); Domain::Artifact::Ptr noteToDrop(new Domain::Note); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex project1Index = model->index(0, 0, projectsIndex); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, taskToDrop).thenReturn(job); QMimeData *data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, project1Index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add taskDropped to project Project 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add taskDropped to project Project 1: Foo")); } void shouldGetAnErrorMessageWhenAssociateContextFailed() { // GIVEN // Two projects auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); - project2->setName("Project 2"); + project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); - context1->setName("context 1"); + context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); - context2->setName("context 2"); + context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Two artifacts (used for dropping later on) Domain::Artifact::Ptr taskToDrop(new Domain::Task); - taskToDrop->setTitle("taskDropped"); + taskToDrop->setTitle(QStringLiteral("taskDropped")); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop.objectCast()).thenReturn(job); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, context1Index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add taskDropped to context context 1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add taskDropped to context context 1: Foo")); } void shouldGetAnErrorMessageWhenDissociateFailed() { // GIVEN // No project auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); // No context auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // Two artifacts (used for dropping later on) Domain::Artifact::Ptr taskToDrop(new Domain::Task); - taskToDrop->setTitle("taskDropped"); + taskToDrop->setTitle(QStringLiteral("taskDropped")); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findAll).when().thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailableTaskPagesModel pages(projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex inboxIndex = model->index(0, 0); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::dissociate).when(taskToDrop).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::dissociateAll).when(taskToDrop.objectCast()).thenReturn(new FakeJob(this)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << taskToDrop)); model->dropMimeData(data, Qt::MoveAction, -1, -1, inboxIndex); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot move taskDropped to Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move taskDropped to Inbox: Foo")); } }; ZANSHIN_TEST_MAIN(AvailableTaskPagesModelTest) #include "availabletaskpagesmodeltest.moc" diff --git a/tests/units/presentation/contextpagemodeltest.cpp b/tests/units/presentation/contextpagemodeltest.cpp index e32df127..4e50c447 100644 --- a/tests/units/presentation/contextpagemodeltest.cpp +++ b/tests/units/presentation/contextpagemodeltest.cpp @@ -1,710 +1,710 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Rémi Benoit 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "domain/context.h" #include "domain/task.h" #include "domain/contextqueries.h" #include "domain/taskqueries.h" #include "domain/contextqueries.h" #include "domain/contextrepository.h" #include "domain/taskrepository.h" #include "domain/noterepository.h" #include "presentation/contextpagemodel.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class ContextPageModelTest : public QObject { Q_OBJECT private slots: void shouldListAssociatedTaskInContextCentralListView() { // GIVEN // A context auto context = Domain::Context::Ptr::create(); // Three tasks auto task1 = Domain::Task::Ptr::create(); - task1->setTitle("task1"); + task1->setTitle(QStringLiteral("task1")); auto task2 = Domain::Task::Ptr::create(); - task2->setTitle("task2"); + task2->setTitle(QStringLiteral("task2")); auto task3 = Domain::Task::Ptr::create(); - task3->setTitle("task3"); + task3->setTitle(QStringLiteral("task3")); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); taskProvider->append(task3); // Two tasks under the task1 auto childTask11 = Domain::Task::Ptr::create(); - childTask11->setTitle("childTask11"); + childTask11->setTitle(QStringLiteral("childTask11")); auto childTask12 = Domain::Task::Ptr::create(); - childTask12->setTitle("childTask12"); + childTask12->setTitle(QStringLiteral("childTask12")); auto childTaskProvider = Domain::QueryResultProvider::Ptr::create(); auto childTaskResult = Domain::QueryResult::create(childTaskProvider); taskProvider->append(childTask12); childTaskProvider->append(childTask11); childTaskProvider->append(childTask12); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(childTaskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task3).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask11).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask12).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject contextRepositoryMock; Utils::MockObject taskRepositoryMock; Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = page.centralListModel(); // THEN const QModelIndex task1Index = model->index(0, 0); const QModelIndex task2Index = model->index(1, 0); const QModelIndex task3Index = model->index(2, 0); const QModelIndex taskChildTask12Index = model->index(3, 0); const QModelIndex childTask11Index = model->index(0, 0, task1Index); const QModelIndex childTask12Index = model->index(1, 0, task1Index); QCOMPARE(page.context(), context); QCOMPARE(model->rowCount(), 4); QCOMPARE(model->rowCount(task1Index), 2); QCOMPARE(model->rowCount(task2Index), 0); QCOMPARE(model->rowCount(task3Index), 0); QCOMPARE(model->rowCount(taskChildTask12Index), 0); QVERIFY(childTask11Index.isValid()); QVERIFY(childTask12Index.isValid()); QCOMPARE(model->rowCount(childTask11Index), 0); QCOMPARE(model->rowCount(childTask12Index), 0); const Qt::ItemFlags taskFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled; QCOMPARE(model->flags(task1Index), taskFlags); QCOMPARE(model->flags(childTask11Index), taskFlags); QCOMPARE(model->flags(childTask12Index), taskFlags); QCOMPARE(model->flags(task2Index), taskFlags); QCOMPARE(model->flags(task3Index), taskFlags); QCOMPARE(model->flags(taskChildTask12Index), taskFlags); QCOMPARE(model->data(task1Index).toString(), task1->title()); QCOMPARE(model->data(childTask11Index).toString(), childTask11->title()); QCOMPARE(model->data(childTask12Index).toString(), childTask12->title()); QCOMPARE(model->data(task2Index).toString(), task2->title()); QCOMPARE(model->data(task3Index).toString(), task3->title()); QCOMPARE(model->data(taskChildTask12Index).toString(), childTask12->title()); QCOMPARE(model->data(task1Index, Qt::EditRole).toString(), task1->title()); QCOMPARE(model->data(childTask11Index, Qt::EditRole).toString(), childTask11->title()); QCOMPARE(model->data(childTask12Index, Qt::EditRole).toString(), childTask12->title()); QCOMPARE(model->data(task2Index, Qt::EditRole).toString(), task2->title()); QCOMPARE(model->data(task3Index, Qt::EditRole).toString(), task3->title()); QCOMPARE(model->data(taskChildTask12Index, Qt::EditRole).toString(), childTask12->title()); QVERIFY(model->data(task1Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTask11Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTask12Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(task2Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(task3Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(taskChildTask12Index, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(task1Index, Qt::CheckStateRole).toBool(), task1->isDone()); QCOMPARE(model->data(childTask11Index, Qt::CheckStateRole).toBool(), childTask11->isDone()); QCOMPARE(model->data(childTask12Index, Qt::CheckStateRole).toBool(), childTask12->isDone()); QCOMPARE(model->data(task2Index, Qt::CheckStateRole).toBool(), task2->isDone()); QCOMPARE(model->data(task3Index, Qt::CheckStateRole).toBool(), task3->isDone()); QCOMPARE(model->data(taskChildTask12Index, Qt::CheckStateRole).toBool(), childTask12->isDone()); // WHEN taskRepositoryMock(&Domain::TaskRepository::update).when(task1).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask11).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask12).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(task2).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(task3).thenReturn(new FakeJob(this)); QVERIFY(model->setData(task1Index, "newTask1")); QVERIFY(model->setData(childTask11Index, "newChildTask11")); QVERIFY(model->setData(task2Index, "newTask2")); QVERIFY(model->setData(task3Index, "newTask3")); QVERIFY(model->setData(taskChildTask12Index, "newChildTask12")); QVERIFY(model->setData(task1Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(childTask11Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(task2Index, Qt::Checked, Qt::CheckStateRole)); QVERIFY(model->setData(task3Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(taskChildTask12Index, Qt::Checked, Qt::CheckStateRole)); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task1).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask11).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask12).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task2).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task3).exactly(2)); - QCOMPARE(task1->title(), QString("newTask1")); - QCOMPARE(childTask11->title(), QString("newChildTask11")); - QCOMPARE(childTask12->title(), QString("newChildTask12")); - QCOMPARE(task2->title(), QString("newTask2")); - QCOMPARE(task3->title(), QString("newTask3")); + QCOMPARE(task1->title(), QStringLiteral("newTask1")); + QCOMPARE(childTask11->title(), QStringLiteral("newChildTask11")); + QCOMPARE(childTask12->title(), QStringLiteral("newChildTask12")); + QCOMPARE(task2->title(), QStringLiteral("newTask2")); + QCOMPARE(task3->title(), QStringLiteral("newTask3")); QCOMPARE(task1->isDone(), false); QCOMPARE(childTask11->isDone(), false); QCOMPARE(childTask12->isDone(), true); QCOMPARE(task2->isDone(), true); QCOMPARE(task3->isDone(), false); // WHEN QVERIFY(!model->setData(task1Index, QVariant(), Qt::WhatsThisRole)); QVERIFY(!model->setData(task1Index, QVariant(), Qt::ForegroundRole)); QVERIFY(!model->setData(task1Index, QVariant(), Qt::InitialSortOrderRole)); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task1).exactly(2)); - QCOMPARE(task1->title(), QString("newTask1")); - QCOMPARE(task2->title(), QString("newTask2")); + QCOMPARE(task1->title(), QStringLiteral("newTask1")); + QCOMPARE(task2->title(), QStringLiteral("newTask2")); // WHEN a task is dragged QMimeData *data = model->mimeData(QModelIndexList() << task2Index); // THEN - QVERIFY(data->hasFormat("application/x-zanshin-object")); + QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Artifact::List() << task2); // WHEN a task is dropped auto childTask2 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask2).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, task1Index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask2).exactly(1)); // WHEN two tasks are dropped auto childTask3 = Domain::Task::Ptr::create(); auto childTask4 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask3).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask4).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask3 << childTask4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, task1Index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask3).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask4).exactly(1)); // WHEN a task and a note are dropped Domain::Artifact::Ptr childTask5(new Domain::Task); Domain::Artifact::Ptr childNote(new Domain::Note); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask5 << childNote)); model->dropMimeData(data, Qt::MoveAction, -1, -1, task1Index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask5.objectCast()).exactly(0)); } void shouldAddTasksInContext() { // GIVEN // One Context auto context = Domain::Context::Ptr::create(); // ... in fact we won't list any model Utils::MockObject contextQueriesMock; Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createInContext).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - auto title = QString("New task"); + auto title = QStringLiteral("New task"); auto task = page.addItem(title).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createInContext).when(any(), any()) .exactly(1)); QVERIFY(task); QCOMPARE(task->title(), title); } void shouldAddChildTask() { // GIVEN // One Context auto context = Domain::Context::Ptr::create(); // A task auto task = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task); auto childProvider = Domain::QueryResultProvider::Ptr::create(); auto childResult = Domain::QueryResult::create(childProvider); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - const auto title = QString("New task"); + const auto title = QStringLiteral("New task"); const auto parentIndex = page.centralListModel()->index(0, 0); const auto createdTask = page.addItem(title, parentIndex).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .exactly(1)); QVERIFY(createdTask); QCOMPARE(createdTask->title(), title); } void shouldRemoveTopLevelItem() { // GIVEN // One context auto context = Domain::Context::Ptr::create(); // A task auto task = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task); auto childProvider = Domain::QueryResultProvider::Ptr::create(); auto childResult = Domain::QueryResult::create(childProvider); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject contextRepositoryMock; contextRepositoryMock(&Domain::ContextRepository::dissociate).when(context, task).thenReturn(new FakeJob(this)); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult); Utils::MockObject taskRepositoryMock; Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex indexTask = page.centralListModel()->index(0, 0); page.removeItem(indexTask); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::dissociate).when(context, task).exactly(1)); } void shouldRemoveChildItem() { // GIVEN // One context auto context = Domain::Context::Ptr::create(); // A task... auto task = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task); // ... with a child auto childTask = Domain::Task::Ptr::create(); auto childProvider = Domain::QueryResultProvider::Ptr::create(); auto childResult = Domain::QueryResult::create(childProvider); childProvider->append(childTask); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyResult = Domain::QueryResult::create(emptyProvider); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(emptyResult); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).thenReturn(new FakeJob(this)); Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const auto taskIndex = page.centralListModel()->index(0, 0); const auto childTaskIndex = page.centralListModel()->index(0, 0, taskIndex); page.removeItem(childTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).exactly(1)); } void shouldPromoteItem() { // GIVEN // One context auto context = Domain::Context::Ptr::create(); // A task auto task = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task); auto childProvider = Domain::QueryResultProvider::Ptr::create(); auto childResult = Domain::QueryResult::create(childProvider); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task).thenReturn(new FakeJob(this)); Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex indexTask = page.centralListModel()->index(0, 0); page.promoteItem(indexTask); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task).exactly(1)); } void shouldGetAnErrorMessageWhenAddTaskFailed() { // GIVEN // One Context auto context = Domain::Context::Ptr::create(); - context->setName("Context1"); + context->setName(QStringLiteral("Context1")); // ... in fact we won't list any model Utils::MockObject contextQueriesMock; Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::createInContext).when(any(), any()) .thenReturn(job); Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN - page.addItem("New task"); + page.addItem(QStringLiteral("New task")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add task New task in context Context1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add task New task in context Context1: Foo")); } void shouldGetAnErrorMessageWhenUpdateTaskFailed() { // GIVEN // A context auto context = Domain::Context::Ptr::create(); - context->setName("Context1"); + context->setName(QStringLiteral("Context1")); // A task auto task = Domain::Task::Ptr::create(); - task->setTitle("A task"); + task->setTitle(QStringLiteral("A task")); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task); auto childProvider = Domain::QueryResultProvider::Ptr::create(); auto childResult = Domain::QueryResult::create(childProvider); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskRepositoryMock; Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = page.centralListModel(); const QModelIndex taskIndex = model->index(0, 0); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::update).when(task).thenReturn(job); QVERIFY(model->setData(taskIndex, "newTask")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify task A task in context Context1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task A task in context Context1: Foo")); } void shouldGetAnErrorMessageWhenAssociateTaskFailed() { // GIVEN // A context auto context = Domain::Context::Ptr::create(); - context->setName("Context1"); + context->setName(QStringLiteral("Context1")); // A parent task and a child task auto parentTask = Domain::Task::Ptr::create(); - parentTask->setTitle("A parent task"); + parentTask->setTitle(QStringLiteral("A parent task")); auto childTask = Domain::Task::Ptr::create(); - childTask->setTitle("A child task"); + childTask->setTitle(QStringLiteral("A child task")); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(parentTask); taskProvider->append(childTask); auto childProvider = Domain::QueryResultProvider::Ptr::create(); auto childResult = Domain::QueryResult::create(childProvider); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(parentTask).thenReturn(childResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(childResult); Utils::MockObject taskRepositoryMock; Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = page.centralListModel(); const QModelIndex parentTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN a task is dropped auto childTask2 = Domain::Task::Ptr::create(); - childTask2->setTitle("childTask2"); + childTask2->setTitle(QStringLiteral("childTask2")); auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::associate).when(parentTask, childTask2).thenReturn(job); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, parentTaskIndex); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot move task childTask2 as sub-task of A parent task: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move task childTask2 as sub-task of A parent task: Foo")); } void shouldAssociateToContextWithNoParentWhenDroppingOnEmptyArea() { // GIVEN // One context auto context = Domain::Context::Ptr::create(); - context->setName("Context"); + context->setName(QStringLiteral("Context")); // One top level task auto topLevelTask = Domain::Task::Ptr::create(); - topLevelTask->setTitle("rootTask"); + topLevelTask->setTitle(QStringLiteral("rootTask")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(topLevelTask); // Two tasks under the top level task auto childTask1 = Domain::Task::Ptr::create(); - childTask1->setTitle("childTask1"); + childTask1->setTitle(QStringLiteral("childTask1")); childTask1->setDone(true); auto childTask2 = Domain::Task::Ptr::create(); - childTask2->setTitle("childTask2"); + childTask2->setTitle(QStringLiteral("childTask2")); childTask2->setDone(false); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask1); taskProvider->append(childTask2); Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(topLevelResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(topLevelTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::ContextPageModel page(context, contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); auto model = page.centralListModel(); // WHEN taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask1).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask1).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask2).thenReturn(new FakeJob(this)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask1 << childTask2)); // both will be DnD on the empty part model->dropMimeData(data, Qt::MoveAction, -1, -1, QModelIndex()); // THEN QTest::qWait(150); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask1).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask1).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask2).exactly(1)); } }; ZANSHIN_TEST_MAIN(ContextPageModelTest) #include "contextpagemodeltest.moc" diff --git a/tests/units/presentation/errorhandlertest.cpp b/tests/units/presentation/errorhandlertest.cpp index 67fef4ca..695bf441 100644 --- a/tests/units/presentation/errorhandlertest.cpp +++ b/tests/units/presentation/errorhandlertest.cpp @@ -1,89 +1,89 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "presentation/errorhandler.h" #include "testlib/fakejob.h" class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class ErrorHandlerTest : public QObject { Q_OBJECT private slots: void shouldDisplayErrorMessage() { // GIVEN // create job auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); // create ErrorHandler FakeErrorHandler errorHandler; - const QString message = "I Failed !!!!!!!!!!"; + const QString message = QStringLiteral("I Failed !!!!!!!!!!"); // WHEN errorHandler.installHandler(job, message); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("I Failed !!!!!!!!!!: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("I Failed !!!!!!!!!!: Foo")); } void shouldDisplayNothing() { // GIVEN // create job auto job = new FakeJob(this); // create ErrorHandler FakeErrorHandler errorHandler; - const QString message = "I Failed !!!!!!!!!!"; + const QString message = QStringLiteral("I Failed !!!!!!!!!!"); // WHEN errorHandler.installHandler(job, message); // THEN QTest::qWait(150); QVERIFY(errorHandler.m_message.isEmpty()); } }; ZANSHIN_TEST_MAIN(ErrorHandlerTest) #include "errorhandlertest.moc" diff --git a/tests/units/presentation/errorhandlingmodelbasetest.cpp b/tests/units/presentation/errorhandlingmodelbasetest.cpp index 1960c904..cdc1de54 100644 --- a/tests/units/presentation/errorhandlingmodelbasetest.cpp +++ b/tests/units/presentation/errorhandlingmodelbasetest.cpp @@ -1,104 +1,104 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "presentation/errorhandlingmodelbase.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class FakeErrorHandlingModelBase : public Presentation::ErrorHandlingModelBase { public: void install(KJob *job, const QString &message) { installHandler(job, message); } }; class ErrorHandlingModelBaseTest : public QObject { Q_OBJECT private slots: void shouldDisplayMessageOnError() { // GIVEN // create job auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); // create ErrorHandlingModelBase FakeErrorHandler errorHandler; FakeErrorHandlingModelBase errorHandling; errorHandling.setErrorHandler(&errorHandler); - const QString message = "I Failed !!!!!!!!!!"; + const QString message = QStringLiteral("I Failed !!!!!!!!!!"); // WHEN errorHandling.install(job, message); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("I Failed !!!!!!!!!!: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("I Failed !!!!!!!!!!: Foo")); QCOMPARE(errorHandling.errorHandler(), &errorHandler); } void shouldNotDisplayMessageWhenNoErrorOccurred() { // GIVEN // create job auto job = new FakeJob(this); // create ErrorHandlingModelBase FakeErrorHandler errorHandler; FakeErrorHandlingModelBase errorHandling; errorHandling.setErrorHandler(&errorHandler); - const QString message = "I Failed !!!!!!!!!!"; + const QString message = QStringLiteral("I Failed !!!!!!!!!!"); // WHEN errorHandling.install(job, message); // THEN QTest::qWait(150); QVERIFY(errorHandler.m_message.isEmpty()); } }; ZANSHIN_TEST_MAIN(ErrorHandlingModelBaseTest) #include "errorhandlingmodelbasetest.moc" diff --git a/tests/units/presentation/noteinboxpagemodeltest.cpp b/tests/units/presentation/noteinboxpagemodeltest.cpp index 9b6bb6d7..f4d7bb7d 100644 --- a/tests/units/presentation/noteinboxpagemodeltest.cpp +++ b/tests/units/presentation/noteinboxpagemodeltest.cpp @@ -1,287 +1,287 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "presentation/noteinboxpagemodel.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class NoteInboxPageModelTest : public QObject { Q_OBJECT private slots: void shouldListInboxInCentralListModel() { // GIVEN // Two notes auto note1 = Domain::Note::Ptr::create(); - note1->setTitle("note1"); + note1->setTitle(QStringLiteral("note1")); auto note2 = Domain::Note::Ptr::create(); - note2->setTitle("note2"); + note2->setTitle(QStringLiteral("note2")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject noteQueriesMock; noteQueriesMock(&Domain::NoteQueries::findInbox).when().thenReturn(noteResult); Utils::MockObject noteRepositoryMock; Presentation::NoteInboxPageModel inbox(noteQueriesMock.getInstance(), noteRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = inbox.centralListModel(); // THEN const QModelIndex note1Index = model->index(0, 0); const QModelIndex note2Index = model->index(1, 0); QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(note1Index), 0); QCOMPARE(model->rowCount(note2Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; QCOMPARE(model->flags(note1Index), defaultFlags); QCOMPARE(model->flags(note2Index), defaultFlags); QCOMPARE(model->data(note1Index).toString(), note1->title()); QCOMPARE(model->data(note2Index).toString(), note2->title()); QCOMPARE(model->data(note1Index, Qt::EditRole).toString(), note1->title()); QCOMPARE(model->data(note2Index, Qt::EditRole).toString(), note2->title()); QVERIFY(!model->data(note1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(note2Index, Qt::CheckStateRole).isValid()); // WHEN noteRepositoryMock(&Domain::NoteRepository::update).when(note1).thenReturn(new FakeJob(this)); noteRepositoryMock(&Domain::NoteRepository::update).when(note2).thenReturn(new FakeJob(this)); QVERIFY(model->setData(note1Index, "newNote1")); QVERIFY(model->setData(note2Index, "newNote2")); QVERIFY(!model->setData(note1Index, Qt::Checked, Qt::CheckStateRole)); QVERIFY(!model->setData(note2Index, Qt::Checked, Qt::CheckStateRole)); // THEN QVERIFY(noteRepositoryMock(&Domain::NoteRepository::update).when(note1).exactly(1)); QVERIFY(noteRepositoryMock(&Domain::NoteRepository::update).when(note2).exactly(1)); - QCOMPARE(note1->title(), QString("newNote1")); - QCOMPARE(note2->title(), QString("newNote2")); + QCOMPARE(note1->title(), QStringLiteral("newNote1")); + QCOMPARE(note2->title(), QStringLiteral("newNote2")); // WHEN QMimeData *data = model->mimeData(QModelIndexList() << note2Index); // THEN - QVERIFY(data->hasFormat("application/x-zanshin-object")); + QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Artifact::List() << note2); } void shouldAddNotes() { // GIVEN // ... in fact we won't list any model Utils::MockObject noteQueriesMock; // We'll gladly create a note though Utils::MockObject noteRepositoryMock; noteRepositoryMock(&Domain::NoteRepository::create).when(any()).thenReturn(new FakeJob(this)); Presentation::NoteInboxPageModel inbox(noteQueriesMock.getInstance(), noteRepositoryMock.getInstance()); // WHEN - auto title = QString("New note"); + auto title = QStringLiteral("New note"); auto note = inbox.addItem(title).objectCast(); // THEN QVERIFY(noteRepositoryMock(&Domain::NoteRepository::create).when(any()).exactly(1)); QVERIFY(note); QCOMPARE(note->title(), title); } void shouldGetAnErrorMessageWhenAddNoteFailed() { // GIVEN // ... in fact we won't list any model Utils::MockObject noteQueriesMock; // We'll gladly create a note though Utils::MockObject noteRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); noteRepositoryMock(&Domain::NoteRepository::create).when(any()).thenReturn(job); Presentation::NoteInboxPageModel inbox(noteQueriesMock.getInstance(), noteRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN - inbox.addItem("New note"); + inbox.addItem(QStringLiteral("New note")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add note New note in Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add note New note in Inbox: Foo")); } void shouldDeleteItems() { // GIVEN // Two notes auto note1 = Domain::Note::Ptr::create(); - note1->setTitle("note1"); + note1->setTitle(QStringLiteral("note1")); auto note2 = Domain::Note::Ptr::create(); - note2->setTitle("note2"); + note2->setTitle(QStringLiteral("note2")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject noteQueriesMock; noteQueriesMock(&Domain::NoteQueries::findInbox).when().thenReturn(noteResult); Utils::MockObject noteRepositoryMock; noteRepositoryMock(&Domain::NoteRepository::remove).when(note2).thenReturn(new FakeJob(this)); Presentation::NoteInboxPageModel inbox(noteQueriesMock.getInstance(), noteRepositoryMock.getInstance()); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.removeItem(index); // THEN QVERIFY(noteRepositoryMock(&Domain::NoteRepository::remove).when(note2).exactly(1)); } void shouldGetAnErrorMessageWhenDeleteItemsFailed() { // GIVEN // Two notes auto note1 = Domain::Note::Ptr::create(); - note1->setTitle("note1"); + note1->setTitle(QStringLiteral("note1")); auto note2 = Domain::Note::Ptr::create(); - note2->setTitle("note2"); + note2->setTitle(QStringLiteral("note2")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject noteQueriesMock; noteQueriesMock(&Domain::NoteQueries::findInbox).when().thenReturn(noteResult); Utils::MockObject noteRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); noteRepositoryMock(&Domain::NoteRepository::remove).when(note2).thenReturn(job); Presentation::NoteInboxPageModel inbox(noteQueriesMock.getInstance(), noteRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.removeItem(index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove note note2 from Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove note note2 from Inbox: Foo")); } void shouldGetAnErrorMessageWhenUpdateNoteFailed() { // GIVEN // Two notes auto note1 = Domain::Note::Ptr::create(); - note1->setTitle("note1"); + note1->setTitle(QStringLiteral("note1")); auto note2 = Domain::Note::Ptr::create(); - note2->setTitle("note2"); + note2->setTitle(QStringLiteral("note2")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject noteQueriesMock; noteQueriesMock(&Domain::NoteQueries::findInbox).when().thenReturn(noteResult); Utils::MockObject noteRepositoryMock; Presentation::NoteInboxPageModel inbox(noteQueriesMock.getInstance(), noteRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex note1Index = model->index(0, 0); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); noteRepositoryMock(&Domain::NoteRepository::update).when(note1).thenReturn(job); QVERIFY(model->setData(note1Index, "newNote1")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify note note1 in Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify note note1 in Inbox: Foo")); } }; ZANSHIN_TEST_MAIN(NoteInboxPageModelTest) #include "noteinboxpagemodeltest.moc" diff --git a/tests/units/presentation/projectpagemodeltest.cpp b/tests/units/presentation/projectpagemodeltest.cpp index fd447b78..d571bd4d 100644 --- a/tests/units/presentation/projectpagemodeltest.cpp +++ b/tests/units/presentation/projectpagemodeltest.cpp @@ -1,646 +1,646 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "presentation/projectpagemodel.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class ProjectPageModelTest : public QObject { Q_OBJECT private slots: void shouldListProjectInCentralListModel() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); // One note and one task auto rootTask = Domain::Task::Ptr::create(); - rootTask->setTitle("rootTask"); + rootTask->setTitle(QStringLiteral("rootTask")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(rootTask); // One task under the root task auto childTask = Domain::Task::Ptr::create(); - childTask->setTitle("childTask"); + childTask->setTitle(QStringLiteral("childTask")); childTask->setDone(true); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = page.centralListModel(); // THEN const QModelIndex rootTaskIndex = model->index(0, 0); const QModelIndex childTaskIndex = model->index(0, 0, rootTaskIndex); QCOMPARE(page.project(), project); QCOMPARE(model->rowCount(), 1); QCOMPARE(model->rowCount(rootTaskIndex), 1); QCOMPARE(model->rowCount(childTaskIndex), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled; QCOMPARE(model->flags(rootTaskIndex), defaultFlags); QCOMPARE(model->flags(childTaskIndex), defaultFlags); QCOMPARE(model->data(rootTaskIndex).toString(), rootTask->title()); QCOMPARE(model->data(childTaskIndex).toString(), childTask->title()); QCOMPARE(model->data(rootTaskIndex, Qt::EditRole).toString(), rootTask->title()); QCOMPARE(model->data(childTaskIndex, Qt::EditRole).toString(), childTask->title()); QVERIFY(model->data(rootTaskIndex, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTaskIndex, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(rootTaskIndex, Qt::CheckStateRole).toBool(), rootTask->isDone()); QCOMPARE(model->data(childTaskIndex, Qt::CheckStateRole).toBool(), childTask->isDone()); // WHEN taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask).thenReturn(new FakeJob(this)); QVERIFY(model->setData(rootTaskIndex, "newRootTask")); QVERIFY(model->setData(childTaskIndex, "newChildTask")); QVERIFY(model->setData(rootTaskIndex, Qt::Checked, Qt::CheckStateRole)); QVERIFY(model->setData(childTaskIndex, Qt::Unchecked, Qt::CheckStateRole)); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask).exactly(2)); - QCOMPARE(rootTask->title(), QString("newRootTask")); - QCOMPARE(childTask->title(), QString("newChildTask")); + QCOMPARE(rootTask->title(), QStringLiteral("newRootTask")); + QCOMPARE(childTask->title(), QStringLiteral("newChildTask")); QCOMPARE(rootTask->isDone(), true); QCOMPARE(childTask->isDone(), false); // WHEN QMimeData *data = model->mimeData(QModelIndexList() << childTaskIndex); // THEN - QVERIFY(data->hasFormat("application/x-zanshin-object")); + QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Artifact::List() << childTask); // WHEN auto childTask2 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask2).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask2).exactly(1)); // WHEN auto childTask3 = Domain::Task::Ptr::create(); auto childTask4 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask3 << childTask4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).exactly(1)); } void shouldAddTasksInProject() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); // ... in fact we won't list any model Utils::MockObject projectQueriesMock; Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createInProject).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - auto title = QString("New task"); + auto title = QStringLiteral("New task"); auto task = page.addItem(title).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createInProject).when(any(), any()) .exactly(1)); QVERIFY(task); QCOMPARE(task->title(), title); } void shouldAddChildTask() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(task1); topLevelProvider->append(task2); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - const auto title = QString("New task"); + const auto title = QStringLiteral("New task"); const auto parentIndex = page.centralListModel()->index(0, 0); const auto createdTask = page.addItem(title, parentIndex).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .exactly(1)); QVERIFY(createdTask); QCOMPARE(createdTask->title(), title); } void shouldGetAnErrorMessageWhenAddTaskFailed() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); - project->setName("Project1"); + project->setName(QStringLiteral("Project1")); // ... in fact we won't list any model Utils::MockObject projectQueriesMock; Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::createInProject).when(any(), any()) .thenReturn(job); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN - page.addItem("New task"); + page.addItem(QStringLiteral("New task")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add task New task in project Project1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add task New task in project Project1: Foo")); } void shouldDeleteItems() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(task1); topLevelProvider->append(task2); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(new FakeJob(this)); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = page.centralListModel()->index(1, 0); page.removeItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).exactly(1)); } void shouldGetAnErrorMessageWhenDeleteItemsFailed() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); - project->setName("Project1"); + project->setName(QStringLiteral("Project1")); // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); - task2->setTitle("Task2"); + task2->setTitle(QStringLiteral("Task2")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(task1); topLevelProvider->append(task2); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(job); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = page.centralListModel()->index(1, 0); page.removeItem(index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove task Task2 from project Project1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove task Task2 from project Project1: Foo")); } void shouldPromoteItem() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(task1); topLevelProvider->append(task2); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(new FakeJob(this)); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = page.centralListModel()->index(1, 0); page.promoteItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).exactly(1)); } void shouldGetAnErrorMessageWhenPromoteItemFailed() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); - project->setName("Project1"); + project->setName(QStringLiteral("Project1")); // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); - task2->setTitle("Task2"); + task2->setTitle(QStringLiteral("Task2")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(task1); topLevelProvider->append(task2); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(job); Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = page.centralListModel()->index(1, 0); page.promoteItem(index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot promote task Task2 to be a project: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot promote task Task2 to be a project: Foo")); } void shouldGetAnErrorMessageWhenUpdateTaskFailed() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); - project->setName("Project1"); + project->setName(QStringLiteral("Project1")); // One note and one task auto rootTask = Domain::Task::Ptr::create(); - rootTask->setTitle("rootTask"); + rootTask->setTitle(QStringLiteral("rootTask")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(rootTask); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = page.centralListModel(); const QModelIndex rootTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).thenReturn(job); QVERIFY(model->setData(rootTaskIndex, "newRootTask")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify task rootTask in project Project1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task rootTask in project Project1: Foo")); } void shouldGetAnErrorMessageWhenAssociateTaskFailed() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); - project->setName("Project1"); + project->setName(QStringLiteral("Project1")); // One note and one task auto rootTask = Domain::Task::Ptr::create(); - rootTask->setTitle("rootTask"); + rootTask->setTitle(QStringLiteral("rootTask")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(rootTask); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = page.centralListModel(); const QModelIndex rootTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN auto childTask3 = Domain::Task::Ptr::create(); - childTask3->setTitle("childTask3"); + childTask3->setTitle(QStringLiteral("childTask3")); auto childTask4 = Domain::Task::Ptr::create(); auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).thenReturn(new FakeJob(this)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask3 << childTask4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot move task childTask3 as a sub-task of rootTask: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move task childTask3 as a sub-task of rootTask: Foo")); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).exactly(1)); } void shouldAssociateToProjectWhenDroppingOnEmptyArea() { // GIVEN // One project auto project = Domain::Project::Ptr::create(); - project->setName("Project"); + project->setName(QStringLiteral("Project")); // One top level task auto topLevelTask = Domain::Task::Ptr::create(); - topLevelTask->setTitle("rootTask"); + topLevelTask->setTitle(QStringLiteral("rootTask")); auto topLevelProvider = Domain::QueryResultProvider::Ptr::create(); auto topLevelResult = Domain::QueryResult::create(topLevelProvider); topLevelProvider->append(topLevelTask); // Two tasks under the top level task auto childTask1 = Domain::Task::Ptr::create(); - childTask1->setTitle("childTask1"); + childTask1->setTitle(QStringLiteral("childTask1")); childTask1->setDone(true); auto childTask2 = Domain::Task::Ptr::create(); - childTask2->setTitle("childTask2"); + childTask2->setTitle(QStringLiteral("childTask2")); childTask2->setDone(false); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask1); taskProvider->append(childTask2); Utils::MockObject projectQueriesMock; projectQueriesMock(&Domain::ProjectQueries::findTopLevel).when(project).thenReturn(topLevelResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findChildren).when(topLevelTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::ProjectPageModel page(project, projectQueriesMock.getInstance(), projectRepositoryMock.getInstance(), taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); auto model = page.centralListModel(); // WHEN projectRepositoryMock(&Domain::ProjectRepository::associate).when(project, childTask1).thenReturn(new FakeJob(this)); projectRepositoryMock(&Domain::ProjectRepository::associate).when(project, childTask2).thenReturn(new FakeJob(this)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask1 << childTask2)); // both will be DnD on the empty part model->dropMimeData(data, Qt::MoveAction, -1, -1, QModelIndex()); // THEN QTest::qWait(150); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project, childTask1).exactly(1)); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project, childTask2).exactly(1)); } }; ZANSHIN_TEST_MAIN(ProjectPageModelTest) #include "projectpagemodeltest.moc" diff --git a/tests/units/presentation/querytreemodeltest.cpp b/tests/units/presentation/querytreemodeltest.cpp index 12235e82..7603c297 100644 --- a/tests/units/presentation/querytreemodeltest.cpp +++ b/tests/units/presentation/querytreemodeltest.cpp @@ -1,980 +1,980 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "utils/mockobject.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/querytreemodel.h" #include "testlib/modeltest.h" using namespace mockitopp; Q_DECLARE_METATYPE(QModelIndex) Q_DECLARE_METATYPE(QList) class QueryTreeModelTest : public QObject { Q_OBJECT public: explicit QueryTreeModelTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } private: Domain::Task::List createTasks() const { Domain::Task::List result; const QStringList titles = {"first", "second", "third"}; const QList doneStates = {true, false, false}; Q_ASSERT(titles.size() == doneStates.size()); for (int i = 0; i < titles.size(); i++) { auto task = Domain::Task::Ptr::create(); task->setTitle(titles.at(i)); task->setDone(doneStates.at(i)); result << task; } return result; } Domain::Task::List createChildrenTasks() const { Domain::Task::List result; const QStringList titles = {"childFirst", "childSecond", "childThird"}; const QList doneStates = {true, false, false}; Q_ASSERT(titles.size() == doneStates.size()); for (int i = 0; i < titles.size(); i++) { auto task = Domain::Task::Ptr::create(); task->setTitle(titles.at(i)); task->setDone(doneStates.at(i)); result << task; } return result; } private slots: void shouldHaveRoleNames() { // GIVEN auto queryGenerator = [](const QColor &) { return Domain::QueryResult::Ptr(); }; auto flagsFunction = [](const QColor &) { return Qt::NoItemFlags; }; auto dataFunction = [](const QColor &, int) { return QVariant(); }; auto setDataFunction = [](const QColor &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction); // WHEN auto roles = model.roleNames(); // THEN QCOMPARE(roles.value(Qt::DisplayRole), QByteArray("display")); QCOMPARE(roles.value(Presentation::QueryTreeModel::ObjectRole), QByteArray("object")); QCOMPARE(roles.value(Presentation::QueryTreeModel::IconNameRole), QByteArray("icon")); QCOMPARE(roles.value(Presentation::QueryTreeModel::IsDefaultRole), QByteArray("default")); } void shouldListTasks() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); for (auto task : childrenTasks) childrenProvider->append(task); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); // WHEN auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); // THEN QCOMPARE(model.rowCount(), 3); QCOMPARE(model.rowCount(model.index(0, 0)), 3); QCOMPARE(model.rowCount(model.index(1, 0)), 0); QCOMPARE(model.rowCount(model.index(2, 0)), 0); QCOMPARE(model.rowCount(model.index(0, 0, model.index(0, 0))), 0); QCOMPARE(model.rowCount(model.index(1, 0, model.index(0, 0))), 0); QCOMPARE(model.rowCount(model.index(2, 0, model.index(0, 0))), 0); QCOMPARE(model.rowCount(model.index(3, 0, model.index(0, 0))), 3); for (int i = 0; i < tasks.size(); i++) { auto task = tasks.at(i); auto index = model.index(i, 0); QCOMPARE(model.data(index), model.data(index, Qt::DisplayRole)); QCOMPARE(model.data(index).toString(), task->title()); QCOMPARE(model.data(index, Qt::CheckStateRole).toInt() == Qt::Checked, task->isDone()); QCOMPARE(model.data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked, !task->isDone()); } for (int i = 0; i < childrenTasks.size(); i++) { auto task = childrenTasks.at(i); auto index = model.index(i, 0, model.index(0, 0)); QCOMPARE(model.data(index), model.data(index, Qt::DisplayRole)); QCOMPARE(model.data(index).toString(), task->title()); QCOMPARE(model.data(index, Qt::CheckStateRole).toInt() == Qt::Checked, task->isDone()); QCOMPARE(model.data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked, !task->isDone()); } } void shouldDealWithNullQueriesProperly() { // GIVEN auto queryGenerator = [](const QString &) { return Domain::QueryResult::Ptr(); }; auto flagsFunction = [](const QString &) { return Qt::NoItemFlags; }; auto dataFunction = [](const QString &, int) { return QVariant(); }; auto setDataFunction = [](const QString &, const QVariant &, int) { return false; }; // WHEN Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); // THEN QCOMPARE(model.rowCount(), 0); } void shouldReactToTaskAdd() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); provider->append(tasks.at(1)); provider->append(tasks.at(2)); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); for (auto task : childrenTasks) childrenProvider->append(task); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); QSignalSpy aboutToBeInsertedSpy(&model, &QAbstractItemModel::rowsAboutToBeInserted); QSignalSpy insertedSpy(&model, &QAbstractItemModel::rowsInserted); // WHEN queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); provider->insert(0, tasks.at(0)); // THEN QCOMPARE(aboutToBeInsertedSpy.size(), 1); QCOMPARE(aboutToBeInsertedSpy.first().at(0).value(), QModelIndex()); QCOMPARE(aboutToBeInsertedSpy.first().at(1).toInt(), 0); QCOMPARE(aboutToBeInsertedSpy.first().at(2).toInt(), 0); QCOMPARE(insertedSpy.size(), 1); QCOMPARE(insertedSpy.first().at(0).value(), QModelIndex()); QCOMPARE(insertedSpy.first().at(1).toInt(), 0); QCOMPARE(insertedSpy.first().at(2).toInt(), 0); } void shouldReactToChilrenTaskAdd() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); childrenProvider->append(childrenTasks.at(0)); childrenProvider->append(childrenTasks.at(1)); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); QSignalSpy aboutToBeInsertedSpy(&model, &QAbstractItemModel::rowsAboutToBeInserted); QSignalSpy insertedSpy(&model, &QAbstractItemModel::rowsInserted); // WHEN queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); childrenProvider->insert(1, tasks.at(2)); // THEN QCOMPARE(aboutToBeInsertedSpy.size(), 1); QCOMPARE(aboutToBeInsertedSpy.first().at(0).value(), model.index(0, 0)); QCOMPARE(aboutToBeInsertedSpy.first().at(1).toInt(), 1); QCOMPARE(aboutToBeInsertedSpy.first().at(2).toInt(), 1); QCOMPARE(insertedSpy.size(), 1); QCOMPARE(insertedSpy.first().at(0).value(), model.index(0, 0)); QCOMPARE(insertedSpy.first().at(1).toInt(), 1); QCOMPARE(insertedSpy.first().at(2).toInt(), 1); } void shouldReactToTaskRemove() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); for (auto task : childrenTasks) childrenProvider->append(task); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); QSignalSpy aboutToBeRemovedSpy(&model, &QAbstractItemModel::rowsAboutToBeRemoved); QSignalSpy removedSpy(&model, &QAbstractItemModel::rowsRemoved); QSignalSpy aboutToBeInsertedSpy(&model, &QAbstractItemModel::rowsAboutToBeInserted); QSignalSpy insertedSpy(&model, &QAbstractItemModel::rowsInserted); QModelIndex removeIndex = model.index(0, 0); // WHEN // Remove children childrenProvider->removeAt(0); childrenProvider->removeAt(0); childrenProvider->removeAt(0); // Move children to Top Level provider->append(childrenTasks.at(0)); provider->append(childrenTasks.at(1)); provider->append(childrenTasks.at(2)); // Remove firt element from topLevel provider->removeAt(0); // THEN QCOMPARE(aboutToBeRemovedSpy.size(), 4); QCOMPARE(removedSpy.size(), 4); for (int i = 0; i < aboutToBeRemovedSpy.size(); i++) { if (i != 3) QCOMPARE(aboutToBeRemovedSpy.at(i).at(0).value(), removeIndex); else QCOMPARE(aboutToBeRemovedSpy.at(i).at(0).value(), QModelIndex()); QCOMPARE(aboutToBeRemovedSpy.at(i).at(1).toInt(), 0); QCOMPARE(aboutToBeRemovedSpy.at(i).at(2).toInt(), 0); if (i != 3) QCOMPARE(removedSpy.at(i).at(0).value(), removeIndex); else QCOMPARE(removedSpy.at(i).at(0).value(), QModelIndex()); QCOMPARE(removedSpy.at(i).at(1).toInt(), 0); QCOMPARE(removedSpy.at(i).at(2).toInt(), 0); } QCOMPARE(aboutToBeInsertedSpy.size(), 3); QCOMPARE(insertedSpy.size(), 3); for (int i = 0; i < aboutToBeInsertedSpy.size(); i++) { QCOMPARE(aboutToBeInsertedSpy.at(i).at(0).value(), QModelIndex()); QCOMPARE(aboutToBeInsertedSpy.at(i).at(1).toInt(), i + 3); QCOMPARE(aboutToBeInsertedSpy.at(i).at(2).toInt(), i + 3); QCOMPARE(insertedSpy.at(i).at(0).value(), QModelIndex()); QCOMPARE(insertedSpy.at(i).at(1).toInt(), i + 3); QCOMPARE(insertedSpy.at(i).at(1).toInt(), i + 3); } } void shouldReactToTaskChange() { // GIVEN // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); for (auto task : childrenTasks) childrenProvider->append(task); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); // WHEN auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); QSignalSpy dataChangedSpy(&model, &QAbstractItemModel::dataChanged); // WHEN tasks.at(2)->setDone(true); childrenTasks.at(2)->setDone(true); provider->replace(2, tasks.at(2)); childrenProvider->replace(2, tasks.at(2)); // THEN QCOMPARE(dataChangedSpy.size(), 2); QCOMPARE(dataChangedSpy.first().at(0).value(), model.index(2, 0)); QCOMPARE(dataChangedSpy.first().at(1).value(), model.index(2, 0)); QCOMPARE(dataChangedSpy.last().at(0).value(), model.index(2, 0, model.index(0, 0))); QCOMPARE(dataChangedSpy.last().at(1).value(), model.index(2, 0, model.index(0, 0))); } void shouldAllowEditsAndChecks() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); for (auto task : childrenTasks) childrenProvider->append(task); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); // WHEN auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); // WHEN // Nothing particular // THEN for (int row = 0; row < tasks.size(); row++) { QVERIFY(model.flags(model.index(row, 0)) & Qt::ItemIsEditable); QVERIFY(model.flags(model.index(row, 0)) & Qt::ItemIsUserCheckable); } for (int row = 0; row < childrenTasks.size(); row++) { QVERIFY(model.flags(model.index(row, 0, model.index(0, 0))) & Qt::ItemIsEditable); QVERIFY(model.flags(model.index(row, 0, model.index(0, 0))) & Qt::ItemIsUserCheckable); } } void shouldSaveChanges() { // GIVEN auto tasks = createTasks(); const int taskPos = 1; const auto task = tasks[taskPos]; auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto childrenTasks = createChildrenTasks(); auto childrenProvider = Domain::QueryResultProvider::Ptr::create(); for (auto task : childrenTasks) childrenProvider->append(task); auto childrenList = Domain::QueryResult::create(childrenProvider); auto emptyProvider = Domain::QueryResultProvider::Ptr::create(); auto emptyList = Domain::QueryResult::create(emptyProvider); Utils::MockObject queryMock; queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(0)).thenReturn(childrenList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(tasks.at(2)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(0)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(1)).thenReturn(emptyList); queryMock(&Domain::TaskQueries::findChildren).when(childrenTasks.at(2)).thenReturn(emptyList); Utils::MockObject repositoryMock; repositoryMock(&Domain::TaskRepository::update).when(task).thenReturn(Q_NULLPTR); auto queryGenerator = [&](const Domain::Task::Ptr &task) { if (!task) return Domain::QueryResult::create(provider); else return queryMock.getInstance()->findChildren(task); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable; }; auto dataFunction = [](const Domain::Task::Ptr &task, int role) -> QVariant { if (role != Qt::DisplayRole && role != Qt::CheckStateRole) { return QVariant(); } if (role == Qt::DisplayRole) return task->title(); else return task->isDone() ? Qt::Checked : Qt::Unchecked; }; auto setDataFunction = [&](const Domain::Task::Ptr &task, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } if (role == Qt::EditRole) { task->setTitle(value.toString()); } else { task->setDone(value.toInt() == Qt::Checked); } repositoryMock.getInstance()->update(task); return true; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, Q_NULLPTR); new ModelTest(&model); QSignalSpy titleChangedSpy(task.data(), &Domain::Task::titleChanged); QSignalSpy doneChangedSpy(task.data(), &Domain::Task::doneChanged); // WHEN const auto index = model.index(taskPos, 0); model.setData(index, "alternate second"); model.setData(index, Qt::Checked, Qt::CheckStateRole); // THEN QVERIFY(repositoryMock(&Domain::TaskRepository::update).when(task).exactly(2)); QCOMPARE(titleChangedSpy.size(), 1); - QCOMPARE(titleChangedSpy.first().first().toString(), QString("alternate second")); + QCOMPARE(titleChangedSpy.first().first().toString(), QStringLiteral("alternate second")); QCOMPARE(doneChangedSpy.size(), 1); QCOMPARE(doneChangedSpy.first().first().toBool(), true); } void shouldProvideUnderlyingObject() { // GIVEN auto provider = Domain::QueryResultProvider::Ptr::create(); provider->append(Qt::red); provider->append(Qt::green); provider->append(Qt::blue); auto queryGenerator = [&](const QColor &color) { if (!color.isValid()) return Domain::QueryResult::create(provider); else return Domain::QueryResult::Ptr(); }; auto flagsFunction = [](const QColor &) { return Qt::NoItemFlags; }; auto dataFunction = [](const QColor &, int) { return QVariant(); }; auto setDataFunction = [](const QColor &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction); new ModelTest(&model); // WHEN const QModelIndex index = model.index(1, 0); const QVariant data = index.data(Presentation::QueryTreeModel::ObjectRole); // THEN QVERIFY(data.isValid()); QCOMPARE(data.value(), provider->data().at(1)); } void shouldProvideUnderlyingTaskAsArtifact() { // GIVEN auto provider = Domain::QueryResultProvider::Ptr::create(); foreach (const auto &task, createTasks()) provider->append(task); auto queryGenerator = [&](const Domain::Task::Ptr &artifact) { if (!artifact) return Domain::QueryResult::create(provider); else return Domain::QueryResult::Ptr(); }; auto flagsFunction = [](const Domain::Task::Ptr &) { return Qt::NoItemFlags; }; auto dataFunction = [](const Domain::Task::Ptr &, int) { return QVariant(); }; auto setDataFunction = [](const Domain::Task::Ptr &, const QVariant &, int) { return false; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction); new ModelTest(&model); // WHEN const QModelIndex index = model.index(1, 0); const QVariant data = index.data(Presentation::QueryTreeModel::ObjectRole); // THEN QVERIFY(data.isValid()); // Note it says Artifact and *not* Task here, it should up-cast automatically QVERIFY(!data.value().isNull()); QCOMPARE(data.value(), provider->data().at(1).staticCast()); } void shouldMoveOnlyDuringDragAndDrop() { // GIVEN auto queryGenerator = [&] (const QColor &) { return Domain::QueryResult::Ptr(); }; auto flagsFunction = [] (const QColor &) { return Qt::NoItemFlags; }; auto dataFunction = [] (const QColor &, int) { return QVariant(); }; auto setDataFunction = [] (const QColor &, const QVariant &, int) { return false; }; auto dropFunction = [] (const QMimeData *, Qt::DropAction, const QColor &) { return false; }; auto dragFunction = [] (const QList &) { return Q_NULLPTR; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, dropFunction, dragFunction); // THEN QCOMPARE(model.supportedDragActions(), Qt::MoveAction); QCOMPARE(model.supportedDropActions(), Qt::MoveAction); } void shouldCreateMimeData() { // GIVEN auto provider = Domain::QueryResultProvider::Ptr::create(); provider->append(Qt::red); provider->append(Qt::green); provider->append(Qt::blue); auto queryGenerator = [&] (const QColor &color) { if (!color.isValid()) return Domain::QueryResult::create(provider); else return Domain::QueryResult::Ptr(); }; auto flagsFunction = [] (const QColor &) { return Qt::NoItemFlags; }; auto dataFunction = [] (const QColor &, int) { return QVariant(); }; auto setDataFunction = [] (const QColor &, const QVariant &, int) { return false; }; auto dropFunction = [] (const QMimeData *, Qt::DropAction, const QColor &) { return false; }; auto dragFunction = [] (const QList &colors) { auto mimeData = new QMimeData; mimeData->setColorData(QVariant::fromValue(colors)); return mimeData; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, dropFunction, dragFunction); new ModelTest(&model); // WHEN auto data = model.mimeData(QList() << model.index(1, 0) << model.index(2, 0)); // THEN QVERIFY(data); - QVERIFY(model.mimeTypes().contains("application/x-zanshin-object")); + QVERIFY(model.mimeTypes().contains(QStringLiteral("application/x-zanshin-object"))); QList colors; colors << Qt::green << Qt::blue; QCOMPARE(data->colorData().value>(), colors); } void shouldDropMimeData_data() { QTest::addColumn("row"); QTest::addColumn("column"); QTest::addColumn("parentRow"); QTest::addColumn("callExpected"); QTest::newRow("drop on object") << -1 << -1 << 2 << true; QTest::newRow("drop between object") << 1 << 0 << -1 << true; QTest::newRow("drop in empty area") << -1 << -1 << -1 << true; } void shouldDropMimeData() { // GIVEN QFETCH(int, row); QFETCH(int, column); QFETCH(int, parentRow); QFETCH(bool, callExpected); bool dropCalled = false; const QMimeData *droppedData = Q_NULLPTR; QColor colorSeen; auto provider = Domain::QueryResultProvider::Ptr::create(); provider->append(Qt::red); provider->append(Qt::green); provider->append(Qt::blue); auto queryGenerator = [&] (const QColor &color) { if (!color.isValid()) return Domain::QueryResult::create(provider); else return Domain::QueryResult::Ptr(); }; auto flagsFunction = [] (const QColor &) { return Qt::NoItemFlags; }; auto dataFunction = [] (const QColor &, int) { return QVariant(); }; auto setDataFunction = [] (const QColor &, const QVariant &, int) { return false; }; auto dropFunction = [&] (const QMimeData *data, Qt::DropAction, const QColor &color) { dropCalled = true; droppedData = data; colorSeen = color; return false; }; auto dragFunction = [] (const QList &) -> QMimeData* { return Q_NULLPTR; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, dropFunction, dragFunction); new ModelTest(&model); // WHEN auto data = new QMimeData; const QModelIndex parent = parentRow >= 0 ? model.index(parentRow, 0) : QModelIndex(); model.dropMimeData(data, Qt::MoveAction, row, column, parent); // THEN QCOMPARE(dropCalled, callExpected); if (callExpected) { QCOMPARE(droppedData, data); QCOMPARE(colorSeen, parent.data(Presentation::QueryTreeModelBase::ObjectRole).value()); } } void shouldPreventCyclesByDragAndDrop() { // GIVEN bool dropCalled = false; auto topProvider = Domain::QueryResultProvider::Ptr::create(); - topProvider->append("1"); - topProvider->append("2"); - topProvider->append("3"); + topProvider->append(QStringLiteral("1")); + topProvider->append(QStringLiteral("2")); + topProvider->append(QStringLiteral("3")); auto firstLevelProvider = Domain::QueryResultProvider::Ptr::create(); - firstLevelProvider->append("2.1"); - firstLevelProvider->append("2.2"); - firstLevelProvider->append("2.3"); + firstLevelProvider->append(QStringLiteral("2.1")); + firstLevelProvider->append(QStringLiteral("2.2")); + firstLevelProvider->append(QStringLiteral("2.3")); auto secondLevelProvider = Domain::QueryResultProvider::Ptr::create(); - secondLevelProvider->append("2.1.1"); - secondLevelProvider->append("2.1.2"); - secondLevelProvider->append("2.1.3"); + secondLevelProvider->append(QStringLiteral("2.1.1")); + secondLevelProvider->append(QStringLiteral("2.1.2")); + secondLevelProvider->append(QStringLiteral("2.1.3")); auto queryGenerator = [&] (const QString &string) { if (string.isEmpty()) return Domain::QueryResult::create(topProvider); - else if (string == "2") + else if (string == QLatin1String("2")) return Domain::QueryResult::create(firstLevelProvider); - else if (string == "2.1") + else if (string == QLatin1String("2.1")) return Domain::QueryResult::create(secondLevelProvider); else return Domain::QueryResult::Ptr(); }; auto flagsFunction = [] (const QString &) { return Qt::NoItemFlags; }; auto dataFunction = [] (const QString &, int) { return QVariant(); }; auto setDataFunction = [] (const QString &, const QVariant &, int) { return false; }; auto dropFunction = [&] (const QMimeData *, Qt::DropAction, const QString &) { dropCalled = true; return false; }; auto dragFunction = [] (const QStringList &strings) -> QMimeData* { auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(strings)); return data; }; Presentation::QueryTreeModel model(queryGenerator, flagsFunction, dataFunction, setDataFunction, dropFunction, dragFunction); new ModelTest(&model); const auto indexes = QModelIndexList() << model.index(0, 0) << model.index(1, 0) << model.index(1, 0, model.index(1, 0)); // WHEN auto data = model.mimeData(indexes); const auto parent = model.index(1, 0, model.index(0, 0, model.index(1, 0))); model.dropMimeData(data, Qt::MoveAction, -1, -1, parent); // THEN QVERIFY(!dropCalled); } }; ZANSHIN_TEST_MAIN(QueryTreeModelTest) #include "querytreemodeltest.moc" diff --git a/tests/units/presentation/tagpagemodeltest.cpp b/tests/units/presentation/tagpagemodeltest.cpp index 8c8fe4f7..ce3df1bb 100644 --- a/tests/units/presentation/tagpagemodeltest.cpp +++ b/tests/units/presentation/tagpagemodeltest.cpp @@ -1,336 +1,336 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Franck Arrecot 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "domain/noterepository.h" #include "domain/tagqueries.h" #include "domain/tagrepository.h" #include "presentation/tagpagemodel.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class TagPageModelTest : public QObject { Q_OBJECT private slots: void shouldListTagNotesInCentralListModel() { // GIVEN // One Tag auto tag = Domain::Tag::Ptr::create(); // Two notes auto note1 = Domain::Note::Ptr::create(); - note1->setTitle("note1"); + note1->setTitle(QStringLiteral("note1")); auto note2 = Domain::Note::Ptr::create(); - note2->setTitle("note2"); + note2->setTitle(QStringLiteral("note2")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findNotes).when(tag).thenReturn(noteResult); Utils::MockObject tagRepositoryMock; Utils::MockObject noteRepositoryMock; Presentation::TagPageModel page(tag, tagQueriesMock.getInstance(), tagRepositoryMock.getInstance(), noteRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = page.centralListModel(); // THEN const QModelIndex note1Index = model->index(0, 0); const QModelIndex note2Index = model->index(1, 0); QCOMPARE(page.tag(), tag); QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(note1Index), 0); QCOMPARE(model->rowCount(note2Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; QCOMPARE(model->flags(note1Index), defaultFlags); QCOMPARE(model->flags(note2Index), defaultFlags); QCOMPARE(model->data(note1Index).toString(), note1->title()); QCOMPARE(model->data(note2Index).toString(), note2->title()); QCOMPARE(model->data(note1Index, Qt::EditRole).toString(), note1->title()); QCOMPARE(model->data(note2Index, Qt::EditRole).toString(), note2->title()); QVERIFY(!model->data(note1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(note2Index, Qt::CheckStateRole).isValid()); // WHEN noteRepositoryMock(&Domain::NoteRepository::update).when(note1).thenReturn(new FakeJob(this)); noteRepositoryMock(&Domain::NoteRepository::update).when(note2).thenReturn(new FakeJob(this)); QVERIFY(model->setData(note1Index, "newNote1")); QVERIFY(model->setData(note2Index, "newNote2")); QVERIFY(!model->setData(note1Index, Qt::Checked, Qt::CheckStateRole)); QVERIFY(!model->setData(note2Index, Qt::Checked, Qt::CheckStateRole)); // THEN QVERIFY(noteRepositoryMock(&Domain::NoteRepository::update).when(note1).exactly(1)); QVERIFY(noteRepositoryMock(&Domain::NoteRepository::update).when(note2).exactly(1)); - QCOMPARE(note1->title(), QString("newNote1")); - QCOMPARE(note2->title(), QString("newNote2")); + QCOMPARE(note1->title(), QStringLiteral("newNote1")); + QCOMPARE(note2->title(), QStringLiteral("newNote2")); // WHEN auto data = model->mimeData(QModelIndexList() << note2Index); // THEN - QVERIFY(data->hasFormat("application/x-zanshin-object")); + QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Artifact::List() << note2); } void shouldAddNotes() { // GIVEN // One Tag auto tag = Domain::Tag::Ptr::create(); // ... in fact we won't list any model Utils::MockObject tagQueriesMock; Utils::MockObject tagRepositoryMock; // We'll gladly create a note though Utils::MockObject noteRepositoryMock; noteRepositoryMock(&Domain::NoteRepository::createInTag).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::TagPageModel page(tag, tagQueriesMock.getInstance(), tagRepositoryMock.getInstance(), noteRepositoryMock.getInstance()); // WHEN - auto title = QString("New note"); + auto title = QStringLiteral("New note"); auto note = page.addItem(title).objectCast(); // THEN QVERIFY(noteRepositoryMock(&Domain::NoteRepository::createInTag).when(any(), any()) .exactly(1)); QVERIFY(note); QCOMPARE(note->title(), title); } void shouldRemoveItem() { // GIVEN // One domain tag auto tag = Domain::Tag::Ptr::create(); // Two notes auto note1 = Domain::Note::Ptr::create(); auto note2 = Domain::Note::Ptr::create(); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findNotes).when(tag).thenReturn(noteResult); Utils::MockObject tagRepositoryMock; tagRepositoryMock(&Domain::TagRepository::dissociate).when(tag, note2).thenReturn(new FakeJob(this)); Utils::MockObject noteRepositoryMock; Presentation::TagPageModel page(tag, tagQueriesMock.getInstance(), tagRepositoryMock.getInstance(), noteRepositoryMock.getInstance()); // WHEN const QModelIndex indexNote2 = page.centralListModel()->index(1, 0); page.removeItem(indexNote2); // THEN QVERIFY(tagRepositoryMock(&Domain::TagRepository::dissociate).when(tag, note2).exactly(1)); } void shouldGetAnErrorMessageWhenRemoveItemFailed() { // GIVEN // One domain tag auto tag = Domain::Tag::Ptr::create(); - tag->setName("Tag1"); + tag->setName(QStringLiteral("Tag1")); // Two notes auto note1 = Domain::Note::Ptr::create(); - note1->setTitle("Note 1"); + note1->setTitle(QStringLiteral("Note 1")); auto note2 = Domain::Note::Ptr::create(); - note2->setTitle("Note 2"); + note2->setTitle(QStringLiteral("Note 2")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(note1); noteProvider->append(note2); Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findNotes).when(tag).thenReturn(noteResult); Utils::MockObject tagRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); tagRepositoryMock(&Domain::TagRepository::dissociate).when(tag, note2).thenReturn(job); Utils::MockObject noteRepositoryMock; Presentation::TagPageModel page(tag, tagQueriesMock.getInstance(), tagRepositoryMock.getInstance(), noteRepositoryMock.getInstance()); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN const QModelIndex indexNote2 = page.centralListModel()->index(1, 0); page.removeItem(indexNote2); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove note Note 2 from tag Tag1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove note Note 2 from tag Tag1: Foo")); } void shouldGetAnErrorMessageWhenAddNoteFailed() { // GIVEN // One Tag auto tag = Domain::Tag::Ptr::create(); - tag->setName("Tag1"); + tag->setName(QStringLiteral("Tag1")); // ... in fact we won't list any model Utils::MockObject tagQueriesMock; Utils::MockObject tagRepositoryMock; // We'll gladly create a note though Utils::MockObject noteRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); noteRepositoryMock(&Domain::NoteRepository::createInTag).when(any(), any()) .thenReturn(job); Presentation::TagPageModel page(tag, tagQueriesMock.getInstance(), tagRepositoryMock.getInstance(), noteRepositoryMock.getInstance()); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN - page.addItem("New note"); + page.addItem(QStringLiteral("New note")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add note New note in tag Tag1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add note New note in tag Tag1: Foo")); } void shouldGetAnErrorMessageWhenUpdateNoteFailed() { // GIVEN // One Tag auto tag = Domain::Tag::Ptr::create(); - tag->setName("Tag1"); + tag->setName(QStringLiteral("Tag1")); // One note and one task auto rootNote = Domain::Note::Ptr::create(); - rootNote->setTitle("rootNote"); + rootNote->setTitle(QStringLiteral("rootNote")); auto noteProvider = Domain::QueryResultProvider::Ptr::create(); auto noteResult = Domain::QueryResult::create(noteProvider); noteProvider->append(rootNote); Utils::MockObject tagQueriesMock; tagQueriesMock(&Domain::TagQueries::findNotes).when(tag).thenReturn(noteResult); Utils::MockObject noteRepositoryMock; Utils::MockObject tagRepositoryMock; Presentation::TagPageModel page(tag, tagQueriesMock.getInstance(), tagRepositoryMock.getInstance(), noteRepositoryMock.getInstance()); QAbstractItemModel *model = page.centralListModel(); const QModelIndex rootNoteIndex = model->index(0, 0); FakeErrorHandler errorHandler; page.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); noteRepositoryMock(&Domain::NoteRepository::update).when(rootNote).thenReturn(job); QVERIFY(model->setData(rootNoteIndex, "newRootNote")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify note rootNote in tag Tag1: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify note rootNote in tag Tag1: Foo")); } }; ZANSHIN_TEST_MAIN(TagPageModelTest) #include "tagpagemodeltest.moc" diff --git a/tests/units/presentation/taskinboxpagemodeltest.cpp b/tests/units/presentation/taskinboxpagemodeltest.cpp index 83dab789..07293382 100644 --- a/tests/units/presentation/taskinboxpagemodeltest.cpp +++ b/tests/units/presentation/taskinboxpagemodeltest.cpp @@ -1,537 +1,537 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/taskinboxpagemodel.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class TaskInboxPageModelTest : public QObject { Q_OBJECT private slots: void shouldListInboxInCentralListModel() { // GIVEN // One note and one task auto rootTask = Domain::Task::Ptr::create(); - rootTask->setTitle("rootTask"); + rootTask->setTitle(QStringLiteral("rootTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(rootTask); // One task under the root task auto childTask = Domain::Task::Ptr::create(); - childTask->setTitle("childTask"); + childTask->setTitle(QStringLiteral("childTask")); childTask->setDone(true); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = inbox.centralListModel(); // THEN const QModelIndex rootTaskIndex = model->index(0, 0); const QModelIndex childTaskIndex = model->index(0, 0, rootTaskIndex); QCOMPARE(model->rowCount(), 1); QCOMPARE(model->rowCount(rootTaskIndex), 1); QCOMPARE(model->rowCount(childTaskIndex), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; QCOMPARE(model->flags(rootTaskIndex), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(childTaskIndex), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->data(rootTaskIndex).toString(), rootTask->title()); QCOMPARE(model->data(childTaskIndex).toString(), childTask->title()); QCOMPARE(model->data(rootTaskIndex, Qt::EditRole).toString(), rootTask->title()); QCOMPARE(model->data(childTaskIndex, Qt::EditRole).toString(), childTask->title()); QVERIFY(model->data(rootTaskIndex, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTaskIndex, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(rootTaskIndex, Qt::CheckStateRole).toBool(), rootTask->isDone()); QCOMPARE(model->data(childTaskIndex, Qt::CheckStateRole).toBool(), childTask->isDone()); // WHEN taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask).thenReturn(new FakeJob(this)); QVERIFY(model->setData(rootTaskIndex, "newRootTask")); QVERIFY(model->setData(childTaskIndex, "newChildTask")); QVERIFY(model->setData(rootTaskIndex, Qt::Checked, Qt::CheckStateRole)); QVERIFY(model->setData(childTaskIndex, Qt::Unchecked, Qt::CheckStateRole)); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask).exactly(2)); - QCOMPARE(rootTask->title(), QString("newRootTask")); - QCOMPARE(childTask->title(), QString("newChildTask")); + QCOMPARE(rootTask->title(), QStringLiteral("newRootTask")); + QCOMPARE(childTask->title(), QStringLiteral("newChildTask")); QCOMPARE(rootTask->isDone(), true); QCOMPARE(childTask->isDone(), false); // WHEN QMimeData *data = model->mimeData(QModelIndexList() << childTaskIndex); // THEN - QVERIFY(data->hasFormat("application/x-zanshin-object")); + QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Artifact::List() << childTask); // WHEN auto childTask2 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask2).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask2).exactly(1)); // WHEN auto childTask3 = Domain::Task::Ptr::create(); auto childTask4 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask3 << childTask4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).exactly(1)); } void shouldAddTasksInInbox() { // GIVEN // ... in fact we won't list any model Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::create).when(any()).thenReturn(new FakeJob(this)); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - auto title = QString("New task"); + auto title = QStringLiteral("New task"); auto task = inbox.addItem(title).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::create).when(any()).exactly(1)); QVERIFY(task); QCOMPARE(task->title(), title); } void shouldAddChildTask() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - const auto title = QString("New task"); + const auto title = QStringLiteral("New task"); const auto parentIndex = inbox.centralListModel()->index(0, 0); const auto createdTask = inbox.addItem(title, parentIndex).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .exactly(1)); QVERIFY(createdTask); QCOMPARE(createdTask->title(), title); } void shouldGetAnErrorMessageWhenAddTaskFailed() { // GIVEN // ... in fact we won't list any model Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::create).when(any()).thenReturn(job); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN - inbox.addItem("New task"); + inbox.addItem(QStringLiteral("New task")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot add task New task in Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add task New task in Inbox: Foo")); } void shouldDeleteItems() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(new FakeJob(this)); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.removeItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).exactly(1)); } void shouldGetAnErrorMessageWhenDeleteItemsFailed() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); - task2->setTitle("task2"); + task2->setTitle(QStringLiteral("task2")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(task1); inboxProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(job); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.removeItem(index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot remove task task2 from Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove task task2 from Inbox: Foo")); } void shouldPromoteItem() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(new FakeJob(this)); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.promoteItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).exactly(1)); } void shouldGetAnErrorMessageWhenPromoteItemFailed() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); - task2->setTitle("task2"); + task2->setTitle(QStringLiteral("task2")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(task1); inboxProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(job); Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.promoteItem(index); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot promote task task2 to be a project: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot promote task task2 to be a project: Foo")); } void shouldGetAnErrorMessageWhenUpdateTaskFailed() { // GIVEN // One note and one task auto rootTask = Domain::Task::Ptr::create(); - rootTask->setTitle("rootTask"); + rootTask->setTitle(QStringLiteral("rootTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(rootTask); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); Utils::MockObject taskRepositoryMock; Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex rootTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).thenReturn(job); QVERIFY(model->setData(rootTaskIndex, "newRootTask")); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot modify task rootTask in Inbox: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task rootTask in Inbox: Foo")); } void shouldGetAnErrorMessageWhenAssociateTaskFailed() { // GIVEN // One note and one task auto rootTask = Domain::Task::Ptr::create(); - rootTask->setTitle("rootTask"); + rootTask->setTitle(QStringLiteral("rootTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(rootTask); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); Utils::MockObject taskRepositoryMock; Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex rootTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto childTask3 = Domain::Task::Ptr::create(); - childTask3->setTitle("childTask3"); + childTask3->setTitle(QStringLiteral("childTask3")); auto childTask4 = Domain::Task::Ptr::create(); auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).thenReturn(new FakeJob(this)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask3 << childTask4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot move task childTask3 as sub-task of rootTask: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move task childTask3 as sub-task of rootTask: Foo")); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).exactly(1)); } void shouldDeparentWhenNoErrorHappens() { // GIVEN // One note and one task, both top level auto topLevelTask = Domain::Task::Ptr::create(); - topLevelTask->setTitle("topLevelTask"); + topLevelTask->setTitle(QStringLiteral("topLevelTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(topLevelTask); // Two tasks under the top level task auto childTask = Domain::Task::Ptr::create(); - childTask->setTitle("childTask"); + childTask->setTitle(QStringLiteral("childTask")); childTask->setDone(true); auto childTask2 = Domain::Task::Ptr::create(); - childTask2->setTitle("childTask2"); + childTask2->setTitle(QStringLiteral("childTask2")); childTask2->setDone(false); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask); taskProvider->append(childTask2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(topLevelTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex emptyPartModel = QModelIndex(); // model root, drop on the empty part is equivalent FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); - job->setExpectedError(KJob::KilledJobError, "Foo"); + job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).thenReturn(new FakeJob(this)); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask << childTask2)); // both will be DnD on the empty part model->dropMimeData(data, Qt::MoveAction, -1, -1, emptyPartModel); // THEN QTest::qWait(150); - QCOMPARE(errorHandler.m_message, QString("Cannot deparent task childTask from its parent: Foo")); + QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot deparent task childTask from its parent: Foo")); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).exactly(1)); } }; ZANSHIN_TEST_MAIN(TaskInboxPageModelTest) #include "taskinboxpagemodeltest.moc" diff --git a/tests/units/presentation/tasklistmodeltest.cpp b/tests/units/presentation/tasklistmodeltest.cpp index 5b8e9ae3..80f12acb 100644 --- a/tests/units/presentation/tasklistmodeltest.cpp +++ b/tests/units/presentation/tasklistmodeltest.cpp @@ -1,236 +1,236 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include "domain/taskrepository.h" #include "presentation/tasklistmodel.h" #include "testlib/modeltest.h" using namespace mockitopp; Q_DECLARE_METATYPE(QModelIndex) class TaskListModelTest : public QObject { Q_OBJECT public: explicit TaskListModelTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } private: Domain::Task::List createTasks() const { Domain::Task::List result; const QStringList titles = {"first", "second", "third"}; const QList doneStates = {true, false, false}; Q_ASSERT(titles.size() == doneStates.size()); for (int i = 0; i < titles.size(); i++) { auto task = Domain::Task::Ptr::create(); task->setTitle(titles.at(i)); task->setDone(doneStates.at(i)); result << task; } return result; } private slots: void shouldListTasks() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto list = Domain::QueryResult::create(provider); // WHEN Presentation::TaskListModel model(list, Domain::TaskRepository::Ptr()); new ModelTest(&model); // THEN QCOMPARE(model.rowCount(), tasks.size()); QCOMPARE(model.rowCount(model.index(0)), 0); for (int i = 0; i < tasks.size(); i++) { auto task = tasks.at(i); auto index = model.index(i); QCOMPARE(model.data(index), model.data(index, Qt::DisplayRole)); QCOMPARE(model.data(index).toString(), task->title()); QCOMPARE(model.data(index, Qt::CheckStateRole).toInt() == Qt::Checked, task->isDone()); QCOMPARE(model.data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked, !task->isDone()); } } void shouldReactToTaskAdd() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); provider->append(tasks.at(0)); provider->append(tasks.at(1)); auto list = Domain::QueryResult::create(provider); Presentation::TaskListModel model(list, Domain::TaskRepository::Ptr()); new ModelTest(&model); QSignalSpy aboutToBeInsertedSpy(&model, &QAbstractItemModel::rowsAboutToBeInserted); QSignalSpy insertedSpy(&model, &QAbstractItemModel::rowsInserted); // WHEN provider->insert(1, tasks.at(2)); // THEN QCOMPARE(aboutToBeInsertedSpy.size(), 1); QCOMPARE(aboutToBeInsertedSpy.first().at(0).value(), QModelIndex()); QCOMPARE(aboutToBeInsertedSpy.first().at(1).toInt(), 1); QCOMPARE(aboutToBeInsertedSpy.first().at(2).toInt(), 1); QCOMPARE(insertedSpy.size(), 1); QCOMPARE(insertedSpy.first().at(0).value(), QModelIndex()); QCOMPARE(insertedSpy.first().at(1).toInt(), 1); QCOMPARE(insertedSpy.first().at(2).toInt(), 1); } void shouldReactToTaskRemove() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto list = Domain::QueryResult::create(provider); Presentation::TaskListModel model(list, Domain::TaskRepository::Ptr()); new ModelTest(&model); QSignalSpy aboutToBeRemovedSpy(&model, &QAbstractItemModel::rowsAboutToBeRemoved); QSignalSpy removedSpy(&model, &QAbstractItemModel::rowsRemoved); // WHEN provider->removeAt(0); // THEN QCOMPARE(aboutToBeRemovedSpy.size(), 1); QCOMPARE(aboutToBeRemovedSpy.first().at(0).value(), QModelIndex()); QCOMPARE(aboutToBeRemovedSpy.first().at(1).toInt(), 0); QCOMPARE(aboutToBeRemovedSpy.first().at(2).toInt(), 0); QCOMPARE(removedSpy.size(), 1); QCOMPARE(removedSpy.first().at(0).value(), QModelIndex()); QCOMPARE(removedSpy.first().at(1).toInt(), 0); QCOMPARE(removedSpy.first().at(2).toInt(), 0); } void shouldReactToTaskChange() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto list = Domain::QueryResult::create(provider); Presentation::TaskListModel model(list, Domain::TaskRepository::Ptr()); new ModelTest(&model); QSignalSpy dataChangedSpy(&model, &QAbstractItemModel::dataChanged); // WHEN tasks.at(2)->setDone(true); provider->replace(2, tasks.at(2)); // THEN QCOMPARE(dataChangedSpy.size(), 1); QCOMPARE(dataChangedSpy.first().at(0).value(), model.index(2)); QCOMPARE(dataChangedSpy.first().at(1).value(), model.index(2)); } void shouldAllowEditsAndChecks() { // GIVEN auto tasks = createTasks(); auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto list = Domain::QueryResult::create(provider); Presentation::TaskListModel model(list, Domain::TaskRepository::Ptr()); new ModelTest(&model); // WHEN // Nothing particular // THEN for (int row = 0; row < tasks.size(); row++) { QVERIFY(model.flags(model.index(row)) & Qt::ItemIsEditable); QVERIFY(model.flags(model.index(row)) & Qt::ItemIsUserCheckable); } } void shouldSaveChanges() { // GIVEN auto tasks = createTasks(); const int taskPos = 1; const auto task = tasks[taskPos]; auto provider = Domain::QueryResultProvider::Ptr::create(); for (auto task : tasks) provider->append(task); auto list = Domain::QueryResult::create(provider); Utils::MockObject repositoryMock; repositoryMock(&Domain::TaskRepository::update).when(task).thenReturn(Q_NULLPTR); Presentation::TaskListModel model(list, repositoryMock.getInstance()); new ModelTest(&model); QSignalSpy titleChangedSpy(task.data(), &Domain::Task::titleChanged); QSignalSpy doneChangedSpy(task.data(), &Domain::Task::doneChanged); // WHEN const auto index = model.index(taskPos); model.setData(index, "alternate second"); model.setData(index, Qt::Checked, Qt::CheckStateRole); // THEN QVERIFY(repositoryMock(&Domain::TaskRepository::update).when(task).exactly(2)); QCOMPARE(titleChangedSpy.size(), 1); - QCOMPARE(titleChangedSpy.first().first().toString(), QString("alternate second")); + QCOMPARE(titleChangedSpy.first().first().toString(), QStringLiteral("alternate second")); QCOMPARE(doneChangedSpy.size(), 1); QCOMPARE(doneChangedSpy.first().first().toBool(), true); } }; ZANSHIN_TEST_MAIN(TaskListModelTest) #include "tasklistmodeltest.moc" diff --git a/tests/units/presentation/workdaypagemodeltest.cpp b/tests/units/presentation/workdaypagemodeltest.cpp index ddc97637..1a78f7ff 100644 --- a/tests/units/presentation/workdaypagemodeltest.cpp +++ b/tests/units/presentation/workdaypagemodeltest.cpp @@ -1,376 +1,376 @@ /* This file is part of Zanshin Copyright 2015 Theo Vaucher 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "utils/datetime.h" #include "utils/mockobject.h" #include "domain/noterepository.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" #include "presentation/workdaypagemodel.h" using namespace mockitopp; using namespace mockitopp::matcher; class WorkdayPageModelTest : public QObject { Q_OBJECT private slots: void shouldListWorkdayInCentralListModel() { // GIVEN const auto today = Utils::DateTime::currentDateTime(); // Three tasks auto task1 = Domain::Task::Ptr::create(); - task1->setTitle("task1"); + task1->setTitle(QStringLiteral("task1")); task1->setStartDate(today.addDays(-10)); task1->setDueDate(today); auto task2 = Domain::Task::Ptr::create(); - task2->setTitle("task2"); + task2->setTitle(QStringLiteral("task2")); task2->setStartDate(today); task2->setDueDate(today.addDays(10)); auto task3 = Domain::Task::Ptr::create(); - task3->setTitle("task3"); + task3->setTitle(QStringLiteral("task3")); task3->setStartDate(today.addYears(-4)); task3->setDueDate(today.addYears(-3)); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); taskProvider->append(task3); // Two tasks under the task1 auto childTask11 = Domain::Task::Ptr::create(); - childTask11->setTitle("childTask11"); + childTask11->setTitle(QStringLiteral("childTask11")); auto childTask12 = Domain::Task::Ptr::create(); - childTask12->setTitle("childTask12"); + childTask12->setTitle(QStringLiteral("childTask12")); childTask12->setStartDate(today); childTask12->setDueDate(today); auto childTaskProvider = Domain::QueryResultProvider::Ptr::create(); auto childTaskResult = Domain::QueryResult::create(childTaskProvider); taskProvider->append(childTask12); childTaskProvider->append(childTask11); childTaskProvider->append(childTask12); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findWorkdayTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(childTaskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task3).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask11).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask12).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; Presentation::WorkdayPageModel workday(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = workday.centralListModel(); // THEN const QModelIndex task1Index = model->index(0, 0); const QModelIndex task2Index = model->index(1, 0); const QModelIndex task3Index = model->index(2, 0); const QModelIndex taskChildTask12Index = model->index(3, 0); const QModelIndex childTask11Index = model->index(0, 0, task1Index); const QModelIndex childTask12Index = model->index(1, 0, task1Index); QCOMPARE(model->rowCount(), 4); QCOMPARE(model->rowCount(task1Index), 2); QCOMPARE(model->rowCount(task2Index), 0); QCOMPARE(model->rowCount(task3Index), 0); QCOMPARE(model->rowCount(taskChildTask12Index), 0); QVERIFY(childTask11Index.isValid()); QVERIFY(childTask12Index.isValid()); QCOMPARE(model->rowCount(childTask11Index), 0); QCOMPARE(model->rowCount(childTask12Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; QCOMPARE(model->flags(task1Index), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(childTask11Index), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(childTask12Index), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(task2Index), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(task3Index), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(taskChildTask12Index), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->data(task1Index).toString(), task1->title()); QCOMPARE(model->data(childTask11Index).toString(), childTask11->title()); QCOMPARE(model->data(childTask12Index).toString(), childTask12->title()); QCOMPARE(model->data(task2Index).toString(), task2->title()); QCOMPARE(model->data(task3Index).toString(), task3->title()); QCOMPARE(model->data(taskChildTask12Index).toString(), childTask12->title()); QCOMPARE(model->data(task1Index, Qt::EditRole).toString(), task1->title()); QCOMPARE(model->data(childTask11Index, Qt::EditRole).toString(), childTask11->title()); QCOMPARE(model->data(childTask12Index, Qt::EditRole).toString(), childTask12->title()); QCOMPARE(model->data(task2Index, Qt::EditRole).toString(), task2->title()); QCOMPARE(model->data(task3Index, Qt::EditRole).toString(), task3->title()); QCOMPARE(model->data(taskChildTask12Index, Qt::EditRole).toString(), childTask12->title()); QVERIFY(model->data(task1Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTask11Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTask12Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(task2Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(task3Index, Qt::CheckStateRole).isValid()); QVERIFY(model->data(taskChildTask12Index, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(task1Index, Qt::CheckStateRole).toBool(), task1->isDone()); QCOMPARE(model->data(childTask11Index, Qt::CheckStateRole).toBool(), childTask11->isDone()); QCOMPARE(model->data(childTask12Index, Qt::CheckStateRole).toBool(), childTask12->isDone()); QCOMPARE(model->data(task2Index, Qt::CheckStateRole).toBool(), task2->isDone()); QCOMPARE(model->data(task3Index, Qt::CheckStateRole).toBool(), task3->isDone()); QCOMPARE(model->data(taskChildTask12Index, Qt::CheckStateRole).toBool(), childTask12->isDone()); // WHEN taskRepositoryMock(&Domain::TaskRepository::update).when(task1).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask11).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask12).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(task2).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(task3).thenReturn(new FakeJob(this)); QVERIFY(model->setData(task1Index, "newTask1")); QVERIFY(model->setData(childTask11Index, "newChildTask11")); QVERIFY(model->setData(task2Index, "newTask2")); QVERIFY(model->setData(task3Index, "newTask3")); QVERIFY(model->setData(taskChildTask12Index, "newChildTask12")); QVERIFY(model->setData(task1Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(childTask11Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(task2Index, Qt::Checked, Qt::CheckStateRole)); QVERIFY(model->setData(task3Index, Qt::Unchecked, Qt::CheckStateRole)); QVERIFY(model->setData(taskChildTask12Index, Qt::Checked, Qt::CheckStateRole)); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task1).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask11).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask12).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task2).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task3).exactly(2)); - QCOMPARE(task1->title(), QString("newTask1")); - QCOMPARE(childTask11->title(), QString("newChildTask11")); - QCOMPARE(childTask12->title(), QString("newChildTask12")); - QCOMPARE(task2->title(), QString("newTask2")); - QCOMPARE(task3->title(), QString("newTask3")); + QCOMPARE(task1->title(), QStringLiteral("newTask1")); + QCOMPARE(childTask11->title(), QStringLiteral("newChildTask11")); + QCOMPARE(childTask12->title(), QStringLiteral("newChildTask12")); + QCOMPARE(task2->title(), QStringLiteral("newTask2")); + QCOMPARE(task3->title(), QStringLiteral("newTask3")); QCOMPARE(task1->isDone(), false); QCOMPARE(childTask11->isDone(), false); QCOMPARE(childTask12->isDone(), true); QCOMPARE(task2->isDone(), true); QCOMPARE(task3->isDone(), false); // WHEN QMimeData *data = model->mimeData(QModelIndexList() << childTask12Index); // THEN - QVERIFY(data->hasFormat("application/x-zanshin-object")); + QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Artifact::List() << childTask12); // WHEN auto childTask2 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(childTask11, childTask2).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask2)); model->dropMimeData(data, Qt::MoveAction, -1, -1, childTask11Index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(childTask11, childTask2).exactly(1)); // WHEN auto childTask3 = Domain::Task::Ptr::create(); auto childTask4 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(childTask12, childTask3).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::associate).when(childTask12, childTask4).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask3 << childTask4)); model->dropMimeData(data, Qt::MoveAction, -1, -1, childTask12Index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(childTask12, childTask3).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(childTask12, childTask4).exactly(1)); // WHEN auto childTask5 = Domain::Task::Ptr::create(); QVERIFY(!childTask5->startDate().isValid()); taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask5).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask5).thenReturn(new FakeJob(this)); data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Artifact::List() << childTask5)); model->dropMimeData(data, Qt::MoveAction, -1, -1, QModelIndex()); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask5).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask5).exactly(1)); QCOMPARE(childTask5->startDate().date(), today.date()); } void shouldAddTasksInWorkdayPage() { // GIVEN // ... in fact we won't list any model Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::create).when(any()).thenReturn(new FakeJob(this)); Presentation::WorkdayPageModel workday(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - auto title = QString("New task"); + auto title = QStringLiteral("New task"); auto today = Utils::DateTime::currentDateTime(); auto task = workday.addItem(title).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::create).when(any()).exactly(1)); QVERIFY(task); QCOMPARE(task->title(), title); QCOMPARE(task->startDate().date(), today.date()); } void shouldAddChildTask() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findWorkdayTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::WorkdayPageModel workday(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN - const auto title = QString("New task"); + const auto title = QStringLiteral("New task"); const auto parentIndex = workday.centralListModel()->index(0, 0); const auto createdTask = workday.addItem(title, parentIndex).objectCast(); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .exactly(1)); QVERIFY(createdTask); QCOMPARE(createdTask->title(), title); QVERIFY(!createdTask->startDate().isValid()); } void shouldDeleteItems() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findWorkdayTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(new FakeJob(this)); Presentation::WorkdayPageModel workday(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = workday.centralListModel()->index(1, 0); workday.removeItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).exactly(1)); } void shouldPromoteItem() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findWorkdayTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(new FakeJob(this)); Presentation::WorkdayPageModel workday(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = workday.centralListModel()->index(1, 0); workday.promoteItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).exactly(1)); } }; ZANSHIN_TEST_MAIN(WorkdayPageModelTest) #include "workdaypagemodeltest.moc" diff --git a/tests/units/scripting/scripthandlertest.cpp b/tests/units/scripting/scripthandlertest.cpp index 173eb8fb..a4603551 100644 --- a/tests/units/scripting/scripthandlertest.cpp +++ b/tests/units/scripting/scripthandlertest.cpp @@ -1,90 +1,90 @@ /* This file is part of Zanshin Copyright 2015 Theo Vaucher 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "scripting/scripthandler.h" #include "utils/mockobject.h" class ScriptHandlerTest : public QObject { Q_OBJECT private slots: void shouldBindObjects() { // GIVEN Utils::MockObject taskRepositoryMock; // WHEN auto scripthandler = new Scripting::ScriptHandler(taskRepositoryMock.getInstance()); // THEN - QVERIFY(!scripthandler->engine()->globalObject().property("task").isNull()); - QVERIFY(scripthandler->engine()->globalObject().property("task").isObject()); + QVERIFY(!scripthandler->engine()->globalObject().property(QStringLiteral("task")).isNull()); + QVERIFY(scripthandler->engine()->globalObject().property(QStringLiteral("task")).isObject()); } void shouldEvaluateString() { // GIVEN Utils::MockObject taskRepositoryMock; auto scripthandler = new Scripting::ScriptHandler(taskRepositoryMock.getInstance()); - auto expression = QString("41+1"); + auto expression = QStringLiteral("41+1"); // WHEN QScriptValue result = scripthandler->evaluateString(expression); // THEN QVERIFY(result.isNumber()); QCOMPARE(result.toInt32(), 42); } void shouldEvaluateFile() { // GIVEN Utils::MockObject taskRepositoryMock; auto scripthandler = new Scripting::ScriptHandler(taskRepositoryMock.getInstance()); - auto expression = QString("41+1"); + auto expression = QStringLiteral("41+1"); QTemporaryFile scriptfile; scriptfile.setAutoRemove(true); scriptfile.open(); scriptfile.write(expression.toLocal8Bit()); scriptfile.close(); // WHEN QScriptValue result = scripthandler->evaluateFile(scriptfile.fileName()); // THEN QVERIFY(result.isNumber()); QCOMPARE(result.toInt32(), 42); } }; ZANSHIN_TEST_MAIN(ScriptHandlerTest) #include "scripthandlertest.moc" diff --git a/tests/units/testlib/akonadifakedatatest.cpp b/tests/units/testlib/akonadifakedatatest.cpp index 46b33c07..bf2eeda9 100644 --- a/tests/units/testlib/akonadifakedatatest.cpp +++ b/tests/units/testlib/akonadifakedatatest.cpp @@ -1,622 +1,622 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/akonadifakedata.h" #include "akonadi/akonadimonitorinterface.h" #include namespace QTest { template inline bool zCompareHelper(bool isOk, const T &left, const T &right, const char *actual, const char *expected, const char *file, int line) { return compare_helper(isOk, isOk ? "COMPARE()" : "Compared values are not the same", toString(left), toString(right), actual, expected, file, line); } // More aggressive compare to make sure we just don't get collections with ids out template <> inline bool qCompare(const Akonadi::Collection &left, const Akonadi::Collection &right, const char *actual, const char *expected, const char *file, int line) { return zCompareHelper((left == right) && (left.displayName() == right.displayName()), left, right, actual, expected, file, line); } // More aggressive compare to make sure we just don't get tags with ids out template <> inline bool qCompare(const Akonadi::Tag &left, const Akonadi::Tag &right, const char *actual, const char *expected, const char *file, int line) { return zCompareHelper((left == right) && (left.name() == right.name()), left, right, actual, expected, file, line); } // More aggressive compare to make sure we just don't get items with ids out template <> inline bool qCompare(const Akonadi::Item &left, const Akonadi::Item &right, const char *actual, const char *expected, const char *file, int line) { return zCompareHelper((left == right) && (left.payloadData() == right.payloadData()), left, right, actual, expected, file, line); } } class AkonadiFakeDataTest : public QObject { Q_OBJECT public: explicit AkonadiFakeDataTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } private slots: void shouldBeInitiallyEmpty() { // GIVEN auto data = Testlib::AkonadiFakeData(); // THEN QVERIFY(data.collections().isEmpty()); QVERIFY(data.tags().isEmpty()); QVERIFY(data.items().isEmpty()); } void shouldCreateCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionAdded); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); auto c2 = Akonadi::Collection(43); - c2.setName("43"); + c2.setName(QStringLiteral("43")); const auto colSet = QSet() << c1 << c2; // WHEN data.createCollection(c1); data.createCollection(c2); // THEN QCOMPARE(data.collections().toList().toSet(), colSet); QCOMPARE(data.collection(c1.id()), c1); QCOMPARE(data.collection(c2.id()), c2); QCOMPARE(spy.size(), 2); QCOMPARE(spy.takeFirst().takeFirst().value(), c1); QCOMPARE(spy.takeFirst().takeFirst().value(), c2); } void shouldModifyCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(c1.id()); - c2.setName("42-bis"); + c2.setName(QStringLiteral("42-bis")); // WHEN data.modifyCollection(c2); // THEN QCOMPARE(data.collections().size(), 1); QCOMPARE(data.collection(c1.id()), c2); QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().value(), c2); } void shouldNotLooseParentCollectionOnModifyCollection() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto root = Akonadi::Collection(42); - root.setName("root"); + root.setName(QStringLiteral("root")); data.createCollection(root); auto c1 = Akonadi::Collection(43); - c1.setName("43"); + c1.setName(QStringLiteral("43")); c1.setParentCollection(Akonadi::Collection(root.id())); data.createCollection(c1); auto c2 = Akonadi::Collection(c1.id()); - c2.setName("43-bis"); + c2.setName(QStringLiteral("43-bis")); // WHEN data.modifyCollection(c2); // THEN QCOMPARE(data.collections().size(), 2); QCOMPARE(data.collection(c1.id()), c2); QCOMPARE(data.collection(c1.id()).parentCollection().id(), root.id()); } void shouldListChildCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); auto c2 = Akonadi::Collection(43); - c2.setName("43"); + c2.setName(QStringLiteral("43")); c2.setParentCollection(Akonadi::Collection(42)); const auto colSet = QSet() << c2; // WHEN data.createCollection(c1); data.createCollection(c2); // THEN QVERIFY(data.childCollections(c2.id()).isEmpty()); QCOMPARE(data.childCollections(c1.id()).toList().toSet(), colSet); } void shouldReparentCollectionsOnModify() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(43); - c2.setName("43"); + c2.setName(QStringLiteral("43")); data.createCollection(c2); auto c3 = Akonadi::Collection(44); c3.setParentCollection(Akonadi::Collection(42)); data.createCollection(c3); // WHEN c3.setParentCollection(Akonadi::Collection(43)); data.modifyCollection(c3); // THEN QVERIFY(data.childCollections(c1.id()).isEmpty()); QCOMPARE(data.childCollections(c2.id()).size(), 1); QCOMPARE(data.childCollections(c2.id()).first(), c3); } void shouldRemoveCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionRemoved); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(43); - c2.setName("43"); + c2.setName(QStringLiteral("43")); c2.setParentCollection(Akonadi::Collection(42)); data.createCollection(c2); auto c3 = Akonadi::Collection(44); - c3.setName("44"); + c3.setName(QStringLiteral("44")); c3.setParentCollection(Akonadi::Collection(43)); data.createCollection(c3); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(43)); data.createItem(i1); auto i2 = Akonadi::Item(43); i2.setPayloadFromData("43"); i2.setParentCollection(Akonadi::Collection(44)); data.createItem(i2); // WHEN data.removeCollection(c2); // THEN QCOMPARE(data.collections().size(), 1); QCOMPARE(data.collections().first(), c1); QVERIFY(!data.collection(c2.id()).isValid()); QVERIFY(!data.collection(c3.id()).isValid()); QVERIFY(data.childCollections(c1.id()).isEmpty()); QVERIFY(data.childCollections(c2.id()).isEmpty()); QVERIFY(data.childCollections(c3.id()).isEmpty()); QVERIFY(data.items().isEmpty()); QVERIFY(!data.item(i1.id()).isValid()); QVERIFY(!data.item(i2.id()).isValid()); QVERIFY(data.childItems(c2.id()).isEmpty()); QVERIFY(data.childItems(c3.id()).isEmpty()); QCOMPARE(spy.size(), 2); QCOMPARE(spy.takeFirst().takeFirst().value(), c3); QCOMPARE(spy.takeFirst().takeFirst().value(), c2); } void shouldCreateTags() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagAdded); auto t1 = Akonadi::Tag(42); - t1.setName("42"); + t1.setName(QStringLiteral("42")); auto t2 = Akonadi::Tag(43); - t2.setName("43"); + t2.setName(QStringLiteral("43")); // WHEN data.createTag(t1); data.createTag(t2); // THEN QCOMPARE(data.tags().size(), 2); QVERIFY(data.tags().contains(t1)); QVERIFY(data.tags().contains(t2)); QCOMPARE(data.tag(t1.id()), t1); QCOMPARE(data.tag(t2.id()), t2); QCOMPARE(spy.size(), 2); QCOMPARE(spy.takeFirst().takeFirst().value(), t1); QCOMPARE(spy.takeFirst().takeFirst().value(), t2); } void shouldModifyTags() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagChanged); auto t1 = Akonadi::Tag(42); - t1.setName("42"); + t1.setName(QStringLiteral("42")); data.createTag(t1); auto t2 = Akonadi::Tag(t1.id()); - t2.setName("42-bis"); + t2.setName(QStringLiteral("42-bis")); // WHEN data.modifyTag(t2); // THEN QCOMPARE(data.tags().size(), 1); QCOMPARE(data.tag(t1.id()), t2); QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().value(), t2); } void shouldRemoveTags() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy tagSpy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved); QSignalSpy itemSpy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); auto c1 = Akonadi::Collection(42); data.createCollection(c1); auto t1 = Akonadi::Tag(42); - t1.setName("42"); + t1.setName(QStringLiteral("42")); data.createTag(t1); auto t2 = Akonadi::Tag(43); - t2.setName("43"); + t2.setName(QStringLiteral("43")); data.createTag(t2); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(c1); i1.setTag(Akonadi::Tag(t1.id())); data.createItem(i1); auto i2 = Akonadi::Item(43); i2.setPayloadFromData("43"); i2.setParentCollection(c1); i2.setTag(Akonadi::Tag(t2.id())); data.createItem(i2); const auto itemSet = QSet() << i1 << i2; // WHEN data.removeTag(t2); // THEN QCOMPARE(data.tags().size(), 1); QCOMPARE(data.tags().first(), t1); QVERIFY(!data.tag(t2.id()).isValid()); QCOMPARE(data.tagItems(t1.id()).size(), 1); QCOMPARE(data.tagItems(t1.id()).first(), i1); QVERIFY(data.tagItems(t2.id()).isEmpty()); QCOMPARE(data.items().toList().toSet(), itemSet); QVERIFY(data.item(i1.id()).isValid()); QVERIFY(data.item(i2.id()).isValid()); QVERIFY(!data.item(i2.id()).tags().contains(t2)); QCOMPARE(tagSpy.size(), 1); QCOMPARE(tagSpy.takeFirst().takeFirst().value(), t2); QCOMPARE(itemSpy.size(), 1); QCOMPARE(itemSpy.first().first().value(), i2); QVERIFY(!itemSpy.first().first().value().tags().contains(t2)); } void shouldCreateItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemAdded); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); auto i2 = Akonadi::Item(43); i2.setPayloadFromData("43"); const auto itemSet = QSet() << i1 << i2; // WHEN data.createItem(i1); data.createItem(i2); // THEN QCOMPARE(data.items().toList().toSet(), itemSet); QCOMPARE(data.item(i1.id()), i1); QCOMPARE(data.item(i2.id()), i2); QCOMPARE(spy.size(), 2); QCOMPARE(spy.takeFirst().takeFirst().value(), i1); QCOMPARE(spy.takeFirst().takeFirst().value(), i2); } void shouldModifyItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); QSignalSpy moveSpy(monitor.data(), &Akonadi::MonitorInterface::itemMoved); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); auto i2 = Akonadi::Item(i1.id()); i2.setPayloadFromData("42-bis"); i2.setParentCollection(Akonadi::Collection(42)); // WHEN data.modifyItem(i2); // THEN QCOMPARE(data.items().size(), 1); QCOMPARE(data.item(i1.id()), i2); QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().value(), i2); QCOMPARE(moveSpy.size(), 0); } void shouldNotLooseParentCollectionOnModifyItem() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); auto i2 = Akonadi::Item(i1.id()); i2.setPayloadFromData("42-bis"); // WHEN data.modifyItem(i2); // THEN QCOMPARE(data.items().size(), 1); QCOMPARE(data.item(i1.id()), i2); QCOMPARE(data.item(i1.id()).parentCollection().id(), c1.id()); } void shouldListChildItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); // WHEN data.createItem(i1); // THEN QCOMPARE(data.childItems(c1.id()).size(), 1); QCOMPARE(data.childItems(c1.id()).first(), i1); } void shouldReparentItemsOnModify() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemMoved); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(43); - c2.setName("43"); + c2.setName(QStringLiteral("43")); data.createCollection(c2); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); // WHEN i1.setPayloadFromData("42-bis"); i1.setParentCollection(Akonadi::Collection(43)); data.modifyItem(i1); // THEN QVERIFY(data.childItems(c1.id()).isEmpty()); QCOMPARE(data.childItems(c2.id()).size(), 1); QCOMPARE(data.childItems(c2.id()).first(), i1); QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().value(), i1); } void shouldListTagItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto t1 = Akonadi::Tag(42); - t1.setName("42"); + t1.setName(QStringLiteral("42")); data.createTag(t1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setTag(Akonadi::Tag(42)); // WHEN data.createItem(i1); // THEN QCOMPARE(data.tagItems(t1.id()).size(), 1); QCOMPARE(data.tagItems(t1.id()).first(), i1); } void shouldRetagItemsOnModify() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); auto t1 = Akonadi::Tag(42); - t1.setName("42"); + t1.setName(QStringLiteral("42")); data.createTag(t1); auto t2 = Akonadi::Tag(43); - t2.setName("43"); + t2.setName(QStringLiteral("43")); data.createTag(t2); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setTag(Akonadi::Tag(42)); data.createItem(i1); // WHEN i1.setPayloadFromData("42-bis"); i1.clearTag(Akonadi::Tag(42)); i1.setTag(Akonadi::Tag(43)); data.modifyItem(i1); // THEN QVERIFY(data.tagItems(t1.id()).isEmpty()); QCOMPARE(data.tagItems(t2.id()).size(), 1); QCOMPARE(data.tagItems(t2.id()).first(), i1); QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().value(), i1); } void shouldRemoveItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); auto c1 = Akonadi::Collection(42); - c1.setName("42"); + c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); // WHEN data.removeItem(i1); // THEN QVERIFY(data.items().isEmpty()); QVERIFY(!data.item(i1.id()).isValid()); QVERIFY(data.childItems(c1.id()).isEmpty()); QCOMPARE(spy.size(), 1); QCOMPARE(spy.takeFirst().takeFirst().value(), i1); } }; ZANSHIN_TEST_MAIN(AkonadiFakeDataTest) #include "akonadifakedatatest.moc" diff --git a/tests/units/testlib/akonadifakedataxmlloadertest.cpp b/tests/units/testlib/akonadifakedataxmlloadertest.cpp index 49387008..dac2f7c5 100644 --- a/tests/units/testlib/akonadifakedataxmlloadertest.cpp +++ b/tests/units/testlib/akonadifakedataxmlloadertest.cpp @@ -1,84 +1,84 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/akonadifakedata.h" #include "testlib/akonadifakedataxmlloader.h" #include class AkonadiFakeDataXmlLoaderTest : public QObject { Q_OBJECT private slots: void shouldLoadFromXmlFile() { // GIVEN auto data = Testlib::AkonadiFakeData(); // Put a first collection with an idea to make sure it isn't lost on loading auto searchCollection = Akonadi::Collection(1); searchCollection.setParentCollection(Akonadi::Collection::root()); - searchCollection.setName("Search"); + searchCollection.setName(QStringLiteral("Search")); data.createCollection(searchCollection); auto loader = Testlib::AkonadiFakeDataXmlLoader(&data); // WHEN loader.load(SOURCE_DIR "/../akonadi/testenv/data/testdata.xml"); // THEN QVERIFY(data.collections().size() > 1); QVERIFY(data.items().size() > 1); QVERIFY(data.tags().size() > 1); // Do a bit of sanity checking, no need to do much more than that as // the xml loading will be extensively used in the AkonadiFakeStorageTest // and AkonadiFakeData has quite a few asserts. QCOMPARE(data.childCollections(Akonadi::Collection::root().id()).size(), 2); const auto res = data.childCollections(Akonadi::Collection::root().id()).at(1); QCOMPARE(res.id(), qint64(2)); const auto children = data.childCollections(res.id()); QCOMPARE(children.size(), 5); - QCOMPARE(children.at(0).name(), QString("Calendar1")); + QCOMPARE(children.at(0).name(), QStringLiteral("Calendar1")); QCOMPARE(children.at(0).id(), qint64(3)); - QCOMPARE(children.at(0).remoteId(), QString("{cdc229c7-a9b5-4d37-989d-a28e372be2a9}")); - QCOMPARE(children.at(1).name(), QString("Emails")); + QCOMPARE(children.at(0).remoteId(), QStringLiteral("{cdc229c7-a9b5-4d37-989d-a28e372be2a9}")); + QCOMPARE(children.at(1).name(), QStringLiteral("Emails")); QCOMPARE(children.at(1).id(), qint64(4)); - QCOMPARE(children.at(1).remoteId(), QString("{14096930-7bfe-46ca-8fba-7c04d3b62ec8}")); - QCOMPARE(children.at(2).name(), QString("Contacts")); + QCOMPARE(children.at(1).remoteId(), QStringLiteral("{14096930-7bfe-46ca-8fba-7c04d3b62ec8}")); + QCOMPARE(children.at(2).name(), QStringLiteral("Contacts")); QCOMPARE(children.at(2).id(), qint64(5)); - QCOMPARE(children.at(2).remoteId(), QString("{36bf43ac-0988-4435-b602-d6c29e606630}")); - QCOMPARE(children.at(3).name(), QString("Destroy me!")); + QCOMPARE(children.at(2).remoteId(), QStringLiteral("{36bf43ac-0988-4435-b602-d6c29e606630}")); + QCOMPARE(children.at(3).name(), QStringLiteral("Destroy me!")); QCOMPARE(children.at(3).id(), qint64(6)); - QCOMPARE(children.at(3).remoteId(), QString("{1f78b360-a01b-4785-9187-75450190342c}")); - QCOMPARE(children.at(4).name(), QString("Change me!")); + QCOMPARE(children.at(3).remoteId(), QStringLiteral("{1f78b360-a01b-4785-9187-75450190342c}")); + QCOMPARE(children.at(4).name(), QStringLiteral("Change me!")); QCOMPARE(children.at(4).id(), qint64(7)); - QCOMPARE(children.at(4).remoteId(), QString("{28ef9f03-4ebc-4e33-970f-f379775894f9}")); + QCOMPARE(children.at(4).remoteId(), QStringLiteral("{28ef9f03-4ebc-4e33-970f-f379775894f9}")); } }; ZANSHIN_TEST_MAIN(AkonadiFakeDataXmlLoaderTest) #include "akonadifakedataxmlloadertest.moc" diff --git a/tests/units/testlib/gencollectiontest.cpp b/tests/units/testlib/gencollectiontest.cpp index f7fbd1eb..6e302e60 100644 --- a/tests/units/testlib/gencollectiontest.cpp +++ b/tests/units/testlib/gencollectiontest.cpp @@ -1,190 +1,190 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/gencollection.h" #include "akonadi/akonadiapplicationselectedattribute.h" #include #include using namespace Testlib; class GenCollectionTest : public QObject { Q_OBJECT private slots: void shouldImplicitlyConvertBackToCollection() { // GIVEN auto col = Akonadi::Collection(42); auto gen = GenCollection(col); // WHEN Akonadi::Collection newCol = gen; // THEN QCOMPARE(newCol, col); } void shouldAllowToSetId() { // GIVEN Akonadi::Collection col = GenCollection().withId(42); // THEN QCOMPARE(col.id(), 42LL); } void shouldAllowToSetParent() { // GIVEN Akonadi::Collection col = GenCollection().withParent(42); // THEN QCOMPARE(col.parentCollection().id(), 42LL); } void shouldAllowToSetRootAsParent() { // GIVEN Akonadi::Collection col = GenCollection().withRootAsParent(); // THEN QCOMPARE(col.parentCollection(), Akonadi::Collection::root()); } void shouldAllowToSetName() { // GIVEN - Akonadi::Collection col = GenCollection().withName("42"); + Akonadi::Collection col = GenCollection().withName(QStringLiteral("42")); // THEN - QCOMPARE(col.name(), QString("42")); + QCOMPARE(col.name(), QStringLiteral("42")); } void shouldAllowToSetIcon() { // GIVEN - Akonadi::Collection col = GenCollection().withIcon("42"); + Akonadi::Collection col = GenCollection().withIcon(QStringLiteral("42")); // THEN - QCOMPARE(col.attribute()->iconName(), QString("42")); + QCOMPARE(col.attribute()->iconName(), QStringLiteral("42")); } void shouldAllowToSetReferenced() { // GIVEN Akonadi::Collection col = GenCollection().referenced(); // THEN QCOMPARE(col.referenced(), true); // WHEN col = GenCollection(col).referenced(false); // THEN QCOMPARE(col.referenced(), false); } void shouldAllowToSetEnabled() { // GIVEN Akonadi::Collection col = GenCollection().enabled(); // THEN QCOMPARE(col.enabled(), true); // WHEN col = GenCollection(col).enabled(false); // THEN QCOMPARE(col.enabled(), false); } void shouldAllowToSetSelected() { // GIVEN Akonadi::Collection col = GenCollection().selected(); // THEN QVERIFY(!col.hasAttribute()); // WHEN col = GenCollection(col).selected(false); // THEN QCOMPARE(col.attribute()->isSelected(), false); } void shouldAllowToSetTaskContent() { // GIVEN Akonadi::Collection col = GenCollection().withTaskContent(); // THEN - QVERIFY(col.contentMimeTypes().contains("application/x-vnd.akonadi.calendar.todo")); + QVERIFY(col.contentMimeTypes().contains(QStringLiteral("application/x-vnd.akonadi.calendar.todo"))); // WHEN col = GenCollection(col).withTaskContent(false); // THEN - QVERIFY(!col.contentMimeTypes().contains("application/x-vnd.akonadi.calendar.todo")); + QVERIFY(!col.contentMimeTypes().contains(QStringLiteral("application/x-vnd.akonadi.calendar.todo"))); } void shouldAllowToSetNoteContent() { // GIVEN Akonadi::Collection col = GenCollection().withNoteContent(); // THEN - QVERIFY(col.contentMimeTypes().contains("text/x-vnd.akonadi.note")); + QVERIFY(col.contentMimeTypes().contains(QStringLiteral("text/x-vnd.akonadi.note"))); // WHEN col = GenCollection(col).withNoteContent(false); // THEN - QVERIFY(!col.contentMimeTypes().contains("text/x-vnd.akonadi.note")); + QVERIFY(!col.contentMimeTypes().contains(QStringLiteral("text/x-vnd.akonadi.note"))); } void shouldAllowToSetNoteAndTaskContent() { // GIVEN Akonadi::Collection col = GenCollection().withTaskContent().withNoteContent(); // THEN - QVERIFY(col.contentMimeTypes().contains("application/x-vnd.akonadi.calendar.todo")); - QVERIFY(col.contentMimeTypes().contains("text/x-vnd.akonadi.note")); + QVERIFY(col.contentMimeTypes().contains(QStringLiteral("application/x-vnd.akonadi.calendar.todo"))); + QVERIFY(col.contentMimeTypes().contains(QStringLiteral("text/x-vnd.akonadi.note"))); // WHEN col = GenCollection(col).withTaskContent(false).withNoteContent(false); // THEN - QVERIFY(!col.contentMimeTypes().contains("application/x-vnd.akonadi.calendar.todo")); - QVERIFY(!col.contentMimeTypes().contains("text/x-vnd.akonadi.note")); + QVERIFY(!col.contentMimeTypes().contains(QStringLiteral("application/x-vnd.akonadi.calendar.todo"))); + QVERIFY(!col.contentMimeTypes().contains(QStringLiteral("text/x-vnd.akonadi.note"))); } }; ZANSHIN_TEST_MAIN(GenCollectionTest) #include "gencollectiontest.moc" diff --git a/tests/units/testlib/gennotetest.cpp b/tests/units/testlib/gennotetest.cpp index e6501ba4..1f2175d0 100644 --- a/tests/units/testlib/gennotetest.cpp +++ b/tests/units/testlib/gennotetest.cpp @@ -1,112 +1,112 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/gennote.h" #include #include #include using namespace Testlib; class GenNoteTest : public QObject { Q_OBJECT private slots: void shouldImplicitlyConvertBackToItem() { // GIVEN auto item = Akonadi::Item(42); auto gen = GenNote(item); // WHEN Akonadi::Item newItem = gen; // THEN QCOMPARE(newItem, item); QCOMPARE(newItem.mimeType(), Akonadi::NoteUtils::noteMimeType()); QVERIFY(newItem.hasPayload()); } void shouldAllowToSetId() { // GIVEN Akonadi::Item item = GenNote().withId(42); // THEN QCOMPARE(item.id(), 42LL); } void shouldAllowToSetParent() { // GIVEN Akonadi::Item item = GenNote().withParent(42); // THEN QCOMPARE(item.parentCollection().id(), 42LL); } void shouldAllowToSetTags() { // GIVEN Akonadi::Item item = GenNote().withTags({42, 43, 44}); // THEN QCOMPARE(item.tags().size(), 3); QCOMPARE(item.tags().at(0).id(), 42LL); QCOMPARE(item.tags().at(1).id(), 43LL); QCOMPARE(item.tags().at(2).id(), 44LL); } void shouldAllowToSetParentUid() { // GIVEN - Akonadi::Item item = GenNote().withParentUid("42"); + Akonadi::Item item = GenNote().withParentUid(QStringLiteral("42")); // THEN - QCOMPARE(item.payload()->headerByType("X-Zanshin-RelatedProjectUid")->asUnicodeString(), QString("42")); + QCOMPARE(item.payload()->headerByType("X-Zanshin-RelatedProjectUid")->asUnicodeString(), QStringLiteral("42")); } void shouldAllowToSetTitle() { // GIVEN - Akonadi::Item item = GenNote().withTitle("42"); + Akonadi::Item item = GenNote().withTitle(QStringLiteral("42")); // THEN - QCOMPARE(item.payload()->subject()->asUnicodeString(), QString("42")); + QCOMPARE(item.payload()->subject()->asUnicodeString(), QStringLiteral("42")); } void shouldAllowToSetText() { // GIVEN - Akonadi::Item item = GenNote().withText("42"); + Akonadi::Item item = GenNote().withText(QStringLiteral("42")); // THEN QCOMPARE(item.payload()->body(), QByteArray("42")); } }; ZANSHIN_TEST_MAIN(GenNoteTest) #include "gennotetest.moc" diff --git a/tests/units/testlib/gentagtest.cpp b/tests/units/testlib/gentagtest.cpp index 0a8ae7a6..d6c195bd 100644 --- a/tests/units/testlib/gentagtest.cpp +++ b/tests/units/testlib/gentagtest.cpp @@ -1,89 +1,89 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/gentag.h" #include #include "akonadi/akonadiserializerinterface.h" using namespace Testlib; class GenTagTest : public QObject { Q_OBJECT private slots: void shouldImplicitlyConvertBackToTag() { // GIVEN auto tag = Akonadi::Tag(42); auto gen = GenTag(tag); // WHEN Akonadi::Tag newTag = gen; // THEN QCOMPARE(newTag, tag); } void shouldAllowToSetId() { // GIVEN Akonadi::Tag tag = GenTag().withId(42); // THEN QCOMPARE(tag.id(), 42LL); } void shouldAllowToSetName() { // GIVEN - Akonadi::Tag tag = GenTag().withName("42"); + Akonadi::Tag tag = GenTag().withName(QStringLiteral("42")); // THEN - QCOMPARE(tag.name(), QString("42")); + QCOMPARE(tag.name(), QStringLiteral("42")); QCOMPARE(tag.gid(), tag.name().toLatin1()); } void shouldAllowToSetContextType() { // GIVEN Akonadi::Tag tag = GenTag().asContext(); // THEN QCOMPARE(tag.type(), Akonadi::SerializerInterface::contextTagType()); } void shouldAllowToSetPlainType() { // GIVEN Akonadi::Tag tag = GenTag().asPlain(); // THEN QCOMPARE(tag.type(), QByteArray(Akonadi::Tag::PLAIN)); } }; ZANSHIN_TEST_MAIN(GenTagTest) #include "gentagtest.moc" diff --git a/tests/units/testlib/gentodotest.cpp b/tests/units/testlib/gentodotest.cpp index 02395390..c393a855 100644 --- a/tests/units/testlib/gentodotest.cpp +++ b/tests/units/testlib/gentodotest.cpp @@ -1,228 +1,228 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/gentodo.h" #include #include using namespace Testlib; class GenTodoTest : public QObject { Q_OBJECT private slots: void shouldImplicitlyConvertBackToItem() { // GIVEN auto item = Akonadi::Item(42); auto gen = GenTodo(item); // WHEN Akonadi::Item newItem = gen; // THEN QCOMPARE(newItem, item); QCOMPARE(newItem.mimeType(), KCalCore::Todo::todoMimeType()); QVERIFY(newItem.hasPayload()); } void shouldAllowToSetId() { // GIVEN Akonadi::Item item = GenTodo().withId(42); // THEN QCOMPARE(item.id(), 42LL); } void shouldAllowToSetParent() { // GIVEN Akonadi::Item item = GenTodo().withParent(42); // THEN QCOMPARE(item.parentCollection().id(), 42LL); } void shouldAllowToSetTags() { // GIVEN Akonadi::Item item = GenTodo().withTags({42, 43, 44}); // THEN QCOMPARE(item.tags().size(), 3); QCOMPARE(item.tags().at(0).id(), 42LL); QCOMPARE(item.tags().at(1).id(), 43LL); QCOMPARE(item.tags().at(2).id(), 44LL); } void shouldAllowToSetProjectType() { // GIVEN Akonadi::Item item = GenTodo().asProject(); // THEN QVERIFY(!item.payload()->customProperty("Zanshin", "Project").isEmpty()); // WHEN item = GenTodo(item).asProject(false); // THEN QVERIFY(item.payload()->customProperty("Zanshin", "Project").isEmpty()); } void shouldAllowToSetUid() { // GIVEN - Akonadi::Item item = GenTodo().withUid("42"); + Akonadi::Item item = GenTodo().withUid(QStringLiteral("42")); // THEN - QCOMPARE(item.payload()->uid(), QString("42")); + QCOMPARE(item.payload()->uid(), QStringLiteral("42")); } void shouldAllowToSetParentUid() { // GIVEN - Akonadi::Item item = GenTodo().withParentUid("42"); + Akonadi::Item item = GenTodo().withParentUid(QStringLiteral("42")); // THEN - QCOMPARE(item.payload()->relatedTo(), QString("42")); + QCOMPARE(item.payload()->relatedTo(), QStringLiteral("42")); } void shouldAllowToSetTitle() { // GIVEN - Akonadi::Item item = GenTodo().withTitle("42"); + Akonadi::Item item = GenTodo().withTitle(QStringLiteral("42")); // THEN - QCOMPARE(item.payload()->summary(), QString("42")); + QCOMPARE(item.payload()->summary(), QStringLiteral("42")); } void shouldAllowToSetText() { // GIVEN - Akonadi::Item item = GenTodo().withText("42"); + Akonadi::Item item = GenTodo().withText(QStringLiteral("42")); // THEN - QCOMPARE(item.payload()->description(), QString("42")); + QCOMPARE(item.payload()->description(), QStringLiteral("42")); } void shouldAllowToSetDoneState() { // GIVEN Akonadi::Item item = GenTodo().done(); // THEN QVERIFY(item.payload()->isCompleted()); // WHEN item = GenTodo(item).done(false); // THEN QVERIFY(!item.payload()->isCompleted()); } void shouldAllowToSetDoneDate() { // GIVEN Akonadi::Item item = GenTodo().withDoneDate(QDateTime(QDate(2015, 4, 12), QTime(12, 00))); // THEN QCOMPARE(item.payload()->completed().date(), QDate(2015, 04, 12)); } void shouldAllowToSetDoneDateString() { // GIVEN - Akonadi::Item item = GenTodo().withDoneDate("2015-04-12"); + Akonadi::Item item = GenTodo().withDoneDate(QStringLiteral("2015-04-12")); // THEN QCOMPARE(item.payload()->completed().date(), QDate(2015, 04, 12)); } void shouldAllowToSetStartDate() { // GIVEN Akonadi::Item item = GenTodo().withStartDate(QDateTime(QDate(2015, 4, 12))); // THEN QCOMPARE(item.payload()->dtStart().date(), QDate(2015, 04, 12)); } void shouldAllowToSetStartDateString() { // GIVEN - Akonadi::Item item = GenTodo().withStartDate("2015-04-12"); + Akonadi::Item item = GenTodo().withStartDate(QStringLiteral("2015-04-12")); // THEN QCOMPARE(item.payload()->dtStart().date(), QDate(2015, 04, 12)); } void shouldAllowToSetDueDate() { // GIVEN Akonadi::Item item = GenTodo().withDueDate(QDateTime(QDate(2015, 4, 12))); // THEN QCOMPARE(item.payload()->dtDue().date(), QDate(2015, 04, 12)); } void shouldAllowToSetDueDateString() { // GIVEN - Akonadi::Item item = GenTodo().withDueDate("2015-04-12"); + Akonadi::Item item = GenTodo().withDueDate(QStringLiteral("2015-04-12")); // THEN QCOMPARE(item.payload()->dtDue().date(), QDate(2015, 04, 12)); } void shouldAllowToSetDelegate() { // GIVEN - Akonadi::Item item = GenTodo().withDelegate("John Doe", "john@doe.net"); + Akonadi::Item item = GenTodo().withDelegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.net")); // THEN QCOMPARE(item.payload()->attendeeCount(), 1); const auto attendees = item.payload()->attendees(); const auto delegate = std::find_if(attendees.begin(), attendees.end(), [] (const KCalCore::Attendee::Ptr &attendee) { return attendee->status() == KCalCore::Attendee::Delegated; }); QVERIFY(delegate != attendees.constEnd()); - QCOMPARE((*delegate)->name(), QString("John Doe")); - QCOMPARE((*delegate)->email(), QString("john@doe.net")); + QCOMPARE((*delegate)->name(), QStringLiteral("John Doe")); + QCOMPARE((*delegate)->email(), QStringLiteral("john@doe.net")); // WHEN item = GenTodo(item).withNoDelegate(); // THEN QCOMPARE(item.payload()->attendeeCount(), 0); } }; ZANSHIN_TEST_MAIN(GenTodoTest) #include "gentodotest.moc" diff --git a/tests/units/utils/compositejobtest.cpp b/tests/units/utils/compositejobtest.cpp index 460834d5..d94a1687 100644 --- a/tests/units/utils/compositejobtest.cpp +++ b/tests/units/utils/compositejobtest.cpp @@ -1,156 +1,156 @@ /* This file is part of Zanshin Copyright 2014 Mario Bensi 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/compositejob.h" #include "testlib/fakejob.h" using namespace Utils; class CompositeJobTest : public QObject { Q_OBJECT public: explicit CompositeJobTest(QObject *parent = Q_NULLPTR) : QObject(parent) , m_callCount(0) { } private: int m_callCount; private slots: void shouldCallHandlers() { // GIVEN int callCount = 0; auto handler = [&]() { callCount++; }; FakeJob *job1 = new FakeJob(this); FakeJob *job2 = new FakeJob(this); CompositeJob *compositeJob = new CompositeJob(this); compositeJob->setAutoDelete(false); QVERIFY(compositeJob->install(job1, handler)); QVERIFY(compositeJob->install(job2, handler)); // WHEN compositeJob->start(); QTest::qWait(FakeJob::DURATION + 10); // THEN QCOMPARE(callCount, 2); QVERIFY(!compositeJob->error()); delete compositeJob; } void shouldCallHandlersWithJob() { // GIVEN int callCount = 0; QList seenJobs; auto handlerWithJob = [&](KJob *job) { callCount++; seenJobs << job; }; FakeJob *job1 = new FakeJob(this); FakeJob *job2 = new FakeJob(this); CompositeJob *compositeJob = new CompositeJob(this); compositeJob->setAutoDelete(false); QVERIFY(compositeJob->install(job1, handlerWithJob)); QVERIFY(compositeJob->install(job2, handlerWithJob)); // WHEN compositeJob->start(); QTest::qWait(FakeJob::DURATION + 10); // THEN QCOMPARE(callCount, 2); QCOMPARE(seenJobs.toSet(), QSet() << job1 << job2); QVERIFY(!compositeJob->error()); delete compositeJob; } void handleJobResult(KJob*) { m_callCount++; } void shouldCallJobInHandler() { // GIVEN CompositeJob *compositeJob = new CompositeJob(this); compositeJob->setAutoDelete(false); auto handler = [&]() { FakeJob *job2 = new FakeJob(this); QObject::connect(job2, &KJob::result, this, &CompositeJobTest::handleJobResult); compositeJob->addSubjob(job2); job2->start(); }; FakeJob *job1 = new FakeJob(this); QVERIFY(compositeJob->install(job1, handler)); // WHEN compositeJob->start(); QTest::qWait(FakeJob::DURATION*2 + 10); QCOMPARE(m_callCount, 1); QVERIFY(!compositeJob->error()); delete compositeJob; } void shouldEmitErrorFromHandler() { // GIVEN CompositeJob *compositeJob = new CompositeJob(this); compositeJob->setAutoDelete(false); auto handler = [&]() { - compositeJob->emitError("Error reached"); + compositeJob->emitError(QStringLiteral("Error reached")); }; FakeJob *job = new FakeJob(this); QVERIFY(compositeJob->install(job, handler)); // WHEN compositeJob->start(); QTest::qWait(FakeJob::DURATION*2 + 10); QCOMPARE(compositeJob->error(), static_cast(KJob::UserDefinedError)); - QCOMPARE(compositeJob->errorText(), QString("Error reached")); + QCOMPARE(compositeJob->errorText(), QStringLiteral("Error reached")); delete compositeJob; } }; ZANSHIN_TEST_MAIN(CompositeJobTest) #include "compositejobtest.moc" diff --git a/tests/units/utils/mockobjecttest.cpp b/tests/units/utils/mockobjecttest.cpp index 59b0f166..be585be6 100644 --- a/tests/units/utils/mockobjecttest.cpp +++ b/tests/units/utils/mockobjecttest.cpp @@ -1,83 +1,83 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" using mockitopp::matcher::any; using namespace Utils; class FakeInterface { public: FakeInterface() {} virtual ~FakeInterface() {} virtual void doSomething() = 0; virtual int computeMe(QString input) = 0; }; class MockObjectTest : public QObject { Q_OBJECT private slots: void testBasics() { MockObject mock; mock(&FakeInterface::doSomething).when().thenReturn(); mock(&FakeInterface::doSomething).when().thenThrow("exception"); for (int i = 0; i < 10; i++) { - mock(&FakeInterface::computeMe).when("A").thenReturn(0); - mock(&FakeInterface::computeMe).when("B").thenReturn(1); - mock(&FakeInterface::computeMe).when("C").thenReturn(-1); - mock(&FakeInterface::computeMe).when("Foo").thenReturn(-1); + mock(&FakeInterface::computeMe).when(QStringLiteral("A")).thenReturn(0); + mock(&FakeInterface::computeMe).when(QStringLiteral("B")).thenReturn(1); + mock(&FakeInterface::computeMe).when(QStringLiteral("C")).thenReturn(-1); + mock(&FakeInterface::computeMe).when(QStringLiteral("Foo")).thenReturn(-1); } QSharedPointer iface1 = mock.getInstance(); QSharedPointer iface2 = mock.getInstance(); // Shouldn't cause a crash later QCOMPARE(iface1.data(), iface2.data()); iface1->doSomething(); try { iface2->doSomething(); QFAIL("No exception thrown"); } catch (...) { // We expect to catch something } for (int i = 0; i < 10; i++) { - QCOMPARE(iface1->computeMe("A"), 0); - QCOMPARE(iface2->computeMe("B"), 1); - QCOMPARE(iface1->computeMe("C"), -1); - QCOMPARE(iface2->computeMe("Foo"), -1); + QCOMPARE(iface1->computeMe(QStringLiteral("A")), 0); + QCOMPARE(iface2->computeMe(QStringLiteral("B")), 1); + QCOMPARE(iface1->computeMe(QStringLiteral("C")), -1); + QCOMPARE(iface2->computeMe(QStringLiteral("Foo")), -1); } QVERIFY(mock(&FakeInterface::doSomething).when().exactly(2)); QVERIFY(mock(&FakeInterface::computeMe).when(any()).exactly(40)); } }; ZANSHIN_TEST_MAIN(MockObjectTest) #include "mockobjecttest.moc" diff --git a/tests/units/widgets/applicationcomponentstest.cpp b/tests/units/widgets/applicationcomponentstest.cpp index 1f821d36..897c1c8c 100644 --- a/tests/units/widgets/applicationcomponentstest.cpp +++ b/tests/units/widgets/applicationcomponentstest.cpp @@ -1,674 +1,674 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include "utils/mem_fn.h" #include "domain/note.h" #include "domain/task.h" #include "presentation/artifactfilterproxymodel.h" #include "presentation/querytreemodelbase.h" #include "widgets/applicationcomponents.h" #include "widgets/availablepagesview.h" #include "widgets/availablesourcesview.h" #include "widgets/editorview.h" #include "widgets/filterwidget.h" #include "widgets/pageview.h" #include "widgets/quickselectdialog.h" class CustomModelStub : public QStandardItemModel { QMimeData *mimeData(const QModelIndexList &indexes) const { QStringList dataString; std::transform(indexes.begin(), indexes.end(), std::back_inserter(dataString), [] (const QModelIndex &index) { return index.data().toString(); }); auto data = new QMimeData; - data->setData("application/x-zanshin-object", "object"); + data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(dataString)); return data; } bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &destination) { Q_UNUSED(action); Q_ASSERT(row == -1); Q_ASSERT(column == -1); Q_ASSERT(destination.isValid()); - Q_ASSERT(data->hasFormat("application/x-zanshin-object")); + Q_ASSERT(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); auto dataString = data->property("objects").value(); Q_ASSERT(!dataString.isEmpty()); droppedItemDataString = dataString; dropDestination = destination.data().toString(); return true; } public: QStringList droppedItemDataString; QString dropDestination; }; class ApplicationModelStub : public QObject { Q_OBJECT Q_PROPERTY(QObject* currentPage READ currentPage WRITE setCurrentPage) public: typedef QSharedPointer Ptr; explicit ApplicationModelStub(QObject *parent = Q_NULLPTR) : QObject(parent), m_currentPage(Q_NULLPTR) {} QObject *currentPage() { return m_currentPage; } void setCurrentPage(QObject *page) { if (page == m_currentPage) return; m_currentPage = page; emit currentPageChanged(m_currentPage); } signals: void currentPageChanged(QObject *page); private: QObject *m_currentPage; }; class AvailablePagesModelStub : public QObject { Q_OBJECT Q_PROPERTY(QAbstractItemModel* pageListModel READ pageListModel) public: explicit AvailablePagesModelStub(QObject *parent = Q_NULLPTR) : QObject(parent) { QStandardItem *inbox = new QStandardItem; inbox->setData("Inbox", Qt::DisplayRole); itemModel.appendRow(inbox); QStandardItem *project = new QStandardItem; project->setData("Project", Qt::DisplayRole); itemModel.appendRow(project); } QAbstractItemModel *pageListModel() { return &itemModel; } Q_SCRIPTABLE QObject *createPageForIndex(const QModelIndex &index) { auto page = new QObject(this); auto model = new QStringListModel(page); - model->setStringList(QStringList() << "Items" << "from" << index.data().toString()); + model->setStringList(QStringList() << QStringLiteral("Items") << QStringLiteral("from") << index.data().toString()); page->setProperty("centralListModel", QVariant::fromValue(model)); createdPages << page; return page; } public: QList createdPages; CustomModelStub itemModel; }; class PageModelStub : public QObject { Q_OBJECT Q_PROPERTY(QAbstractItemModel* centralListModel READ centralListModel) public: QAbstractItemModel *centralListModel() { return &itemModel; } template void addItem(const QString &title) { auto artifact = T::Ptr::create(); artifact->setTitle(title); addItem(artifact); } void addItem(const Domain::Artifact::Ptr &artifact) { QStandardItem *item = new QStandardItem; item->setData(QVariant::fromValue(artifact), Presentation::QueryTreeModelBase::ObjectRole); item->setData(artifact->title(), Qt::DisplayRole); itemModel.appendRow(item); } Domain::Artifact::Ptr itemAtRow(int row) const { return itemModel.index(row, 0).data(Presentation::QueryTreeModelBase::ObjectRole) .value(); } QModelIndexList selectedIndexes() const { return selectedItems; } public: QModelIndexList selectedItems; CustomModelStub itemModel; }; class EditorModelStub : public QObject { Q_OBJECT public: explicit EditorModelStub(QObject *parent = Q_NULLPTR) : QObject(parent) { } void setPropertyAndSignal(const QByteArray &name, const QVariant &value) { if (property(name) == value) return; setProperty(name, value); if (name == "text") emit textChanged(value.toString()); else if (name == "title") emit titleChanged(value.toString()); else if (name == "done") emit doneChanged(value.toBool()); else if (name == "startDate") emit startDateChanged(value.toDateTime()); else if (name == "dueDate") emit dueDateChanged(value.toDateTime()); else if (name == "hasTaskProperties") emit hasTaskPropertiesChanged(value.toBool()); else qFatal("Unsupported property %s", name.constData()); } public slots: void setTitle(const QString &title) { setPropertyAndSignal("title", title); } void setText(const QString &text) { setPropertyAndSignal("text", text); } void setDone(bool done) { setPropertyAndSignal("done", done); } void setStartDate(const QDateTime &start) { setPropertyAndSignal("startDate", start); } void setDueDate(const QDateTime &due) { setPropertyAndSignal("dueDate", due); } signals: void hasTaskPropertiesChanged(bool hasTaskProperties); void textChanged(const QString &text); void titleChanged(const QString &title); void doneChanged(bool done); void startDateChanged(const QDateTime &date); void dueDateChanged(const QDateTime &due); }; class QuickSelectDialogStub : public Widgets::QuickSelectDialogInterface { public: typedef QSharedPointer Ptr; explicit QuickSelectDialogStub() : parent(Q_NULLPTR), execCount(0), itemModel(Q_NULLPTR) { } int exec() { execCount++; return QDialog::Accepted; } void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE { itemModel = model; } QPersistentModelIndex selectedIndex() const Q_DECL_OVERRIDE { return index; } QWidget *parent; int execCount; QAbstractItemModel *itemModel; QPersistentModelIndex index; }; class ApplicationComponentsTest : public QObject { Q_OBJECT public: explicit ApplicationComponentsTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qputenv("ZANSHIN_UNIT_TEST_RUN", "1"); } private slots: void shouldHaveApplicationModel() { // GIVEN Widgets::ApplicationComponents components; auto model = QObjectPtr::create(); // WHEN components.setModel(model); // THEN QCOMPARE(components.model(), model); } void shouldApplyAvailableSourcesModelToAvailableSourcesView() { // GIVEN Widgets::ApplicationComponents components; auto model = QObjectPtr::create(); QObject availableSources; model->setProperty("availableSources", QVariant::fromValue(&availableSources)); // WHEN components.setModel(model); // THEN QCOMPARE(components.availableSourcesView()->model(), &availableSources); } void shouldApplyAvailableSourcesModelAlsoToCreatedAvailableSourcesView() { // GIVEN Widgets::ApplicationComponents components; // Force creation components.availableSourcesView(); auto model = QObjectPtr::create(); QObject availableSources; model->setProperty("availableSources", QVariant::fromValue(&availableSources)); // WHEN components.setModel(model); // THEN QCOMPARE(components.availableSourcesView()->model(), &availableSources); } void shouldApplyAvailablePagesModelToAvailablePagesView() { // GIVEN Widgets::ApplicationComponents components; auto model = QObjectPtr::create(); QObject availablePages; model->setProperty("availablePages", QVariant::fromValue(&availablePages)); QObject availableSources; QAbstractItemModel *sourcesModel = new QStandardItemModel(model.data()); availableSources.setProperty("sourceListModel", QVariant::fromValue(sourcesModel)); model->setProperty("availableSources", QVariant::fromValue(&availableSources)); // WHEN components.setModel(model); // THEN QCOMPARE(components.availablePagesView()->model(), &availablePages); QCOMPARE(components.availablePagesView()->projectSourcesModel(), sourcesModel); } void shouldApplyAvailablePagesModelAlsoToCreatedAvailablePagesView() { // GIVEN Widgets::ApplicationComponents components; // Force creation components.availablePagesView(); auto model = QObjectPtr::create(); QObject availablePages; QAbstractItemModel *sourcesModel = new QStandardItemModel(model.data()); model->setProperty("dataSourcesModel", QVariant::fromValue(sourcesModel)); model->setProperty("availablePages", QVariant::fromValue(&availablePages)); // WHEN components.setModel(model); // THEN QCOMPARE(components.availablePagesView()->model(), &availablePages); QCOMPARE(components.availablePagesView()->projectSourcesModel(), sourcesModel); } void shouldApplyCurrentPageModelToPageView() { // GIVEN Widgets::ApplicationComponents components; auto model = QObjectPtr::create(); QObject currentPage; model->setProperty("currentPage", QVariant::fromValue(¤tPage)); // WHEN components.setModel(model); // THEN QCOMPARE(components.pageView()->model(), ¤tPage); } void shouldApplyCurrentPageModelAlsoToCreatedPageView() { // GIVEN Widgets::ApplicationComponents components; // Force creation components.pageView(); auto model = QObjectPtr::create(); QObject currentPage; model->setProperty("currentPage", QVariant::fromValue(¤tPage)); // WHEN components.setModel(model); // THEN QCOMPARE(components.pageView()->model(), ¤tPage); } void shouldApplyEditorModelToEditorView() { // GIVEN Widgets::ApplicationComponents components; auto model = QObjectPtr::create(); QObject *editorModel = new EditorModelStub(model.data()); model->setProperty("editor", QVariant::fromValue(editorModel)); // WHEN components.setModel(model); // THEN QCOMPARE(components.editorView()->model(), editorModel); } void shouldApplyEditorModelAltoToCreatedPageView() { // GIVEN Widgets::ApplicationComponents components; // Force creation components.editorView(); auto model = QObjectPtr::create(); QObject *editorModel = new EditorModelStub(model.data()); model->setProperty("editor", QVariant::fromValue(editorModel)); // WHEN components.setModel(model); // THEN QCOMPARE(components.editorView()->model(), editorModel); } void shouldPropageNullModelsToViews() { // GIVEN Widgets::ApplicationComponents components; auto model = QObjectPtr::create(); auto availableSources = new QObject(model.data()); model->setProperty("availableSources", QVariant::fromValue(availableSources)); auto availablePages = new QObject(model.data()); model->setProperty("availablePages", QVariant::fromValue(availablePages)); auto currentPage = new QObject(model.data()); model->setProperty("currentPage", QVariant::fromValue(currentPage)); auto editorModel = new EditorModelStub(model.data()); model->setProperty("editor", QVariant::fromValue(editorModel)); components.setModel(model); // WHEN components.setModel(QObjectPtr()); components.availableSourcesView(); components.availablePagesView(); components.pageView(); components.editorView(); // THEN QVERIFY(!components.availableSourcesView()->model()); QVERIFY(!components.availablePagesView()->model()); QVERIFY(!components.pageView()->model()); QVERIFY(!components.editorView()->model()); } void shouldPropageNullModelsToCreatedViews() { // GIVEN Widgets::ApplicationComponents components; components.availableSourcesView(); components.availablePagesView(); components.pageView(); components.editorView(); auto model = QObjectPtr::create(); auto availableSources = new QObject(model.data()); model->setProperty("availableSources", QVariant::fromValue(availableSources)); auto availablePages = new QObject(model.data()); model->setProperty("availablePages", QVariant::fromValue(availablePages)); auto currentPage = new QObject(model.data()); model->setProperty("currentPage", QVariant::fromValue(currentPage)); auto editorModel = new EditorModelStub(model.data()); model->setProperty("editor", QVariant::fromValue(editorModel)); components.setModel(model); // WHEN components.setModel(QObjectPtr()); // THEN QVERIFY(!components.availableSourcesView()->model()); QVERIFY(!components.availablePagesView()->model()); QVERIFY(!components.pageView()->model()); QVERIFY(!components.editorView()->model()); } void shouldApplyAvailablePagesSelectionToApplicationModel() { // GIVEN auto model = ApplicationModelStub::Ptr::create(); AvailablePagesModelStub availablePagesModel; model->setProperty("availablePages", QVariant::fromValue(&availablePagesModel)); model->setProperty("currentPage", QVariant::fromValue(Q_NULLPTR)); QObject editorModel; editorModel.setProperty("artifact", QVariant::fromValue(Domain::Task::Ptr::create())); model->setProperty("editor", QVariant::fromValue(&editorModel)); Widgets::ApplicationComponents components; components.setModel(model); Widgets::AvailablePagesView *availablePagesView = components.availablePagesView(); - auto pagesView = availablePagesView->findChild("pagesView"); + auto pagesView = availablePagesView->findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); Widgets::PageView *pageView = components.pageView(); QVERIFY(pageView); QVERIFY(!pageView->model()); QModelIndex index = pagesView->model()->index(0, 0); // WHEN pagesView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); // THEN QCOMPARE(availablePagesModel.createdPages.size(), 1); QCOMPARE(model->property("currentPage").value(), availablePagesModel.createdPages.first()); QCOMPARE(pageView->model(), availablePagesModel.createdPages.first()); QVERIFY(editorModel.property("artifact").value().isNull()); } void shouldApplyPageViewSelectionToEditorModel() { // GIVEN auto model = QObjectPtr::create(); PageModelStub pageModel; - pageModel.addItem("0. First task"); - pageModel.addItem("1. A note"); - pageModel.addItem("2. Second task"); - pageModel.addItem("3. Another note"); + pageModel.addItem(QStringLiteral("0. First task")); + pageModel.addItem(QStringLiteral("1. A note")); + pageModel.addItem(QStringLiteral("2. Second task")); + pageModel.addItem(QStringLiteral("3. Another note")); model->setProperty("currentPage", QVariant::fromValue(&pageModel)); EditorModelStub editorModel; model->setProperty("editor", QVariant::fromValue(&editorModel)); Widgets::ApplicationComponents components; components.setModel(model); Widgets::PageView *pageView = components.pageView(); - auto centralView = pageView->findChild("centralView"); + auto centralView = pageView->findChild(QStringLiteral("centralView")); QModelIndex index = centralView->model()->index(2, 0); // WHEN centralView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); // THEN QCOMPARE(editorModel.property("artifact").value(), pageModel.itemAtRow(index.row())); } void shouldHaveDefaultActionsList() { // GIVEN Widgets::ApplicationComponents components; // WHEN auto actions = components.globalActions(); // THEN // availablePages view auto available = components.availablePagesView(); foreach (const auto &key, available->globalActions().keys()) QCOMPARE(actions.value(key), available->globalActions().value(key)); // availableSources view auto availableSources = components.availableSourcesView(); foreach (const auto &key, availableSources->globalActions().keys()) QCOMPARE(actions.value(key), availableSources->globalActions().value(key)); // page view auto page = components.pageView(); foreach (const auto &key, page->globalActions().keys()) QCOMPARE(actions.value(key), page->globalActions().value(key)); // application component own action - auto moveAction = components.findChild("moveItemAction"); - QCOMPARE(actions.value("page_view_move"), moveAction); + auto moveAction = components.findChild(QStringLiteral("moveItemAction")); + QCOMPARE(actions.value(QStringLiteral("page_view_move")), moveAction); } void shouldMoveItem() { // GIVEN auto model = QObjectPtr::create(); PageModelStub pageModel; - pageModel.addItem("0. First task"); - pageModel.addItem("1. A note"); - pageModel.addItem("2. Second task"); - pageModel.addItem("3. Another note"); + pageModel.addItem(QStringLiteral("0. First task")); + pageModel.addItem(QStringLiteral("1. A note")); + pageModel.addItem(QStringLiteral("2. Second task")); + pageModel.addItem(QStringLiteral("3. Another note")); model->setProperty("currentPage", QVariant::fromValue(&pageModel)); AvailablePagesModelStub availablePagesModelStub; model->setProperty("availablePages", QVariant::fromValue(&availablePagesModelStub)); QWidget *mainWidget = new QWidget; Widgets::ApplicationComponents components(mainWidget); components.setModel(model); auto availablePageView = components.availablePagesView(); - auto availablePagesTreeView = availablePageView->findChild("pagesView"); + auto availablePagesTreeView = availablePageView->findChild(QStringLiteral("pagesView")); Q_ASSERT(availablePagesTreeView); auto dialogStub = QuickSelectDialogStub::Ptr::create(); dialogStub->index = availablePagesModelStub.pageListModel()->index(0, 0); // inbox selected components.setQuickSelectDialogFactory([dialogStub] (QWidget *parent) { dialogStub->parent = parent; return dialogStub; }); auto pageView = components.pageView(); - auto centralView = pageView->findChild("centralView"); + auto centralView = pageView->findChild(QStringLiteral("centralView")); QModelIndex index1 = pageModel.itemModel.index(0,0); QModelIndex index2 = pageModel.itemModel.index(2,0); - auto filterWidget = pageView->findChild("filterWidget"); + auto filterWidget = pageView->findChild(QStringLiteral("filterWidget")); auto displayedModel = filterWidget->proxyModel(); auto displayedIndex = displayedModel->index(0, 0); auto displayedIndex2 = displayedModel->index(2, 0); - auto moveAction = components.findChild("moveItemAction"); + auto moveAction = components.findChild(QStringLiteral("moveItemAction")); // WHEN pageModel.selectedItems << index1 << index2; centralView->selectionModel()->setCurrentIndex(displayedIndex, QItemSelectionModel::ClearAndSelect); centralView->selectionModel()->setCurrentIndex(displayedIndex2, QItemSelectionModel::Select); moveAction->trigger(); // THEN QCOMPARE(dialogStub->execCount, 1); QCOMPARE(dialogStub->parent, pageView); QCOMPARE(dialogStub->itemModel, availablePagesModelStub.pageListModel()); - QCOMPARE(availablePagesModelStub.itemModel.dropDestination, QString("Inbox")); + QCOMPARE(availablePagesModelStub.itemModel.dropDestination, QStringLiteral("Inbox")); QCOMPARE(availablePagesModelStub.itemModel.droppedItemDataString.size(), 2); QCOMPARE(availablePagesModelStub.itemModel.droppedItemDataString.at(0), index1.data().toString()); QCOMPARE(availablePagesModelStub.itemModel.droppedItemDataString.at(1), index2.data().toString()); } }; ZANSHIN_TEST_MAIN(ApplicationComponentsTest) #include "applicationcomponentstest.moc" diff --git a/tests/units/widgets/availablepagesviewtest.cpp b/tests/units/widgets/availablepagesviewtest.cpp index 316949cb..01ad5d0a 100644 --- a/tests/units/widgets/availablepagesviewtest.cpp +++ b/tests/units/widgets/availablepagesviewtest.cpp @@ -1,598 +1,598 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "domain/project.h" #include "domain/context.h" #include "domain/tag.h" #include "presentation/metatypes.h" #include "presentation/querytreemodelbase.h" #include "widgets/availablepagesview.h" #include "widgets/newprojectdialog.h" #include "widgets/quickselectdialog.h" #include "messageboxstub.h" class NewProjectDialogStub : public Widgets::NewProjectDialogInterface { public: typedef QSharedPointer Ptr; explicit NewProjectDialogStub() : parent(Q_NULLPTR), execCount(0), sourceModel(Q_NULLPTR), source(Domain::DataSource::Ptr::create()) { } int exec() { execCount++; return QDialog::Accepted; } void setDataSourcesModel(QAbstractItemModel *model) Q_DECL_OVERRIDE { sourceModel = model; } QString name() const Q_DECL_OVERRIDE { - return "name"; + return QStringLiteral("name"); } Domain::DataSource::Ptr dataSource() const Q_DECL_OVERRIDE { return source; } QWidget *parent; int execCount; QAbstractItemModel *sourceModel; Domain::DataSource::Ptr source; }; class QuickSelectDialogStub : public Widgets::QuickSelectDialogInterface { public: typedef QSharedPointer Ptr; explicit QuickSelectDialogStub() : parent(Q_NULLPTR), execCount(0), itemModel(Q_NULLPTR) { } int exec() { execCount++; return QDialog::Accepted; } void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE { itemModel = model; } QPersistentModelIndex selectedIndex() const Q_DECL_OVERRIDE { return index; } QWidget *parent; int execCount; QAbstractItemModel *itemModel; QPersistentModelIndex index; }; class AvailablePagesModelStub : public QObject { Q_OBJECT public: explicit AvailablePagesModelStub(QObject *parent = Q_NULLPTR) : QObject(parent) { } public slots: void addProject(const QString &name, const Domain::DataSource::Ptr &source) { projectNames << name; sources << source; } void addContext(const QString &name) { contextNames << name; } void addTag(const QString &name) { tagNames << name; } void removeItem(const QModelIndex &index) { projectRemoved = index.data().toString(); } public Q_SLOTS: QObject *createPageForIndex(const QModelIndex &) { return Q_NULLPTR; } public: QStringList projectNames; QStringList contextNames; QStringList tagNames; QList sources; QString projectRemoved; }; class AvailablePagesViewTest : public QObject { Q_OBJECT private slots: void shouldHaveDefaultState() { Widgets::AvailablePagesView available; QVERIFY(!available.model()); QVERIFY(!available.projectSourcesModel()); QVERIFY(available.defaultProjectSource().isNull()); - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QVERIFY(pagesView->isVisibleTo(&available)); QVERIFY(!pagesView->header()->isVisibleTo(&available)); QCOMPARE(pagesView->dragDropMode(), QTreeView::DropOnly); - auto actionBar = available.findChild("actionBar"); + auto actionBar = available.findChild(QStringLiteral("actionBar")); QVERIFY(actionBar); QVERIFY(actionBar->isVisibleTo(&available)); - auto addProjectAction = available.findChild("addProjectAction"); + auto addProjectAction = available.findChild(QStringLiteral("addProjectAction")); QVERIFY(addProjectAction); - auto addContextAction = available.findChild("addContextAction"); + auto addContextAction = available.findChild(QStringLiteral("addContextAction")); QVERIFY(addContextAction); - auto addTagAction = available.findChild("addTagAction"); + auto addTagAction = available.findChild(QStringLiteral("addTagAction")); QVERIFY(addTagAction); - auto removeAction = available.findChild("removeAction"); + auto removeAction = available.findChild(QStringLiteral("removeAction")); QVERIFY(removeAction); - auto goPreviousAction = available.findChild("goPreviousAction"); + auto goPreviousAction = available.findChild(QStringLiteral("goPreviousAction")); QVERIFY(goPreviousAction); - auto goNextAction = available.findChild("goNextAction"); + auto goNextAction = available.findChild(QStringLiteral("goNextAction")); QVERIFY(goNextAction); - auto goToAction = available.findChild("goToAction"); + auto goToAction = available.findChild(QStringLiteral("goToAction")); QVERIFY(goToAction); auto projectDialogFactory = available.projectDialogFactory(); QVERIFY(projectDialogFactory(&available).dynamicCast()); auto quickSelectDialogFactory = available.quickSelectDialogFactory(); QVERIFY(quickSelectDialogFactory(&available).dynamicCast()); auto actions = available.globalActions(); - QCOMPARE(actions.value("pages_project_add"), addProjectAction); - QCOMPARE(actions.value("pages_context_add"), addContextAction); - QCOMPARE(actions.value("pages_tag_add"), addTagAction); - QCOMPARE(actions.value("pages_remove"), removeAction); - QCOMPARE(actions.value("pages_go_previous"), goPreviousAction); - QCOMPARE(actions.value("pages_go_next"), goNextAction); - QCOMPARE(actions.value("pages_go_to"), goToAction); + QCOMPARE(actions.value(QStringLiteral("pages_project_add")), addProjectAction); + QCOMPARE(actions.value(QStringLiteral("pages_context_add")), addContextAction); + QCOMPARE(actions.value(QStringLiteral("pages_tag_add")), addTagAction); + QCOMPARE(actions.value(QStringLiteral("pages_remove")), removeAction); + QCOMPARE(actions.value(QStringLiteral("pages_go_previous")), goPreviousAction); + QCOMPARE(actions.value(QStringLiteral("pages_go_next")), goNextAction); + QCOMPARE(actions.value(QStringLiteral("pages_go_to")), goToAction); } void shouldShowOnlyAddActionsNeededByTheModel_data() { QTest::addColumn("hasProjects"); QTest::addColumn("hasContexts"); QTest::addColumn("hasTags"); QTest::newRow("!projects !contexts !tags") << false << false << false; QTest::newRow("!projects !contexts tags") << false << false << true; QTest::newRow("!projects contexts !tags") << false << true << false; QTest::newRow("!projects contexts tags") << false << true << true; QTest::newRow("projects !contexts !tags") << true << false << false; QTest::newRow("projects !contexts tags") << true << false << true; QTest::newRow("projects contexts !tags") << true << true << false; QTest::newRow("projects contexts tags") << true << true << true; } void shouldShowOnlyAddActionsNeededByTheModel() { // GIVEN QFETCH(bool, hasProjects); QFETCH(bool, hasContexts); QFETCH(bool, hasTags); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("hasProjectPages", hasProjects); stubPagesModel.setProperty("hasContextPages", hasContexts); stubPagesModel.setProperty("hasTagPages", hasTags); Widgets::AvailablePagesView available; - auto addProjectAction = available.findChild("addProjectAction"); + auto addProjectAction = available.findChild(QStringLiteral("addProjectAction")); QVERIFY(addProjectAction); - auto addContextAction = available.findChild("addContextAction"); + auto addContextAction = available.findChild(QStringLiteral("addContextAction")); QVERIFY(addContextAction); - auto addTagAction = available.findChild("addTagAction"); + auto addTagAction = available.findChild(QStringLiteral("addTagAction")); QVERIFY(addTagAction); // WHEN available.setModel(&stubPagesModel); // THEN QCOMPARE(addProjectAction->isVisible(), hasProjects); QCOMPARE(addContextAction->isVisible(), hasContexts); QCOMPARE(addTagAction->isVisible(), hasTags); } void shouldDisplayListFromPageModel() { // GIVEN - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("pageListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailablePagesView available; - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QVERIFY(!pagesView->model()); // WHEN available.setModel(&stubPagesModel); QTest::qWait(10); // THEN QCOMPARE(pagesView->model(), &model); QCOMPARE(pagesView->selectionModel()->currentIndex(), model.index(0, 0)); } void shouldNotCrashWithNullModel() { // GIVEN - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("pageListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailablePagesView available; available.setModel(&stubPagesModel); QTest::qWait(10); - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QCOMPARE(pagesView->model(), &model); // WHEN available.setModel(Q_NULLPTR); QTest::qWait(10); // THEN QVERIFY(!available.isEnabled()); QVERIFY(!pagesView->model()); } void shouldAddNewProjects() { // GIVEN AvailablePagesModelStub model; QStringListModel sourceModel; auto dialogStub = NewProjectDialogStub::Ptr::create(); auto source = Domain::DataSource::Ptr::create(); Widgets::AvailablePagesView available; available.setModel(&model); available.setProjectSourcesModel(&sourceModel); available.setDefaultProjectSource(source); available.setProjectDialogFactory([dialogStub] (QWidget *parent) { dialogStub->parent = parent; return dialogStub; }); - auto addProjectAction = available.findChild("addProjectAction"); + auto addProjectAction = available.findChild(QStringLiteral("addProjectAction")); // WHEN addProjectAction->trigger(); // THEN QCOMPARE(dialogStub->execCount, 1); QCOMPARE(dialogStub->parent, &available); QCOMPARE(dialogStub->sourceModel, &sourceModel); QCOMPARE(model.projectNames.size(), 1); QCOMPARE(model.projectNames.first(), dialogStub->name()); QCOMPARE(model.sources.size(), 1); QCOMPARE(model.sources.first(), dialogStub->dataSource()); QCOMPARE(available.defaultProjectSource(), dialogStub->dataSource()); } void shouldAddNewContexts() { // GIVEN AvailablePagesModelStub model; QStringListModel sourceModel; auto dialogStub = NewProjectDialogStub::Ptr::create(); auto source = Domain::DataSource::Ptr::create(); auto msgBoxStub = MessageBoxStub::Ptr::create(); - msgBoxStub->setTextInput("Foo"); + msgBoxStub->setTextInput(QStringLiteral("Foo")); Widgets::AvailablePagesView available; available.setModel(&model); available.setProjectSourcesModel(&sourceModel); available.setDefaultProjectSource(source); available.setMessageBoxInterface(msgBoxStub); - auto addContextAction = available.findChild("addContextAction"); + auto addContextAction = available.findChild(QStringLiteral("addContextAction")); // WHEN addContextAction->trigger(); // THEN QVERIFY(msgBoxStub->called()); QCOMPARE(model.contextNames.size(), 1); - QCOMPARE(model.contextNames.first(), QString("Foo")); + QCOMPARE(model.contextNames.first(), QStringLiteral("Foo")); } void shouldAddNewTags() { // GIVEN AvailablePagesModelStub model; QStringListModel sourceModel; auto dialogStub = NewProjectDialogStub::Ptr::create(); auto source = Domain::DataSource::Ptr::create(); auto msgBoxStub = MessageBoxStub::Ptr::create(); - msgBoxStub->setTextInput("Foo"); + msgBoxStub->setTextInput(QStringLiteral("Foo")); Widgets::AvailablePagesView available; available.setModel(&model); available.setProjectSourcesModel(&sourceModel); available.setDefaultProjectSource(source); available.setMessageBoxInterface(msgBoxStub); - auto addTagAction = available.findChild("addTagAction"); + auto addTagAction = available.findChild(QStringLiteral("addTagAction")); // WHEN addTagAction->trigger(); // THEN QVERIFY(msgBoxStub->called()); QCOMPARE(model.tagNames.size(), 1); - QCOMPARE(model.tagNames.first(), QString("Foo")); + QCOMPARE(model.tagNames.first(), QStringLiteral("Foo")); } void shouldRemoveAPage_data() { QTest::addColumn("object"); QTest::addColumn("actionEnabled"); auto project1 = Domain::Project::Ptr::create(); - project1->setName("Project 1"); + project1->setName(QStringLiteral("Project 1")); QTest::newRow("project") << QObjectPtr(project1) << true; auto context1 = Domain::Context::Ptr::create(); - context1->setName("Context 1"); + context1->setName(QStringLiteral("Context 1")); QTest::newRow("context") << QObjectPtr(context1) << true; auto tag1 = Domain::Tag::Ptr::create(); - tag1->setName("Tag 1"); + tag1->setName(QStringLiteral("Tag 1")); QTest::newRow("tag") << QObjectPtr(tag1) << true; QTest::newRow("non removable") << QObjectPtr::create() << false; } void shouldRemoveAPage() { QFETCH(QObjectPtr, object); QFETCH(bool, actionEnabled); // GIVEN QStringList list; - list << "A" << "B" << "C"; + list << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C"); QStandardItemModel model; for (int row = 0; row < list.count(); ++row) { model.setItem(row, new QStandardItem(list.at(row))); } QVERIFY(model.setData(model.index(0, 0), QVariant::fromValue(object), Presentation::QueryTreeModelBase::ObjectRole)); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("pageListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailablePagesView available; - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QVERIFY(!pagesView->model()); available.setModel(&stubPagesModel); QTest::qWait(10); - auto removeAction = available.findChild("removeAction"); + auto removeAction = available.findChild(QStringLiteral("removeAction")); auto msgbox = MessageBoxStub::Ptr::create(); available.setMessageBoxInterface(msgbox); // WHEN if (actionEnabled) removeAction->trigger(); // THEN QCOMPARE(removeAction->isEnabled(), actionEnabled); if (actionEnabled) { QCOMPARE(stubPagesModel.projectRemoved, list.first()); } } void shouldGoToPreviousSelectablePage() { // GIVEN QStandardItemModel model; - model.appendRow(new QStandardItem("Inbox")); - auto projects = new QStandardItem("Projects"); + model.appendRow(new QStandardItem(QStringLiteral("Inbox"))); + auto projects = new QStandardItem(QStringLiteral("Projects")); projects->setFlags(Qt::NoItemFlags); model.appendRow(projects); - projects->appendRow(new QStandardItem("Project 1")); - projects->appendRow(new QStandardItem("Project 2")); + projects->appendRow(new QStandardItem(QStringLiteral("Project 1"))); + projects->appendRow(new QStandardItem(QStringLiteral("Project 2"))); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("pageListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailablePagesView available; - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QVERIFY(!pagesView->model()); available.setModel(&stubPagesModel); QTest::qWait(10); - auto goPreviousAction = available.findChild("goPreviousAction"); + auto goPreviousAction = available.findChild(QStringLiteral("goPreviousAction")); pagesView->setCurrentIndex(model.index(1, 0, model.indexFromItem(projects))); // WHEN goPreviousAction->trigger(); // THEN QCOMPARE(pagesView->currentIndex(), model.index(0, 0, model.indexFromItem(projects))); // WHEN goPreviousAction->trigger(); // THEN QCOMPARE(pagesView->currentIndex(), model.index(0, 0)); // WHEN goPreviousAction->trigger(); // THEN QCOMPARE(pagesView->currentIndex(), model.index(0, 0)); } void shouldGoToNextSelectablePage() { // GIVEN QStandardItemModel model; - model.appendRow(new QStandardItem("Inbox")); - auto projects = new QStandardItem("Projects"); + model.appendRow(new QStandardItem(QStringLiteral("Inbox"))); + auto projects = new QStandardItem(QStringLiteral("Projects")); projects->setFlags(Qt::NoItemFlags); model.appendRow(projects); - projects->appendRow(new QStandardItem("Project 1")); - projects->appendRow(new QStandardItem("Project 2")); + projects->appendRow(new QStandardItem(QStringLiteral("Project 1"))); + projects->appendRow(new QStandardItem(QStringLiteral("Project 2"))); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("pageListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailablePagesView available; - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QVERIFY(!pagesView->model()); available.setModel(&stubPagesModel); QTest::qWait(10); - auto goNextAction = available.findChild("goNextAction"); + auto goNextAction = available.findChild(QStringLiteral("goNextAction")); pagesView->setCurrentIndex(model.index(0, 0)); // WHEN goNextAction->trigger(); // THEN QCOMPARE(pagesView->currentIndex(), model.index(0, 0, model.indexFromItem(projects))); // WHEN goNextAction->trigger(); // THEN QCOMPARE(pagesView->currentIndex(), model.index(1, 0, model.indexFromItem(projects))); // WHEN goNextAction->trigger(); // THEN QCOMPARE(pagesView->currentIndex(), model.index(1, 0, model.indexFromItem(projects))); } void shouldGoToUserSelectedIndex() { // GIVEN QStandardItemModel model; - model.appendRow(new QStandardItem("Inbox")); - auto projects = new QStandardItem("Projects"); + model.appendRow(new QStandardItem(QStringLiteral("Inbox"))); + auto projects = new QStandardItem(QStringLiteral("Projects")); projects->setFlags(Qt::NoItemFlags); model.appendRow(projects); - projects->appendRow(new QStandardItem("Project 1")); - projects->appendRow(new QStandardItem("Project 2")); + projects->appendRow(new QStandardItem(QStringLiteral("Project 1"))); + projects->appendRow(new QStandardItem(QStringLiteral("Project 2"))); AvailablePagesModelStub stubPagesModel; stubPagesModel.setProperty("pageListModel", QVariant::fromValue(static_cast(&model))); auto dialogStub = QuickSelectDialogStub::Ptr::create(); // Project 2 will be selected dialogStub->index = model.index(1, 0, model.index(1, 0)); Widgets::AvailablePagesView available; available.setModel(&stubPagesModel); available.setQuickSelectDialogFactory([dialogStub] (QWidget *parent) { dialogStub->parent = parent; return dialogStub; }); - auto pagesView = available.findChild("pagesView"); + auto pagesView = available.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QCOMPARE(pagesView->model(), &model); - auto goToAction = available.findChild("goToAction"); + auto goToAction = available.findChild(QStringLiteral("goToAction")); // WHEN goToAction->trigger(); // THEN QCOMPARE(dialogStub->execCount, 1); QCOMPARE(dialogStub->parent, &available); QCOMPARE(dialogStub->itemModel, &model); QCOMPARE(QPersistentModelIndex(pagesView->currentIndex()), dialogStub->index); } }; ZANSHIN_TEST_MAIN(AvailablePagesViewTest) #include "availablepagesviewtest.moc" diff --git a/tests/units/widgets/availablesourcesviewtest.cpp b/tests/units/widgets/availablesourcesviewtest.cpp index d6d89828..7a4b4ef8 100644 --- a/tests/units/widgets/availablesourcesviewtest.cpp +++ b/tests/units/widgets/availablesourcesviewtest.cpp @@ -1,419 +1,419 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "presentation/metatypes.h" #include "presentation/querytreemodelbase.h" #include "widgets/availablesourcesview.h" #include "widgets/datasourcedelegate.h" class AvailableSourcesModelStub : public QObject { Q_OBJECT Q_PROPERTY(QString searchTerm READ searchTerm WRITE setSearchTerm) public: explicit AvailableSourcesModelStub(QObject *parent = Q_NULLPTR) : QObject(parent), settingsCalled(false) { } QString searchTerm() const { return m_searchTerm; } public slots: void showConfigDialog() { settingsCalled = true; } void setDefaultItem(const QModelIndex &index) { defaultIndex = index; } void setSearchTerm(const QString &term) { m_searchTerm = term; } void listSource(const Domain::DataSource::Ptr &source) { listedSources << source; } void unlistSource(const Domain::DataSource::Ptr &source) { unlistedSources << source; } void bookmarkSource(const Domain::DataSource::Ptr &source) { bookmarkedSources << source; } public: bool settingsCalled; QList listedSources; QList unlistedSources; QList bookmarkedSources; QPersistentModelIndex defaultIndex; private: QString m_searchTerm; }; class AvailableSourcesViewTest : public QObject { Q_OBJECT private slots: void shouldHaveDefaultState() { Widgets::AvailableSourcesView available; QVERIFY(!available.model()); - auto sourcesView = available.findChild("sourcesView"); + auto sourcesView = available.findChild(QStringLiteral("sourcesView")); QVERIFY(sourcesView); QVERIFY(sourcesView->isVisibleTo(&available)); QVERIFY(!sourcesView->header()->isVisibleTo(&available)); auto delegate = qobject_cast(sourcesView->itemDelegate()); #ifdef ZANSHIN_HIDING_SOURCES_ENABLED QVERIFY(delegate->actionsEnabled()); #else QVERIFY(!delegate->isActionsEnabled()); #endif - auto searchEdit = available.findChild("searchEdit"); + auto searchEdit = available.findChild(QStringLiteral("searchEdit")); QVERIFY(searchEdit); #ifdef ZANSHIN_HIDING_SOURCES_ENABLED QVERIFY(searchEdit->isVisibleTo(&available)); #else QVERIFY(!searchEdit->isVisibleTo(&available)); #endif QVERIFY(searchEdit->isClearButtonShown()); QCOMPARE(searchEdit->placeholderText(), tr("Search...")); auto proxy = qobject_cast(sourcesView->model()); QVERIFY(proxy); QVERIFY(proxy->dynamicSortFilter()); QCOMPARE(proxy->sortColumn(), 0); QCOMPARE(proxy->sortOrder(), Qt::AscendingOrder); - auto actionBar = available.findChild("actionBar"); + auto actionBar = available.findChild(QStringLiteral("actionBar")); QVERIFY(actionBar); QVERIFY(actionBar->isVisibleTo(&available)); - auto defaultAction = available.findChild("defaultAction"); + auto defaultAction = available.findChild(QStringLiteral("defaultAction")); QVERIFY(defaultAction); - auto settingsAction = available.findChild("settingsAction"); + auto settingsAction = available.findChild(QStringLiteral("settingsAction")); QVERIFY(settingsAction); auto actions = available.globalActions(); - QCOMPARE(actions.value("options_configure"), settingsAction); + QCOMPARE(actions.value(QStringLiteral("options_configure")), settingsAction); } void shouldDisplayListFromPageModel() { // GIVEN - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); QObject stubPagesModel; stubPagesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailableSourcesView available; - auto sourcesView = available.findChild("sourcesView"); + auto sourcesView = available.findChild(QStringLiteral("sourcesView")); QVERIFY(sourcesView); auto proxy = qobject_cast(sourcesView->model()); QVERIFY(proxy); QVERIFY(!proxy->sourceModel()); // WHEN available.setModel(&stubPagesModel); QTest::qWait(10); // THEN QCOMPARE(proxy->sourceModel(), &model); } void shouldNotCrashWithNullModel() { // GIVEN - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); QObject stubPagesModel; stubPagesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailableSourcesView available; - auto sourcesView = available.findChild("sourcesView"); + auto sourcesView = available.findChild(QStringLiteral("sourcesView")); QVERIFY(sourcesView); auto proxy = qobject_cast(sourcesView->model()); QVERIFY(proxy); QVERIFY(!proxy->sourceModel()); available.setModel(&stubPagesModel); QTest::qWait(10); // WHEN available.setModel(Q_NULLPTR); QTest::qWait(10); // THEN QVERIFY(!available.isEnabled()); QVERIFY(!proxy->sourceModel()); } void shouldSetSelectedAsDefault() { // GIVEN QStandardItemModel model; - auto itemA = new QStandardItem("A"); + auto itemA = new QStandardItem(QStringLiteral("A")); auto sourceA = Domain::DataSource::Ptr::create(); sourceA->setContentTypes(Domain::DataSource::Tasks); itemA->setData(QVariant::fromValue(sourceA), Presentation::QueryTreeModelBase::ObjectRole); model.appendRow(itemA); - auto itemB = new QStandardItem("B"); + auto itemB = new QStandardItem(QStringLiteral("B")); auto sourceB = Domain::DataSource::Ptr::create(); sourceB->setContentTypes(Domain::DataSource::Tasks); itemB->setData(QVariant::fromValue(sourceB), Presentation::QueryTreeModelBase::ObjectRole); model.appendRow(itemB); - auto itemC = new QStandardItem("C"); + auto itemC = new QStandardItem(QStringLiteral("C")); auto sourceC = Domain::DataSource::Ptr::create(); sourceC->setContentTypes(Domain::DataSource::NoContent); itemC->setData(QVariant::fromValue(sourceC), Presentation::QueryTreeModelBase::ObjectRole); model.appendRow(itemC); AvailableSourcesModelStub stubSourcesModel; stubSourcesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailableSourcesView available; available.setModel(&stubSourcesModel); - auto sourcesView = available.findChild("sourcesView"); + auto sourcesView = available.findChild(QStringLiteral("sourcesView")); QVERIFY(sourcesView); auto proxy = qobject_cast(sourcesView->model()); QVERIFY(proxy); - auto defaultAction = available.findChild("defaultAction"); + auto defaultAction = available.findChild(QStringLiteral("defaultAction")); QVERIFY(defaultAction); // WHEN auto selectedIndex = QPersistentModelIndex(model.index(1, 0)); sourcesView->setCurrentIndex(proxy->mapFromSource(selectedIndex)); // THEN QVERIFY(defaultAction->isEnabled()); // WHEN defaultAction->trigger(); // THEN QCOMPARE(stubSourcesModel.defaultIndex, selectedIndex); // WHEN sourcesView->selectionModel()->clear(); // THEN QVERIFY(!defaultAction->isEnabled()); // WHEN selectedIndex = QPersistentModelIndex(model.index(2, 0)); sourcesView->setCurrentIndex(proxy->mapFromSource(selectedIndex)); // THEN QVERIFY(!defaultAction->isEnabled()); } void shouldInvokeModelSettingsDialog() { // GIVEN AvailableSourcesModelStub stubSourcesModel; QVERIFY(!stubSourcesModel.settingsCalled); Widgets::AvailableSourcesView available; available.setModel(&stubSourcesModel); - auto settingsAction = available.findChild("settingsAction"); + auto settingsAction = available.findChild(QStringLiteral("settingsAction")); QVERIFY(settingsAction); // WHEN settingsAction->trigger(); // THEN QVERIFY(stubSourcesModel.settingsCalled); } void shouldListASourceWhenTheDelegateButtonIsClicked() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); AvailableSourcesModelStub stubPagesModel; stubPagesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailableSourcesView available; auto sourcesDelegate = available.findChild(); QVERIFY(sourcesDelegate); available.setModel(&stubPagesModel); QTest::qWait(10); // WHEN QVERIFY(QMetaObject::invokeMethod(sourcesDelegate, "actionTriggered", Q_ARG(Domain::DataSource::Ptr, source), Q_ARG(int, Widgets::DataSourceDelegate::AddToList))); // THEN QCOMPARE(stubPagesModel.listedSources.size(), 1); QCOMPARE(stubPagesModel.listedSources.first(), source); } void shouldUnlistASourceWhenTheDelegateButtonIsClicked() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); AvailableSourcesModelStub stubPagesModel; stubPagesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailableSourcesView available; auto sourcesDelegate = available.findChild(); QVERIFY(sourcesDelegate); available.setModel(&stubPagesModel); QTest::qWait(10); // WHEN QVERIFY(QMetaObject::invokeMethod(sourcesDelegate, "actionTriggered", Q_ARG(Domain::DataSource::Ptr, source), Q_ARG(int, Widgets::DataSourceDelegate::RemoveFromList))); // THEN QCOMPARE(stubPagesModel.unlistedSources.size(), 1); QCOMPARE(stubPagesModel.unlistedSources.first(), source); } void shouldBookmarkASourceWhenTheDelegateButtonIsClicked() { // GIVEN auto source = Domain::DataSource::Ptr::create(); - QStringListModel model(QStringList() << "A" << "B" << "C" ); + QStringListModel model(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); AvailableSourcesModelStub stubPagesModel; stubPagesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&model))); Widgets::AvailableSourcesView available; auto sourcesDelegate = available.findChild(); QVERIFY(sourcesDelegate); available.setModel(&stubPagesModel); QTest::qWait(10); // WHEN QVERIFY(QMetaObject::invokeMethod(sourcesDelegate, "actionTriggered", Q_ARG(Domain::DataSource::Ptr, source), Q_ARG(int, Widgets::DataSourceDelegate::Bookmark))); // THEN QCOMPARE(stubPagesModel.bookmarkedSources.size(), 1); QCOMPARE(stubPagesModel.bookmarkedSources.first(), source); } void shouldSwitchToSearchListWhenASearchTermIsGiven() { // GIVEN - QStringListModel sourceModel(QStringList() << "A" << "B" << "C" ); - QStringListModel searchModel(QStringList() << "D" << "E" << "F" ); + QStringListModel sourceModel(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C") ); + QStringListModel searchModel(QStringList() << QStringLiteral("D") << QStringLiteral("E") << QStringLiteral("F") ); AvailableSourcesModelStub stubPagesModel; stubPagesModel.setProperty("sourceListModel", QVariant::fromValue(static_cast(&sourceModel))); stubPagesModel.setProperty("searchListModel", QVariant::fromValue(static_cast(&searchModel))); Widgets::AvailableSourcesView available; - auto sourcesView = available.findChild("sourcesView"); + auto sourcesView = available.findChild(QStringLiteral("sourcesView")); QVERIFY(sourcesView); auto proxy = qobject_cast(sourcesView->model()); QVERIFY(proxy); available.setModel(&stubPagesModel); QCOMPARE(proxy->sourceModel(), &sourceModel); - auto searchEdit = available.findChild("searchEdit"); + auto searchEdit = available.findChild(QStringLiteral("searchEdit")); QVERIFY(searchEdit); // WHEN QTest::keyClick(searchEdit, 'm'); // THEN QCOMPARE(proxy->sourceModel(), &sourceModel); QVERIFY(stubPagesModel.searchTerm().isEmpty()); // WHEN QTest::keyClick(searchEdit, 'y'); // THEN QCOMPARE(proxy->sourceModel(), &sourceModel); QVERIFY(stubPagesModel.searchTerm().isEmpty()); // WHEN QTest::keyClick(searchEdit, ' '); // THEN QCOMPARE(proxy->sourceModel(), &searchModel); - QCOMPARE(stubPagesModel.searchTerm(), QString("my ")); + QCOMPARE(stubPagesModel.searchTerm(), QStringLiteral("my ")); // WHEN - QTest::keyClicks(searchEdit, "term"); + QTest::keyClicks(searchEdit, QStringLiteral("term")); // THEN QCOMPARE(proxy->sourceModel(), &searchModel); - QCOMPARE(stubPagesModel.searchTerm(), QString("my term")); + QCOMPARE(stubPagesModel.searchTerm(), QStringLiteral("my term")); // WHEN searchEdit->clear(); // THEN QCOMPARE(proxy->sourceModel(), &sourceModel); QVERIFY(stubPagesModel.searchTerm().isEmpty()); } }; ZANSHIN_TEST_MAIN(AvailableSourcesViewTest) #include "availablesourcesviewtest.moc" diff --git a/tests/units/widgets/datasourcedelegatetest.cpp b/tests/units/widgets/datasourcedelegatetest.cpp index b571b17c..14f60982 100644 --- a/tests/units/widgets/datasourcedelegatetest.cpp +++ b/tests/units/widgets/datasourcedelegatetest.cpp @@ -1,150 +1,150 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "domain/datasource.h" #include "presentation/querytreemodelbase.h" #include "widgets/datasourcedelegate.h" Q_DECLARE_METATYPE(QList) class DataSourceDelegateTest : public QObject { Q_OBJECT public: explicit DataSourceDelegateTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); } QStandardItem *itemFromSource(const Domain::DataSource::Ptr &source) { auto item = new QStandardItem; item->setText(source->name()); item->setIcon(QIcon::fromTheme(source->iconName())); item->setData(QVariant::fromValue(source), Presentation::QueryTreeModelBase::ObjectRole); return item; } private slots: void shouldHandleClickOnButtons_data() { QTest::addColumn("actionsEnabled"); QTest::addColumn("source"); QTest::addColumn>("expectedActions"); QList actions; auto source = Domain::DataSource::Ptr::create(); - source->setName("No Content"); - source->setIconName("folder"); + source->setName(QStringLiteral("No Content")); + source->setIconName(QStringLiteral("folder")); source->setListStatus(Domain::DataSource::Bookmarked); QTest::newRow("no content") << true << source << actions; actions.clear(); actions << Widgets::DataSourceDelegate::AddToList; source = Domain::DataSource::Ptr::create(); - source->setName("Not listed"); - source->setIconName("folder"); + source->setName(QStringLiteral("Not listed")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setListStatus(Domain::DataSource::Unlisted); QTest::newRow("not listed") << true << source << actions; actions.clear(); actions << Widgets::DataSourceDelegate::Bookmark << Widgets::DataSourceDelegate::RemoveFromList; source = Domain::DataSource::Ptr::create(); - source->setName("Listed"); - source->setIconName("folder"); + source->setName(QStringLiteral("Listed")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setListStatus(Domain::DataSource::Listed); QTest::newRow("listed") << true << source << actions; actions.clear(); actions << Widgets::DataSourceDelegate::Bookmark << Widgets::DataSourceDelegate::RemoveFromList; source = Domain::DataSource::Ptr::create(); - source->setName("Bookmarked"); - source->setIconName("folder"); + source->setName(QStringLiteral("Bookmarked")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setListStatus(Domain::DataSource::Bookmarked); QTest::newRow("bookmarked") << true << source << actions; actions.clear(); source = Domain::DataSource::Ptr::create(); - source->setName("Listed"); - source->setIconName("folder"); + source->setName(QStringLiteral("Listed")); + source->setIconName(QStringLiteral("folder")); source->setContentTypes(Domain::DataSource::Tasks); source->setListStatus(Domain::DataSource::Listed); QTest::newRow("actions disabled") << false << source << actions; } void shouldHandleClickOnButtons() { // GIVEN QFETCH(bool, actionsEnabled); QFETCH(Domain::DataSource::Ptr, source); QFETCH(QList, expectedActions); Widgets::DataSourceDelegate delegate; delegate.setActionsEnabled(actionsEnabled); QSignalSpy spy(&delegate, &Widgets::DataSourceDelegate::actionTriggered); QStandardItemModel model; model.appendRow(itemFromSource(source)); QTreeView view; view.header()->hide(); view.setItemDelegate(&delegate); view.setModel(&model); view.show(); QTest::qWaitForWindowShown(&view); // WHEN QPoint clickPoint = view.rect().topRight() + QPoint(-30, 10); for (int i = 0; i < 5; i++) { QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, clickPoint); clickPoint += QPoint(-20, 0); } // THEN QList actions; while (!spy.isEmpty()) { auto parameters = spy.takeFirst(); QCOMPARE(parameters.first().value(), source); actions << parameters.last().toInt(); } QCOMPARE(actions, expectedActions); } }; ZANSHIN_TEST_MAIN(DataSourceDelegateTest) #include "datasourcedelegatetest.moc" diff --git a/tests/units/widgets/editorviewtest.cpp b/tests/units/widgets/editorviewtest.cpp index 01b67380..53e54846 100644 --- a/tests/units/widgets/editorviewtest.cpp +++ b/tests/units/widgets/editorviewtest.cpp @@ -1,703 +1,703 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include "domain/note.h" #include "domain/task.h" #include "widgets/editorview.h" #include "addressline/addresseelineedit.h" #include "kdateedit.h" class EditorModelStub : public QObject { Q_OBJECT public: void setPropertyAndSignal(const QByteArray &name, const QVariant &value) { if (property(name) == value) return; setProperty(name, value); if (name == "artifact") emit artifactChanged(value.value()); else if (name == "text") emit textChanged(value.toString()); else if (name == "title") emit titleChanged(value.toString()); else if (name == "done") emit doneChanged(value.toBool()); else if (name == "startDate") emit startDateChanged(value.toDateTime()); else if (name == "dueDate") emit dueDateChanged(value.toDateTime()); else if (name == "delegateText") emit delegateTextChanged(value.toString()); else if (name == "hasTaskProperties") emit hasTaskPropertiesChanged(value.toBool()); else qFatal("Unsupported property %s", name.constData()); } public slots: void setArtifact(const Domain::Artifact::Ptr &artifact) { setPropertyAndSignal("artifact", QVariant::fromValue(artifact)); } void setTitle(const QString &title) { setPropertyAndSignal("title", title); } void setText(const QString &text) { setPropertyAndSignal("text", text); } void setDone(bool done) { setPropertyAndSignal("done", done); } void setStartDate(const QDateTime &start) { setPropertyAndSignal("startDate", start); } void setDueDate(const QDateTime &due) { setPropertyAndSignal("dueDate", due); } void setDelegateText(const QString &text) { setPropertyAndSignal("delegateText", text); } void makeTaskAvailable() { setArtifact(Domain::Artifact::Ptr(new Domain::Task)); } void delegate(const QString &name, const QString &email) { delegateNames << name; delegateEmails << email; } signals: void artifactChanged(const Domain::Artifact::Ptr &artifact); void hasTaskPropertiesChanged(bool hasTaskProperties); void textChanged(const QString &text); void titleChanged(const QString &title); void doneChanged(bool done); void startDateChanged(const QDateTime &date); void dueDateChanged(const QDateTime &due); void delegateTextChanged(const QString &delegateText); public: QStringList delegateNames; QStringList delegateEmails; }; class EditorViewTest : public QObject { Q_OBJECT public: explicit EditorViewTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qputenv("ZANSHIN_UNIT_TEST_RUN", "1"); } private slots: void shouldHaveDefaultState() { Widgets::EditorView editor; QVERIFY(!editor.isEnabled()); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); QVERIFY(textEdit); QVERIFY(textEdit->isVisibleTo(&editor)); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); QVERIFY(startDateEdit); QVERIFY(!startDateEdit->isVisibleTo(&editor)); - auto dueDateEdit = editor.findChild("dueDateEdit"); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); QVERIFY(dueDateEdit); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); - auto doneButton = editor.findChild("doneButton"); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(doneButton); QVERIFY(!doneButton->isVisibleTo(&editor)); - auto delegateLabel = editor.findChild("delegateLabel"); + auto delegateLabel = editor.findChild(QStringLiteral("delegateLabel")); QVERIFY(delegateLabel); QVERIFY(!delegateLabel->isVisibleTo(&editor)); - auto delegateEdit = editor.findChild("delegateEdit"); + auto delegateEdit = editor.findChild(QStringLiteral("delegateEdit")); QVERIFY(delegateEdit); QVERIFY(!delegateEdit->isVisibleTo(&editor)); } void shouldNotCrashForNullModel() { // GIVEN Widgets::EditorView editor; EditorModelStub model; - model.setTitle("Foo"); - model.setText("Bar"); + model.setTitle(QStringLiteral("Foo")); + model.setText(QStringLiteral("Bar")); model.setPropertyAndSignal("hasTaskProperties", true); editor.setModel(&model); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); QVERIFY(textEdit); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); QVERIFY(startDateEdit); - auto dueDateEdit = editor.findChild("dueDateEdit"); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); QVERIFY(dueDateEdit); - auto doneButton = editor.findChild("doneButton"); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(doneButton); - auto delegateLabel = editor.findChild("delegateLabel"); + auto delegateLabel = editor.findChild(QStringLiteral("delegateLabel")); QVERIFY(delegateLabel); - auto delegateEdit = editor.findChild("delegateEdit"); + auto delegateEdit = editor.findChild(QStringLiteral("delegateEdit")); QVERIFY(delegateEdit); // WHEN editor.setModel(Q_NULLPTR); // THEN QVERIFY(!editor.isEnabled()); QVERIFY(textEdit->toPlainText().isEmpty()); QVERIFY(!startDateEdit->isVisibleTo(&editor)); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); QVERIFY(!doneButton->isVisibleTo(&editor)); QVERIFY(!delegateLabel->isVisibleTo(&editor)); QVERIFY(!delegateEdit->isVisibleTo(&editor)); } void shouldShowTaskPropertiesEditorsOnlyForTasks() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.setPropertyAndSignal("hasTaskProperties", true); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); QVERIFY(!startDateEdit->isVisibleTo(&editor)); - auto dueDateEdit = editor.findChild("dueDateEdit"); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); - auto doneButton = editor.findChild("doneButton"); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(!doneButton->isVisibleTo(&editor)); - auto delegateLabel = editor.findChild("delegateLabel"); + auto delegateLabel = editor.findChild(QStringLiteral("delegateLabel")); QVERIFY(!delegateLabel->isVisibleTo(&editor)); - auto delegateEdit = editor.findChild("delegateEdit"); + auto delegateEdit = editor.findChild(QStringLiteral("delegateEdit")); QVERIFY(!delegateEdit->isVisibleTo(&editor)); // WHEN editor.setModel(&model); // THEN QVERIFY(startDateEdit->isVisibleTo(&editor)); QVERIFY(dueDateEdit->isVisibleTo(&editor)); QVERIFY(doneButton->isVisibleTo(&editor)); QVERIFY(!delegateLabel->isVisibleTo(&editor)); QVERIFY(delegateEdit->isVisibleTo(&editor)); } void shouldDisplayDelegateLabelOnlyWhenNeeded() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); - model.setDelegateText("John Doe"); + model.setDelegateText(QStringLiteral("John Doe")); - auto delegateLabel = editor.findChild("delegateLabel"); + auto delegateLabel = editor.findChild(QStringLiteral("delegateLabel")); QVERIFY(!delegateLabel->isVisibleTo(&editor)); // WHEN editor.setModel(&model); // THEN auto expectedText = tr("Delegated to: %1").arg(model.property("delegateText").toString()); QVERIFY(delegateLabel->isVisibleTo(&editor)); QCOMPARE(delegateLabel->text(), expectedText); } void shouldBeEnabledOnlyWhenAnArtifactIsAvailable() { // GIVEN Widgets::EditorView editor; EditorModelStub model; // WHEN editor.setModel(&model); // THEN QVERIFY(!editor.isEnabled()); // WHEN // like model.makeTaskAvailable() does: Domain::Artifact::Ptr artifact(new Domain::Task); model.setPropertyAndSignal("artifact", QVariant::fromValue(artifact)); // THEN QVERIFY(editor.isEnabled()); // WHEN model.setPropertyAndSignal("artifact", QVariant::fromValue(Domain::Artifact::Ptr())); // THEN QVERIFY(!editor.isEnabled()); // GIVEN EditorModelStub model2; model2.setPropertyAndSignal("artifact", QVariant::fromValue(artifact)); // WHEN editor.setModel(&model2); // THEN QVERIFY(editor.isEnabled()); } void shouldReactToHasTaskPropertiesChanged() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); QVERIFY(!startDateEdit->isVisibleTo(&editor)); - auto dueDateEdit = editor.findChild("dueDateEdit"); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); QVERIFY(!dueDateEdit->isVisibleTo(&editor)); - auto doneButton = editor.findChild("doneButton"); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(!doneButton->isVisibleTo(&editor)); // WHEN model.setPropertyAndSignal("hasTaskProperties", true); // THEN QVERIFY(startDateEdit->isVisibleTo(&editor)); QVERIFY(dueDateEdit->isVisibleTo(&editor)); QVERIFY(doneButton->isVisibleTo(&editor)); } void shouldDisplayModelProperties() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("hasTaskProperties", true); model.setProperty("title", "My title"); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", true); - auto textEdit = editor.findChild("textEdit"); - auto startDateEdit = editor.findChild("startDateEdit"); - auto dueDateEdit = editor.findChild("dueDateEdit"); - auto doneButton = editor.findChild("doneButton"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); // WHEN editor.setModel(&model); // THEN QCOMPARE(textEdit->toPlainText(), QString(model.property("title").toString() + "\n" + model.property("text").toString())); QCOMPARE(startDateEdit->date(), model.property("startDate").toDateTime().date()); QCOMPARE(dueDateEdit->date(), model.property("dueDate").toDateTime().date()); QCOMPARE(doneButton->isChecked(), model.property("done").toBool()); } void shouldReactToTitleChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("title", "My title"); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", true); editor.setModel(&model); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); // WHEN model.setPropertyAndSignal("title", "New title"); // THEN QCOMPARE(textEdit->toPlainText(), QString(model.property("title").toString() + "\n" + model.property("text").toString())); } void shouldNotReactToTitleTrim() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("title", "My title "); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", true); editor.setModel(&model); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); // WHEN model.setPropertyAndSignal("title", "My title"); // THEN QCOMPARE(textEdit->toPlainText(), QString(model.property("title").toString() + " " + "\n" + model.property("text").toString())); } void shouldReactToTextChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("title", "My title"); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", true); editor.setModel(&model); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); // WHEN model.setPropertyAndSignal("text", "\nNew text"); // THEN QCOMPARE(textEdit->toPlainText(), QString(model.property("title").toString() + "\n" + model.property("text").toString())); } void shouldNotReactToTextTrim_data() { QTest::addColumn("title"); QTest::addColumn("text"); QTest::newRow("nominal case") << "My title" << "\nMy text \n "; QTest::newRow("parentheses in the title") << "My (special) title" << "\nMy text \n "; QTest::newRow("parentheses in the text") << "My title" << "\nMy (special) text \n "; QTest::newRow("special char in the title") << "My +title" << "\nMy text \n "; QTest::newRow("special char in the text") << "My title" << "\nMy +text \n "; } void shouldNotReactToTextTrim() { // GIVEN QFETCH(QString, title); QFETCH(QString, text); Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("title", title); model.setProperty("text", text); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", true); editor.setModel(&model); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); // WHEN model.setPropertyAndSignal("text", text.trimmed()); // THEN QCOMPARE(model.property("text").toString(), text.trimmed()); QCOMPARE(textEdit->toPlainText(), QString(model.property("title").toString() + "\n" + text)); } void shouldApplyTextEditChanges_data() { QTest::addColumn("plainText"); QTest::addColumn("expectedTitle"); QTest::addColumn("expectedText"); QTest::newRow("nominal case") << "Title\n\nText" << "Title" << "\nText"; QTest::newRow("single line") << "Title" << "Title" << ""; } void shouldApplyTextEditChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto textEdit = editor.findChild("textEdit"); + auto textEdit = editor.findChild(QStringLiteral("textEdit")); // WHEN QFETCH(QString, plainText); textEdit->setPlainText(plainText); // THEN QFETCH(QString, expectedTitle); QCOMPARE(model.property("title").toString(), expectedTitle); QFETCH(QString, expectedText); QCOMPARE(model.property("text").toString(), expectedText); } void shouldReactToDoneChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("title", "My title"); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", false); editor.setModel(&model); - auto doneButton = editor.findChild("doneButton"); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); QVERIFY(!doneButton->isChecked()); // WHEN model.setPropertyAndSignal("done", true); // THEN QVERIFY(doneButton->isChecked()); } void shouldApplyDoneButtonChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto doneButton = editor.findChild("doneButton"); + auto doneButton = editor.findChild(QStringLiteral("doneButton")); // WHEN doneButton->setChecked(true); // THEN QCOMPARE(model.property("done").toBool(), true); } void shouldReactToStartDateChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); model.setProperty("title", "My title"); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", false); editor.setModel(&model); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); // WHEN model.setPropertyAndSignal("startDate", QDateTime::currentDateTime().addDays(-2)); // THEN QCOMPARE(startDateEdit->date(), model.property("startDate").toDateTime().date()); } void shouldApplyStartDateEditChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); auto today = QDate::currentDate(); // WHEN - startDateEdit->setEditText(today.toString("dd/MM/yyyy")); + startDateEdit->setEditText(today.toString(QStringLiteral("dd/MM/yyyy"))); QTest::keyClick(startDateEdit, Qt::Key_Enter); // THEN QCOMPARE(model.property("startDate").toDateTime().date(), today); } void shouldReactToDueDateChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.setProperty("title", "My title"); model.setProperty("text", "\nMy text"); model.setProperty("startDate", QDateTime::currentDateTime()); model.setProperty("dueDate", QDateTime::currentDateTime().addDays(2)); model.setProperty("done", false); editor.setModel(&model); - auto dueDateEdit = editor.findChild("dueDateEdit"); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); // WHEN model.setPropertyAndSignal("dueDate", QDateTime::currentDateTime().addDays(-2)); // THEN QCOMPARE(dueDateEdit->date(), model.property("dueDate").toDateTime().date()); } void shouldApplyDueDateEditChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto dueDateEdit = editor.findChild("dueDateEdit"); + auto dueDateEdit = editor.findChild(QStringLiteral("dueDateEdit")); auto today = QDate::currentDate(); // WHEN QVERIFY(dueDateEdit->isEnabled()); - dueDateEdit->setEditText(today.toString("dd/MM/yyyy")); + dueDateEdit->setEditText(today.toString(QStringLiteral("dd/MM/yyyy"))); QTest::keyClick(dueDateEdit, Qt::Key_Enter); // THEN QCOMPARE(model.property("dueDate").toDateTime().date(), today); } void shouldApplyStartTodayChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - QAbstractButton *startTodayButton = editor.findChild("startTodayButton"); + QAbstractButton *startTodayButton = editor.findChild(QStringLiteral("startTodayButton")); QVERIFY(startTodayButton); - auto startDateEdit = editor.findChild("startDateEdit"); + auto startDateEdit = editor.findChild(QStringLiteral("startDateEdit")); auto today = QDate::currentDate(); // WHEN QVERIFY(startTodayButton->isEnabled()); startTodayButton->click(); // THEN - QCOMPARE(startDateEdit->currentText(), today.toString("dd/MM/yyyy")); + QCOMPARE(startDateEdit->currentText(), today.toString(QStringLiteral("dd/MM/yyyy"))); QCOMPARE(model.property("startDate").toDateTime().date(), today); } void shouldReactToDelegateTextChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); - model.setDelegateText("John Doe"); + model.setDelegateText(QStringLiteral("John Doe")); editor.setModel(&model); - auto delegateLabel = editor.findChild("delegateLabel"); + auto delegateLabel = editor.findChild(QStringLiteral("delegateLabel")); // WHEN - model.setDelegateText("John Smith"); + model.setDelegateText(QStringLiteral("John Smith")); // THEN auto expectedText = tr("Delegated to: %1").arg(model.property("delegateText").toString()); QCOMPARE(delegateLabel->text(), expectedText); } void shouldClearDelegateEditOnArtifactChanges() { // GIVEN Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto delegateEdit = editor.findChild("delegateEdit"); - delegateEdit->setText("Foo"); + auto delegateEdit = editor.findChild(QStringLiteral("delegateEdit")); + delegateEdit->setText(QStringLiteral("Foo")); // WHEN model.makeTaskAvailable(); // simulates an artifact change // THEN QVERIFY(delegateEdit->text().isEmpty()); } void shouldRequestDelegationOnInput_data() { QTest::addColumn("userInput"); QTest::addColumn("expectedName"); QTest::addColumn("expectedEmail"); QTest::addColumn("expectedCall"); QTest::newRow("nominal case") << "John Doe " << "John Doe" << "john@doe.com" << true; QTest::newRow("nominal case") << "John Doe " << "John Doe" << "j.doe@some.server.com" << true; QTest::newRow("only name") << "John Doe" << QString() << QString() << false; QTest::newRow("only email") << "john@doe.com" << QString() << "john@doe.com" << true; QTest::newRow("only email again") << "" << QString() << "john@doe.com" << true; QTest::newRow("nonsense case") << "bleh" << QString() << QString() << false; } void shouldRequestDelegationOnInput() { // GIVEN QFETCH(QString, userInput); QFETCH(QString, expectedName); QFETCH(QString, expectedEmail); QFETCH(bool, expectedCall); Widgets::EditorView editor; EditorModelStub model; model.makeTaskAvailable(); editor.setModel(&model); - auto delegateEdit = editor.findChild("delegateEdit"); + auto delegateEdit = editor.findChild(QStringLiteral("delegateEdit")); // WHEN QVERIFY(delegateEdit->isEnabled()); delegateEdit->setText(userInput); QTest::keyClick(delegateEdit, Qt::Key_Enter); // THEN if (expectedCall) { QCOMPARE(model.delegateNames.size(), 1); QCOMPARE(model.delegateNames.first(), expectedName); QCOMPARE(model.delegateEmails.size(), 1); QCOMPARE(model.delegateEmails.first(), expectedEmail); QVERIFY(delegateEdit->text().isEmpty()); } else { QCOMPARE(model.delegateNames.size(), 0); QCOMPARE(model.delegateEmails.size(), 0); } } }; ZANSHIN_TEST_MAIN(EditorViewTest) #include "editorviewtest.moc" diff --git a/tests/units/widgets/filterwidgettest.cpp b/tests/units/widgets/filterwidgettest.cpp index b07715df..b198c307 100644 --- a/tests/units/widgets/filterwidgettest.cpp +++ b/tests/units/widgets/filterwidgettest.cpp @@ -1,181 +1,181 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include "widgets/filterwidget.h" #include "presentation/artifactfilterproxymodel.h" class FilterWidgetTest : public QObject { Q_OBJECT private slots: void shouldHaveDefaultState() { Widgets::FilterWidget filter; QVERIFY(filter.proxyModel()); QVERIFY(!filter.proxyModel()->sourceModel()); QCOMPARE(filter.proxyModel()->filterRegExp(), QRegExp()); QCOMPARE(filter.proxyModel()->sortOrder(), Qt::AscendingOrder); QCOMPARE(filter.proxyModel()->sortType(), Presentation::ArtifactFilterProxyModel::TitleSort); - QLineEdit *filterEdit = filter.findChild("filterEdit"); + QLineEdit *filterEdit = filter.findChild(QStringLiteral("filterEdit")); QVERIFY(filterEdit); QVERIFY(filterEdit->isVisibleTo(&filter)); QVERIFY(filterEdit->text().isEmpty()); QCOMPARE(filterEdit->placeholderText(), tr("Filter...")); - QAbstractButton *extensionButton = filter.findChild("extensionButton"); + QAbstractButton *extensionButton = filter.findChild(QStringLiteral("extensionButton")); QVERIFY(extensionButton); QVERIFY(extensionButton->isVisibleTo(&filter)); QVERIFY(!extensionButton->isChecked()); - QCOMPARE(extensionButton->icon(), QIcon::fromTheme("arrow-down-double")); + QCOMPARE(extensionButton->icon(), QIcon::fromTheme(QStringLiteral("arrow-down-double"))); - QComboBox *sortTypeCombo = filter.findChild("sortTypeCombo"); + QComboBox *sortTypeCombo = filter.findChild(QStringLiteral("sortTypeCombo")); QVERIFY(sortTypeCombo); QVERIFY(!sortTypeCombo->isVisibleTo(&filter)); QCOMPARE(sortTypeCombo->currentIndex(), 0); - QAbstractButton *ascendingButton = filter.findChild("ascendingButton"); + QAbstractButton *ascendingButton = filter.findChild(QStringLiteral("ascendingButton")); QVERIFY(ascendingButton); QVERIFY(!ascendingButton->isVisibleTo(&filter)); QVERIFY(ascendingButton->isChecked()); - QCOMPARE(ascendingButton->icon(), QIcon::fromTheme("arrow-up")); + QCOMPARE(ascendingButton->icon(), QIcon::fromTheme(QStringLiteral("arrow-up"))); - QAbstractButton *descendingButton = filter.findChild("descendingButton"); + QAbstractButton *descendingButton = filter.findChild(QStringLiteral("descendingButton")); QVERIFY(descendingButton); QVERIFY(!descendingButton->isVisibleTo(&filter)); QVERIFY(!descendingButton->isChecked()); - QCOMPARE(descendingButton->icon(), QIcon::fromTheme("arrow-down")); + QCOMPARE(descendingButton->icon(), QIcon::fromTheme(QStringLiteral("arrow-down"))); } void shouldChangeAppliedFilter() { // GIVEN Widgets::FilterWidget filter; - QLineEdit *filterEdit = filter.findChild("filterEdit"); + QLineEdit *filterEdit = filter.findChild(QStringLiteral("filterEdit")); QVERIFY(filterEdit); // WHEN - QTest::keyClicks(filterEdit, "find me"); + QTest::keyClicks(filterEdit, QStringLiteral("find me")); // THEN - QCOMPARE(filter.proxyModel()->filterRegExp().pattern(), QString("find me")); + QCOMPARE(filter.proxyModel()->filterRegExp().pattern(), QStringLiteral("find me")); } void shouldShowExtension() { // GIVEN Widgets::FilterWidget filter; - QAbstractButton *extensionButton = filter.findChild("extensionButton"); + QAbstractButton *extensionButton = filter.findChild(QStringLiteral("extensionButton")); QVERIFY(extensionButton); - QComboBox *sortTypeCombo = filter.findChild("sortTypeCombo"); + QComboBox *sortTypeCombo = filter.findChild(QStringLiteral("sortTypeCombo")); QVERIFY(sortTypeCombo); - QAbstractButton *ascendingButton = filter.findChild("ascendingButton"); + QAbstractButton *ascendingButton = filter.findChild(QStringLiteral("ascendingButton")); QVERIFY(ascendingButton); - QAbstractButton *descendingButton = filter.findChild("descendingButton"); + QAbstractButton *descendingButton = filter.findChild(QStringLiteral("descendingButton")); QVERIFY(descendingButton); // WHEN extensionButton->click(); // THEN QVERIFY(extensionButton->isChecked()); QVERIFY(sortTypeCombo->isVisibleTo(&filter)); QVERIFY(descendingButton->isVisibleTo(&filter)); QVERIFY(descendingButton->isVisibleTo(&filter)); // WHEN extensionButton->click(); // THEN QVERIFY(!extensionButton->isChecked()); QVERIFY(!sortTypeCombo->isVisibleTo(&filter)); QVERIFY(!descendingButton->isVisibleTo(&filter)); QVERIFY(!descendingButton->isVisibleTo(&filter)); } void shouldChangeSortType() { // GIVEN Widgets::FilterWidget filter; - QComboBox *sortTypeCombo = filter.findChild("sortTypeCombo"); + QComboBox *sortTypeCombo = filter.findChild(QStringLiteral("sortTypeCombo")); QVERIFY(sortTypeCombo); // WHEN sortTypeCombo->setCurrentIndex(1); // THEN QCOMPARE(filter.proxyModel()->sortType(), Presentation::ArtifactFilterProxyModel::DateSort); // WHEN sortTypeCombo->setCurrentIndex(0); // THEN QCOMPARE(filter.proxyModel()->sortType(), Presentation::ArtifactFilterProxyModel::TitleSort); } void shouldChangeSortOrder() { // GIVEN Widgets::FilterWidget filter; - QAbstractButton *ascendingButton = filter.findChild("ascendingButton"); + QAbstractButton *ascendingButton = filter.findChild(QStringLiteral("ascendingButton")); QVERIFY(ascendingButton); - QAbstractButton *descendingButton = filter.findChild("descendingButton"); + QAbstractButton *descendingButton = filter.findChild(QStringLiteral("descendingButton")); QVERIFY(descendingButton); // WHEN descendingButton->click(); // THEN QVERIFY(!ascendingButton->isChecked()); QVERIFY(descendingButton->isChecked()); QCOMPARE(filter.proxyModel()->sortOrder(), Qt::DescendingOrder); // WHEN ascendingButton->click(); // THEN QVERIFY(ascendingButton->isChecked()); QVERIFY(!descendingButton->isChecked()); QCOMPARE(filter.proxyModel()->sortOrder(), Qt::AscendingOrder); } }; ZANSHIN_TEST_MAIN(FilterWidgetTest) #include "filterwidgettest.moc" diff --git a/tests/units/widgets/newprojectdialogtest.cpp b/tests/units/widgets/newprojectdialogtest.cpp index b342a2aa..fec9caed 100644 --- a/tests/units/widgets/newprojectdialogtest.cpp +++ b/tests/units/widgets/newprojectdialogtest.cpp @@ -1,242 +1,242 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "presentation/querytreemodelbase.h" #include "widgets/newprojectdialog.h" class UserInputSimulator : public QObject { Q_OBJECT public: explicit UserInputSimulator(QObject *parent = Q_NULLPTR) : QObject(parent), dialog(Q_NULLPTR), reject(false), sourceComboIndex(-1) {} void exec() { Q_ASSERT(dialog); QTimer::singleShot(50, Qt::PreciseTimer, this, &UserInputSimulator::onTimeout); dialog->exec(); } private slots: void onTimeout() { if (!nameInput.isEmpty()) { - auto nameEdit = dialog->findChild("nameEdit"); + auto nameEdit = dialog->findChild(QStringLiteral("nameEdit")); QTest::keyClicks(nameEdit, nameInput); } if (sourceComboIndex >= 0) { - auto sourceCombo = dialog->findChild("sourceCombo"); + auto sourceCombo = dialog->findChild(QStringLiteral("sourceCombo")); sourceCombo->setCurrentIndex(sourceComboIndex); } - auto buttonBox = dialog->findChild("buttonBox"); + auto buttonBox = dialog->findChild(QStringLiteral("buttonBox")); if (reject) buttonBox->button(QDialogButtonBox::Cancel)->click(); else buttonBox->button(QDialogButtonBox::Ok)->click(); } public: Widgets::NewProjectDialog *dialog; bool reject; QString nameInput; int sourceComboIndex; }; class NewProjectDialogTest : public QObject { Q_OBJECT private: QStandardItem *createSourceItem(const QString &name, QStandardItem *parent = Q_NULLPTR) { auto source = Domain::DataSource::Ptr::create(); source->setName(name); auto item = new QStandardItem(name); item->setData(QVariant::fromValue(source), Presentation::QueryTreeModelBase::ObjectRole); if (parent) parent->appendRow(item); return item; } QStandardItem *createTaskSourceItem(const QString &name, QStandardItem *parent = Q_NULLPTR) { auto item = createSourceItem(name, parent); auto source = item->data(Presentation::QueryTreeModelBase::ObjectRole).value(); source->setContentTypes(Domain::DataSource::Tasks); return item; } QStandardItem *createDefaultSourceItem(const QString &name, QStandardItem *parent = Q_NULLPTR) { auto item = createTaskSourceItem(name, parent); item->setData(true, Presentation::QueryTreeModelBase::IsDefaultRole); return item; } QStandardItemModel *createSourceModel() { auto model = new QStandardItemModel(this); - auto root1 = createSourceItem("Root 1"); - createSourceItem("Null", root1); - createTaskSourceItem("Task 1.1", root1); - createTaskSourceItem("Task 1.2", root1); + auto root1 = createSourceItem(QStringLiteral("Root 1")); + createSourceItem(QStringLiteral("Null"), root1); + createTaskSourceItem(QStringLiteral("Task 1.1"), root1); + createTaskSourceItem(QStringLiteral("Task 1.2"), root1); model->appendRow(root1); - auto root2 = createSourceItem("Root 2"); - createDefaultSourceItem("Task 2.1", root2); - createTaskSourceItem("Task 2.2", root2); + auto root2 = createSourceItem(QStringLiteral("Root 2")); + createDefaultSourceItem(QStringLiteral("Task 2.1"), root2); + createTaskSourceItem(QStringLiteral("Task 2.2"), root2); model->appendRow(root2); return model; } private slots: void shouldHaveDefaultState() { Widgets::NewProjectDialog dialog; QVERIFY(dialog.name().isEmpty()); QVERIFY(dialog.dataSource().isNull()); - auto nameEdit = dialog.findChild("nameEdit"); + auto nameEdit = dialog.findChild(QStringLiteral("nameEdit")); QVERIFY(nameEdit); QVERIFY(nameEdit->isVisibleTo(&dialog)); - auto sourceCombo = dialog.findChild("sourceCombo"); + auto sourceCombo = dialog.findChild(QStringLiteral("sourceCombo")); QVERIFY(sourceCombo); QVERIFY(sourceCombo->isVisibleTo(&dialog)); - auto buttonBox = dialog.findChild("buttonBox"); + auto buttonBox = dialog.findChild(QStringLiteral("buttonBox")); QVERIFY(buttonBox); QVERIFY(buttonBox->isVisibleTo(&dialog)); QVERIFY(buttonBox->button(QDialogButtonBox::Ok)); QVERIFY(buttonBox->button(QDialogButtonBox::Cancel)); } void shouldPositionDefaultProperties() { // GIVEN Widgets::NewProjectDialog dialog; auto sourceModel = createSourceModel(); - auto sourceCombo = dialog.findChild("sourceCombo"); + auto sourceCombo = dialog.findChild(QStringLiteral("sourceCombo")); // WHEN dialog.setDataSourcesModel(sourceModel); // THEN QCOMPARE(sourceCombo->currentIndex(), 2); - QCOMPARE(sourceCombo->currentText(), QString("Root 2 / Task 2.1")); + QCOMPARE(sourceCombo->currentText(), QStringLiteral("Root 2 / Task 2.1")); } void shouldProvideUserInputWhenAccepted() { // GIVEN Widgets::NewProjectDialog dialog; auto sourceModel = createSourceModel(); dialog.setDataSourcesModel(sourceModel); UserInputSimulator userInput; userInput.dialog = &dialog; userInput.sourceComboIndex = 1; - userInput.nameInput = "name"; + userInput.nameInput = QStringLiteral("name"); auto expectedSource = sourceModel->item(0) ->child(2) ->data(Presentation::QueryTreeModelBase::ObjectRole) .value(); // WHEN userInput.exec(); // THEN QCOMPARE(dialog.name(), userInput.nameInput); QVERIFY(dialog.dataSource()); QCOMPARE(dialog.dataSource(), expectedSource); } void shouldNotProvideUserInputWhenReject() { // GIVEN Widgets::NewProjectDialog dialog; auto sourceModel = createSourceModel(); dialog.setDataSourcesModel(sourceModel); UserInputSimulator userInput; userInput.dialog = &dialog; userInput.sourceComboIndex = 1; - userInput.nameInput = "name"; + userInput.nameInput = QStringLiteral("name"); userInput.reject = true; // WHEN userInput.exec(); // THEN QCOMPARE(dialog.name(), QString()); QCOMPARE(dialog.dataSource(), Domain::DataSource::Ptr()); } void shouldNotAllowEmptyName() { // GIVEN Widgets::NewProjectDialog dialog; auto sourceModel = createSourceModel(); dialog.setDataSourcesModel(sourceModel); UserInputSimulator userInput; userInput.dialog = &dialog; userInput.sourceComboIndex = 0; userInput.nameInput = QString(); userInput.reject = true; // WHEN userInput.exec(); // THEN - auto buttonOk = dialog.findChild("buttonBox")->button(QDialogButtonBox::Ok); + auto buttonOk = dialog.findChild(QStringLiteral("buttonBox"))->button(QDialogButtonBox::Ok); QVERIFY(!buttonOk->isEnabled()); QCOMPARE(dialog.name(), QString()); QCOMPARE(dialog.dataSource(), Domain::DataSource::Ptr()); } }; ZANSHIN_TEST_MAIN(NewProjectDialogTest) #include "newprojectdialogtest.moc" diff --git a/tests/units/widgets/pageviewtest.cpp b/tests/units/widgets/pageviewtest.cpp index 126a1eda..ad3cac7c 100644 --- a/tests/units/widgets/pageviewtest.cpp +++ b/tests/units/widgets/pageviewtest.cpp @@ -1,555 +1,561 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "domain/task.h" #include "presentation/artifactfilterproxymodel.h" #include "presentation/metatypes.h" #include "widgets/filterwidget.h" #include "widgets/itemdelegate.h" #include "widgets/pageview.h" #include "messageboxstub.h" class PageModelStub : public QObject { Q_OBJECT Q_PROPERTY(QAbstractItemModel* centralListModel READ centralListModel) public: QAbstractItemModel *centralListModel() { return &itemModel; } void addStubItem(const QString &title, QStandardItem *parentItem = Q_NULLPTR) { QStandardItem *item = new QStandardItem; item->setData(title, Qt::DisplayRole); if (!parentItem) itemModel.appendRow(item); else parentItem->appendRow(item); taskNames << title; } void addStubItems(const QStringList &list) { foreach (const QString &title, list) { addStubItem(title); } } public slots: void addItem(const QString &name, const QModelIndex &parentIndex) { taskNames << name; parentIndices << parentIndex; } void removeItem(const QModelIndex &index) { removedIndices << index; } void promoteItem(const QModelIndex &index) { promotedIndices << index; } public: QStringList taskNames; QList parentIndices; QList removedIndices; QList promotedIndices; QStandardItemModel itemModel; }; class PageViewTest : public QObject { Q_OBJECT private slots: void shouldHaveDefaultState() { Widgets::PageView page; - auto centralView = page.findChild("centralView"); + auto centralView = page.findChild(QStringLiteral("centralView")); QVERIFY(centralView); QVERIFY(centralView->isVisibleTo(&page)); QVERIFY(!centralView->header()->isVisibleTo(&page)); QVERIFY(qobject_cast(centralView->itemDelegate())); QVERIFY(centralView->alternatingRowColors()); QCOMPARE(centralView->dragDropMode(), QTreeView::DragDrop); - auto filter = page.findChild("filterWidget"); + auto filter = page.findChild(QStringLiteral("filterWidget")); QVERIFY(filter); QVERIFY(filter->proxyModel()); QCOMPARE(filter->proxyModel(), centralView->model()); - QLineEdit *quickAddEdit = page.findChild("quickAddEdit"); + QLineEdit *quickAddEdit = page.findChild(QStringLiteral("quickAddEdit")); QVERIFY(quickAddEdit); QVERIFY(quickAddEdit->isVisibleTo(&page)); QVERIFY(quickAddEdit->text().isEmpty()); QCOMPARE(quickAddEdit->placeholderText(), tr("Type and press enter to add an item")); - auto addAction = page.findChild("addItemAction"); + auto addAction = page.findChild(QStringLiteral("addItemAction")); QVERIFY(addAction); - auto cancelAddAction = page.findChild("cancelAddItemAction"); + auto cancelAddAction = page.findChild(QStringLiteral("cancelAddItemAction")); QVERIFY(cancelAddAction); - auto removeAction = page.findChild("removeItemAction"); + auto removeAction = page.findChild(QStringLiteral("removeItemAction")); QVERIFY(removeAction); - auto promoteAction = page.findChild("promoteItemAction"); + auto promoteAction = page.findChild(QStringLiteral("promoteItemAction")); QVERIFY(promoteAction); - auto filterAction = page.findChild("filterViewAction"); + auto filterAction = page.findChild(QStringLiteral("filterViewAction")); QVERIFY(filterAction); auto actions = page.globalActions(); - QCOMPARE(actions.value("page_view_add"), addAction); - QCOMPARE(actions.value("page_view_remove"), removeAction); - QCOMPARE(actions.value("page_view_promote"), promoteAction); - QCOMPARE(actions.value("page_view_filter"), filterAction); + QCOMPARE(actions.value(QStringLiteral("page_view_add")), addAction); + QCOMPARE(actions.value(QStringLiteral("page_view_remove")), removeAction); + QCOMPARE(actions.value(QStringLiteral("page_view_promote")), promoteAction); + QCOMPARE(actions.value(QStringLiteral("page_view_filter")), filterAction); } void shouldDisplayListFromPageModel() { // GIVEN QStandardItemModel model; QObject stubPageModel; stubPageModel.setProperty("centralListModel", QVariant::fromValue(static_cast(&model))); Widgets::PageView page; - auto centralView = page.findChild("centralView"); + auto centralView = page.findChild(QStringLiteral("centralView")); QVERIFY(centralView); auto proxyModel = qobject_cast(centralView->model()); QVERIFY(proxyModel); QVERIFY(!proxyModel->sourceModel()); // WHEN page.setModel(&stubPageModel); // THEN QCOMPARE(page.model(), &stubPageModel); QVERIFY(page.isEnabled()); QCOMPARE(proxyModel->sourceModel(), &model); } void shouldNotCrashWithNullModel() { // GIVEN QStandardItemModel model; QObject stubPageModel; stubPageModel.setProperty("centralListModel", QVariant::fromValue(static_cast(&model))); Widgets::PageView page; page.setModel(&stubPageModel); - auto centralView = page.findChild("centralView"); + auto centralView = page.findChild(QStringLiteral("centralView")); QVERIFY(centralView); auto proxyModel = qobject_cast(centralView->model()); QVERIFY(proxyModel); QCOMPARE(proxyModel->sourceModel(), &model); // WHEN page.setModel(Q_NULLPTR); // THEN QVERIFY(!page.model()); QVERIFY(!page.isEnabled()); QVERIFY(!proxyModel->sourceModel()); } void shouldManageFocusThroughActions() { // GIVEN Widgets::PageView page; - auto centralView = page.findChild("centralView"); - auto quickAddEdit = page.findChild("quickAddEdit"); - auto filter = page.findChild("filterWidget"); + auto centralView = page.findChild(QStringLiteral("centralView")); + auto quickAddEdit = page.findChild(QStringLiteral("quickAddEdit")); + auto filter = page.findChild(QStringLiteral("filterWidget")); auto filterEdit = filter->findChild(); QVERIFY(filterEdit); page.show(); QTest::qWaitForWindowShown(&page); centralView->setFocus(); QVERIFY(centralView->hasFocus()); QVERIFY(!quickAddEdit->hasFocus()); QVERIFY(!filterEdit->hasFocus()); - auto addAction = page.findChild("addItemAction"); - auto cancelAddAction = page.findChild("cancelAddItemAction"); - auto filterAction = page.findChild("filterViewAction"); + auto addAction = page.findChild(QStringLiteral("addItemAction")); + auto cancelAddAction = page.findChild(QStringLiteral("cancelAddItemAction")); + auto filterAction = page.findChild(QStringLiteral("filterViewAction")); // WHEN addAction->trigger(); // THEN QVERIFY(!centralView->hasFocus()); QVERIFY(quickAddEdit->hasFocus()); QVERIFY(!filterEdit->hasFocus()); // WHEN cancelAddAction->trigger(); // THEN QVERIFY(centralView->hasFocus()); QVERIFY(!quickAddEdit->hasFocus()); QVERIFY(!filterEdit->hasFocus()); // WHEN filterAction->trigger(); // THEN QVERIFY(!centralView->hasFocus()); QVERIFY(!quickAddEdit->hasFocus()); QVERIFY(filterEdit->hasFocus()); // WHEN cancelAddAction->trigger(); // THEN QVERIFY(centralView->hasFocus()); QVERIFY(!quickAddEdit->hasFocus()); QVERIFY(!filterEdit->hasFocus()); } void shouldCreateTasksWithNoParentWhenHittingReturnWithoutSelectedIndex() { // GIVEN PageModelStub stubPageModel; Widgets::PageView page; page.setModel(&stubPageModel); - auto quickAddEdit = page.findChild("quickAddEdit"); + auto quickAddEdit = page.findChild(QStringLiteral("quickAddEdit")); // WHEN QTest::keyClick(quickAddEdit, Qt::Key_Return); // Does nothing (edit empty) - QTest::keyClicks(quickAddEdit, "Foo"); + QTest::keyClicks(quickAddEdit, QStringLiteral("Foo")); QTest::keyClick(quickAddEdit, Qt::Key_Return); QTest::keyClick(quickAddEdit, Qt::Key_Return); // Does nothing (edit empty) - QTest::keyClicks(quickAddEdit, "Bar"); + QTest::keyClicks(quickAddEdit, QStringLiteral("Bar")); QTest::keyClick(quickAddEdit, Qt::Key_Return); QTest::keyClick(quickAddEdit, Qt::Key_Return); // Does nothing (edit empty) // THEN - QCOMPARE(stubPageModel.taskNames, QStringList() << "Foo" << "Bar"); + QCOMPARE(stubPageModel.taskNames, QStringList() << QStringLiteral("Foo") << QStringLiteral("Bar")); QCOMPARE(stubPageModel.parentIndices.size(), 2); QCOMPARE(stubPageModel.parentIndices.first(), QPersistentModelIndex()); QCOMPARE(stubPageModel.parentIndices.last(), QPersistentModelIndex()); } void shouldCreateTasksWithNoParentWhenHittingReturnWithSeveralSelectedIndices() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); QPersistentModelIndex index0 = stubPageModel.itemModel.index(0, 0); QPersistentModelIndex index1 = stubPageModel.itemModel.index(1, 0); Widgets::PageView page; page.setModel(&stubPageModel); - auto centralView = page.findChild("centralView"); + auto centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->select(index0, QItemSelectionModel::ClearAndSelect); centralView->selectionModel()->select(index1, QItemSelectionModel::Select); - auto quickAddEdit = page.findChild("quickAddEdit"); + auto quickAddEdit = page.findChild(QStringLiteral("quickAddEdit")); // WHEN - QTest::keyClicks(quickAddEdit, "Foo"); + QTest::keyClicks(quickAddEdit, QStringLiteral("Foo")); QTest::keyClick(quickAddEdit, Qt::Key_Return); // THEN - QCOMPARE(stubPageModel.taskNames, QStringList() << "A" << "B" << "C" << "Foo"); + QCOMPARE(stubPageModel.taskNames, QStringList() << QStringLiteral("A") + << QStringLiteral("B") + << QStringLiteral("C") + << QStringLiteral("Foo")); QCOMPARE(stubPageModel.parentIndices.size(), 1); QCOMPARE(stubPageModel.parentIndices.first(), QPersistentModelIndex()); } void shouldCreateTasksWithParentWhenHittingReturnWithOneSelectedIndex() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); QPersistentModelIndex index = stubPageModel.itemModel.index(1, 0); Widgets::PageView page; page.setModel(&stubPageModel); - auto centralView = page.findChild("centralView"); + auto centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); - auto quickAddEdit = page.findChild("quickAddEdit"); + auto quickAddEdit = page.findChild(QStringLiteral("quickAddEdit")); // WHEN - QTest::keyClicks(quickAddEdit, "Foo"); + QTest::keyClicks(quickAddEdit, QStringLiteral("Foo")); QTest::keyClick(quickAddEdit, Qt::Key_Return); // THEN - QCOMPARE(stubPageModel.taskNames, QStringList() << "A" << "B" << "C" << "Foo"); + QCOMPARE(stubPageModel.taskNames, QStringList() << QStringLiteral("A") + << QStringLiteral("B") + << QStringLiteral("C") + << QStringLiteral("Foo")); QCOMPARE(stubPageModel.parentIndices.size(), 1); QCOMPARE(stubPageModel.parentIndices.first(), index); } void shouldDeleteItemWhenHittingTheDeleteKey() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); QPersistentModelIndex index = stubPageModel.itemModel.index(1, 0); Widgets::PageView page; page.setModel(&stubPageModel); - QTreeView *centralView = page.findChild("centralView"); + QTreeView *centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); centralView->setFocus(); // Needed for shortcuts to work page.show(); QTest::qWaitForWindowShown(&page); QTest::qWait(100); // WHEN QTest::keyPress(centralView, Qt::Key_Delete); // THEN QCOMPARE(stubPageModel.removedIndices.size(), 1); QCOMPARE(stubPageModel.removedIndices.first(), index); } void shouldNoteTryToDeleteIfThereIsNoSelection() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); Widgets::PageView page; page.setModel(&stubPageModel); - QTreeView *centralView = page.findChild("centralView"); + QTreeView *centralView = page.findChild(QStringLiteral("centralView")); centralView->clearSelection(); - page.findChild("quickAddEdit")->setFocus(); + page.findChild(QStringLiteral("quickAddEdit"))->setFocus(); // Needed for shortcuts to work page.show(); QTest::qWaitForWindowShown(&page); QTest::qWait(100); // WHEN QTest::keyPress(centralView, Qt::Key_Delete); // THEN QVERIFY(stubPageModel.removedIndices.isEmpty()); } void shouldDisplayNotificationWhenHittingTheDeleteKeyOnAnItemWithChildren() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B")); QStandardItem *parentIndex = stubPageModel.itemModel.item(1, 0); - stubPageModel.addStubItem("C", parentIndex); + stubPageModel.addStubItem(QStringLiteral("C"), parentIndex); QPersistentModelIndex index = stubPageModel.itemModel.index(1, 0); Widgets::PageView page; page.setModel(&stubPageModel); auto msgbox = MessageBoxStub::Ptr::create(); page.setMessageBoxInterface(msgbox); - QTreeView *centralView = page.findChild("centralView"); + QTreeView *centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); centralView->setFocus(); // Needed for shortcuts to work page.show(); QTest::qWaitForWindowShown(&page); QTest::qWait(100); // WHEN QTest::keyPress(centralView, Qt::Key_Delete); // THEN QVERIFY(msgbox->called()); QCOMPARE(stubPageModel.removedIndices.size(), 1); QCOMPARE(stubPageModel.removedIndices.first(), index); } void shouldDeleteItemsWhenHittingTheDeleteKey() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); QPersistentModelIndex index = stubPageModel.itemModel.index(1, 0); QPersistentModelIndex index2 = stubPageModel.itemModel.index(2, 0); Widgets::PageView page; page.setModel(&stubPageModel); auto msgbox = MessageBoxStub::Ptr::create(); page.setMessageBoxInterface(msgbox); - QTreeView *centralView = page.findChild("centralView"); + QTreeView *centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); centralView->selectionModel()->setCurrentIndex(index2, QItemSelectionModel::Select); centralView->setFocus(); // Needed for shortcuts to work page.show(); QTest::qWaitForWindowShown(&page); QTest::qWait(100); // WHEN QTest::keyPress(centralView, Qt::Key_Delete); // THEN QVERIFY(msgbox->called()); QCOMPARE(stubPageModel.removedIndices.size(), 2); QCOMPARE(stubPageModel.removedIndices.first(), index); QCOMPARE(stubPageModel.removedIndices.at(1), index2); } void shouldPromoteItem() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); QPersistentModelIndex index = stubPageModel.itemModel.index(1, 0); Widgets::PageView page; page.setModel(&stubPageModel); - auto promoteAction = page.findChild("promoteItemAction"); + auto promoteAction = page.findChild(QStringLiteral("promoteItemAction")); QVERIFY(promoteAction); - QTreeView *centralView = page.findChild("centralView"); + QTreeView *centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); centralView->setFocus(); // WHEN promoteAction->trigger(); // THEN QCOMPARE(stubPageModel.promotedIndices.size(), 1); QCOMPARE(stubPageModel.promotedIndices.first(), index); } void shouldNotTryToPromoteItemIfThereIsNoSelection() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); Widgets::PageView page; page.setModel(&stubPageModel); - auto promoteAction = page.findChild("promoteItemAction"); + auto promoteAction = page.findChild(QStringLiteral("promoteItemAction")); QVERIFY(promoteAction); - QTreeView *centralView = page.findChild("centralView"); + QTreeView *centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->clear(); centralView->setFocus(); // WHEN promoteAction->trigger(); // THEN QVERIFY(stubPageModel.promotedIndices.isEmpty()); } void shouldClearCentralViewSelectionOnEscape() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); QPersistentModelIndex index = stubPageModel.itemModel.index(1, 0); Widgets::PageView page; page.setModel(&stubPageModel); - auto centralView = page.findChild("centralView"); + auto centralView = page.findChild(QStringLiteral("centralView")); centralView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); QVERIFY(!centralView->selectionModel()->selectedIndexes().isEmpty()); // WHEN QTest::keyClick(centralView, Qt::Key_Escape); // THEN QVERIFY(centralView->selectionModel()->selectedIndexes().isEmpty()); } void shouldReturnSelectedIndexes() { // GIVEN PageModelStub stubPageModel; Q_ASSERT(stubPageModel.property("centralListModel").canConvert()); - stubPageModel.addStubItems(QStringList() << "A" << "B" << "C"); + stubPageModel.addStubItems(QStringList() << QStringLiteral("A") << QStringLiteral("B") << QStringLiteral("C")); auto index = stubPageModel.itemModel.index(1, 0); auto index2 = stubPageModel.itemModel.index(2, 0); Widgets::PageView page; page.setModel(&stubPageModel); - auto centralView = page.findChild("centralView"); - auto filterWidget = page.findChild("filterWidget"); + auto centralView = page.findChild(QStringLiteral("centralView")); + auto filterWidget = page.findChild(QStringLiteral("filterWidget")); auto displayedModel = filterWidget->proxyModel(); auto displayedIndex = displayedModel->index(1, 0); auto displayedIndex2 = displayedModel->index(2, 0); // WHEN centralView->selectionModel()->setCurrentIndex(displayedIndex, QItemSelectionModel::ClearAndSelect); centralView->selectionModel()->setCurrentIndex(displayedIndex2, QItemSelectionModel::Select); // THEN auto selectedIndexes = page.selectedIndexes(); QCOMPARE(selectedIndexes.size(), 2); QCOMPARE(selectedIndexes.at(0), index); QCOMPARE(selectedIndexes.at(1), index2); QCOMPARE(selectedIndexes.at(0).model(), index.model()); QCOMPARE(selectedIndexes.at(1).model(), index2.model()); } }; ZANSHIN_TEST_MAIN(PageViewTest) #include "pageviewtest.moc" diff --git a/tests/units/widgets/quickselectdialogtest.cpp b/tests/units/widgets/quickselectdialogtest.cpp index a9f58176..6a05ac80 100644 --- a/tests/units/widgets/quickselectdialogtest.cpp +++ b/tests/units/widgets/quickselectdialogtest.cpp @@ -1,227 +1,227 @@ /* This file is part of Zanshin Copyright 2015 Franck Arrecot 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "widgets/quickselectdialog.h" Q_DECLARE_METATYPE(QStandardItemModel*) class QuickSelectDialogTest : public QObject { Q_OBJECT private: template T *widgetFromQuickSelectDialog(Widgets::QuickSelectDialog *dlg) { auto widgets = dlg->findChildren(); Q_ASSERT(widgets.size() == 1); return widgets.first(); } QModelIndex modelIndexFromNameHelper(QAbstractItemModel *model, const QString &name, const QModelIndex &root = QModelIndex()) { for (int i = 0; i < model->rowCount(root); i++) { auto idx = model->index(i, 0, root); if (idx.data().toString() == name) { return idx; } else if (model->rowCount(idx) > 0) { auto idxChild = modelIndexFromNameHelper(model, name, idx); if (idxChild.isValid()) { return idxChild; } } } return {}; } QAbstractItemModel *prepareQuickSelectDialogData() { // GIVEN // a model with items auto model = new QStandardItemModel(); - auto inbox = new QStandardItem("Inbox"); - auto workday = new QStandardItem("Workday"); - auto projects= new QStandardItem("Projects"); - auto contexts = new QStandardItem("Contexts"); + auto inbox = new QStandardItem(QStringLiteral("Inbox")); + auto workday = new QStandardItem(QStringLiteral("Workday")); + auto projects= new QStandardItem(QStringLiteral("Projects")); + auto contexts = new QStandardItem(QStringLiteral("Contexts")); auto structureNodeFlags = Qt::NoItemFlags; projects->setFlags(structureNodeFlags); contexts->setFlags(structureNodeFlags); // with items children - auto projectChildOne = new QStandardItem("ProjectOne"); - auto projectChildTwo = new QStandardItem("ProjectTwo"); + auto projectChildOne = new QStandardItem(QStringLiteral("ProjectOne")); + auto projectChildTwo = new QStandardItem(QStringLiteral("ProjectTwo")); projects->setChild(0, 0, projectChildOne); projects->setChild(1, 0,projectChildTwo); - auto contextChildOne = new QStandardItem("ContextOne"); - auto contextChildTwo = new QStandardItem("ContextTwo"); + auto contextChildOne = new QStandardItem(QStringLiteral("ContextOne")); + auto contextChildTwo = new QStandardItem(QStringLiteral("ContextTwo")); contexts->setChild(0, 0, contextChildOne); contexts->setChild(1, 0, contextChildTwo); auto items = QVector(); items << inbox << workday << projects << contexts; for (int i = 0; i < items.size(); ++i) model->setItem(i, items.at(i)); return model; } private slots: void shouldHaveDefaultState() { Widgets::QuickSelectDialog dlg; - auto pagesView = dlg.findChild("pagesView"); + auto pagesView = dlg.findChild(QStringLiteral("pagesView")); QVERIFY(pagesView); QVERIFY(pagesView->isVisibleTo(&dlg)); QVERIFY(!pagesView->header()->isVisibleTo(&dlg)); } void shouldCloseDialogOnOk() { // GIVEN auto model = prepareQuickSelectDialogData(); Widgets::QuickSelectDialog dlg; dlg.setModel(model); auto treeView = widgetFromQuickSelectDialog(&dlg); dlg.show(); // WHEN QTest::keyClick(treeView, Qt::Key_Enter); //THEN QCOMPARE(dlg.result(), static_cast(QDialog::Accepted)); } void shouldDisplayTheProperTreeModel() { // GIVEN auto model = prepareQuickSelectDialogData(); Widgets::QuickSelectDialog dlg; dlg.setModel(model); auto treeView = widgetFromQuickSelectDialog(&dlg); auto displayModel = treeView->model(); // WHEN dlg.show(); // THEN auto inbox = displayModel->index(0,0); auto workday = displayModel->index(1,0); auto projects = displayModel->index(2,0); auto contexts = displayModel->index(3,0); - QCOMPARE(inbox.data().toString(), QString("Inbox")); - QCOMPARE(workday.data().toString(), QString("Workday")); - QCOMPARE(projects.data().toString(), QString("Projects")); - QCOMPARE(contexts.data().toString(), QString("Contexts")); + QCOMPARE(inbox.data().toString(), QStringLiteral("Inbox")); + QCOMPARE(workday.data().toString(), QStringLiteral("Workday")); + QCOMPARE(projects.data().toString(), QStringLiteral("Projects")); + QCOMPARE(contexts.data().toString(), QStringLiteral("Contexts")); QCOMPARE(displayModel->columnCount(), 1); QCOMPARE(displayModel->rowCount(), 4); // inbox, workday, projects, contexts QCOMPARE(displayModel->rowCount(inbox), 0); // inbox do not expose any children QCOMPARE(displayModel->rowCount(workday), 0); // worday do not expose any children QCOMPARE(displayModel->rowCount(projects), 2); // two children projects created QCOMPARE(displayModel->rowCount(contexts), 2); // two children contexts created } void shouldFilterTreeOnTyping() { // GIVEN auto model = prepareQuickSelectDialogData(); Widgets::QuickSelectDialog dlg; dlg.setModel(model); auto treeView = widgetFromQuickSelectDialog(&dlg); auto displayModel = treeView->model(); auto labelFilter = widgetFromQuickSelectDialog(&dlg); // WHEN QTest::keyClick(treeView, Qt::Key_O, Qt::NoModifier, 20); QTest::keyClick(treeView, Qt::Key_N, Qt::NoModifier, 20); QTest::keyClick(treeView, Qt::Key_E, Qt::NoModifier, 20); dlg.show(); // THEN auto projects = displayModel->index(0,0); auto contexts = displayModel->index(1,0); - QCOMPARE(labelFilter->text(), QString("Path: one")); + QCOMPARE(labelFilter->text(), QStringLiteral("Path: one")); QCOMPARE(displayModel->columnCount(), 1); QCOMPARE(displayModel->rowCount(), 2); - QCOMPARE(projects.data().toString(), QString("Projects")); - QCOMPARE(contexts.data().toString(), QString("Contexts")); + QCOMPARE(projects.data().toString(), QStringLiteral("Projects")); + QCOMPARE(contexts.data().toString(), QStringLiteral("Contexts")); QCOMPARE(displayModel->rowCount(projects), 1); auto projectsChild = displayModel->index(0, 0, projects); - QCOMPARE(projectsChild.data().toString(), QString("ProjectOne")); + QCOMPARE(projectsChild.data().toString(), QStringLiteral("ProjectOne")); QCOMPARE(displayModel->rowCount(contexts), 1); auto contextsChild = displayModel->index(0, 0, contexts); - QCOMPARE(contextsChild.data().toString(), QString("ContextOne")); + QCOMPARE(contextsChild.data().toString(), QStringLiteral("ContextOne")); } void shouldReturnTheSelectedIndex() { // GIVEN auto model = prepareQuickSelectDialogData(); Widgets::QuickSelectDialog dlg; dlg.setModel(model); dlg.show(); auto selectedItemNames = QVector(); - selectedItemNames << "Inbox" << "Workday" << "ProjectOne" << "ProjectTwo" << "ContextOne" << "ContextTwo" << "TagOne" << "TagTwo"; + selectedItemNames << QStringLiteral("Inbox") << QStringLiteral("Workday") << QStringLiteral("ProjectOne") << QStringLiteral("ProjectTwo") << QStringLiteral("ContextOne") << QStringLiteral("ContextTwo") << QStringLiteral("TagOne") << QStringLiteral("TagTwo"); foreach (const auto &itemName, selectedItemNames) { auto treeview = widgetFromQuickSelectDialog(&dlg); auto selectedItem = modelIndexFromNameHelper(treeview->model(), itemName); // WHEN treeview->setCurrentIndex(selectedItem); // THEN QCOMPARE(dlg.selectedIndex().data(), selectedItem.data() ); } } }; ZANSHIN_TEST_MAIN(QuickSelectDialogTest) #include "quickselectdialogtest.moc"