forked from qt-creator/qt-creator
It move the magic number of column results to the sql statement and improves the mock a little bit. Change-Id: I101067444cf27ec5dea0c72de7fd484a7e8710f0 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
713 lines
19 KiB
C++
713 lines
19 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2020 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of Qt Creator.
|
|
**
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3 as published by the Free Software
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
** included in the packaging of this file. Please review the following
|
|
** information to ensure the GNU General Public License requirements will
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "googletest.h"
|
|
|
|
#include <sqlitedatabase.h>
|
|
#include <sqlitereadstatement.h>
|
|
#include <sqlitesessionchangeset.h>
|
|
#include <sqlitesessions.h>
|
|
#include <sqlitetransaction.h>
|
|
#include <sqlitewritestatement.h>
|
|
|
|
#include <ostream>
|
|
|
|
namespace {
|
|
|
|
using Sqlite::Operation;
|
|
using Sqlite::SessionChangeSet;
|
|
using Sqlite::SessionChangeSets;
|
|
using Sqlite::SessionChangeSetInternal::ValueViews;
|
|
|
|
class DatabaseExecute
|
|
{
|
|
public:
|
|
DatabaseExecute(Utils::SmallStringView sqlStatement, Sqlite::Database &database)
|
|
{
|
|
database.execute(sqlStatement);
|
|
}
|
|
};
|
|
|
|
class Data
|
|
{
|
|
public:
|
|
Data(Sqlite::ValueView name, Sqlite::ValueView number, Sqlite::ValueView value)
|
|
: name(name)
|
|
, number(number)
|
|
, value(value)
|
|
{}
|
|
|
|
Sqlite::Value name;
|
|
Sqlite::Value number;
|
|
Sqlite::Value value;
|
|
};
|
|
|
|
std::ostream &operator<<(std::ostream &out, const Data &data)
|
|
{
|
|
return out << "(" << data.name << ", " << data.number << " " << data.value << ")";
|
|
}
|
|
|
|
MATCHER_P3(HasData,
|
|
name,
|
|
number,
|
|
value,
|
|
std::string(negation ? "hasn't " : "has ") + PrintToString(name) + ", "
|
|
+ PrintToString(number) + ", " + PrintToString(value))
|
|
{
|
|
const Data &data = arg;
|
|
|
|
return data.name == name && data.number == number && data.value == value;
|
|
}
|
|
|
|
MATCHER_P2(HasValues,
|
|
newValue,
|
|
oldValue,
|
|
std::string(negation ? "hasn't " : "has ") + PrintToString(newValue) + ", "
|
|
+ PrintToString(oldValue))
|
|
{
|
|
const ValueViews &values = arg;
|
|
|
|
return values.newValue == newValue && values.oldValue == oldValue;
|
|
}
|
|
|
|
class Tag
|
|
{
|
|
public:
|
|
Tag(Sqlite::ValueView name, Sqlite::ValueView tag)
|
|
: name(name)
|
|
, tag(tag)
|
|
{}
|
|
|
|
Sqlite::Value name;
|
|
Sqlite::Value tag;
|
|
};
|
|
|
|
std::ostream &operator<<(std::ostream &out, const Tag &tag)
|
|
{
|
|
return out << "(" << tag.name << ", " << tag.tag << ")";
|
|
}
|
|
|
|
MATCHER_P2(HasTag,
|
|
name,
|
|
tag,
|
|
std::string(negation ? "hasn't " : "has ") + PrintToString(name) + ", " + PrintToString(tag))
|
|
{
|
|
const Tag &t = arg;
|
|
|
|
return t.name == name && t.tag == tag;
|
|
}
|
|
|
|
class Sessions : public testing::Test
|
|
{
|
|
protected:
|
|
Sessions() { sessions.setAttachedTables({"data", "tags"}); }
|
|
|
|
std::vector<Data> fetchData() { return selectData.values<Data>(8); }
|
|
std::vector<Tag> fetchTags() { return selectTags.values<Tag>(8); }
|
|
|
|
protected:
|
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
|
DatabaseExecute createTable{"CREATE TABLE data(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT "
|
|
"UNIQUE, number NUMERIC, value NUMERIC)",
|
|
database};
|
|
DatabaseExecute createTable2{"CREATE TABLE tags(id INTEGER PRIMARY KEY AUTOINCREMENT, dataId "
|
|
"INTEGER NOT NULL REFERENCES data ON DELETE CASCADE DEFERRABLE "
|
|
"INITIALLY DEFERRED, tag NUMERIC)",
|
|
database};
|
|
Sqlite::Sessions sessions{database, "main", "testsessions"};
|
|
Sqlite::WriteStatement insertData{"INSERT INTO data(name, number, value) VALUES (?1, ?2, ?3) "
|
|
"ON CONFLICT (name) DO UPDATE SET (number, value) = (?2, ?3)",
|
|
database};
|
|
Sqlite::WriteStatement insertOneDatum{"INSERT INTO data(value, name) VALUES (?1, ?2) "
|
|
"ON CONFLICT (name) DO UPDATE SET (value) = (?2)",
|
|
database};
|
|
Sqlite::WriteStatement updateNumber{"UPDATE data SET number = ?002 WHERE name=?001", database};
|
|
Sqlite::WriteStatement updateValue{"UPDATE data SET value = ?002 WHERE name=?001", database};
|
|
Sqlite::WriteStatement deleteData{"DELETE FROM data WHERE name=?", database};
|
|
Sqlite::WriteStatement deleteTag{
|
|
"DELETE FROM tags WHERE dataId=(SELECT id FROM data WHERE name=?)", database};
|
|
Sqlite::WriteStatement insertTag{
|
|
"INSERT INTO tags(dataId, tag) VALUES ((SELECT id FROM data WHERE name=?1), ?2) ", database};
|
|
Sqlite::ReadStatement<3> selectData{"SELECT name, number, value FROM data", database};
|
|
Sqlite::ReadStatement<2> selectTags{
|
|
"SELECT name, tag FROM tags JOIN data ON data.id=tags.dataId", database};
|
|
Sqlite::ReadStatement<1> selectChangeSets{"SELECT changeset FROM testsessions", database};
|
|
};
|
|
|
|
TEST_F(Sessions, DontThrowForCommittingWithoutSessionStart)
|
|
{
|
|
ASSERT_NO_THROW(sessions.commit());
|
|
}
|
|
|
|
TEST_F(Sessions, CreateEmptySession)
|
|
{
|
|
sessions.create();
|
|
sessions.commit();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), IsEmpty());
|
|
}
|
|
|
|
TEST_F(Sessions, CreateSessionWithInsert)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), SizeIs(1));
|
|
}
|
|
|
|
TEST_F(Sessions, CreateSessionWithUpdate)
|
|
{
|
|
insertData.write("foo", 22, 3.14);
|
|
|
|
sessions.create();
|
|
updateNumber.write("foo", "bar");
|
|
sessions.commit();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), SizeIs(1));
|
|
}
|
|
|
|
TEST_F(Sessions, CreateSessionWithDelete)
|
|
{
|
|
insertData.write("foo", 22, 3.14);
|
|
|
|
sessions.create();
|
|
deleteData.write("foo");
|
|
sessions.commit();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), SizeIs(1));
|
|
}
|
|
|
|
TEST_F(Sessions, CreateSessionWithInsertAndUpdate)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
|
|
sessions.create();
|
|
updateNumber.write("foo", "bar");
|
|
sessions.commit();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), SizeIs(2));
|
|
}
|
|
|
|
TEST_F(Sessions, CreateSession)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
|
|
sessions.commit();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), SizeIs(1));
|
|
}
|
|
|
|
TEST_F(Sessions, RevertSession)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
|
|
sessions.revert();
|
|
|
|
ASSERT_THAT(fetchData(), IsEmpty());
|
|
}
|
|
|
|
TEST_F(Sessions, RevertSessionToBase)
|
|
{
|
|
insertData.write("bar", "foo", 99);
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
|
|
sessions.revert();
|
|
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("bar", "foo", 99)));
|
|
}
|
|
|
|
TEST_F(Sessions, RevertMultipleSession)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
sessions.create();
|
|
updateNumber.write("foo", "bar");
|
|
sessions.commit();
|
|
|
|
sessions.revert();
|
|
|
|
ASSERT_THAT(fetchData(), IsEmpty());
|
|
}
|
|
|
|
TEST_F(Sessions, ApplySession)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", 22, 3.14)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplySessionAfterAddingNewEntries)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
insertData.write("bar", "foo", 99);
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(),
|
|
UnorderedElementsAre(HasData("foo", 22, 3.14), HasData("bar", "foo", 99)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyOverridesEntriesWithUniqueConstraint)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
insertData.write("foo", "bar", 3.14);
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", 22, 3.14)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyDoesNotOverrideDeletedEntries)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
insertData.write("foo", 22, 3.14);
|
|
sessions.commit();
|
|
deleteData.write("foo");
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(), IsEmpty());
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyDoesOnlyOverwriteUpdatedValues)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 1234);
|
|
sessions.commit();
|
|
insertData.write("foo", "poo", 891);
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", "poo", 1234)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyDoesDoesNotOverrideForeignKeyIfReferenceIsDeleted)
|
|
{
|
|
insertData.write("foo2", "bar", 3.14);
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
insertTag.write("foo2", 4321);
|
|
insertTag.write("foo", 1234);
|
|
sessions.commit();
|
|
deleteData.write("foo");
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchTags(), ElementsAre(HasTag("foo2", 4321)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyDoesDoesNotOverrideIfConstraintsIsApplied)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
deleteData.write("foo");
|
|
sessions.commit();
|
|
sessions.revert();
|
|
insertTag.write("foo", 1234);
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchTags(), IsEmpty());
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyDoesDoesNotOverrideForeignKeyIfReferenceIsDeletedDeferred)
|
|
{
|
|
Sqlite::DeferredTransaction transaction{database};
|
|
insertData.write("foo2", "bar", 3.14);
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
insertTag.write("foo2", 4321);
|
|
insertTag.write("foo", 1234);
|
|
sessions.commit();
|
|
deleteData.write("foo");
|
|
|
|
sessions.apply();
|
|
|
|
transaction.commit();
|
|
ASSERT_THAT(fetchTags(), ElementsAre(HasTag("foo2", 4321)));
|
|
}
|
|
|
|
TEST_F(Sessions, EndSessionOnRollback)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.rollback();
|
|
sessions.commit();
|
|
sessions.create();
|
|
updateNumber.write("foo", 333);
|
|
sessions.commit();
|
|
updateValue.write("foo", 666);
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", 333, 666)));
|
|
}
|
|
|
|
TEST_F(Sessions, EndSessionOnCommit)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
updateValue.write("foo", 666);
|
|
sessions.commit();
|
|
|
|
sessions.apply();
|
|
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", "bar", 99)));
|
|
}
|
|
|
|
TEST_F(Sessions, DeleteSessions)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
sessions.revert();
|
|
|
|
sessions.deleteAll();
|
|
|
|
sessions.apply();
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", "bar", 3.14)));
|
|
}
|
|
|
|
TEST_F(Sessions, DeleteAllSessions)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
sessions.revert();
|
|
|
|
sessions.deleteAll();
|
|
|
|
sessions.apply();
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", "bar", 3.14)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyAndUpdateSessions)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
updateValue.write("foo", 99);
|
|
|
|
sessions.applyAndUpdateSessions();
|
|
|
|
updateValue.write("foo", 22);
|
|
sessions.apply();
|
|
ASSERT_THAT(fetchData(), ElementsAre(HasData("foo", "bar", 22)));
|
|
}
|
|
|
|
TEST_F(Sessions, ApplyAndUpdateSessionsHasOnlyOneChangeSet)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
updateValue.write("foo", 99);
|
|
|
|
sessions.applyAndUpdateSessions();
|
|
|
|
ASSERT_THAT(sessions.changeSets(), SizeIs(1));
|
|
}
|
|
|
|
TEST_F(Sessions, ForEmptySessionBeginEqualsEnd)
|
|
{
|
|
auto changeSets = sessions.changeSets();
|
|
|
|
auto begin = changeSets.begin();
|
|
|
|
ASSERT_THAT(begin, Eq(changeSets.end()));
|
|
}
|
|
|
|
TEST_F(Sessions, IteratorBeginUnequalsEndIfChangeSetHasContent)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
|
|
auto begin = changeSet.begin();
|
|
|
|
ASSERT_THAT(begin, Ne(changeSet.end()));
|
|
}
|
|
|
|
TEST_F(Sessions, NextIteratorUnequalsBeginIfChangeSetHasContent)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
|
|
auto next = std::next(changeSet.begin());
|
|
|
|
ASSERT_NE(next, changeSet.begin());
|
|
}
|
|
|
|
TEST_F(Sessions, NextIteratorEqualsEndIfChangeSetHasContent)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
|
|
auto next = std::next(changeSet.begin());
|
|
|
|
ASSERT_THAT(next, Eq(changeSet.end()));
|
|
}
|
|
|
|
TEST_F(Sessions, NextIteratorNotUnqualsEndIfChangeSetHasContent)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
|
|
auto next = std::next(changeSet.begin());
|
|
|
|
ASSERT_THAT(next, Not(Ne(changeSet.end())));
|
|
}
|
|
|
|
TEST_F(Sessions, BeginIteratorHasInsertOperation)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
|
|
auto tuple = (*begin);
|
|
|
|
ASSERT_THAT(tuple.operation, Eq(Operation::Insert));
|
|
}
|
|
|
|
TEST_F(Sessions, BeginIteratorHasUpdateOperation)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
|
|
auto tuple = (*begin);
|
|
|
|
ASSERT_THAT(tuple.operation, Eq(Operation::Update));
|
|
}
|
|
|
|
TEST_F(Sessions, BeginIteratorHasDeleteOperation)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
deleteData.write("foo");
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
|
|
auto tuple = (*begin);
|
|
|
|
ASSERT_THAT(tuple.operation, Eq(Operation::Delete));
|
|
}
|
|
|
|
TEST_F(Sessions, BeginIteratorHasDataTableName)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
|
|
auto tuple = (*begin);
|
|
|
|
ASSERT_THAT(tuple.table, Eq("data"));
|
|
}
|
|
|
|
TEST_F(Sessions, ConvertAllValueTypesInChangeSet)
|
|
{
|
|
sessions.create();
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
auto tuple = (*begin);
|
|
|
|
std::vector<ValueViews> values{tuple.begin(), tuple.end()};
|
|
|
|
ASSERT_THAT(values,
|
|
ElementsAre(HasValues(1, nullptr),
|
|
HasValues("foo", nullptr),
|
|
HasValues("bar", nullptr),
|
|
HasValues(3.14, nullptr)));
|
|
}
|
|
|
|
TEST_F(Sessions, InsertOneValueChangeSet)
|
|
{
|
|
sessions.create();
|
|
insertOneDatum.write("foo");
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
auto tuple = (*begin);
|
|
|
|
std::vector<ValueViews> values{tuple.begin(), tuple.end()};
|
|
|
|
ASSERT_THAT(values,
|
|
ElementsAre(HasValues(1, nullptr),
|
|
HasValues(nullptr, nullptr),
|
|
HasValues(nullptr, nullptr),
|
|
HasValues("foo", nullptr)));
|
|
}
|
|
|
|
TEST_F(Sessions, UpdateOneValueChangeSet)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
auto tuple = (*begin);
|
|
|
|
std::vector<ValueViews> values{tuple.begin(), tuple.end()};
|
|
|
|
ASSERT_THAT(values,
|
|
ElementsAre(HasValues(nullptr, 1),
|
|
HasValues(nullptr, nullptr),
|
|
HasValues(nullptr, nullptr),
|
|
HasValues(99, 3.14)));
|
|
}
|
|
|
|
TEST_F(Sessions, DeleteRowChangeSet)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
deleteData.write("foo");
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
|
|
auto tuple = (*begin);
|
|
|
|
std::vector<ValueViews> values{tuple.begin(), tuple.end()};
|
|
|
|
ASSERT_THAT(values,
|
|
ElementsAre(HasValues(nullptr, 1),
|
|
HasValues(nullptr, "foo"),
|
|
HasValues(nullptr, "bar"),
|
|
HasValues(nullptr, 3.14)));
|
|
}
|
|
|
|
TEST_F(Sessions, EmptyChangeSet)
|
|
{
|
|
sessions.create();
|
|
sessions.commit();
|
|
|
|
auto changeSets = sessions.changeSets();
|
|
|
|
ASSERT_THAT(changeSets, ElementsAre());
|
|
}
|
|
|
|
TEST_F(Sessions, AccessInsertOneValueChangeSet)
|
|
{
|
|
sessions.create();
|
|
insertOneDatum.write("foo");
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
auto tuple = (*begin);
|
|
|
|
ValueViews value = tuple[3];
|
|
|
|
ASSERT_THAT(value, HasValues("foo", nullptr));
|
|
}
|
|
|
|
TEST_F(Sessions, AccessUpdateOneValueChangeSet)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
updateValue.write("foo", 99);
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
auto tuple = (*begin);
|
|
|
|
ValueViews value = tuple[3];
|
|
|
|
ASSERT_THAT(value, HasValues(99, 3.14));
|
|
}
|
|
|
|
TEST_F(Sessions, AccessDeleteRowChangeSet)
|
|
{
|
|
insertData.write("foo", "bar", 3.14);
|
|
sessions.create();
|
|
deleteData.write("foo");
|
|
sessions.commit();
|
|
auto changeSets = sessions.changeSets();
|
|
auto &&changeSet = changeSets.front();
|
|
auto begin = changeSet.begin();
|
|
auto tuple = (*begin);
|
|
|
|
ValueViews value = tuple[0];
|
|
|
|
ASSERT_THAT(value, HasValues(nullptr, 1));
|
|
}
|
|
} // namespace
|