Skip to content

Commit

Permalink
Storage: added on_create signal
Browse files Browse the repository at this point in the history
  • Loading branch information
srouquette committed Sep 4, 2015
1 parent ce7783a commit 9474a21
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 16 deletions.
4 changes: 0 additions & 4 deletions include/filesystem/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

#include <mutex> // NOLINT
#include <string>
#include <typeindex>
#include <unordered_map>


namespace kodama { namespace filesystem {
Expand All @@ -22,7 +20,6 @@ namespace fs = FILESYSTEM_NAMESPACE;
class Entry {
public:
friend class Storage;
friend class MockStorage;
class key {
friend class Storage;
key() {}
Expand All @@ -49,7 +46,6 @@ class Entry {
private:
void throws_if_nonexistent() const;

using property_map_t = std::unordered_map<std::type_index, property_ptr_t>;
mutable std::mutex mutex_;
mutable boost::shared_mutex shared_mutex_;
fs::file_status status_;
Expand Down
15 changes: 14 additions & 1 deletion include/filesystem/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#include "filesystem/namespace.h"

#include <boost/signals2.hpp>

#include <map>
#include <mutex> // NOLINT
#include <string>
Expand All @@ -25,6 +27,8 @@ namespace fs = FILESYSTEM_NAMESPACE;
class Storage : public std::enable_shared_from_this<Storage> {
public:
friend Entry;
using signal_t = boost::signals2::signal<void (const Entry&)>;

explicit Storage(const std::string& scheme);
Storage(const Storage&) = default;
Storage(Storage&&) = default;
Expand All @@ -35,17 +39,26 @@ class Storage : public std::enable_shared_from_this<Storage> {
const std::string& scheme() const;
virtual entry_ptr_t resolve(const std::string& url);

void on_create(signal_t::slot_type callback);
void on_delete(signal_t::slot_type callback);
void on_content_update(signal_t::slot_type callback);

protected:
virtual entry_ptr_t make(const std::string& url, const fs::file_status& status);
virtual entry_ptr_t create(const std::string& url, const fs::file_status& status);
virtual bool is_dir(const Entry& entry) const;
virtual bool exists(const Entry& entry) const;
fs::path split(const std::string& url) const;

private:
using entries_t = std::map<std::string, entry_ptr_t>;

entries_t entries_;
mutable std::mutex mutex_;
std::string scheme_;

signal_t on_create_;
signal_t on_delete_;
signal_t on_content_update_;
};

} // namespace filesystem
Expand Down
20 changes: 18 additions & 2 deletions src/filesystem/storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Storage::Storage(const std::string& scheme)
: entries_{}
, mutex_{}
, scheme_{ scheme }
, on_create_{}
, on_delete_{}
, on_content_update_{}
{}

Storage::~Storage()
Expand All @@ -35,12 +38,25 @@ entry_ptr_t Storage::resolve(const std::string& url) {
if (!fs::exists(status)) {
return nullptr;
}
auto entry = make(url, status);
auto entry = create(url, status);
entries_.insert(lb, entries_t::value_type{ url, entry });
on_create_(*entry);
return entry;
}

entry_ptr_t Storage::make(const std::string& url, const fs::file_status& status) {
void Storage::on_create(signal_t::slot_type callback) {
on_create_.connect(callback);
}

void Storage::on_delete(signal_t::slot_type callback) {
on_delete_.connect(callback);
}

void Storage::on_content_update(signal_t::slot_type callback) {
on_content_update_.connect(callback);
}

entry_ptr_t Storage::create(const std::string& url, const fs::file_status& status) {
return std::make_shared<Entry>(shared_from_this(), url, status, Entry::key{});
}

Expand Down
12 changes: 6 additions & 6 deletions test/filesystem/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ const fs::file_status STATUS;

TEST(EntryTest, same_url) {
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
ASSERT_EQ(entry->url(), URL);
}

TEST(EntryTest, is_dir) {
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
EXPECT_CALL(*storage, is_dir(testing::Ref(*entry))).WillOnce(testing::Return(false));
ASSERT_FALSE(entry->is_dir());
Expand All @@ -37,7 +37,7 @@ TEST(EntryTest, is_dir) {

TEST(EntryTest, exists) {
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
EXPECT_CALL(*storage, exists(testing::Ref(*entry))).WillOnce(testing::Return(false));
ASSERT_FALSE(entry->exists());
Expand All @@ -47,7 +47,7 @@ TEST(EntryTest, exists) {

TEST(EntryTest, shared_lock) {
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
EXPECT_CALL(*storage, exists(testing::Ref(*entry))).WillOnce(testing::Return(false));
ASSERT_THROW(entry->shared_lock(), filesystem_error);
Expand All @@ -57,7 +57,7 @@ TEST(EntryTest, shared_lock) {

TEST(EntryTest, unique_lock) {
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
EXPECT_CALL(*storage, exists(testing::Ref(*entry))).WillOnce(testing::Return(false));
ASSERT_THROW(entry->unique_lock(), filesystem_error);
Expand All @@ -67,7 +67,7 @@ TEST(EntryTest, unique_lock) {

TEST(EntryTest, invalidate) {
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
entry->invalidate();
EXPECT_CALL(*storage, exists(testing::Ref(*entry))).Times(0);
Expand Down
2 changes: 1 addition & 1 deletion test/filesystem/mock/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace kodama { namespace filesystem {
class MockStorage : public Storage {
public:
using Storage::Storage;
using Storage::make;
using Storage::create;

MOCK_METHOD1(resolve, entry_ptr_t (const std::string& url));
MOCK_CONST_METHOD1(is_dir, bool (const Entry& entry));
Expand Down
25 changes: 25 additions & 0 deletions test/filesystem/pattern/storage_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@ TEST_P(StoragePattern, resolve_valid_path_then_check_entry) {
ASSERT_TRUE(entry->exists());
}

TEST_P(StoragePattern, on_create_signal) {
auto storage = GetParam().storage();
auto path = GetParam().create_dir(DIRNAME);
std::string url, expected = storage->scheme() + path;
storage->on_create([&url](const Entry& entry) { url = entry.url(); });
ASSERT_NE(nullptr, storage->resolve(expected));
ASSERT_EQ(url, expected);
}

TEST_P(StoragePattern, on_delete_signal) {
auto storage = GetParam().storage();
auto path = GetParam().create_dir(DIRNAME);
std::string url, expected = storage->scheme() + path;
storage->on_delete([&url](const Entry& entry) { url = entry.url(); });
// TODO(Syl): delete entry from teh cache
}

TEST_P(StoragePattern, on_content_update_signal) {
auto storage = GetParam().storage();
auto path = GetParam().create_dir(DIRNAME);
std::string url, expected = storage->scheme() + path;
storage->on_content_update([&url](const Entry& entry) { url = entry.url(); });
// TODO(Syl): list directory content and update entry
}

TEST_P(StoragePattern, use_cache) {
auto storage = GetParam().storage();
auto path = GetParam().create_dir(DIRNAME);
Expand Down
4 changes: 2 additions & 2 deletions test/filesystem/url_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ TEST(UrlResolverTest, can_resolve_url) {
UrlResolver resolver;
entry_ptr_t result;
auto storage = std::make_shared<MockStorage>(SCHEME);
auto entry = storage->make(URL, STATUS);
auto entry = storage->create(URL, STATUS);
ASSERT_NE(entry, nullptr);
EXPECT_CALL(*storage, resolve(URL)).WillOnce(testing::Return(entry));
ASSERT_NO_THROW(resolver.add(storage));
Expand All @@ -62,7 +62,7 @@ TEST(UrlResolverTest, resolve_url_with_appropriate_storage) {
const std::string url = good_scheme + PATH;
auto good_storage = std::make_shared<MockStorage>(good_scheme);
auto bad_storage = std::make_shared<MockStorage>(bad_scheme);
auto entry = good_storage->make(good_scheme, STATUS);
auto entry = good_storage->create(good_scheme, STATUS);
ASSERT_NE(entry, nullptr);
EXPECT_CALL(*bad_storage, resolve(url)).WillOnce(testing::Return(nullptr));
EXPECT_CALL(*good_storage, resolve(url)).WillOnce(testing::Return(entry));
Expand Down

0 comments on commit 9474a21

Please sign in to comment.