Added some foreachSubRange
This commit is contained in:
@@ -26,208 +26,225 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
// Caution: do not change enum values if they are set!
|
// Caution: do not change enum values if they are set!
|
||||||
|
|
||||||
// Request:
|
// Request:
|
||||||
// size = 0 => no size limit!
|
// size = 0 => no size limit!
|
||||||
// Response (via RangeResults)
|
// Response (via RangeResults)
|
||||||
// size => results size
|
// size => results size
|
||||||
struct Range
|
struct Range
|
||||||
{
|
{
|
||||||
std::size_t offset {};
|
std::size_t offset{};
|
||||||
std::size_t size {};
|
std::size_t size{};
|
||||||
|
|
||||||
// TODO remove this
|
// TODO remove this
|
||||||
operator bool() const { return size != 0; }
|
operator bool() const { return size != 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
// Func must return true to continue iterating
|
||||||
struct RangeResults
|
template <typename Func>
|
||||||
{
|
void foreachSubRange(Range range, std::size_t subRangeSize, Func&& func)
|
||||||
Range range;
|
{
|
||||||
std::vector<T> results;
|
assert(subRangeSize > 0);
|
||||||
bool moreResults{};
|
|
||||||
|
|
||||||
RangeResults getSubRange(Range subRange)
|
Range subRange{ range.offset, std::min(range.size, subRangeSize) };
|
||||||
{
|
while (subRange.size > 0)
|
||||||
assert(subRange.offset >= range.offset);
|
{
|
||||||
|
if (!func(subRange))
|
||||||
|
break;
|
||||||
|
|
||||||
if (!subRange.size)
|
subRange.offset += subRange.size;
|
||||||
subRange.size = range.size - (subRange.offset - range.offset);
|
subRange.size = std::min(subRangeSize, range.size - (subRange.offset - range.offset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
subRange.offset = std::min(subRange.offset, range.offset + range.size);
|
template <typename T>
|
||||||
subRange.size = std::min(subRange.size, range.offset + range.size - subRange.offset);
|
struct RangeResults
|
||||||
|
{
|
||||||
|
Range range;
|
||||||
|
std::vector<T> results;
|
||||||
|
bool moreResults{};
|
||||||
|
|
||||||
RangeResults subResults;
|
RangeResults getSubRange(Range subRange)
|
||||||
|
{
|
||||||
|
assert(subRange.offset >= range.offset);
|
||||||
|
|
||||||
auto itBegin {std::cbegin(results) + subRange.offset - range.offset};
|
if (!subRange.size)
|
||||||
auto itEnd {itBegin + subRange.size};
|
subRange.size = range.size - (subRange.offset - range.offset);
|
||||||
subResults.results.reserve(std::distance(itBegin, itEnd));
|
|
||||||
std::copy(itBegin, itEnd, std::back_inserter(subResults.results));
|
|
||||||
|
|
||||||
subResults.range = subRange;
|
subRange.offset = std::min(subRange.offset, range.offset + range.size);
|
||||||
if (subRange.offset + subRange.size == range.offset + range.size)
|
subRange.size = std::min(subRange.size, range.offset + range.size - subRange.offset);
|
||||||
subResults.moreResults = moreResults;
|
|
||||||
else
|
|
||||||
subResults.moreResults = true;
|
|
||||||
|
|
||||||
return subResults;
|
RangeResults subResults;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DateRange
|
auto itBegin{ std::cbegin(results) + subRange.offset - range.offset };
|
||||||
{
|
auto itEnd{ itBegin + subRange.size };
|
||||||
Wt::WDate begin;
|
subResults.results.reserve(std::distance(itBegin, itEnd));
|
||||||
Wt::WDate end;
|
std::copy(itBegin, itEnd, std::back_inserter(subResults.results));
|
||||||
|
|
||||||
static DateRange fromYearRange(int from, int to);
|
subResults.range = subRange;
|
||||||
};
|
if (subRange.offset + subRange.size == range.offset + range.size)
|
||||||
|
subResults.moreResults = moreResults;
|
||||||
|
else
|
||||||
|
subResults.moreResults = true;
|
||||||
|
|
||||||
struct DiscInfo
|
return subResults;
|
||||||
{
|
}
|
||||||
std::size_t position;
|
};
|
||||||
std::string name;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ArtistSortMethod
|
struct DateRange
|
||||||
{
|
{
|
||||||
None,
|
Wt::WDate begin;
|
||||||
ByName,
|
Wt::WDate end;
|
||||||
BySortName,
|
|
||||||
Random,
|
|
||||||
LastWritten,
|
|
||||||
StarredDateDesc,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ReleaseSortMethod
|
static DateRange fromYearRange(int from, int to);
|
||||||
{
|
};
|
||||||
None,
|
|
||||||
Name,
|
|
||||||
Date,
|
|
||||||
OriginalDate,
|
|
||||||
OriginalDateDesc,
|
|
||||||
Random,
|
|
||||||
LastWritten,
|
|
||||||
StarredDateDesc,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TrackListSortMethod
|
struct DiscInfo
|
||||||
{
|
{
|
||||||
None,
|
std::size_t position;
|
||||||
Name,
|
std::string name;
|
||||||
LastModifiedDesc,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
enum class TrackSortMethod
|
enum class ArtistSortMethod
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
Random,
|
ByName,
|
||||||
LastWritten,
|
BySortName,
|
||||||
StarredDateDesc,
|
Random,
|
||||||
Name,
|
LastWritten,
|
||||||
DateDescAndRelease,
|
StarredDateDesc,
|
||||||
Release, // order by disc/track number
|
};
|
||||||
TrackList, // order by asc order in tracklist
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TrackArtistLinkType
|
enum class ReleaseSortMethod
|
||||||
{
|
{
|
||||||
Artist = 0, // regular track artist
|
None,
|
||||||
Arranger = 1,
|
Name,
|
||||||
Composer = 2,
|
Date,
|
||||||
Conductor = 3,
|
OriginalDate,
|
||||||
Lyricist = 4,
|
OriginalDateDesc,
|
||||||
Mixer = 5,
|
Random,
|
||||||
Performer = 6,
|
LastWritten,
|
||||||
Producer = 7,
|
StarredDateDesc,
|
||||||
ReleaseArtist = 8,
|
};
|
||||||
Remixer = 9,
|
|
||||||
Writer = 10,
|
|
||||||
};
|
|
||||||
|
|
||||||
// User selectable audio file formats
|
enum class TrackListSortMethod
|
||||||
enum class AudioFormat
|
{
|
||||||
{
|
None,
|
||||||
MP3 = 1,
|
Name,
|
||||||
OGG_OPUS = 2,
|
LastModifiedDesc,
|
||||||
OGG_VORBIS = 3,
|
};
|
||||||
WEBM_VORBIS = 4,
|
|
||||||
MATROSKA_OPUS = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
using Bitrate = std::uint32_t;
|
enum class TrackSortMethod
|
||||||
// Do not remove values!
|
{
|
||||||
void visitAllowedAudioBitrates(std::function<void(Bitrate)>);
|
None,
|
||||||
bool isAudioBitrateAllowed(Bitrate bitrate);
|
Random,
|
||||||
|
LastWritten,
|
||||||
|
StarredDateDesc,
|
||||||
|
Name,
|
||||||
|
DateDescAndRelease,
|
||||||
|
Release, // order by disc/track number
|
||||||
|
TrackList, // order by asc order in tracklist
|
||||||
|
};
|
||||||
|
|
||||||
enum class ScrobblingBackend
|
enum class TrackArtistLinkType
|
||||||
{
|
{
|
||||||
Internal = 0,
|
Artist = 0, // regular track artist
|
||||||
ListenBrainz = 1,
|
Arranger = 1,
|
||||||
};
|
Composer = 2,
|
||||||
|
Conductor = 3,
|
||||||
|
Lyricist = 4,
|
||||||
|
Mixer = 5,
|
||||||
|
Performer = 6,
|
||||||
|
Producer = 7,
|
||||||
|
ReleaseArtist = 8,
|
||||||
|
Remixer = 9,
|
||||||
|
Writer = 10,
|
||||||
|
};
|
||||||
|
|
||||||
enum class FeedbackBackend
|
// User selectable audio file formats
|
||||||
{
|
enum class AudioFormat
|
||||||
Internal = 0,
|
{
|
||||||
ListenBrainz = 1,
|
MP3 = 1,
|
||||||
};
|
OGG_OPUS = 2,
|
||||||
|
OGG_VORBIS = 3,
|
||||||
|
WEBM_VORBIS = 4,
|
||||||
|
MATROSKA_OPUS = 5,
|
||||||
|
};
|
||||||
|
|
||||||
enum class SyncState
|
using Bitrate = std::uint32_t;
|
||||||
{
|
// Do not remove values!
|
||||||
PendingAdd = 0,
|
void visitAllowedAudioBitrates(std::function<void(Bitrate)>);
|
||||||
Synchronized = 1,
|
bool isAudioBitrateAllowed(Bitrate bitrate);
|
||||||
PendingRemove = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class UserType
|
enum class ScrobblingBackend
|
||||||
{
|
{
|
||||||
REGULAR = 0,
|
Internal = 0,
|
||||||
ADMIN = 1,
|
ListenBrainz = 1,
|
||||||
DEMO = 2,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
enum class UITheme
|
enum class FeedbackBackend
|
||||||
{
|
{
|
||||||
Light = 0,
|
Internal = 0,
|
||||||
Dark = 1,
|
ListenBrainz = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SubsonicArtistListMode
|
enum class SyncState
|
||||||
{
|
{
|
||||||
AllArtists = 0,
|
PendingAdd = 0,
|
||||||
ReleaseArtists = 1,
|
Synchronized = 1,
|
||||||
TrackArtists = 2,
|
PendingRemove = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TrackListType
|
enum class UserType
|
||||||
{
|
{
|
||||||
Playlist, // user controlled playlists
|
REGULAR = 0,
|
||||||
Internal, // internal usage (current playqueue, history, ...)
|
ADMIN = 1,
|
||||||
};
|
DEMO = 2,
|
||||||
|
};
|
||||||
|
|
||||||
// as defined in https://musicbrainz.org/doc/Release_Group/Type
|
enum class UITheme
|
||||||
enum class ReleaseTypePrimary
|
{
|
||||||
{
|
Light = 0,
|
||||||
Album,
|
Dark = 1,
|
||||||
Single,
|
};
|
||||||
EP,
|
|
||||||
Broadcast,
|
|
||||||
Other,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ReleaseTypeSecondary
|
enum class SubsonicArtistListMode
|
||||||
{
|
{
|
||||||
Compilation,
|
AllArtists = 0,
|
||||||
Soundtrack,
|
ReleaseArtists = 1,
|
||||||
Spokenword,
|
TrackArtists = 2,
|
||||||
Interview,
|
};
|
||||||
Audiobook,
|
|
||||||
AudioDrama,
|
enum class TrackListType
|
||||||
Live,
|
{
|
||||||
Remix,
|
Playlist, // user controlled playlists
|
||||||
DJMix,
|
Internal, // internal usage (current playqueue, history, ...)
|
||||||
Mixtape_Street,
|
};
|
||||||
Demo,
|
|
||||||
};
|
// as defined in https://musicbrainz.org/doc/Release_Group/Type
|
||||||
|
enum class ReleaseTypePrimary
|
||||||
|
{
|
||||||
|
Album,
|
||||||
|
Single,
|
||||||
|
EP,
|
||||||
|
Broadcast,
|
||||||
|
Other,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ReleaseTypeSecondary
|
||||||
|
{
|
||||||
|
Compilation,
|
||||||
|
Soundtrack,
|
||||||
|
Spokenword,
|
||||||
|
Interview,
|
||||||
|
Audiobook,
|
||||||
|
AudioDrama,
|
||||||
|
Live,
|
||||||
|
Remix,
|
||||||
|
DJMix,
|
||||||
|
Mixtape_Street,
|
||||||
|
Demo,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,174 +36,212 @@
|
|||||||
#include "services/database/User.hpp"
|
#include "services/database/User.hpp"
|
||||||
|
|
||||||
TmpDatabase::TmpDatabase()
|
TmpDatabase::TmpDatabase()
|
||||||
: _tmpFile {std::tmpnam(nullptr)}
|
: _tmpFile{ std::tmpnam(nullptr) }
|
||||||
, _fileDeleter {_tmpFile}
|
, _fileDeleter{ _tmpFile }
|
||||||
, _db {_tmpFile}
|
, _db{ _tmpFile }
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::Db&
|
Database::Db&
|
||||||
TmpDatabase::getDb()
|
TmpDatabase::getDb()
|
||||||
{
|
{
|
||||||
return _db;
|
return _db;
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseFixture::~DatabaseFixture()
|
DatabaseFixture::~DatabaseFixture()
|
||||||
{
|
{
|
||||||
testDatabaseEmpty();
|
testDatabaseEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DatabaseFixture::SetUpTestCase()
|
DatabaseFixture::SetUpTestCase()
|
||||||
{
|
{
|
||||||
_tmpDb = std::make_unique<TmpDatabase>();
|
_tmpDb = std::make_unique<TmpDatabase>();
|
||||||
{
|
{
|
||||||
Database::Session s {_tmpDb->getDb()};
|
Database::Session s{ _tmpDb->getDb() };
|
||||||
s.prepareTables();
|
s.prepareTables();
|
||||||
s.analyze();
|
s.analyze();
|
||||||
|
|
||||||
// remove default created entries
|
// remove default created entries
|
||||||
{
|
{
|
||||||
auto transaction {s.createUniqueTransaction()};
|
auto transaction{ s.createUniqueTransaction() };
|
||||||
auto clusterTypes {Database::ClusterType::find(s, Database::Range {})};
|
auto clusterTypes{ Database::ClusterType::find(s, Database::Range {}) };
|
||||||
for (auto clusterTypeId : clusterTypes.results)
|
for (auto clusterTypeId : clusterTypes.results)
|
||||||
{
|
{
|
||||||
auto clusterType {Database::ClusterType::find(s, clusterTypeId)};
|
auto clusterType{ Database::ClusterType::find(s, clusterTypeId) };
|
||||||
clusterType.remove();
|
clusterType.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DatabaseFixture::TearDownTestCase()
|
DatabaseFixture::TearDownTestCase()
|
||||||
{
|
{
|
||||||
_tmpDb.reset();
|
_tmpDb.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DatabaseFixture::testDatabaseEmpty()
|
DatabaseFixture::testDatabaseEmpty()
|
||||||
{
|
{
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
auto uniqueTransaction {session.createUniqueTransaction()};
|
auto uniqueTransaction{ session.createUniqueTransaction() };
|
||||||
|
|
||||||
EXPECT_EQ(Artist::getCount(session), 0);
|
EXPECT_EQ(Artist::getCount(session), 0);
|
||||||
EXPECT_EQ(Cluster::getCount(session), 0);
|
EXPECT_EQ(Cluster::getCount(session), 0);
|
||||||
EXPECT_EQ(ClusterType::getCount(session), 0);
|
EXPECT_EQ(ClusterType::getCount(session), 0);
|
||||||
EXPECT_EQ(Listen::getCount(session), 0);
|
EXPECT_EQ(Listen::getCount(session), 0);
|
||||||
EXPECT_EQ(Release::getCount(session), 0);
|
EXPECT_EQ(Release::getCount(session), 0);
|
||||||
EXPECT_EQ(StarredArtist::getCount(session), 0);
|
EXPECT_EQ(StarredArtist::getCount(session), 0);
|
||||||
EXPECT_EQ(StarredRelease::getCount(session), 0);
|
EXPECT_EQ(StarredRelease::getCount(session), 0);
|
||||||
EXPECT_EQ(StarredTrack::getCount(session), 0);
|
EXPECT_EQ(StarredTrack::getCount(session), 0);
|
||||||
EXPECT_EQ(Track::getCount(session), 0);
|
EXPECT_EQ(Track::getCount(session), 0);
|
||||||
EXPECT_EQ(TrackBookmark::getCount(session), 0);
|
EXPECT_EQ(TrackBookmark::getCount(session), 0);
|
||||||
EXPECT_EQ(TrackList::getCount(session), 0);
|
EXPECT_EQ(TrackList::getCount(session), 0);
|
||||||
EXPECT_EQ(User::getCount(session), 0);
|
EXPECT_EQ(User::getCount(session), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DatabaseFixture, Common_subRangeEmpty)
|
TEST_F(DatabaseFixture, Common_subRangeEmpty)
|
||||||
{
|
{
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
RangeResults<int> results;
|
RangeResults<int> results;
|
||||||
results.range = Range {0, 0};
|
results.range = Range{ 0, 0 };
|
||||||
results.results = {};
|
results.results = {};
|
||||||
results.moreResults = false;
|
results.moreResults = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {0, 0})};
|
auto subRange{ results.getSubRange(Range {0, 0}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 0);
|
ASSERT_EQ(subRange.results.size(), 0);
|
||||||
EXPECT_EQ(subRange.range, Range {});
|
EXPECT_EQ(subRange.range, Range{});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {0, 1})};
|
auto subRange{ results.getSubRange(Range {0, 1}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 0);
|
ASSERT_EQ(subRange.results.size(), 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DatabaseFixture, Common_subRangeForeach)
|
||||||
|
{
|
||||||
|
using namespace Database;
|
||||||
|
|
||||||
|
struct TestCase
|
||||||
|
{
|
||||||
|
Range range;
|
||||||
|
std::size_t subRangeSize;
|
||||||
|
std::vector<Range> expectedSubRanges;
|
||||||
|
};
|
||||||
|
|
||||||
|
TestCase testCases[]
|
||||||
|
{
|
||||||
|
{Range{0, 0}, 1, {}},
|
||||||
|
{Range{1, 0}, 1, {}},
|
||||||
|
{Range{1, 1}, 1, { Range{ 1,1 } }},
|
||||||
|
{Range{1, 3}, 1, { Range{ 1,1 }, Range {2,1}, Range{3,1} }},
|
||||||
|
{Range{0, 100}, 100, { Range{0,100} }},
|
||||||
|
{Range{0, 50}, 100, { Range{0,50} }},
|
||||||
|
{Range{100, 200}, 100, { Range{100,100}, Range{200,100} }},
|
||||||
|
{Range{100, 101}, 100, { Range{100,100}, Range{200,1}}},
|
||||||
|
{Range{1000, 10}, 100, { Range{1000,10} }},
|
||||||
|
{Range{1, 100}, 50, { Range{1,50}, Range{51, 50} }},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const TestCase& test : testCases)
|
||||||
|
{
|
||||||
|
std::vector<Range> subRanges;
|
||||||
|
foreachSubRange(test.range, test.subRangeSize, [&](Range subRange)
|
||||||
|
{
|
||||||
|
subRanges.push_back(subRange);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_EQ(subRanges, test.expectedSubRanges) << ", test index = " << std::distance(std::cbegin(testCases), &test);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DatabaseFixture, Common_IdType)
|
TEST_F(DatabaseFixture, Common_IdType)
|
||||||
{
|
{
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
{
|
{
|
||||||
const IdType id{};
|
const IdType id{};
|
||||||
EXPECT_FALSE(id.isValid());
|
EXPECT_FALSE(id.isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const IdType id{0};
|
const IdType id{ 0 };
|
||||||
EXPECT_TRUE(id.isValid());
|
EXPECT_TRUE(id.isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const IdType id1{0};
|
const IdType id1{ 0 };
|
||||||
const IdType id2{0};
|
const IdType id2{ 0 };
|
||||||
EXPECT_EQ(id1, id2);
|
EXPECT_EQ(id1, id2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const IdType id1{0};
|
const IdType id1{ 0 };
|
||||||
const IdType id2{1};
|
const IdType id2{ 1 };
|
||||||
EXPECT_NE(id1, id2);
|
EXPECT_NE(id1, id2);
|
||||||
EXPECT_LT(id1, id2);
|
EXPECT_LT(id1, id2);
|
||||||
EXPECT_GT(id2, id1);
|
EXPECT_GT(id2, id1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DatabaseFixture, Common_subRange)
|
TEST_F(DatabaseFixture, Common_subRange)
|
||||||
{
|
{
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
RangeResults<int> results;
|
RangeResults<int> results;
|
||||||
results.range = Range {0, 2};
|
results.range = Range{ 0, 2 };
|
||||||
results.results = {5, 6};
|
results.results = { 5, 6 };
|
||||||
results.moreResults = false;
|
results.moreResults = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {0, 1})};
|
auto subRange{ results.getSubRange(Range {0, 1}) };
|
||||||
EXPECT_TRUE(subRange.moreResults);
|
EXPECT_TRUE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 1);
|
ASSERT_EQ(subRange.results.size(), 1);
|
||||||
EXPECT_EQ(subRange.results.front(), 5);
|
EXPECT_EQ(subRange.results.front(), 5);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {1, 1})};
|
auto subRange{ results.getSubRange(Range {1, 1}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 1);
|
ASSERT_EQ(subRange.results.size(), 1);
|
||||||
EXPECT_EQ(subRange.results.front(), 6);
|
EXPECT_EQ(subRange.results.front(), 6);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {0, 2})};
|
auto subRange{ results.getSubRange(Range {0, 2}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 2);
|
ASSERT_EQ(subRange.results.size(), 2);
|
||||||
EXPECT_EQ(subRange.results.front(), 5);
|
EXPECT_EQ(subRange.results.front(), 5);
|
||||||
EXPECT_EQ(subRange.results.back(), 6);
|
EXPECT_EQ(subRange.results.back(), 6);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {})};
|
auto subRange{ results.getSubRange(Range {}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 2);
|
ASSERT_EQ(subRange.results.size(), 2);
|
||||||
EXPECT_EQ(subRange.results.front(), 5);
|
EXPECT_EQ(subRange.results.front(), 5);
|
||||||
EXPECT_EQ(subRange.results.back(), 6);
|
EXPECT_EQ(subRange.results.back(), 6);
|
||||||
EXPECT_EQ(subRange.range, results.range);
|
EXPECT_EQ(subRange.range, results.range);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {1, 0})};
|
auto subRange{ results.getSubRange(Range {1, 0}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 1);
|
ASSERT_EQ(subRange.results.size(), 1);
|
||||||
EXPECT_EQ(subRange.results.front(), 6);
|
EXPECT_EQ(subRange.results.front(), 6);
|
||||||
const Range expectedRange {1, 1};
|
const Range expectedRange{ 1, 1 };
|
||||||
EXPECT_EQ(subRange.range, expectedRange);
|
EXPECT_EQ(subRange.range, expectedRange);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto subRange {results.getSubRange(Range {3, 2})};
|
auto subRange{ results.getSubRange(Range {3, 2}) };
|
||||||
EXPECT_FALSE(subRange.moreResults);
|
EXPECT_FALSE(subRange.moreResults);
|
||||||
ASSERT_EQ(subRange.results.size(), 0);
|
ASSERT_EQ(subRange.results.size(), 0);
|
||||||
const Range expectedRange {2, 0};
|
const Range expectedRange{ 2, 0 };
|
||||||
EXPECT_EQ(subRange.range, expectedRange);
|
EXPECT_EQ(subRange.range, expectedRange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user