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