Storage refactoring.
This commit is contained in:
parent
36f3d63540
commit
37494c342d
14 changed files with 237 additions and 163 deletions
|
@ -17,7 +17,6 @@ LOCAL_SRC_FILES := \
|
|||
# Storage files
|
||||
LOCAL_SRC_FILES += \
|
||||
../../storage/storage.cpp \
|
||||
../../storage/article_info_storage.cpp \
|
||||
../../storage/index_storage.cpp \
|
||||
../../storage/article_info.cpp \
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
#include "jni_util.hpp"
|
||||
|
||||
#include "../../storage/storage.hpp"
|
||||
#include "../../storage/article_info_storage.hpp"
|
||||
#include "../../storage/index_storage.hpp"
|
||||
|
||||
|
||||
class AndStorage
|
||||
{
|
||||
public:
|
||||
AndStorage()
|
||||
: m_storage(new ArticleInfoStorageMock(), new IndexStorageMock()) {}
|
||||
|
||||
static AndStorage & Instance()
|
||||
{
|
||||
|
@ -36,7 +33,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Storage m_storage;
|
||||
StorageMock m_storage;
|
||||
vector<ArticleInfo> m_result;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A3E221EF17AFB4AE0018AB9E /* article_info_storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3E221EE17AFB4AE0018AB9E /* article_info_storage.cpp */; };
|
||||
A3E221F117AFB4B90018AB9E /* index_storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3E221F017AFB4B90018AB9E /* index_storage.cpp */; };
|
||||
7722E14817B01B0700CFB817 /* article_info.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7722E14717B01B0700CFB817 /* article_info.cpp */; };
|
||||
A3E221F317AFB4C20018AB9E /* storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3E221F217AFB4C20018AB9E /* storage.cpp */; };
|
||||
A3E2220C17AFD5840018AB9E /* data in Resources */ = {isa = PBXBuildFile; fileRef = A3E2220B17AFD5840018AB9E /* data */; };
|
||||
A3E2220F17AFD9E10018AB9E /* assert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3E2220E17AFD9E10018AB9E /* assert.cpp */; };
|
||||
|
@ -28,8 +27,7 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A3E221EE17AFB4AE0018AB9E /* article_info_storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = article_info_storage.cpp; path = ../../storage/article_info_storage.cpp; sourceTree = "<group>"; };
|
||||
A3E221F017AFB4B90018AB9E /* index_storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = index_storage.cpp; path = ../../storage/index_storage.cpp; sourceTree = "<group>"; };
|
||||
7722E14717B01B0700CFB817 /* article_info.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = article_info.cpp; path = ../../storage/article_info.cpp; sourceTree = "<group>"; };
|
||||
A3E221F217AFB4C20018AB9E /* storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = storage.cpp; path = ../../storage/storage.cpp; sourceTree = "<group>"; };
|
||||
A3E2220B17AFD5840018AB9E /* data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = data; path = ../../data; sourceTree = "<group>"; };
|
||||
A3E2220E17AFD9E10018AB9E /* assert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = assert.cpp; path = ../../env/assert.cpp; sourceTree = "<group>"; };
|
||||
|
@ -71,9 +69,8 @@
|
|||
A3E221ED17AFB49B0018AB9E /* storage */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7722E14717B01B0700CFB817 /* article_info.cpp */,
|
||||
A3E221F217AFB4C20018AB9E /* storage.cpp */,
|
||||
A3E221F017AFB4B90018AB9E /* index_storage.cpp */,
|
||||
A3E221EE17AFB4AE0018AB9E /* article_info_storage.cpp */,
|
||||
);
|
||||
name = storage;
|
||||
sourceTree = "<group>";
|
||||
|
@ -217,11 +214,10 @@
|
|||
ED81955717AED762004F3803 /* AppDelegate.mm in Sources */,
|
||||
ED81956517AEE129004F3803 /* ArticleVC.mm in Sources */,
|
||||
ED81956A17AEF6B6004F3803 /* GuideVC.mm in Sources */,
|
||||
A3E221EF17AFB4AE0018AB9E /* article_info_storage.cpp in Sources */,
|
||||
A3E221F117AFB4B90018AB9E /* index_storage.cpp in Sources */,
|
||||
A3E221F317AFB4C20018AB9E /* storage.cpp in Sources */,
|
||||
A3E2220F17AFD9E10018AB9E /* assert.cpp in Sources */,
|
||||
A3E2221117AFDA0A0018AB9E /* source_address.cpp in Sources */,
|
||||
7722E14817B01B0700CFB817 /* article_info.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -2,17 +2,18 @@
|
|||
#import "GuideVC.h"
|
||||
|
||||
#import "../../storage/storage.hpp"
|
||||
#import "../../storage/article_info_storage.hpp"
|
||||
#import "../../storage/article_info.hpp"
|
||||
#import "../../storage/index_storage.hpp"
|
||||
#import "../../std/vector.hpp"
|
||||
|
||||
#import "../../env/assert.hpp"
|
||||
|
||||
#import "../../std/vector.hpp"
|
||||
|
||||
|
||||
#define THUMBNAILSFOLDER @"/data/thumbnails/"
|
||||
|
||||
@interface ArticleVC ()
|
||||
{
|
||||
Storage * m_storage;
|
||||
StorageMock m_storage;
|
||||
vector<ArticleInfo> m_infos;
|
||||
}
|
||||
|
||||
|
@ -30,7 +31,6 @@
|
|||
self.searchBar.delegate = self;
|
||||
self.tableView.tableHeaderView = self.searchBar;
|
||||
self.searchBar.text = @"";
|
||||
m_storage = new Storage(new ArticleInfoStorageMock(), new IndexStorageMock());
|
||||
[self searchBar:self.searchBar textDidChange:@""];
|
||||
}
|
||||
return self;
|
||||
|
@ -70,7 +70,7 @@
|
|||
string imageType = info->m_thumbnailUrl.substr(pos+1);
|
||||
NSString * imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:imageName.c_str()] ofType:[NSString stringWithUTF8String:imageType.c_str()] inDirectory:THUMBNAILSFOLDER];
|
||||
|
||||
cell.detailTextLabel.text = [NSString stringWithUTF8String:info->m_parentPath.c_str()];
|
||||
cell.detailTextLabel.text = [NSString stringWithUTF8String:info->m_parentUrl.c_str()];
|
||||
|
||||
UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
|
||||
cell.imageView.image = image;
|
||||
|
@ -106,7 +106,7 @@
|
|||
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
|
||||
{
|
||||
//@todo add lat and lon to QueryInfos
|
||||
m_storage->QueryArticleInfos(m_infos, [searchText UTF8String]);
|
||||
m_storage.QueryArticleInfos(m_infos, [searchText UTF8String]);
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
|
|
28
storage/article_info.cpp
Normal file
28
storage/article_info.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include "article_info.hpp"
|
||||
|
||||
#include "../std/iterator.hpp"
|
||||
#include "../std/algorithm.hpp"
|
||||
|
||||
|
||||
void ArticleInfo::GenerateKey()
|
||||
{
|
||||
m_key.reserve(m_title.size());
|
||||
transform(m_title.begin(), m_title.end(), back_inserter(m_key), &::tolower);
|
||||
}
|
||||
|
||||
double ArticleInfo::Score(double currLat, double currLon) const
|
||||
{
|
||||
/// @todo
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void ArticleInfo::Swap(ArticleInfo & i)
|
||||
{
|
||||
m_key.swap(i.m_key);
|
||||
m_url.swap(i.m_url);
|
||||
m_title.swap(i.m_title);
|
||||
m_thumbnailUrl.swap(i.m_thumbnailUrl);
|
||||
m_parentUrl.swap(i.m_parentUrl);
|
||||
std::swap(m_lat, i.m_lat);
|
||||
std::swap(m_lon, i.m_lon);
|
||||
}
|
|
@ -1,31 +1,86 @@
|
|||
#pragma once
|
||||
|
||||
#include "storage_common.hpp"
|
||||
#include <iostream>
|
||||
|
||||
struct ArticleInfo
|
||||
#include "../std/algorithm.hpp"
|
||||
|
||||
|
||||
class ArticleInfo
|
||||
{
|
||||
void GenerateKey();
|
||||
|
||||
string m_key;
|
||||
|
||||
public:
|
||||
ArticleInfo() {}
|
||||
ArticleInfo(string const & url, string const & title, string const & thumbnailUrl, string const & parentPath)
|
||||
: m_url(url), m_title(title), m_thumbnailUrl(thumbnailUrl), m_parentPath(parentPath) {}
|
||||
ArticleInfo(string const & title) : m_title(title)
|
||||
{
|
||||
GenerateKey();
|
||||
}
|
||||
|
||||
string m_url;
|
||||
string m_title;
|
||||
string m_thumbnailUrl;
|
||||
string m_parentPath;
|
||||
string m_parentUrl;
|
||||
|
||||
double m_lat, m_lon;
|
||||
|
||||
double Score(double currLat, double currLon) const;
|
||||
|
||||
void Swap(ArticleInfo & i);
|
||||
|
||||
class LessScore
|
||||
{
|
||||
double m_lat, m_lon;
|
||||
public:
|
||||
LessScore(double lat, double lon) : m_lat(lat), m_lon(lon) {}
|
||||
bool operator() (ArticleInfo const & i1, ArticleInfo const & i2) const
|
||||
{
|
||||
return i1.Score(m_lat, m_lon) < i2.Score(m_lat, m_lon);
|
||||
}
|
||||
};
|
||||
|
||||
struct LessStorage
|
||||
{
|
||||
bool operator() (ArticleInfo const & i1, ArticleInfo const & i2) const
|
||||
{
|
||||
return (i1.m_key < i2.m_key);
|
||||
}
|
||||
};
|
||||
|
||||
class LessPrefix
|
||||
{
|
||||
int Compare(ArticleInfo const & info, string const & prefix) const
|
||||
{
|
||||
size_t const count = min(info.m_key.size(), prefix.size());
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (info.m_key[i] < prefix[i])
|
||||
return -1;
|
||||
else if (info.m_key[i] > prefix[i])
|
||||
return 1;
|
||||
}
|
||||
return (info.m_key.size() < prefix.size() ? -1 : 0);
|
||||
}
|
||||
|
||||
public:
|
||||
bool operator() (ArticleInfo const & info, string const & prefix) const
|
||||
{
|
||||
return (Compare(info, prefix) == -1);
|
||||
}
|
||||
bool operator() (string const & prefix, ArticleInfo const & info) const
|
||||
{
|
||||
return (Compare(info, prefix) == 1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
inline bool operator == (ArticleInfo const & a1, ArticleInfo const & a2)
|
||||
inline void swap(ArticleInfo & a1, ArticleInfo & a2)
|
||||
{
|
||||
return a1.m_url == a2.m_url && a1.m_title == a2.m_title &&
|
||||
a1.m_thumbnailUrl == a2.m_thumbnailUrl && a1.m_parentPath == a2.m_parentPath;
|
||||
a1.Swap(a2);
|
||||
}
|
||||
|
||||
// It's important that PrintTo() is defined in the SAME
|
||||
// namespace that defines Bar. C++'s look-up rules rely on that.
|
||||
inline void PrintTo(ArticleInfo const & artInfo, ::std::ostream* os) {
|
||||
*os << "ArticleInfi {" << artInfo.m_url << ", "
|
||||
<< artInfo.m_title << ", "
|
||||
<< artInfo.m_thumbnailUrl << ", "
|
||||
<< artInfo.m_parentPath << "}";
|
||||
inline string ToString(ArticleInfo const & i)
|
||||
{
|
||||
return i.m_title;
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#include "article_info_storage.hpp"
|
||||
|
||||
bool ArticleInfoStorageMock::GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id)
|
||||
{
|
||||
if (id > 2)
|
||||
return false;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case 0:
|
||||
out.m_thumbnailUrl = "london.jpg";
|
||||
out.m_url = "London.html";
|
||||
out.m_title = "London";
|
||||
out.m_parentPath = "Europe -> Great Britain";
|
||||
return true;
|
||||
case 1:
|
||||
out.m_thumbnailUrl = "lancaster.jpg";
|
||||
out.m_url = "Lancaster.html";
|
||||
out.m_title = "Lancaster";
|
||||
out.m_parentPath = "Europe -> Great Britain";
|
||||
return true;
|
||||
case 2:
|
||||
out.m_thumbnailUrl = "great_britain.jpg";
|
||||
out.m_url = "GreatBritain.html";
|
||||
out.m_title = "Great Britain";
|
||||
out.m_parentPath = "Europe";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "../std/string.hpp"
|
||||
#include "article_info.hpp"
|
||||
#include "storage_common.hpp"
|
||||
|
||||
class ArticleInfoStorage
|
||||
{
|
||||
public:
|
||||
virtual ~ArticleInfoStorage() {}
|
||||
virtual bool GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id) = 0;
|
||||
};
|
||||
|
||||
class ArticleInfoStorageMock: public ArticleInfoStorage
|
||||
{
|
||||
public:
|
||||
virtual bool GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id);
|
||||
};
|
|
@ -1,15 +0,0 @@
|
|||
#include "index_storage.hpp"
|
||||
|
||||
void IndexStorageMock::QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
|
||||
double /*lat*/, double /*lon*/) const
|
||||
{
|
||||
out.clear();
|
||||
if (prefix.empty())
|
||||
for (uint32_t i = 0; i < 3; ++i)
|
||||
out.push_back(i);
|
||||
else if (prefix == "L")
|
||||
for (uint32_t i = 0; i < 2; ++i)
|
||||
out.push_back(i);
|
||||
else if (prefix.size() <= 6 && string("London").substr(0, prefix.size()) == prefix)
|
||||
out.push_back(0);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "article_info.hpp"
|
||||
|
||||
#include "../std/vector.hpp"
|
||||
#include "../std/string.hpp"
|
||||
|
||||
class IndexStorage
|
||||
{
|
||||
public:
|
||||
virtual ~IndexStorage() {}
|
||||
virtual void QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
|
||||
double lat = INVALID_LAT, double lon = INVALID_LON) const = 0;
|
||||
};
|
||||
|
||||
class IndexStorageMock : public IndexStorage
|
||||
{
|
||||
public:
|
||||
virtual void QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
|
||||
double lat = INVALID_LAT, double lon = INVALID_LON) const;
|
||||
};
|
|
@ -1,21 +1,42 @@
|
|||
#include "storage.hpp"
|
||||
#include "../std/vector.hpp"
|
||||
|
||||
#include "../std/algorithm.hpp"
|
||||
#include "../std/utility.hpp"
|
||||
|
||||
Storage::Storage(ArticleInfoStorage * artInfoStorage, IndexStorage * indexStorage)
|
||||
{
|
||||
m_articleInfoStorage.reset(artInfoStorage);
|
||||
m_indexStorage.reset(indexStorage);
|
||||
}
|
||||
|
||||
void Storage::QueryArticleInfos(vector<ArticleInfo> & out, string const & prefix,
|
||||
double lat, double lon) const
|
||||
{
|
||||
vector<ArticleInfoId> ids;
|
||||
m_indexStorage->QueryArticleInfos(ids, prefix, lat, lon);
|
||||
out.clear();
|
||||
out.resize(ids.size());
|
||||
for (size_t i = 0; i < ids.size(); ++i)
|
||||
m_articleInfoStorage->GetArticleInfoById(out[i], ids[i]);
|
||||
|
||||
typedef vector<ArticleInfo>::const_iterator IterT;
|
||||
pair<IterT, IterT> const range = equal_range(m_info.begin(), m_info.end(),
|
||||
prefix, ArticleInfo::LessPrefix());
|
||||
|
||||
out.assign(range.first, range.second);
|
||||
sort(out.begin(), out.end(), ArticleInfo::LessScore(lat, lon));
|
||||
}
|
||||
|
||||
|
||||
StorageMock::StorageMock()
|
||||
{
|
||||
ArticleInfo i1("London");
|
||||
i1.m_url = "London";
|
||||
i1.m_thumbnailUrl = "london.jpg";
|
||||
i1.m_parentUrl = "Europe -> Great Britain";
|
||||
m_info.push_back(i1);
|
||||
|
||||
ArticleInfo i2("Lancaster");
|
||||
i2.m_url = "Lancaster";
|
||||
i2.m_thumbnailUrl = "lancaster.jpg";
|
||||
i2.m_parentUrl = "Europe -> Great Britain";
|
||||
m_info.push_back(i2);
|
||||
|
||||
ArticleInfo i3("Great Britain");
|
||||
i3.m_url = "Great_Britain";
|
||||
i3.m_thumbnailUrl = "great_britain.jpg";
|
||||
i3.m_parentUrl = "Europe";
|
||||
m_info.push_back(i3);
|
||||
|
||||
sort(m_info.begin(), m_info.end(), ArticleInfo::LessStorage());
|
||||
}
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
# pragma once
|
||||
#pragma once
|
||||
|
||||
#include "article_info_storage.hpp"
|
||||
#include "index_storage.hpp"
|
||||
#include "article_info.hpp"
|
||||
|
||||
#include "../std/scoped_ptr.hpp"
|
||||
#include "../std/vector.hpp"
|
||||
|
||||
|
||||
class Storage
|
||||
{
|
||||
public:
|
||||
/// @note takes ownership of @link(ArticleInfoStorage) and @link(IndexStorage)
|
||||
Storage(ArticleInfoStorage * artInfoStorage, IndexStorage * indexStorage);
|
||||
void Load(string const & path);
|
||||
|
||||
void QueryArticleInfos(vector<ArticleInfo> & out, string const & prefix,
|
||||
double lat = INVALID_LAT, double lon = INVALID_LON) const;
|
||||
|
||||
private:
|
||||
scoped_ptr<ArticleInfoStorage> m_articleInfoStorage;
|
||||
scoped_ptr<IndexStorage> m_indexStorage;
|
||||
protected:
|
||||
vector<ArticleInfo> m_info;
|
||||
};
|
||||
|
||||
|
||||
class StorageMock : public Storage
|
||||
{
|
||||
public:
|
||||
StorageMock();
|
||||
};
|
||||
|
|
|
@ -7,15 +7,17 @@ INCLUDEPATH += ../3rdparty/boost ../3rdparty/googletest/include
|
|||
|
||||
HEADERS += \
|
||||
storage.hpp \
|
||||
article_info_storage.hpp \
|
||||
article_info.hpp \
|
||||
index_storage.hpp \
|
||||
storage_common.hpp \
|
||||
|
||||
SOURCES += \
|
||||
article_info_storage.cpp \
|
||||
index_storage.cpp \
|
||||
storage.cpp \
|
||||
article_info.cpp \
|
||||
|
||||
# env sources
|
||||
SOURCES += \
|
||||
../env/logging.cpp \
|
||||
../env/source_address.cpp \
|
||||
|
||||
# unit tests
|
||||
SOURCES += \
|
||||
|
|
|
@ -1,33 +1,89 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "storage.hpp"
|
||||
#include "article_info_storage.hpp"
|
||||
#include "index_storage.hpp"
|
||||
|
||||
TEST(Storage, Smoke)
|
||||
#include "../env/message_std.hpp"
|
||||
#include "../env/logging.hpp"
|
||||
|
||||
#include "../std/array.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Storage storage(new ArticleInfoStorageMock(), new IndexStorageMock());
|
||||
|
||||
vector<ArticleInfo> artInfos;
|
||||
storage.QueryArticleInfos(artInfos, "");
|
||||
void CheckBounds(vector<ArticleInfo> const & v, string const & beg, string const & end)
|
||||
{
|
||||
EXPECT_FALSE(v.empty());
|
||||
EXPECT_EQ(v.front().m_title, beg);
|
||||
EXPECT_EQ(v.back().m_title, end);
|
||||
}
|
||||
|
||||
ArticleInfo expected[] =
|
||||
class StorageTest : public Storage
|
||||
{
|
||||
public:
|
||||
void FillStorage(char const * arr[], size_t size)
|
||||
{
|
||||
ArticleInfo("London", "London", "london.jpg", "Europe -> Great Britain"),
|
||||
ArticleInfo("Lancaster", "Lancaster", "lancaster.jpg", "Europe -> Great Britain"),
|
||||
ArticleInfo("Great_Britain", "Great Britain", "great_britain.jpg", "Europe"),
|
||||
};
|
||||
m_info.clear();
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
m_info.push_back(ArticleInfo(arr[i]));
|
||||
|
||||
sort(m_info.begin(), m_info.end(), ArticleInfo::LessStorage());
|
||||
}
|
||||
|
||||
void CheckBounds(string const & beg, string const & end) const
|
||||
{
|
||||
::CheckBounds(m_info, beg, end);
|
||||
}
|
||||
};
|
||||
|
||||
EXPECT_EQ(vector<ArticleInfo>(&expected[0], &expected[0] + 3), artInfos);
|
||||
}
|
||||
|
||||
TEST(Storage, PrefixQuery)
|
||||
TEST(Storage, PrefixQuery1)
|
||||
{
|
||||
Storage storage(new ArticleInfoStorageMock(), new IndexStorageMock());
|
||||
StorageTest storage;
|
||||
|
||||
vector<ArticleInfo> artInfos;
|
||||
storage.QueryArticleInfos(artInfos, "Lo");
|
||||
char const * arrTitle[] = { "London", "Lomdon", "Z", "a", "london", "las vegas", "los angeles" };
|
||||
size_t const count = ArraySize(arrTitle);
|
||||
|
||||
EXPECT_EQ(artInfos.size(), 1);
|
||||
EXPECT_EQ(artInfos[0], ArticleInfo("London", "London", "london.jpg", "Europe -> Great Britain"));
|
||||
storage.FillStorage(arrTitle, count);
|
||||
storage.CheckBounds("a", "Z");
|
||||
|
||||
vector<ArticleInfo> out;
|
||||
storage.QueryArticleInfos(out, "");
|
||||
EXPECT_EQ(out.size(), count);
|
||||
storage.CheckBounds("a", "Z");
|
||||
|
||||
storage.QueryArticleInfos(out, "l");
|
||||
EXPECT_EQ(out.size(), 5);
|
||||
CheckBounds(out, "las vegas", "los angeles");
|
||||
|
||||
storage.QueryArticleInfos(out, "lo");
|
||||
EXPECT_EQ(out.size(), 4);
|
||||
CheckBounds(out, "Lomdon", "los angeles");
|
||||
|
||||
storage.QueryArticleInfos(out, "lon");
|
||||
EXPECT_EQ(out.size(), 2);
|
||||
CheckBounds(out, "London", "london");
|
||||
|
||||
storage.QueryArticleInfos(out, "lx");
|
||||
EXPECT_EQ(out.size(), 0);
|
||||
|
||||
storage.QueryArticleInfos(out, "lor");
|
||||
EXPECT_EQ(out.size(), 0);
|
||||
}
|
||||
|
||||
TEST(Storage, PrefixQuery2)
|
||||
{
|
||||
StorageTest storage;
|
||||
|
||||
char const * arrTitle[] = { "London", "Lancaster", "Great Britan" };
|
||||
size_t const count = ArraySize(arrTitle);
|
||||
|
||||
storage.FillStorage(arrTitle, count);
|
||||
|
||||
vector<ArticleInfo> out;
|
||||
storage.QueryArticleInfos(out, "l");
|
||||
EXPECT_EQ(out.size(), 2);
|
||||
CheckBounds(out, "Lancaster", "London");
|
||||
}
|
||||
|
|
Reference in a new issue