Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions trview.app.tests/Filters/FilterStoreTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include <trview.app/Filters/FilterStore.h>
#include <trview.app/Mocks/Filters/IFilterable.h>
#include <trview.common/Mocks/IFiles.h>

using namespace trview;
using namespace trview::tests;
using namespace trview::mocks;
using namespace testing;

namespace
{
TEST(FilterStore, AddAndGet)
{
auto files = mock_shared<MockFiles>();
UserSettings settings;
FilterStore store(files, settings);

Filters::Filter filter{ .type_key = "Test" };
Filters::Filter filter2{ .type_key = "Test" };
Filters::Filter filter3{ .type_key = "Unrelated" };
store.add("Test filter 1", filter);
store.add("Test filter 2", filter2);
store.add("Test filter 1", filter3);

auto results = store.filters_for_key("Test");

ASSERT_EQ(results.size(), 2);

auto found1 = results.find("Test filter 1");
ASSERT_NE(found1, results.end());
ASSERT_EQ(found1->first, "Test filter 1");

auto found2 = results.find("Test filter 2");
ASSERT_NE(found2, results.end());
ASSERT_EQ(found2->first, "Test filter 2");

auto found3 = results.find("Test filter 1");
ASSERT_NE(found3, results.end());
ASSERT_EQ(found3->first, "Test filter 1");
}

TEST(FilterStore, LoadTypeKeys)
{
const std::vector<IFiles::Directory> directories
{
{.path = "Test", .friendly_name = "Test" },
{.path = "Test 2", .friendly_name = "Test 2" }
};

const std::vector<IFiles::File> test_files
{
{.path = "Test1_1" },
{.path = "Test1_2" }
};

const std::vector<IFiles::File> test2_files
{
{.path = "Test2_1" }
};

auto files = mock_shared<MockFiles>();
ON_CALL(*files, get_directories("dir")).WillByDefault(Return(directories));
ON_CALL(*files, get_files("Test", "\\*.json")).WillByDefault(Return(test_files));
ON_CALL(*files, get_files("Test 2", "\\*.json")).WillByDefault(Return(test2_files));
ON_CALL(*files, load_file("Test1_1")).WillByDefault(Return(std::string("{\"name\":\"Test filter 1\"}") | std::ranges::to<std::vector<uint8_t>>()));
ON_CALL(*files, load_file("Test1_2")).WillByDefault(Return(std::string("{\"name\":\"Test filter 2\"}") | std::ranges::to<std::vector<uint8_t>>()));
ON_CALL(*files, load_file("Test2_1")).WillByDefault(Return(std::string("{\"name\":\"Test filter 1\"}") | std::ranges::to<std::vector<uint8_t>>()));

UserSettings settings{ .filter_directory = "dir" };
FilterStore store(files, settings);

store.load();

auto results = store.filters_for_key("Test");
auto found1 = results.find("Test filter 1");
ASSERT_NE(found1, results.end());
ASSERT_EQ(found1->first, "Test filter 1");

auto found2 = results.find("Test filter 2");
ASSERT_NE(found2, results.end());
ASSERT_EQ(found2->first, "Test filter 2");

auto results2 = store.filters_for_key("Test 2");
auto found3 = results2.find("Test filter 1");
ASSERT_NE(found3, results2.end());
ASSERT_EQ(found3->first, "Test filter 1");
}

TEST(FilterStore, Remove)
{
UserSettings settings;
FilterStore store(mock_shared<MockFiles>(), settings);

Filters::Filter filter{ .type_key = "Test" };
store.add("Test filter 1", filter);

auto results = store.filters_for_key("Test");
auto found1 = results.find("Test filter 1");
ASSERT_NE(found1, results.end());
ASSERT_EQ(found1->first, "Test filter 1");

store.remove("Test", "Test filter 1");

results = store.filters_for_key("Test");
found1 = results.find("Test filter 1");
ASSERT_EQ(found1, results.end());
}

TEST(FilterStore, Save)
{
std::string filename;
std::string data;

auto files = mock_shared<MockFiles>();
EXPECT_CALL(*files, save_file(An<const std::string&>(), An<const std::string&>())).WillOnce(SaveArg<1>(&data));

UserSettings settings;
FilterStore store(files, settings);

Filters::Filter filter{ .type_key = "Test" };
store.add("Test filter 1", filter);

store.save();

std::string result = data;

ASSERT_EQ(result, "{\"filter\":{\"children\":[],\"compare\":\"Equal\",\"invert\":false,\"key\":\"\",\"op\":\"And\",\"type_key\":\"Test\",\"value\":\"\",\"value2\":\"\"},\"name\":\"Test filter 1\"}");
}
}
38 changes: 38 additions & 0 deletions trview.app.tests/Filters/FiltersTests.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <trview.app/Filters/Filters.h>
#include <trview.app/Mocks/Filters/IFilterable.h>

using namespace trview;
using namespace trview::tests;
Expand All @@ -12,6 +13,7 @@ namespace
std::string text;
std::vector<std::string> texts;
std::optional<float> option;
std::vector<std::weak_ptr<IFilterable>> filterables;

Object with_number(float value)
{
Expand Down Expand Up @@ -43,6 +45,12 @@ namespace
return *this;
}

Object with_filterables(const std::vector<std::weak_ptr<IFilterable>>& value)
{
filterables = value;
return *this;
}

int32_t filterable_index() const
{
return static_cast<int32_t>(number);
Expand Down Expand Up @@ -233,6 +241,36 @@ TEST(Filters, PresentFloat)
ASSERT_FALSE(filters.match(Object().with_numbers({ })));
}

TEST(Filters, PresentFilterable)
{
Filters filters;
filters.add_getters(Filters::GettersBuilder()
.with_multi_getter<Object, std::weak_ptr<IFilterable>>("value", [](auto&& o) { return o.filterables; })
.build());

Filters::Filter present_filterable = make_filter().key("value").compare_op(CompareOp::Exists);
filters.set_filters({ present_filterable });

auto filterable = mock_shared<mocks::MockFilterable>();
ASSERT_TRUE(filters.match(Object().with_filterables({ filterable })));
ASSERT_FALSE(filters.match(Object().with_filterables({ })));
}

TEST(Filters, NotPresentFilterable)
{
Filters filters;
filters.add_getters(Filters::GettersBuilder()
.with_multi_getter<Object, std::weak_ptr<IFilterable>>("value", [](auto&& o) { return o.filterables; })
.build());

Filters::Filter present_filterable = make_filter().key("value").compare_op(CompareOp::NotExists);
filters.set_filters({ present_filterable });

auto filterable = mock_shared<mocks::MockFilterable>();
ASSERT_FALSE(filters.match(Object().with_filterables({ filterable })));
ASSERT_TRUE(filters.match(Object().with_filterables({ })));
}

TEST(Filters, IsString)
{
Filters filters;
Expand Down
4 changes: 3 additions & 1 deletion trview.app.tests/RoomsWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <trview.app/Mocks/Elements/ITrigger.h>
#include <trview.common/Mocks/Windows/IClipboard.h>
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

using namespace trview;
using namespace trview::tests;
Expand All @@ -19,10 +20,11 @@ namespace
IMapRenderer::Source map_renderer_source{ [](auto&&...) { return mock_unique<MockMapRenderer>(); } };
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<RoomsWindow> build()
{
return std::make_unique<RoomsWindow>(map_renderer_source, clipboard, messaging);
return std::make_unique<RoomsWindow>(map_renderer_source, clipboard, filter_store, messaging);
}

test_module& with_map_renderer_source(IMapRenderer::Source map_renderer_source)
Expand Down
4 changes: 2 additions & 2 deletions trview.app.tests/Settings/SettingsLoaderTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace
{
const auto contents = to_bytes(setting);
auto files = mock_shared<MockFiles>();
EXPECT_CALL(*files, appdata_directory).Times(2).WillRepeatedly(Return("appdata"));
EXPECT_CALL(*files, appdata_directory).Times(3).WillRepeatedly(Return("appdata"));
EXPECT_CALL(*files, load_file("appdata\\trview\\settings.txt")).Times(1).WillRepeatedly(Return(contents));
EXPECT_CALL(*files, load_file("appdata\\trview\\randomizer.json")).Times(1).WillRepeatedly(Return(to_bytes(randomizer_settings)));
return register_test_module().with_files(files).build();
Expand All @@ -60,7 +60,7 @@ namespace
TEST(SettingsLoader, FileNotFound)
{
auto files = mock_shared<MockFiles>();
EXPECT_CALL(*files, appdata_directory).Times(1).WillRepeatedly(Return("appdata"));
EXPECT_CALL(*files, appdata_directory).Times(2).WillRepeatedly(Return("appdata"));
EXPECT_CALL(*files, load_file("appdata\\trview\\settings.txt")).Times(1);
auto loader = register_test_module().with_files(files).build();
auto settings = loader->load_user_settings();
Expand Down
1 change: 1 addition & 0 deletions trview.app.tests/trview.app.tests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<ClCompile Include="Elements\TypeInfoLookupTests.cpp" />
<ClCompile Include="Filters\FiltersTests.cpp" />
<ClCompile Include="CameraTests.cpp" />
<ClCompile Include="Filters\FilterStoreTests.cpp" />
<ClCompile Include="Graphics\LevelTextureStorageTests.cpp" />
<ClCompile Include="Graphics\MeshStorageTests.cpp" />
<ClCompile Include="Graphics\TextureStorage.cpp" />
Expand Down
1 change: 1 addition & 0 deletions trview.app.tests/trview.app.tests.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<ClCompile Include="Lua\Camera\Lua_CameraTests.cpp" Filter="Lua\Camera" />
<ClCompile Include="Sound\SoundStorageTests.cpp" Filter="Sound" />
<ClCompile Include="Elements\FlybyTests.cpp" Filter="Elements" />
<ClCompile Include="Filters\FilterStoreTests.cpp" Filter="Filters" />
</ItemGroup>
<ItemGroup>
<Filter Include="Input">
Expand Down
4 changes: 3 additions & 1 deletion trview.app.ui.tests/CameraSinkWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.app/Messages/Messages.h>
#include <trview.tests.common/Messages.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

using namespace testing;
using namespace trview;
Expand All @@ -27,10 +28,11 @@ namespace
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<ICamera> camera{ mock_shared<MockCamera>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<CameraSinkWindow> build()
{
return std::make_unique<CameraSinkWindow>(clipboard, camera, messaging);
return std::make_unique<CameraSinkWindow>(clipboard, camera, filter_store, messaging);
}

test_module& with_messaging(const std::shared_ptr<IMessageSystem>& messaging)
Expand Down
4 changes: 3 additions & 1 deletion trview.app.ui.tests/ItemsWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.tests.common/Messages.h>
#include <trview.app/Messages/Messages.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

#include <ranges>
#include <format>
Expand All @@ -26,10 +27,11 @@ namespace
{
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<ItemsWindow> build()
{
return std::make_unique<ItemsWindow>(clipboard, messaging);
return std::make_unique<ItemsWindow>(clipboard, filter_store, messaging);
}

test_module& with_clipboard(const std::shared_ptr<IClipboard>& clipboard)
Expand Down
4 changes: 3 additions & 1 deletion trview.app.ui.tests/LightsWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.tests.common/Messages.h>
#include <trview.app/Messages/Messages.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

using namespace testing;
using namespace trview;
Expand All @@ -21,10 +22,11 @@ namespace
{
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<LightsWindow> build()
{
return std::make_unique<LightsWindow>(clipboard, messaging);
return std::make_unique<LightsWindow>(clipboard, filter_store, messaging);
}

test_module& with_messaging(const std::shared_ptr<IMessageSystem>& messaging)
Expand Down
4 changes: 3 additions & 1 deletion trview.app.ui.tests/RoomsWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <trview.app/Mocks/Elements/ITrigger.h>
#include <trview.common/Mocks/Windows/IClipboard.h>
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

using namespace trview;
using namespace trview::tests;
Expand All @@ -21,10 +22,11 @@ namespace
IMapRenderer::Source map_renderer_source{ [](auto&&...) { return mock_unique<MockMapRenderer>(); } };
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<RoomsWindow> build()
{
return std::make_unique<RoomsWindow>(map_renderer_source, clipboard, messaging);
return std::make_unique<RoomsWindow>(map_renderer_source, clipboard, filter_store, messaging);
}

test_module& with_map_renderer_source(IMapRenderer::Source map_renderer_source)
Expand Down
4 changes: 3 additions & 1 deletion trview.app.ui.tests/StaticsWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.tests.common/Messages.h>
#include <trview.app/Messages/Messages.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

#include <format>
#include <ranges>
Expand All @@ -24,10 +25,11 @@ namespace
{
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<StaticsWindow> build()
{
return std::make_unique<StaticsWindow>(clipboard, messaging);
return std::make_unique<StaticsWindow>(clipboard, filter_store, messaging);
}

test_module& with_clipboard(const std::shared_ptr<IClipboard>& clipboard)
Expand Down
4 changes: 3 additions & 1 deletion trview.app.ui.tests/TriggersWindowTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <trview.common/Mocks/Messages/IMessageSystem.h>
#include <trview.tests.common/Messages.h>
#include <trview.app/Messages/Messages.h>
#include <trview.app/Mocks/Filters/IFilterStore.h>

using namespace trview;
using namespace trview::mocks;
Expand All @@ -25,10 +26,11 @@ namespace
{
std::shared_ptr<IClipboard> clipboard{ mock_shared<MockClipboard>() };
std::shared_ptr<IMessageSystem> messaging{ mock_shared<MockMessageSystem>() };
std::shared_ptr<IFilterStore> filter_store{ mock_shared<MockFilterStore>() };

std::unique_ptr<TriggersWindow> build()
{
return std::make_unique<TriggersWindow>(clipboard, messaging);
return std::make_unique<TriggersWindow>(clipboard, filter_store, messaging);
}

test_module& with_messaging(const std::shared_ptr<MockMessageSystem>& messaging)
Expand Down
Loading
Loading