[core] Storage.hpp as facade for core.
This commit is contained in:
parent
8f89d40423
commit
e0e098a178
14 changed files with 189 additions and 65 deletions
|
@ -1,6 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
class Article
|
||||
{
|
||||
|
||||
};
|
28
storage/article_info.hpp
Normal file
28
storage/article_info.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "storage_common.hpp"
|
||||
#include <iostream>
|
||||
|
||||
struct ArticleInfo
|
||||
{
|
||||
ArticleInfo() {}
|
||||
ArticleInfo(string const & url, string const & title, string const & thumbnailUrl)
|
||||
: m_url(url), m_title(title), m_thumbnailUrl(thumbnailUrl) {}
|
||||
|
||||
string m_url;
|
||||
string m_title;
|
||||
string m_thumbnailUrl;
|
||||
};
|
||||
|
||||
inline bool operator == (ArticleInfo const & a1, ArticleInfo const & a2)
|
||||
{
|
||||
return a1.m_url == a2.m_url && a1.m_title == a2.m_title && a1.m_thumbnailUrl == a2.m_thumbnailUrl;
|
||||
}
|
||||
|
||||
// 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 << "}";
|
||||
}
|
25
storage/article_info_storage.cpp
Normal file
25
storage/article_info_storage.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "article_info_storage.hpp"
|
||||
|
||||
bool ArticleInfoStorageMock::GetArticleInfoById(ArticleInfo & out, ArticleInfoId const & id)
|
||||
{
|
||||
if (id > 2)
|
||||
return false;
|
||||
|
||||
out.m_thumbnailUrl = "stub_url.png";
|
||||
switch (id)
|
||||
{
|
||||
case 0:
|
||||
out.m_url = "London";
|
||||
out.m_title = "London";
|
||||
return true;
|
||||
case 1:
|
||||
out.m_url = "Lancaster";
|
||||
out.m_title = "Lancaster";
|
||||
return true;
|
||||
case 2:
|
||||
out.m_url = "Great_Britain";
|
||||
out.m_title = "Great Britain";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
18
storage/article_info_storage.hpp
Normal file
18
storage/article_info_storage.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#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,10 +0,0 @@
|
|||
#include "article_storage.hpp"
|
||||
|
||||
bool ArticleStorageMock::GetArticleById(string const & id, Article & out) const
|
||||
{
|
||||
ArticleMap::const_iterator it = m_articles.find(id);
|
||||
if (it == m_articles.end())
|
||||
return false;
|
||||
out = it->second;
|
||||
return true;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "article.hpp"
|
||||
|
||||
#include "../std/map.hpp"
|
||||
#include "../std/string.hpp"
|
||||
|
||||
class ArticleStorage
|
||||
{
|
||||
public:
|
||||
virtual ~ArticleStorage() {}
|
||||
virtual bool GetArticleById(string const & id, Article & out) const = 0;
|
||||
};
|
||||
|
||||
class ArticleStorageMock : public ArticleStorage
|
||||
{
|
||||
public:
|
||||
ArticleStorageMock(map<string, Article> articles) : m_articles(articles) {}
|
||||
virtual bool GetArticleById(string const & id, Article & out) const;
|
||||
private:
|
||||
typedef map<string, Article> ArticleMap;
|
||||
ArticleMap m_articles;
|
||||
};
|
||||
|
||||
class ArticleStorageTable : public ArticleStorage
|
||||
{
|
||||
public:
|
||||
virtual bool GetArticleById(string const & id, Article & out) const;
|
||||
};
|
||||
|
15
storage/index_storage.cpp
Normal file
15
storage/index_storage.cpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "index_storage.hpp"
|
||||
|
||||
void IndexStorageMock::QueryArticleInfos(vector<ArticleInfoId> & out, string const & prefix,
|
||||
double /*lat*/, double /*lon*/) const
|
||||
{
|
||||
out.clear();
|
||||
if (prefix.empty())
|
||||
for (int i = 0; i < 3; ++i)
|
||||
out.push_back(i);
|
||||
else if (prefix == "L")
|
||||
for (int i = 0; i < 2; ++i)
|
||||
out.push_back(i);
|
||||
else if (prefix.size() <= 6 && string("London").substr(prefix.size()) == prefix)
|
||||
out.push_back(1);
|
||||
}
|
21
storage/index_storage.hpp
Normal file
21
storage/index_storage.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#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;
|
||||
};
|
21
storage/storage.cpp
Normal file
21
storage/storage.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "storage.hpp"
|
||||
#include "../std/vector.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]);
|
||||
}
|
||||
|
21
storage/storage.hpp
Normal file
21
storage/storage.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
# pragma once
|
||||
|
||||
#include "article_info_storage.hpp"
|
||||
#include "index_storage.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 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;
|
||||
};
|
|
@ -6,14 +6,19 @@ CONFIG -= app_bundle
|
|||
INCLUDEPATH += ../3rdparty/boost ../3rdparty/googletest/include
|
||||
|
||||
HEADERS += \
|
||||
article.hpp \
|
||||
article_storage.hpp \
|
||||
storage.hpp \
|
||||
article_info_storage.hpp \
|
||||
article_info.hpp \
|
||||
index_storage.hpp \
|
||||
storage_common.hpp \
|
||||
|
||||
SOURCES += \
|
||||
article_storage.cpp
|
||||
article_info_storage.cpp \
|
||||
tests/storage_test.cpp \
|
||||
index_storage.cpp \
|
||||
storage.cpp \
|
||||
|
||||
# unit tests
|
||||
SOURCES += \
|
||||
../3rdparty/googletest/src/gtest-all.cc \
|
||||
../3rdparty/googletest/src/gtest_main.cc \
|
||||
tests/article_storage_test.cpp \
|
||||
|
|
9
storage/storage_common.hpp
Normal file
9
storage/storage_common.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "../std/string.hpp"
|
||||
#include "../std/stdint.hpp"
|
||||
|
||||
typedef uint32_t ArticleInfoId;
|
||||
|
||||
#define INVALID_LAT -720.0
|
||||
#define INVALID_LON -720.0
|
|
@ -1,15 +0,0 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include "../std/utility.hpp"
|
||||
|
||||
#include "../article_storage.hpp"
|
||||
#include "../std/scoped_ptr.hpp"
|
||||
|
||||
TEST(ArticleStorageMock, ReturnsIfAnArticleExists)
|
||||
{
|
||||
map<string, Article> articles;
|
||||
articles.insert(make_pair("SomeId", Article()));
|
||||
scoped_ptr<ArticleStorage> storage(new ArticleStorageMock(articles));
|
||||
Article article;
|
||||
EXPECT_TRUE(storage->GetArticleById("SomeId", article));
|
||||
EXPECT_FALSE(storage->GetArticleById("SomeIdThatDoesNotExist", article));
|
||||
}
|
22
storage/tests/storage_test.cpp
Normal file
22
storage/tests/storage_test.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "storage.hpp"
|
||||
#include "article_info_storage.hpp"
|
||||
#include "index_storage.hpp"
|
||||
|
||||
TEST(Storage, Smoke)
|
||||
{
|
||||
Storage storage(new ArticleInfoStorageMock(), new IndexStorageMock());
|
||||
|
||||
vector<ArticleInfo> artInfos;
|
||||
storage.QueryArticleInfos(artInfos, "");
|
||||
|
||||
ArticleInfo expected[] =
|
||||
{
|
||||
ArticleInfo("London", "London", "stub_url.png"),
|
||||
ArticleInfo("Lancaster", "Lancaster", "stub_url.png"),
|
||||
ArticleInfo("Great_Britain", "Great Britain", "stub_url.png"),
|
||||
};
|
||||
|
||||
EXPECT_EQ(vector<ArticleInfo>(&expected[0], &expected[0] + 3), artInfos);
|
||||
}
|
Reference in a new issue