src: replaced unit test framework CxxTest with Catch2
This commit is contained in:
Vendored
+2
@@ -1,6 +1,8 @@
|
||||
add_files(
|
||||
EXTERNAL
|
||||
|
||||
catch/catch.hpp
|
||||
|
||||
sqlite/CppSQLite3.cpp
|
||||
sqlite/CppSQLite3.h
|
||||
|
||||
|
||||
Vendored
+14361
File diff suppressed because it is too large
Load Diff
@@ -159,6 +159,11 @@ bool NodeType::operator==(const NodeType& o) const
|
||||
return m_type == o.m_type;
|
||||
}
|
||||
|
||||
bool NodeType::operator!=(const NodeType& o) const
|
||||
{
|
||||
return !operator==(o);
|
||||
}
|
||||
|
||||
bool NodeType::operator<(const NodeType& o) const
|
||||
{
|
||||
return m_type < o.m_type;
|
||||
|
||||
@@ -88,6 +88,7 @@ public:
|
||||
NodeType(Type type);
|
||||
|
||||
bool operator==(const NodeType& o) const;
|
||||
bool operator!=(const NodeType& o) const;
|
||||
bool operator<(const NodeType& o) const;
|
||||
|
||||
Type getType() const;
|
||||
|
||||
+37
-39
@@ -5,43 +5,41 @@ add_files(
|
||||
helper/TestFileRegister.h
|
||||
helper/TestIntermediateStorage.h
|
||||
|
||||
TestSuiteFixture.cpp
|
||||
TestSuiteFixture.h
|
||||
|
||||
CommandlineTestSuite.h
|
||||
ConfigManagerTestSuite.h
|
||||
CxxIncludeProcessingTestSuite.h
|
||||
CxxIndexSampleProjectsTestSuite.h
|
||||
CxxParserTestSuite.h
|
||||
CxxTypeNameTestSuite.h
|
||||
FileManagerTestSuite.h
|
||||
FilePathFilterTestSuite.h
|
||||
FilePathTestSuite.h
|
||||
FileSystemTestSuite.h
|
||||
GraphTestSuite.h
|
||||
LogManagerTestSuite.h
|
||||
LowMemoryStringMapTestSuite.h
|
||||
MatrixBaseTestSuite.h
|
||||
MessageQueueTestSuite.h
|
||||
NetworkProtocolHelperTestSuite.h
|
||||
RefreshInfoGeneratorTestSuite.h
|
||||
SearchIndexTestSuite.h
|
||||
SettingsMigratorTestSuite.h
|
||||
SettingsTestSuite.h
|
||||
SharedMemoryTestSuite.h
|
||||
SourceLocationCollectionTestSuite.h
|
||||
SqliteBookmarkStorageTestSuite.h
|
||||
SqliteIndexStorageTestSuite.h
|
||||
StorageTestSuite.h
|
||||
TaskSchedulerTestSuite.h
|
||||
TextAccessTestSuite.h
|
||||
UtilityMavenTestSuite.h
|
||||
UtilityStringTestSuite.h
|
||||
UtilityTestSuite.h
|
||||
Vector2TestSuite.h
|
||||
|
||||
# Java tests need to be executed last because of some linux related issues.
|
||||
JavaParserTestSuite.h
|
||||
JavaIndexSampleProjectsTestSuite.h
|
||||
SourceGroupTestSuite.h
|
||||
test_main.cpp
|
||||
|
||||
CommandlineTestSuite.cpp
|
||||
ConfigManagerTestSuite.cpp
|
||||
CxxIncludeProcessingTestSuite.cpp
|
||||
CxxIndexSampleProjectsTestSuite.cpp
|
||||
CxxParserTestSuite.cpp
|
||||
CxxTypeNameTestSuite.cpp
|
||||
FileManagerTestSuite.cpp
|
||||
FilePathFilterTestSuite.cpp
|
||||
FilePathTestSuite.cpp
|
||||
FileSystemTestSuite.cpp
|
||||
GraphTestSuite.cpp
|
||||
JavaIndexSampleProjectsTestSuite.cpp
|
||||
JavaParserTestSuite.cpp
|
||||
LogManagerTestSuite.cpp
|
||||
LowMemoryStringMapTestSuite.cpp
|
||||
MatrixBaseTestSuite.cpp
|
||||
MatrixDynamicBaseTestSuite.cpp
|
||||
MessageQueueTestSuite.cpp
|
||||
NetworkProtocolHelperTestSuite.cpp
|
||||
RefreshInfoGeneratorTestSuite.cpp
|
||||
SearchIndexTestSuite.cpp
|
||||
SettingsMigratorTestSuite.cpp
|
||||
SettingsTestSuite.cpp
|
||||
SharedMemoryTestSuite.cpp
|
||||
SourceGroupTestSuite.cpp
|
||||
SourceLocationCollectionTestSuite.cpp
|
||||
SqliteBookmarkStorageTestSuite.cpp
|
||||
SqliteIndexStorageTestSuite.cpp
|
||||
StorageTestSuite.cpp
|
||||
TaskSchedulerTestSuite.cpp
|
||||
TextAccessTestSuite.cpp
|
||||
UtilityMavenTestSuite.cpp
|
||||
UtilityStringTestSuite.cpp
|
||||
UtilityTestSuite.cpp
|
||||
Vector2TestSuite.cpp
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "CommandLineParser.h"
|
||||
#include "ApplicationSettings.h"
|
||||
@@ -7,21 +7,12 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
class CommandlineTestSuite: public CxxTest::TestSuite
|
||||
TEST_CASE("command line")
|
||||
{
|
||||
public:
|
||||
void setUp()
|
||||
{
|
||||
m_appSettingsPath = ApplicationSettings::getInstance()->getFilePath();
|
||||
ApplicationSettings::getInstance()->load(FilePath(L"data/CommandlineTestSuite/settings.xml"));
|
||||
}
|
||||
FilePath appSettingsPath = ApplicationSettings::getInstance()->getFilePath();
|
||||
ApplicationSettings::getInstance()->load(FilePath(L"data/CommandlineTestSuite/settings.xml"));
|
||||
|
||||
void tearDown()
|
||||
{
|
||||
ApplicationSettings::getInstance()->load(m_appSettingsPath);
|
||||
}
|
||||
|
||||
void test_commandline_version()
|
||||
SECTION("commandline version")
|
||||
{
|
||||
std::vector<std::string> args({"--version", "help"});
|
||||
|
||||
@@ -34,15 +25,15 @@ public:
|
||||
|
||||
std::cout.rdbuf( oldBuf );
|
||||
|
||||
TS_ASSERT_EQUALS(redStream.str(), "Sourcetrail Version 2016.1\n");
|
||||
REQUIRE(redStream.str() == "Sourcetrail Version 2016.1\n");
|
||||
}
|
||||
|
||||
void test_command_config_help()
|
||||
SECTION("command config help")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void test_command_config_filepathVector()
|
||||
SECTION("command config filepathVector")
|
||||
{
|
||||
std::vector<std::string> args(
|
||||
{
|
||||
@@ -60,12 +51,12 @@ public:
|
||||
parser.parse();
|
||||
|
||||
std::vector<FilePath> paths = ApplicationSettings::getInstance()->getHeaderSearchPaths();
|
||||
TS_ASSERT_EQUALS(paths[0].wstr(), L"/usr")
|
||||
TS_ASSERT_EQUALS(paths[1].wstr(), L"/usr/share/include")
|
||||
TS_ASSERT_EQUALS(paths[2].wstr(), L"/opt/test/include")
|
||||
REQUIRE(paths[0].wstr() == L"/usr");
|
||||
REQUIRE(paths[1].wstr() == L"/usr/share/include");
|
||||
REQUIRE(paths[2].wstr() == L"/opt/test/include");
|
||||
}
|
||||
|
||||
void test_command_config_string_filepath_option()
|
||||
SECTION("command config string filepath option")
|
||||
{
|
||||
std::vector<std::string> args(
|
||||
{
|
||||
@@ -84,11 +75,11 @@ public:
|
||||
std::cout.rdbuf( oldBuf );
|
||||
|
||||
FilePath path = ApplicationSettings::getInstance()->getMavenPath();
|
||||
TS_ASSERT_EQUALS( path.wstr(), L"/opt/testpath/mvn")
|
||||
REQUIRE( path.wstr() == L"/opt/testpath/mvn");
|
||||
|
||||
}
|
||||
|
||||
void test_command_config_filepathVector_comma_separated()
|
||||
SECTION("command config filepathVector comma separated")
|
||||
{
|
||||
std::vector<std::string> args(
|
||||
{
|
||||
@@ -102,14 +93,14 @@ public:
|
||||
parser.parse();
|
||||
|
||||
std::vector<FilePath> paths = ApplicationSettings::getInstance()->getHeaderSearchPaths();
|
||||
TS_ASSERT_EQUALS( paths[0].wstr(), L"/usr")
|
||||
TS_ASSERT_EQUALS( paths[1].wstr(), L"/usr/include")
|
||||
TS_ASSERT_EQUALS( paths[2].wstr(), L"/include")
|
||||
TS_ASSERT_EQUALS( paths[3].wstr(), L"/opt/include")
|
||||
REQUIRE( paths[0].wstr() == L"/usr");
|
||||
REQUIRE( paths[1].wstr() == L"/usr/include");
|
||||
REQUIRE( paths[2].wstr() == L"/include");
|
||||
REQUIRE( paths[3].wstr() == L"/opt/include");
|
||||
|
||||
}
|
||||
|
||||
void test_command_config_bool_options()
|
||||
SECTION("command config bool options")
|
||||
{
|
||||
std::vector<std::string> args(
|
||||
{
|
||||
@@ -123,7 +114,7 @@ public:
|
||||
parser.parse();
|
||||
|
||||
bool processes = ApplicationSettings::getInstance()->getMultiProcessIndexingEnabled();
|
||||
TS_ASSERT_EQUALS( processes, 0);
|
||||
REQUIRE( processes == 0);
|
||||
|
||||
std::vector<std::string> args1(
|
||||
{
|
||||
@@ -136,9 +127,8 @@ public:
|
||||
parser.parse();
|
||||
|
||||
processes = ApplicationSettings::getInstance()->getMultiProcessIndexingEnabled();
|
||||
TS_ASSERT_EQUALS( processes, 1);
|
||||
REQUIRE( processes == 1);
|
||||
}
|
||||
|
||||
private:
|
||||
FilePath m_appSettingsPath;
|
||||
};
|
||||
ApplicationSettings::getInstance()->load(appSettingsPath);
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "TextAccess.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::shared_ptr<TextAccess> getConfigTextAccess()
|
||||
{
|
||||
std::string text =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <path>\n"
|
||||
" <to>\n"
|
||||
" <bool_that_is_false>0</bool_that_is_false>\n"
|
||||
" <bool_that_is_true>1</bool_that_is_true>\n"
|
||||
" <single_value>42</single_value>\n"
|
||||
" </to>\n"
|
||||
" </path>\n"
|
||||
" <paths>\n"
|
||||
" <nopath>4</nopath>\n"
|
||||
" <path>2</path>\n"
|
||||
" <path>5</path>\n"
|
||||
" <path>8</path>\n"
|
||||
" </paths>\n"
|
||||
"</config>\n";
|
||||
return TextAccess::createFromString(text);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("config manager returns true when key is found")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success = config->getValue("path/to/single_value", value);
|
||||
|
||||
REQUIRE(success);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("config manager returns false when key is not found")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success = config->getValue("path/to/nowhere", value);
|
||||
|
||||
REQUIRE(!success);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("config manager returns correct string for key")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
std::wstring value;
|
||||
config->getValue("path/to/single_value", value);
|
||||
|
||||
REQUIRE(L"42" == value);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("config manager returns correct float for key")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
config->getValue("path/to/single_value", value);
|
||||
|
||||
REQUIRE(value == Approx(42.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("config manager returns correct bool for key if value is true")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success(config->getValue("path/to/bool_that_is_true", value));
|
||||
|
||||
REQUIRE(success);
|
||||
REQUIRE(value);
|
||||
}
|
||||
|
||||
TEST_CASE("config manager returns correct bool for key if value is false")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success(config->getValue("path/to/bool_that_is_false", value));
|
||||
|
||||
REQUIRE(success);
|
||||
REQUIRE(!value);
|
||||
}
|
||||
|
||||
TEST_CASE("config manager adds new key when empty")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createEmpty();
|
||||
|
||||
config->setValue("path/to/true_bool", true);
|
||||
|
||||
bool value = false;
|
||||
bool success(config->getValue("path/to/true_bool", value));
|
||||
|
||||
REQUIRE(success);
|
||||
REQUIRE(value);
|
||||
}
|
||||
|
||||
TEST_CASE("config manager adds new key when not empty")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
config->setValue("path/to/true_bool", true);
|
||||
|
||||
bool value = false;
|
||||
bool success(config->getValue("path/to/true_bool", value));
|
||||
|
||||
REQUIRE(success);
|
||||
REQUIRE(value);
|
||||
}
|
||||
|
||||
TEST_CASE("config manager returns correct list for key")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
std::vector<int> values;
|
||||
|
||||
bool success(config->getValues("paths/path", values));
|
||||
|
||||
REQUIRE(success);
|
||||
REQUIRE(values.size() == 3);
|
||||
REQUIRE(values[0] == 2);
|
||||
REQUIRE(values[1] == 5);
|
||||
REQUIRE(values[2] == 8);
|
||||
}
|
||||
|
||||
TEST_CASE("config manager save and load configuration and compare")
|
||||
{
|
||||
const FilePath path(L"data/ConfigManagerTestSuite/temp.xml");
|
||||
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
config->save(path.str());
|
||||
std::shared_ptr<ConfigManager> config2 = ConfigManager::createAndLoad(TextAccess::createFromFile(path));
|
||||
REQUIRE(config->toString() == config2->toString());
|
||||
}
|
||||
|
||||
TEST_CASE("config manager loads special character")
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(
|
||||
TextAccess::createFromFile(FilePath(L"data/ConfigManagerTestSuite/test_data.xml"))
|
||||
);
|
||||
std::wstring loadedSpecialCharacter;
|
||||
config->getValue("path/to/special_character", loadedSpecialCharacter);
|
||||
|
||||
REQUIRE(loadedSpecialCharacter.size() == 1);
|
||||
REQUIRE(loadedSpecialCharacter[0] == wchar_t(252));; // special character needs to be encoded as ASCII code because
|
||||
// otherwise python and cxx compiler may be complaining
|
||||
}
|
||||
|
||||
TEST_CASE("config manager save and load special character and compare")
|
||||
{
|
||||
const FilePath path(L"data/ConfigManagerTestSuite/temp.xml");
|
||||
std::wstring specialCharacter;
|
||||
specialCharacter.push_back(wchar_t(252));
|
||||
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createEmpty();
|
||||
config->setValue("path/to/special_character", specialCharacter);
|
||||
config->save(path.str());
|
||||
|
||||
std::shared_ptr<ConfigManager> config2 = ConfigManager::createAndLoad(TextAccess::createFromFile(path));
|
||||
REQUIRE(config->toString() == config2->toString());
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "TextAccess.h"
|
||||
|
||||
class ConfigManagerTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_config_manager_returns_true_when_key_is_found()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success = config->getValue("path/to/single_value", value);
|
||||
|
||||
TS_ASSERT(success);
|
||||
}
|
||||
|
||||
|
||||
void test_config_manager_returns_false_when_key_is_not_found()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success = config->getValue("path/to/nowhere", value);
|
||||
|
||||
TS_ASSERT(!success);
|
||||
}
|
||||
|
||||
|
||||
void test_config_manager_returns_correct_string_for_key()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
std::wstring value;
|
||||
config->getValue("path/to/single_value", value);
|
||||
|
||||
TS_ASSERT_EQUALS(L"42", value);
|
||||
}
|
||||
|
||||
|
||||
void test_config_manager_returns_correct_float_for_key()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
config->getValue("path/to/single_value", value);
|
||||
|
||||
TS_ASSERT_DELTA(42.0f, value, 0.0001f);
|
||||
}
|
||||
|
||||
void test_config_manager_returns_correct_bool_for_key_if_value_is_true()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success(config->getValue("path/to/bool_that_is_true", value));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT(value);
|
||||
}
|
||||
|
||||
void test_config_manager_returns_correct_bool_for_key_if_value_is_false()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
float value;
|
||||
bool success(config->getValue("path/to/bool_that_is_false", value));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT(!value);
|
||||
}
|
||||
|
||||
void test_config_manager_adds_new_key_when_empty()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createEmpty();
|
||||
|
||||
config->setValue("path/to/true_bool", true);
|
||||
|
||||
bool value = false;
|
||||
bool success(config->getValue("path/to/true_bool", value));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT(value);
|
||||
}
|
||||
|
||||
void test_config_manager_adds_new_key_when_not_empty()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
config->setValue("path/to/true_bool", true);
|
||||
|
||||
bool value = false;
|
||||
bool success(config->getValue("path/to/true_bool", value));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT(value);
|
||||
}
|
||||
|
||||
void test_config_manager_returns_correct_list_for_key()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
std::vector<int> values;
|
||||
|
||||
bool success(config->getValues("paths/path", values));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT_EQUALS(values.size(), 3);
|
||||
TS_ASSERT_EQUALS(values[0], 2);
|
||||
TS_ASSERT_EQUALS(values[1], 5);
|
||||
TS_ASSERT_EQUALS(values[2], 8);
|
||||
}
|
||||
|
||||
void test_config_manager_save_and_load_configuration_and_compare()
|
||||
{
|
||||
const FilePath path(L"data/ConfigManagerTestSuite/temp.xml");
|
||||
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
config->save(path.str());
|
||||
std::shared_ptr<ConfigManager> config2 = ConfigManager::createAndLoad(TextAccess::createFromFile(path));
|
||||
TS_ASSERT_EQUALS(config->toString(), config2->toString());
|
||||
}
|
||||
|
||||
void test_config_manager_loads_special_character()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(
|
||||
TextAccess::createFromFile(FilePath(L"data/ConfigManagerTestSuite/test_data.xml"))
|
||||
);
|
||||
std::wstring loadedSpecialCharacter;
|
||||
config->getValue("path/to/special_character", loadedSpecialCharacter);
|
||||
|
||||
TS_ASSERT_EQUALS(loadedSpecialCharacter.size(), 1);
|
||||
TS_ASSERT_EQUALS(loadedSpecialCharacter[0], wchar_t(252)); // special character needs to be encoded as ASCII code because
|
||||
// otherwise python and cxx compiler may be complaining
|
||||
}
|
||||
|
||||
void test_config_manager_save_and_load_special_character_and_compare()
|
||||
{
|
||||
const FilePath path(L"data/ConfigManagerTestSuite/temp.xml");
|
||||
std::wstring specialCharacter;
|
||||
specialCharacter.push_back(wchar_t(252));
|
||||
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createEmpty();
|
||||
config->setValue("path/to/special_character", specialCharacter);
|
||||
config->save(path.str());
|
||||
|
||||
std::shared_ptr<ConfigManager> config2 = ConfigManager::createAndLoad(TextAccess::createFromFile(path));
|
||||
TS_ASSERT_EQUALS(config->toString(), config2->toString());
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<TextAccess> getConfigTextAccess()
|
||||
{
|
||||
std::string text =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <path>\n"
|
||||
" <to>\n"
|
||||
" <bool_that_is_false>0</bool_that_is_false>\n"
|
||||
" <bool_that_is_true>1</bool_that_is_true>\n"
|
||||
" <single_value>42</single_value>\n"
|
||||
" </to>\n"
|
||||
" </path>\n"
|
||||
" <paths>\n"
|
||||
" <nopath>4</nopath>\n"
|
||||
" <path>2</path>\n"
|
||||
" <path>5</path>\n"
|
||||
" <path>8</path>\n"
|
||||
" </paths>\n"
|
||||
"</config>\n";
|
||||
return TextAccess::createFromString(text);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,145 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "TextAccess.h"
|
||||
#include "IncludeDirective.h"
|
||||
#include "IncludeProcessing.h"
|
||||
#include "utility.h"
|
||||
|
||||
TEST_CASE("include detection finds include with quotes")
|
||||
{
|
||||
std::vector<IncludeDirective> includeDirectives = IncludeProcessing::getIncludeDirectives(TextAccess::createFromString(
|
||||
"#include \"foo.h\"",
|
||||
FilePath(L"foo.cpp")
|
||||
));
|
||||
|
||||
REQUIRE(!includeDirectives.empty());
|
||||
|
||||
if (!includeDirectives.empty())
|
||||
{
|
||||
REQUIRE(L"foo.h" == includeDirectives.front().getIncludedFile().wstr());
|
||||
REQUIRE(L"foo.cpp" == includeDirectives.front().getIncludingFile().wstr());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("include detection finds include with angle brackets")
|
||||
{
|
||||
std::vector<IncludeDirective> includeDirectives = IncludeProcessing::getIncludeDirectives(TextAccess::createFromString(
|
||||
"#include <foo.h>",
|
||||
FilePath(L"foo.cpp")
|
||||
));
|
||||
|
||||
REQUIRE(!includeDirectives.empty());
|
||||
|
||||
if (!includeDirectives.empty())
|
||||
{
|
||||
REQUIRE(L"foo.h" == includeDirectives.front().getIncludedFile().wstr());
|
||||
REQUIRE(L"foo.cpp" == includeDirectives.front().getIncludingFile().wstr());
|
||||
}
|
||||
}
|
||||
TEST_CASE("include detection finds include with quotes and space before keyword")
|
||||
{
|
||||
std::vector<IncludeDirective> includeDirectives = IncludeProcessing::getIncludeDirectives(TextAccess::createFromString(
|
||||
"# include \"foo.h\"",
|
||||
FilePath(L"foo.cpp")
|
||||
));
|
||||
|
||||
REQUIRE(!includeDirectives.empty());
|
||||
|
||||
if (!includeDirectives.empty())
|
||||
{
|
||||
REQUIRE(L"foo.h" == includeDirectives.front().getIncludedFile().wstr());
|
||||
REQUIRE(L"foo.cpp" == includeDirectives.front().getIncludingFile().wstr());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("include detection does not find include in empty file")
|
||||
{
|
||||
REQUIRE(IncludeProcessing::getIncludeDirectives(TextAccess::createFromString("")).empty());
|
||||
}
|
||||
|
||||
TEST_CASE("include detection does not find include in file without preprocessor directive")
|
||||
{
|
||||
REQUIRE(IncludeProcessing::getIncludeDirectives(TextAccess::createFromString("foo")).empty());
|
||||
}
|
||||
|
||||
TEST_CASE("include detection does not find include in file without include preprocessor directive")
|
||||
{
|
||||
REQUIRE(IncludeProcessing::getIncludeDirectives(TextAccess::createFromString("#ifdef xx\n#endif")).empty());
|
||||
}
|
||||
|
||||
TEST_CASE("header search path detection does not find path relative to including file")
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_does_not_find_path_relative_to_including_file/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_does_not_find_path_relative_to_including_file") },
|
||||
{ },
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
REQUIRE(headerSearchDirectories.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("header search path detection finds path inside sub directory")
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_inside_sub_directory/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_inside_sub_directory") },
|
||||
{},
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_inside_sub_directory/include").makeAbsolute()
|
||||
));
|
||||
}
|
||||
|
||||
TEST_CASE("header search path detection finds path relative to sub directory")
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_relative_to_sub_directory/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_relative_to_sub_directory") },
|
||||
{},
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_relative_to_sub_directory/include").makeAbsolute()
|
||||
));
|
||||
}
|
||||
|
||||
TEST_CASE("header search path detection finds path included in header search path")
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/include_b") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/include_a") },
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/include_b").makeAbsolute()
|
||||
));
|
||||
}
|
||||
|
||||
TEST_CASE("header search path detection finds path included in future header search path")
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path") },
|
||||
{ },
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path/include_a").makeAbsolute()
|
||||
));
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path/include_b").makeAbsolute()
|
||||
));
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "TextAccess.h"
|
||||
#include "IncludeDirective.h"
|
||||
#include "IncludeProcessing.h"
|
||||
#include "utility.h"
|
||||
|
||||
class CxxIncludeProcessingTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_include_detection_finds_include_with_quotes()
|
||||
{
|
||||
std::vector<IncludeDirective> includeDirectives = IncludeProcessing::getIncludeDirectives(TextAccess::createFromString(
|
||||
"#include \"foo.h\"",
|
||||
FilePath(L"foo.cpp")
|
||||
));
|
||||
|
||||
TS_ASSERT(!includeDirectives.empty());
|
||||
|
||||
if (!includeDirectives.empty())
|
||||
{
|
||||
TS_ASSERT_EQUALS(L"foo.h", includeDirectives.front().getIncludedFile().wstr());
|
||||
TS_ASSERT_EQUALS(L"foo.cpp", includeDirectives.front().getIncludingFile().wstr());
|
||||
}
|
||||
}
|
||||
|
||||
void test_include_detection_finds_include_with_angle_brackets()
|
||||
{
|
||||
std::vector<IncludeDirective> includeDirectives = IncludeProcessing::getIncludeDirectives(TextAccess::createFromString(
|
||||
"#include <foo.h>",
|
||||
FilePath(L"foo.cpp")
|
||||
));
|
||||
|
||||
TS_ASSERT(!includeDirectives.empty());
|
||||
|
||||
if (!includeDirectives.empty())
|
||||
{
|
||||
TS_ASSERT_EQUALS(L"foo.h", includeDirectives.front().getIncludedFile().wstr());
|
||||
TS_ASSERT_EQUALS(L"foo.cpp", includeDirectives.front().getIncludingFile().wstr());
|
||||
}
|
||||
}
|
||||
void test_include_detection_finds_include_with_quotes_and_space_before_keyword()
|
||||
{
|
||||
std::vector<IncludeDirective> includeDirectives = IncludeProcessing::getIncludeDirectives(TextAccess::createFromString(
|
||||
"# include \"foo.h\"",
|
||||
FilePath(L"foo.cpp")
|
||||
));
|
||||
|
||||
TS_ASSERT(!includeDirectives.empty());
|
||||
|
||||
if (!includeDirectives.empty())
|
||||
{
|
||||
TS_ASSERT_EQUALS(L"foo.h", includeDirectives.front().getIncludedFile().wstr());
|
||||
TS_ASSERT_EQUALS(L"foo.cpp", includeDirectives.front().getIncludingFile().wstr());
|
||||
}
|
||||
}
|
||||
|
||||
void test_include_detection_does_not_find_include_in_empty_file()
|
||||
{
|
||||
TS_ASSERT(IncludeProcessing::getIncludeDirectives(TextAccess::createFromString("")).empty());
|
||||
}
|
||||
|
||||
void test_include_detection_does_not_find_include_in_file_without_preprocessor_directive()
|
||||
{
|
||||
TS_ASSERT(IncludeProcessing::getIncludeDirectives(TextAccess::createFromString("foo")).empty());
|
||||
}
|
||||
|
||||
void test_include_detection_does_not_find_include_in_file_without_include_preprocessor_directive()
|
||||
{
|
||||
TS_ASSERT(IncludeProcessing::getIncludeDirectives(TextAccess::createFromString("#ifdef xx\n#endif")).empty());
|
||||
}
|
||||
|
||||
void test_header_search_path_detection_does_not_find_path_relative_to_including_file()
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_does_not_find_path_relative_to_including_file/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_does_not_find_path_relative_to_including_file") },
|
||||
{ },
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
TS_ASSERT(headerSearchDirectories.empty());
|
||||
}
|
||||
|
||||
void test_header_search_path_detection_finds_path_inside_sub_directory()
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_inside_sub_directory/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_inside_sub_directory") },
|
||||
{},
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_inside_sub_directory/include").makeAbsolute()
|
||||
));
|
||||
}
|
||||
|
||||
void test_header_search_path_detection_finds_path_relative_to_sub_directory()
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_relative_to_sub_directory/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_relative_to_sub_directory") },
|
||||
{},
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_relative_to_sub_directory/include").makeAbsolute()
|
||||
));
|
||||
}
|
||||
|
||||
void test_header_search_path_detection_finds_path_included_in_header_search_path()
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/include_b") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/include_a") },
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_header_search_path/include_b").makeAbsolute()
|
||||
));
|
||||
}
|
||||
|
||||
void test_header_search_path_detection_finds_path_included_in_future_header_search_path()
|
||||
{
|
||||
std::vector<FilePath> headerSearchDirectories = utility::toVector(IncludeProcessing::getHeaderSearchDirectories(
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path/a.cpp") },
|
||||
{ FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path") },
|
||||
{ },
|
||||
1, [](float) {}
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path/include_a").makeAbsolute()
|
||||
));
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
headerSearchDirectories,
|
||||
FilePath(L"data/CxxIncludeProcessingTestSuite/test_header_search_path_detection_finds_path_included_in_future_header_search_path/include_b").makeAbsolute()
|
||||
));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,221 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "ApplicationSettings.h"
|
||||
#include "CxxParser.h"
|
||||
#include "FileRegister.h"
|
||||
#include "IndexerCommandCxx.h"
|
||||
#include "IndexerStateInfo.h"
|
||||
#include "ParserClientImpl.h"
|
||||
#include "TestIntermediateStorage.h"
|
||||
#include "TextAccess.h"
|
||||
#include "TimeStamp.h"
|
||||
#include "utility.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
#define REQUIRE_MESSAGE(msg, cond) do { INFO(msg); REQUIRE(cond); } while((void)0, 0)
|
||||
|
||||
namespace
|
||||
{
|
||||
const bool updateExpectedOutput = false;
|
||||
const bool trackTime = true;
|
||||
size_t duration;
|
||||
|
||||
std::shared_ptr<TextAccess> parseCode(const FilePath& sourceFilePath, const FilePath& projectDataSrcRoot)
|
||||
{
|
||||
const std::set<FilePath> indexedPaths = { projectDataSrcRoot.getCanonical() };
|
||||
const std::set<FilePathFilter> excludedFilters = {};
|
||||
const std::set<FilePathFilter> includedFilters = {};
|
||||
const FilePath workingDirectory(L".");
|
||||
|
||||
std::vector<std::wstring> compilerFlags;
|
||||
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(
|
||||
utility::concat(std::vector<FilePath> { projectDataSrcRoot }, ApplicationSettings::getInstance()->getHeaderSearchPathsExpanded())
|
||||
));
|
||||
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForFrameworkSearchPaths(
|
||||
ApplicationSettings::getInstance()->getFrameworkSearchPathsExpanded()
|
||||
));
|
||||
#ifdef _WIN32
|
||||
// compilerFlags.emplace_back(L"--target=x86_64-pc-windows-msvc");
|
||||
#else // _WIN32
|
||||
compilerFlags.emplace_back(L"-xc++");
|
||||
#endif // _WIN32
|
||||
compilerFlags.emplace_back(L"-std=c++1z");
|
||||
compilerFlags.emplace_back(sourceFilePath.wstr());
|
||||
|
||||
std::shared_ptr<FileRegister> fileRegister = std::make_shared<FileRegister>(
|
||||
sourceFilePath,
|
||||
indexedPaths,
|
||||
excludedFilters
|
||||
);
|
||||
|
||||
TestIntermediateStorage storage;
|
||||
CxxParser parser(std::make_shared<ParserClientImpl>(&storage), fileRegister, std::make_shared<IndexerStateInfo>());
|
||||
|
||||
std::shared_ptr<IndexerCommandCxx> command = std::make_shared<IndexerCommandCxx>(
|
||||
sourceFilePath,
|
||||
indexedPaths,
|
||||
excludedFilters,
|
||||
includedFilters,
|
||||
workingDirectory,
|
||||
compilerFlags
|
||||
);
|
||||
|
||||
TimeStamp startTime = TimeStamp::now();
|
||||
parser.buildIndex(command);
|
||||
duration += TimeStamp::now().deltaMS(startTime);
|
||||
|
||||
storage.generateStringLists();
|
||||
|
||||
return TextAccess::createFromLines(storage.m_lines);
|
||||
}
|
||||
|
||||
void processSourceFile(const std::wstring& projectName, const FilePath& sourceFilePath)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath(L"data/CxxIndexSampleProjectsTestSuite/" + projectName).makeAbsolute();
|
||||
const FilePath projectDataSrcRoot = projectDataRoot.getConcatenated(L"src");
|
||||
const FilePath projectDataExpectedOutputRoot = projectDataRoot.getConcatenated(L"expected_output");
|
||||
|
||||
std::shared_ptr<TextAccess> output = parseCode(projectDataSrcRoot.getConcatenated(sourceFilePath), projectDataSrcRoot);
|
||||
|
||||
FilePath expectedOutputFilePath = projectDataExpectedOutputRoot.getConcatenated(utility::replace(sourceFilePath.withoutExtension().wstr() + L".txt", L"/", L"_"));
|
||||
if (updateExpectedOutput || !expectedOutputFilePath.exists())
|
||||
{
|
||||
std::ofstream expectedOutputFile;
|
||||
expectedOutputFile.open(expectedOutputFilePath.str());
|
||||
expectedOutputFile << output->getText();
|
||||
expectedOutputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<TextAccess> expectedOutput = TextAccess::createFromFile(expectedOutputFilePath);
|
||||
REQUIRE_MESSAGE(("Output does not match the expected line count for file " + sourceFilePath.str() + " in project " + utility::encodeToUtf8(projectName)).c_str(), expectedOutput->getLineCount() == output->getLineCount());
|
||||
if (expectedOutput->getLineCount() == output->getLineCount())
|
||||
{
|
||||
for (size_t i = 1; i <= expectedOutput->getLineCount(); i++)
|
||||
{
|
||||
REQUIRE(expectedOutput->getLine(i) == output->getLine(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processSourceFiles(const std::wstring& projectName, const std::vector<FilePath>& sourceFilePaths)
|
||||
{
|
||||
duration = 0;
|
||||
for (const FilePath& filePath : sourceFilePaths)
|
||||
{
|
||||
processSourceFile(projectName, filePath);
|
||||
}
|
||||
if (trackTime)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath(L"data/CxxIndexSampleProjectsTestSuite/" + projectName).makeAbsolute();
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open(FilePath(projectDataRoot.wstr() + L"/" + projectName + L".timing").str(), std::ios_base::app);
|
||||
outfile << TimeStamp::now().toString() << " - " << duration << " ms\n";
|
||||
outfile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("index tictactoe project")
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
processSourceFiles(
|
||||
L"TicTacToe",
|
||||
{
|
||||
FilePath("artificial_player.cpp"),
|
||||
FilePath("field.cpp"),
|
||||
FilePath("player.cpp"),
|
||||
FilePath("tictactoe.cpp"),
|
||||
FilePath("human_player.cpp"),
|
||||
FilePath("main.cpp"),
|
||||
}
|
||||
);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
TEST_CASE("index box2d project")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifdef NDEBUG
|
||||
processSourceFiles(
|
||||
L"Box2D",
|
||||
{
|
||||
FilePath("Box2D/Collision/b2BroadPhase.cpp"),
|
||||
FilePath("Box2D/Collision/b2CollideCircle.cpp"),
|
||||
FilePath("Box2D/Collision/b2CollideEdge.cpp"),
|
||||
FilePath("Box2D/Collision/b2CollidePolygon.cpp"),
|
||||
FilePath("Box2D/Collision/b2Collision.cpp"),
|
||||
FilePath("Box2D/Collision/b2Distance.cpp"),
|
||||
FilePath("Box2D/Collision/b2DynamicTree.cpp"),
|
||||
FilePath("Box2D/Collision/b2TimeOfImpact.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2ChainShape.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2CircleShape.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2EdgeShape.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2PolygonShape.cpp"),
|
||||
FilePath("Box2D/Common/b2BlockAllocator.cpp"),
|
||||
FilePath("Box2D/Common/b2Draw.cpp"),
|
||||
FilePath("Box2D/Common/b2Math.cpp"),
|
||||
FilePath("Box2D/Common/b2Settings.cpp"),
|
||||
FilePath("Box2D/Common/b2StackAllocator.cpp"),
|
||||
FilePath("Box2D/Common/b2Timer.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2Body.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2ContactManager.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2Fixture.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2Island.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2World.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2WorldCallbacks.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2CircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2Contact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2ContactSolver.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2PolygonContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2DistanceJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2FrictionJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2GearJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2Joint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2MotorJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2MouseJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2PrismaticJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2PulleyJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2RevoluteJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2RopeJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2WeldJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2WheelJoint.cpp"),
|
||||
FilePath("Box2D/Rope/b2Rope.cpp")
|
||||
}
|
||||
);
|
||||
#endif // NDEBUG
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
TEST_CASE("index bullet3 project")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifdef NDEBUG
|
||||
processSourceFiles(
|
||||
L"Bullet3",
|
||||
{
|
||||
FilePath("Bullet3Collision/BroadPhaseCollision/b3DynamicBvh.cpp"),
|
||||
FilePath("Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.cpp"),
|
||||
FilePath("Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.cpp"),
|
||||
FilePath("Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.cpp"),
|
||||
FilePath("Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp"),
|
||||
FilePath("Bullet3Common/b3AlignedAllocator.cpp"),
|
||||
FilePath("Bullet3Common/b3Logging.cpp"),
|
||||
FilePath("Bullet3Common/b3Vector3.cpp"),
|
||||
FilePath("Bullet3Geometry/b3ConvexHullComputer.cpp"),
|
||||
FilePath("Bullet3Geometry/b3GeometryUtil.cpp")
|
||||
}
|
||||
);
|
||||
#endif // NDEBUG
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "ApplicationSettings.h"
|
||||
#include "CxxParser.h"
|
||||
#include "FileRegister.h"
|
||||
#include "IndexerCommandCxx.h"
|
||||
#include "IndexerStateInfo.h"
|
||||
#include "ParserClientImpl.h"
|
||||
#include "TestIntermediateStorage.h"
|
||||
#include "TextAccess.h"
|
||||
#include "TimeStamp.h"
|
||||
#include "utility.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
class CxxIndexSampleProjectsTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
static const bool s_updateExpectedOutput = false;
|
||||
static const bool s_trackTime = true;
|
||||
|
||||
void test_index_tictactoe_project()
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
processSourceFiles(
|
||||
L"TicTacToe",
|
||||
{
|
||||
FilePath("artificial_player.cpp"),
|
||||
FilePath("field.cpp"),
|
||||
FilePath("player.cpp"),
|
||||
FilePath("tictactoe.cpp"),
|
||||
FilePath("human_player.cpp"),
|
||||
FilePath("main.cpp"),
|
||||
}
|
||||
);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
void test_index_box2d_project()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifdef NDEBUG
|
||||
processSourceFiles(
|
||||
L"Box2D",
|
||||
{
|
||||
FilePath("Box2D/Collision/b2BroadPhase.cpp"),
|
||||
FilePath("Box2D/Collision/b2CollideCircle.cpp"),
|
||||
FilePath("Box2D/Collision/b2CollideEdge.cpp"),
|
||||
FilePath("Box2D/Collision/b2CollidePolygon.cpp"),
|
||||
FilePath("Box2D/Collision/b2Collision.cpp"),
|
||||
FilePath("Box2D/Collision/b2Distance.cpp"),
|
||||
FilePath("Box2D/Collision/b2DynamicTree.cpp"),
|
||||
FilePath("Box2D/Collision/b2TimeOfImpact.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2ChainShape.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2CircleShape.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2EdgeShape.cpp"),
|
||||
FilePath("Box2D/Collision/Shapes/b2PolygonShape.cpp"),
|
||||
FilePath("Box2D/Common/b2BlockAllocator.cpp"),
|
||||
FilePath("Box2D/Common/b2Draw.cpp"),
|
||||
FilePath("Box2D/Common/b2Math.cpp"),
|
||||
FilePath("Box2D/Common/b2Settings.cpp"),
|
||||
FilePath("Box2D/Common/b2StackAllocator.cpp"),
|
||||
FilePath("Box2D/Common/b2Timer.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2Body.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2ContactManager.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2Fixture.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2Island.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2World.cpp"),
|
||||
FilePath("Box2D/Dynamics/b2WorldCallbacks.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2CircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2Contact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2ContactSolver.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Contacts/b2PolygonContact.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2DistanceJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2FrictionJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2GearJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2Joint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2MotorJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2MouseJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2PrismaticJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2PulleyJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2RevoluteJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2RopeJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2WeldJoint.cpp"),
|
||||
FilePath("Box2D/Dynamics/Joints/b2WheelJoint.cpp"),
|
||||
FilePath("Box2D/Rope/b2Rope.cpp")
|
||||
}
|
||||
);
|
||||
#endif // NDEBUG
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void test_index_bullet3_project()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifdef NDEBUG
|
||||
processSourceFiles(
|
||||
L"Bullet3",
|
||||
{
|
||||
FilePath("Bullet3Collision/BroadPhaseCollision/b3DynamicBvh.cpp"),
|
||||
FilePath("Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.cpp"),
|
||||
FilePath("Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.cpp"),
|
||||
FilePath("Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.cpp"),
|
||||
FilePath("Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp"),
|
||||
FilePath("Bullet3Common/b3AlignedAllocator.cpp"),
|
||||
FilePath("Bullet3Common/b3Logging.cpp"),
|
||||
FilePath("Bullet3Common/b3Vector3.cpp"),
|
||||
FilePath("Bullet3Geometry/b3ConvexHullComputer.cpp"),
|
||||
FilePath("Bullet3Geometry/b3GeometryUtil.cpp")
|
||||
}
|
||||
);
|
||||
#endif // NDEBUG
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void processSourceFiles(const std::wstring& projectName, const std::vector<FilePath>& sourceFilePaths)
|
||||
{
|
||||
m_duration = 0;
|
||||
for (const FilePath& filePath : sourceFilePaths)
|
||||
{
|
||||
processSourceFile(projectName, filePath);
|
||||
}
|
||||
if (s_trackTime)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath(L"data/CxxIndexSampleProjectsTestSuite/" + projectName).makeAbsolute();
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open(FilePath(projectDataRoot.wstr() + L"/" + projectName + L".timing").str(), std::ios_base::app);
|
||||
outfile << TimeStamp::now().toString() << " - " << m_duration << " ms\n";
|
||||
outfile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void processSourceFile(const std::wstring& projectName, const FilePath& sourceFilePath)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath(L"data/CxxIndexSampleProjectsTestSuite/" + projectName).makeAbsolute();
|
||||
const FilePath projectDataSrcRoot = projectDataRoot.getConcatenated(L"src");
|
||||
const FilePath projectDataExpectedOutputRoot = projectDataRoot.getConcatenated(L"expected_output");
|
||||
|
||||
std::shared_ptr<TextAccess> output = parseCode(projectDataSrcRoot.getConcatenated(sourceFilePath), projectDataSrcRoot);
|
||||
|
||||
FilePath expectedOutputFilePath = projectDataExpectedOutputRoot.getConcatenated(utility::replace(sourceFilePath.withoutExtension().wstr() + L".txt", L"/", L"_"));
|
||||
if (s_updateExpectedOutput || !expectedOutputFilePath.exists())
|
||||
{
|
||||
std::ofstream expectedOutputFile;
|
||||
expectedOutputFile.open(expectedOutputFilePath.str());
|
||||
expectedOutputFile << output->getText();
|
||||
expectedOutputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<TextAccess> expectedOutput = TextAccess::createFromFile(expectedOutputFilePath);
|
||||
TSM_ASSERT_EQUALS(L"Output does not match the expected line count for file " + sourceFilePath.wstr() + L" in project " + projectName, expectedOutput->getLineCount(), output->getLineCount());
|
||||
if (expectedOutput->getLineCount() == output->getLineCount())
|
||||
{
|
||||
for (size_t i = 1; i <= expectedOutput->getLineCount(); i++)
|
||||
{
|
||||
TS_ASSERT_EQUALS(expectedOutput->getLine(i), output->getLine(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<TextAccess> parseCode(const FilePath& sourceFilePath, const FilePath& projectDataSrcRoot)
|
||||
{
|
||||
const std::set<FilePath> indexedPaths = { projectDataSrcRoot.getCanonical() };
|
||||
const std::set<FilePathFilter> excludedFilters = {};
|
||||
const std::set<FilePathFilter> includedFilters = {};
|
||||
const FilePath workingDirectory(L".");
|
||||
|
||||
std::vector<std::wstring> compilerFlags;
|
||||
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForSystemHeaderSearchPaths(
|
||||
utility::concat(std::vector<FilePath> { projectDataSrcRoot }, ApplicationSettings::getInstance()->getHeaderSearchPathsExpanded())
|
||||
));
|
||||
utility::append(compilerFlags, IndexerCommandCxx::getCompilerFlagsForFrameworkSearchPaths(
|
||||
ApplicationSettings::getInstance()->getFrameworkSearchPathsExpanded()
|
||||
));
|
||||
#ifdef _WIN32
|
||||
// compilerFlags.emplace_back(L"--target=x86_64-pc-windows-msvc");
|
||||
#else // _WIN32
|
||||
compilerFlags.emplace_back(L"-xc++");
|
||||
#endif // _WIN32
|
||||
compilerFlags.emplace_back(L"-std=c++1z");
|
||||
compilerFlags.emplace_back(sourceFilePath.wstr());
|
||||
|
||||
std::shared_ptr<FileRegister> fileRegister = std::make_shared<FileRegister>(
|
||||
sourceFilePath,
|
||||
indexedPaths,
|
||||
excludedFilters
|
||||
);
|
||||
|
||||
TestIntermediateStorage storage;
|
||||
CxxParser parser(std::make_shared<ParserClientImpl>(&storage), fileRegister, std::make_shared<IndexerStateInfo>());
|
||||
|
||||
std::shared_ptr<IndexerCommandCxx> command = std::make_shared<IndexerCommandCxx>(
|
||||
sourceFilePath,
|
||||
indexedPaths,
|
||||
excludedFilters,
|
||||
includedFilters,
|
||||
workingDirectory,
|
||||
compilerFlags
|
||||
);
|
||||
|
||||
TimeStamp startTime = TimeStamp::now();
|
||||
parser.buildIndex(command);
|
||||
m_duration += TimeStamp::now().deltaMS(startTime);
|
||||
|
||||
storage.generateStringLists();
|
||||
|
||||
return TextAccess::createFromLines(storage.m_lines);
|
||||
}
|
||||
|
||||
size_t m_duration;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "CxxTypeName.h"
|
||||
|
||||
TEST_CASE("type name created with name has no qualifiers or modifiers")
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
REQUIRE(L"int" == typeName.toString());
|
||||
}
|
||||
|
||||
TEST_CASE("type name created with name and const qualifier has no modifiers")
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
|
||||
REQUIRE(L"const int" == typeName.toString());
|
||||
}
|
||||
|
||||
TEST_CASE("type name created with name and array modifier has array modifier")
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"[]"));
|
||||
REQUIRE(L"int []" == typeName.toString());
|
||||
}
|
||||
|
||||
TEST_CASE("type name created with name and const pointer modifier has const pointer modifier")
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"*"));
|
||||
typeName.addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
|
||||
REQUIRE(L"int * const" == typeName.toString());
|
||||
}
|
||||
|
||||
TEST_CASE("type name created with name and pointer pointer modifier has pointer pointer modifier")
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"*"));
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"*"));
|
||||
REQUIRE(L"int * *" == typeName.toString());
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "CxxTypeName.h"
|
||||
|
||||
class CxxTypeNameTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_type_name_created_with_name_has_no_qualifiers_or_modifiers()
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
TS_ASSERT_EQUALS(L"int", typeName.toString());
|
||||
}
|
||||
|
||||
void test_type_name_created_with_name_and_const_qualifier_has_no_modifiers()
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
|
||||
TS_ASSERT_EQUALS(L"const int", typeName.toString());
|
||||
}
|
||||
|
||||
void test_type_name_created_with_name_and_array_modifier_has_array_modifier()
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"[]"));
|
||||
TS_ASSERT_EQUALS(L"int []", typeName.toString());
|
||||
}
|
||||
|
||||
void test_type_name_created_with_name_and_const_pointer_modifier_has_const_pointer_modifier()
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"*"));
|
||||
typeName.addQualifier(CxxQualifierFlags::QUALIFIER_CONST);
|
||||
TS_ASSERT_EQUALS(L"int * const", typeName.toString());
|
||||
}
|
||||
|
||||
void test_type_name_created_with_name_and_pointer_pointer_modifier_has_pointer_pointer_modifier()
|
||||
{
|
||||
CxxTypeName typeName(L"int", std::vector<std::wstring>(), std::shared_ptr<CxxName>());
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"*"));
|
||||
typeName.addModifier(CxxTypeName::Modifier(L"*"));
|
||||
TS_ASSERT_EQUALS(L"int * *", typeName.toString());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "FileManager.h"
|
||||
#include "FilePath.h"
|
||||
#include "FilePathFilter.h"
|
||||
#include "FileSystem.h"
|
||||
#include "utility.h"
|
||||
|
||||
TEST_CASE("file manager has added file paths after first fetch")
|
||||
{
|
||||
std::vector<FilePath> sourcePaths;
|
||||
sourcePaths.push_back(FilePath(L"./data/FileManagerTestSuite/src/"));
|
||||
sourcePaths.push_back(FilePath(L"./data/FileManagerTestSuite/include/"));
|
||||
std::vector<FilePath> headerPaths;
|
||||
std::vector<FilePathFilter> excludeFilters;
|
||||
|
||||
// catch exceptions thrown on linux build machine
|
||||
try
|
||||
{
|
||||
std::vector<FilePath> filePaths = FileSystem::getFilePathsFromDirectory(FilePath(L"./data/FileManagerTestSuite/src/"));
|
||||
REQUIRE(filePaths.size() == 3);
|
||||
|
||||
std::vector<std::wstring> sourceExtensions;
|
||||
for (FilePath p : filePaths)
|
||||
{
|
||||
sourceExtensions.push_back(p.extension());
|
||||
}
|
||||
REQUIRE(sourceExtensions.size() == 3);
|
||||
|
||||
FileManager fm;
|
||||
fm.update(sourcePaths, excludeFilters, sourceExtensions);
|
||||
std::vector<FilePath> foundSourcePaths = utility::toVector(fm.getAllSourceFilePaths());
|
||||
|
||||
REQUIRE(foundSourcePaths.size() == 3);
|
||||
REQUIRE(utility::containsElement<FilePath>(foundSourcePaths, filePaths[0]));
|
||||
REQUIRE(utility::containsElement<FilePath>(foundSourcePaths, filePaths[1]));
|
||||
REQUIRE(utility::containsElement<FilePath>(foundSourcePaths, filePaths[2]));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "FileManager.h"
|
||||
#include "FilePath.h"
|
||||
#include "FileSystem.h"
|
||||
#include "utility.h"
|
||||
|
||||
class FileManagerTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_file_manager_has_added_file_paths_after_first_fetch()
|
||||
{
|
||||
std::vector<FilePath> sourcePaths;
|
||||
sourcePaths.push_back(FilePath(L"./data/FileManagerTestSuite/src/"));
|
||||
sourcePaths.push_back(FilePath(L"./data/FileManagerTestSuite/include/"));
|
||||
std::vector<FilePath> headerPaths;
|
||||
std::vector<FilePathFilter> excludeFilters;
|
||||
|
||||
// catch exceptions thrown on linux build machine
|
||||
try
|
||||
{
|
||||
std::vector<FilePath> filePaths = FileSystem::getFilePathsFromDirectory(FilePath(L"./data/FileManagerTestSuite/src/"));
|
||||
TS_ASSERT_EQUALS(filePaths.size(), 3);
|
||||
|
||||
std::vector<std::wstring> sourceExtensions;
|
||||
for (FilePath p : filePaths)
|
||||
{
|
||||
sourceExtensions.push_back(p.extension());
|
||||
}
|
||||
TS_ASSERT_EQUALS(sourceExtensions.size(), 3);
|
||||
|
||||
FileManager fm;
|
||||
fm.update(sourcePaths, excludeFilters, sourceExtensions);
|
||||
std::vector<FilePath> foundSourcePaths = utility::toVector(fm.getAllSourceFilePaths());
|
||||
|
||||
TS_ASSERT_EQUALS(foundSourcePaths.size(), 3);
|
||||
TS_ASSERT(utility::containsElement<FilePath>(foundSourcePaths, filePaths[0]));
|
||||
TS_ASSERT(utility::containsElement<FilePath>(foundSourcePaths, filePaths[1]));
|
||||
TS_ASSERT(utility::containsElement<FilePath>(foundSourcePaths, filePaths[2]));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,123 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "FilePathFilter.h"
|
||||
|
||||
TEST_CASE("file path filter finds exact match")
|
||||
{
|
||||
FilePathFilter filter(L"test.h");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter finds match with single asterisk in same level")
|
||||
{
|
||||
FilePathFilter filter(L"*test.*");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"this_is_a_test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter finds match with single asterisk in different level")
|
||||
{
|
||||
FilePathFilter filter(L"*/this_is_a_test.h");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"folder/this_is_a_test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter does not find match with single asterisk in different level")
|
||||
{
|
||||
FilePathFilter filter(L"*/test.h");
|
||||
|
||||
REQUIRE(!filter.isMatching(FilePath(L"test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter finds match with multiple asterisk in same level")
|
||||
{
|
||||
FilePathFilter filter(L"**test.h");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"folder/this_is_a_test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter finds match with multiple asterisk in different level")
|
||||
{
|
||||
FilePathFilter filter(L"root/**/test.h");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"root/folder1/folder2/test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter does not find match with multiple asterisk in different level")
|
||||
{
|
||||
FilePathFilter filter(L"**/test.h");
|
||||
|
||||
REQUIRE(!filter.isMatching(FilePath(L"folder/this_is_a_test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes dot character")
|
||||
{
|
||||
FilePathFilter filter(L"test.h");
|
||||
|
||||
REQUIRE(!filter.isMatching(FilePath(L"testyh")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes plus character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test+.h").isMatching(FilePath(L"folder/test+.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes minus character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test[-].h").isMatching(FilePath(L"folder/test[-].h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes dollar character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test$.h").isMatching(FilePath(L"folder/test$.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes circumflex character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test^.h").isMatching(FilePath(L"folder/test^.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes open round brace character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test(.h").isMatching(FilePath(L"folder/test(.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes close round brace character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder\\test).h").isMatching(FilePath(L"folder/test).h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes open curly brace character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test{.h").isMatching(FilePath(L"folder/test{.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes close curly brace character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test}.h").isMatching(FilePath(L"folder/test}.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes open squared brace character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder/test[.h").isMatching(FilePath(L"folder/test[.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter escapes close squared brace character")
|
||||
{
|
||||
REQUIRE(FilePathFilter(L"folder\\test].h").isMatching(FilePath(L"folder/test].h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter finds backslash if slash was provided")
|
||||
{
|
||||
FilePathFilter filter(L"folder/test.h");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"folder\\test.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("file path filter finds slash if backslash was provided")
|
||||
{
|
||||
FilePathFilter filter(L"folder\\test.h");
|
||||
|
||||
REQUIRE(filter.isMatching(FilePath(L"folder/test.h")));
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "FilePathFilter.h"
|
||||
|
||||
class FilePathFilterTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_file_path_filter_finds_exact_match()
|
||||
{
|
||||
FilePathFilter filter(L"test.h");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_finds_match_with_single_asterisk_in_same_level()
|
||||
{
|
||||
FilePathFilter filter(L"*test.*");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"this_is_a_test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_finds_match_with_single_asterisk_in_different_level()
|
||||
{
|
||||
FilePathFilter filter(L"*/this_is_a_test.h");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"folder/this_is_a_test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_does_not_find_match_with_single_asterisk_in_different_level()
|
||||
{
|
||||
FilePathFilter filter(L"*/test.h");
|
||||
|
||||
TS_ASSERT(!filter.isMatching(FilePath(L"test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_finds_match_with_multiple_asterisk_in_same_level()
|
||||
{
|
||||
FilePathFilter filter(L"**test.h");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"folder/this_is_a_test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_finds_match_with_multiple_asterisk_in_different_level()
|
||||
{
|
||||
FilePathFilter filter(L"root/**/test.h");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"root/folder1/folder2/test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_does_not_find_match_with_multiple_asterisk_in_different_level()
|
||||
{
|
||||
FilePathFilter filter(L"**/test.h");
|
||||
|
||||
TS_ASSERT(!filter.isMatching(FilePath(L"folder/this_is_a_test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_dot_character()
|
||||
{
|
||||
FilePathFilter filter(L"test.h");
|
||||
|
||||
TS_ASSERT(!filter.isMatching(FilePath(L"testyh")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_plus_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test+.h").isMatching(FilePath(L"folder/test+.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_minus_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test[-].h").isMatching(FilePath(L"folder/test[-].h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_dollar_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test$.h").isMatching(FilePath(L"folder/test$.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_circumflex_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test^.h").isMatching(FilePath(L"folder/test^.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_open_round_brace_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test(.h").isMatching(FilePath(L"folder/test(.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_close_round_brace_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder\\test).h").isMatching(FilePath(L"folder/test).h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_open_curly_brace_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test{.h").isMatching(FilePath(L"folder/test{.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_close_curly_brace_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test}.h").isMatching(FilePath(L"folder/test}.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_open_squared_brace_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder/test[.h").isMatching(FilePath(L"folder/test[.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_escapes_close_squared_brace_character()
|
||||
{
|
||||
TS_ASSERT(FilePathFilter(L"folder\\test].h").isMatching(FilePath(L"folder/test].h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_finds_backslash_if_slash_was_provided()
|
||||
{
|
||||
FilePathFilter filter(L"folder/test.h");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"folder\\test.h")));
|
||||
}
|
||||
|
||||
void test_file_path_filter_finds_slash_if_backslash_was_provided()
|
||||
{
|
||||
FilePathFilter filter(L"folder\\test.h");
|
||||
|
||||
TS_ASSERT(filter.isMatching(FilePath(L"folder/test.h")));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,212 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "FilePath.h"
|
||||
|
||||
TEST_CASE("file_path_gets_created_empty")
|
||||
{
|
||||
const FilePath path;
|
||||
|
||||
REQUIRE(path.wstr() == L"");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_gets_created_with_string")
|
||||
{
|
||||
const std::wstring str(L"data/FilePathTestSuite/main.cpp");
|
||||
const FilePath path(str);
|
||||
|
||||
REQUIRE(path.wstr() == str);
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_gets_created_other_file_path")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/main.cpp");
|
||||
const FilePath path2(path);
|
||||
|
||||
REQUIRE(path == path2);
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_empty")
|
||||
{
|
||||
const FilePath path1(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath path2;
|
||||
|
||||
REQUIRE(!path1.empty());
|
||||
REQUIRE(path2.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_exists")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
REQUIRE(path.exists());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_not_exists")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.h");
|
||||
|
||||
REQUIRE(!path.exists());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_is_directory")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
REQUIRE(!path.isDirectory());
|
||||
REQUIRE(path.getParentDirectory().isDirectory());
|
||||
}
|
||||
|
||||
TEST_CASE("empty_file_path_has_empty_parent_directory")
|
||||
{
|
||||
const FilePath path;
|
||||
|
||||
REQUIRE(path.empty());
|
||||
REQUIRE(path.getParentDirectory().empty());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_without_parent_has_empty_parent_directory")
|
||||
{
|
||||
const FilePath path(L"a.cpp");
|
||||
|
||||
REQUIRE(path.getParentDirectory().empty());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_is_absolute")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
REQUIRE(!path.isAbsolute());
|
||||
REQUIRE(path.getAbsolute().isAbsolute());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_parent_directory")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
REQUIRE(path.getParentDirectory().wstr() == L"data/FilePathTestSuite");
|
||||
REQUIRE(path.getParentDirectory().getParentDirectory().wstr() == L"data");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_relative_to_other_path")
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/test/c.h");
|
||||
|
||||
REQUIRE(pathA.getRelativeTo(pathB).wstr() == L"../a.cpp");
|
||||
REQUIRE(pathB.getRelativeTo(pathA).wstr() == L"test/c.h");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_relative_to_other_directory")
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/test");
|
||||
|
||||
REQUIRE(pathA.getRelativeTo(pathB).wstr() == L"../a.cpp");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_relative_to_same_directory")
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/test");
|
||||
|
||||
REQUIRE(pathA.getRelativeTo(pathA).wstr() == L"./");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_file_name")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/abc.h");
|
||||
|
||||
REQUIRE(path.fileName() == L"abc.h");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_extension")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.h");
|
||||
|
||||
REQUIRE(path.extension() == L".h");
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_without_extension")
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.h");
|
||||
|
||||
REQUIRE(path.withoutExtension() == FilePath(L"data/FilePathTestSuite/a"));
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_has_extension")
|
||||
{
|
||||
std::vector<std::wstring> extensions;
|
||||
extensions.push_back(L".h");
|
||||
extensions.push_back(L".cpp");
|
||||
extensions.push_back(L".cc");
|
||||
|
||||
REQUIRE(FilePath(L"data/FilePathTestSuite/a.h").hasExtension(extensions));
|
||||
REQUIRE(FilePath(L"data/FilePathTestSuite/b.cpp").hasExtension(extensions));
|
||||
REQUIRE(!FilePath(L"data/FilePathTestSuite/a.m").hasExtension(extensions));
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_equals_file_with_different_relative_paths")
|
||||
{
|
||||
const FilePath path1(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath path2(L"data/../data/FilePathTestSuite/./a.cpp");
|
||||
|
||||
REQUIRE(path1 == path2);
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_equals_relative_and_absolute_paths")
|
||||
{
|
||||
const FilePath path1(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath path2 = path1.getAbsolute();
|
||||
|
||||
REQUIRE(path1 == path2);
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_equals_absolute_and_canonical_paths")
|
||||
{
|
||||
const FilePath path(L"data/../data/FilePathTestSuite/./a.cpp");
|
||||
|
||||
REQUIRE(path.getAbsolute() == path.getCanonical());
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_canonical_removes_symlinks")
|
||||
{
|
||||
#ifndef _WIN32
|
||||
const FilePath pathA(L"data/FilePathTestSuite/parent/target/d.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/target/d.cpp");
|
||||
|
||||
REQUIRE(pathB.getAbsolute() == pathA.getCanonical());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_compares_paths_with_posix_and_windows_format")
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.cc");
|
||||
const FilePath pathB2(L"data\\FilePathTestSuite\\b.cc");
|
||||
|
||||
REQUIRE(pathB == pathB2);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_differs_for_different_existing_files")
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.cc");
|
||||
|
||||
REQUIRE(pathA != pathB);
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_differs_for_different_nonexisting_files")
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.h");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.c");
|
||||
|
||||
REQUIRE(pathA != pathB);
|
||||
}
|
||||
|
||||
TEST_CASE("file_path_differs_for_existing_and_nonexisting_files")
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.h");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.cc");
|
||||
|
||||
REQUIRE(pathA != pathB);
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "FilePath.h"
|
||||
|
||||
class FilePathTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_file_path_gets_created_empty()
|
||||
{
|
||||
const FilePath path;
|
||||
|
||||
TS_ASSERT_EQUALS(path.wstr(), L"");
|
||||
}
|
||||
|
||||
void test_file_path_gets_created_with_string()
|
||||
{
|
||||
const std::wstring str(L"data/FilePathTestSuite/main.cpp");
|
||||
const FilePath path(str);
|
||||
|
||||
TS_ASSERT_EQUALS(path.wstr(), str);
|
||||
}
|
||||
|
||||
void test_file_path_gets_created_other_file_path()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/main.cpp");
|
||||
const FilePath path2(path);
|
||||
|
||||
TS_ASSERT_EQUALS(path, path2);
|
||||
}
|
||||
|
||||
void test_file_path_empty()
|
||||
{
|
||||
const FilePath path1(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath path2;
|
||||
|
||||
TS_ASSERT(!path1.empty());
|
||||
TS_ASSERT(path2.empty());
|
||||
}
|
||||
|
||||
void test_file_path_exists()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
TS_ASSERT(path.exists());
|
||||
}
|
||||
|
||||
void test_file_path_not_exists()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.h");
|
||||
|
||||
TS_ASSERT(!path.exists());
|
||||
}
|
||||
|
||||
void test_file_path_is_directory()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
TS_ASSERT(!path.isDirectory());
|
||||
TS_ASSERT(path.getParentDirectory().isDirectory());
|
||||
}
|
||||
|
||||
void test_empty_file_path_has_empty_parent_directory()
|
||||
{
|
||||
const FilePath path;
|
||||
|
||||
TS_ASSERT(path.empty());
|
||||
TS_ASSERT(path.getParentDirectory().empty());
|
||||
}
|
||||
|
||||
void test_file_path_without_parent_has_empty_parent_directory()
|
||||
{
|
||||
const FilePath path(L"a.cpp");
|
||||
|
||||
TS_ASSERT(path.getParentDirectory().empty());
|
||||
}
|
||||
|
||||
void test_file_path_is_absolute()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
TS_ASSERT(!path.isAbsolute());
|
||||
TS_ASSERT(path.getAbsolute().isAbsolute());
|
||||
}
|
||||
|
||||
void test_file_path_parent_directory()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.cpp");
|
||||
|
||||
TS_ASSERT(path.getParentDirectory().wstr() == L"data/FilePathTestSuite");
|
||||
TS_ASSERT(path.getParentDirectory().getParentDirectory().wstr() == L"data");
|
||||
}
|
||||
|
||||
void test_file_path_relative_to_other_path()
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/test/c.h");
|
||||
|
||||
TS_ASSERT_EQUALS(pathA.getRelativeTo(pathB).wstr(), L"../a.cpp");
|
||||
TS_ASSERT_EQUALS(pathB.getRelativeTo(pathA).wstr(), L"test/c.h");
|
||||
}
|
||||
|
||||
void test_file_path_relative_to_other_directory()
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/test");
|
||||
|
||||
TS_ASSERT_EQUALS(pathA.getRelativeTo(pathB).wstr(), L"../a.cpp");
|
||||
}
|
||||
|
||||
void test_file_path_relative_to_same_directory()
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/test");
|
||||
|
||||
TS_ASSERT_EQUALS(pathA.getRelativeTo(pathA).wstr(), L"./");
|
||||
}
|
||||
|
||||
void test_file_path_file_name()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/abc.h");
|
||||
|
||||
TS_ASSERT_EQUALS(path.fileName(), L"abc.h");
|
||||
}
|
||||
|
||||
void test_file_path_extension()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.h");
|
||||
|
||||
TS_ASSERT_EQUALS(path.extension(), L".h");
|
||||
}
|
||||
|
||||
void test_file_path_without_extension()
|
||||
{
|
||||
const FilePath path(L"data/FilePathTestSuite/a.h");
|
||||
|
||||
TS_ASSERT_EQUALS(path.withoutExtension(), FilePath(L"data/FilePathTestSuite/a"));
|
||||
}
|
||||
|
||||
void test_file_path_has_extension()
|
||||
{
|
||||
std::vector<std::wstring> extensions;
|
||||
extensions.push_back(L".h");
|
||||
extensions.push_back(L".cpp");
|
||||
extensions.push_back(L".cc");
|
||||
|
||||
TS_ASSERT(FilePath(L"data/FilePathTestSuite/a.h").hasExtension(extensions));
|
||||
TS_ASSERT(FilePath(L"data/FilePathTestSuite/b.cpp").hasExtension(extensions));
|
||||
TS_ASSERT(!FilePath(L"data/FilePathTestSuite/a.m").hasExtension(extensions));
|
||||
}
|
||||
|
||||
void test_file_path_equals_file_with_different_relative_paths()
|
||||
{
|
||||
const FilePath path1(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath path2(L"data/../data/FilePathTestSuite/./a.cpp");
|
||||
|
||||
TS_ASSERT_EQUALS(path1, path2);
|
||||
}
|
||||
|
||||
void test_file_path_equals_relative_and_absolute_paths()
|
||||
{
|
||||
const FilePath path1(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath path2 = path1.getAbsolute();
|
||||
|
||||
TS_ASSERT_EQUALS(path1, path2);
|
||||
}
|
||||
|
||||
void test_file_path_equals_absolute_and_canonical_paths()
|
||||
{
|
||||
const FilePath path(L"data/../data/FilePathTestSuite/./a.cpp");
|
||||
|
||||
TS_ASSERT_EQUALS(path.getAbsolute(), path.getCanonical());
|
||||
}
|
||||
|
||||
void test_file_path_canonical_removes_symlinks()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
const FilePath pathA(L"data/FilePathTestSuite/parent/target/d.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/target/d.cpp");
|
||||
|
||||
TS_ASSERT_EQUALS(pathB.getAbsolute(), pathA.getCanonical());
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_file_path_compares_paths_with_posix_and_windows_format()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.cc");
|
||||
const FilePath pathB2(L"data\\FilePathTestSuite\\b.cc");
|
||||
|
||||
TS_ASSERT_EQUALS(pathB, pathB2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_file_path_differs_for_different_existing_files()
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.cpp");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.cc");
|
||||
|
||||
TS_ASSERT_DIFFERS(pathA, pathB);
|
||||
}
|
||||
|
||||
void test_file_path_differs_for_different_nonexisting_files()
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.h");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.c");
|
||||
|
||||
TS_ASSERT_DIFFERS(pathA, pathB);
|
||||
}
|
||||
|
||||
void test_file_path_differs_for_existing_and_nonexisting_files()
|
||||
{
|
||||
const FilePath pathA(L"data/FilePathTestSuite/a.h");
|
||||
const FilePath pathB(L"data/FilePathTestSuite/b.cc");
|
||||
|
||||
TS_ASSERT_DIFFERS(pathA, pathB);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "utility.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isInFiles(const std::set<FilePath>& files, const FilePath& filename)
|
||||
{
|
||||
return std::end(files) != files.find(filename);
|
||||
}
|
||||
|
||||
bool isInFileInfos(const std::vector<FileInfo>& infos, const std::wstring& filename)
|
||||
{
|
||||
for (const FileInfo& info : infos)
|
||||
{
|
||||
if (info.path.wstr() == filename)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isInFileInfos(const std::vector<FileInfo>& infos, const std::wstring& filename, const std::wstring& filename2)
|
||||
{
|
||||
for (const FileInfo& info : infos)
|
||||
{
|
||||
if (info.path.wstr() == filename || info.path.wstr() == filename2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("find cpp files")
|
||||
{
|
||||
std::vector<std::wstring> cppFiles = utility::convert<FilePath, std::wstring>(
|
||||
FileSystem::getFilePathsFromDirectory(FilePath(L"data/FileSystemTestSuite"), { L".cpp" }),
|
||||
[](const FilePath& filePath){ return filePath.wstr(); }
|
||||
);
|
||||
|
||||
REQUIRE(cppFiles.size() == 4);
|
||||
REQUIRE(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/main.cpp"));
|
||||
REQUIRE(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/Settings/sample.cpp"));
|
||||
REQUIRE(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/src/main.cpp"));
|
||||
REQUIRE(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/src/test.cpp"));
|
||||
}
|
||||
|
||||
TEST_CASE("find h files")
|
||||
{
|
||||
std::vector<std::wstring> headerFiles = utility::convert<FilePath, std::wstring>(
|
||||
FileSystem::getFilePathsFromDirectory(FilePath(L"data/FileSystemTestSuite"), { L".h" }),
|
||||
[](const FilePath& filePath){ return filePath.wstr(); }
|
||||
);
|
||||
|
||||
REQUIRE(headerFiles.size() == 3);
|
||||
REQUIRE(utility::containsElement<std::wstring>(headerFiles, L"data/FileSystemTestSuite/tictactoe.h"));
|
||||
REQUIRE(utility::containsElement<std::wstring>(headerFiles, L"data/FileSystemTestSuite/Settings/player.h"));
|
||||
REQUIRE(utility::containsElement<std::wstring>(headerFiles, L"data/FileSystemTestSuite/src/test.h"));
|
||||
}
|
||||
|
||||
TEST_CASE("find all source files")
|
||||
{
|
||||
std::vector<std::wstring> sourceFiles = utility::convert<FilePath, std::wstring>(
|
||||
FileSystem::getFilePathsFromDirectory(FilePath(L"data/FileSystemTestSuite"), { L".h", L".hpp", L".cpp" }),
|
||||
[](const FilePath& filePath){ return filePath.wstr(); }
|
||||
);
|
||||
|
||||
REQUIRE(sourceFiles.size() == 8);
|
||||
}
|
||||
|
||||
TEST_CASE("find file infos")
|
||||
{
|
||||
#ifndef _WIN32
|
||||
std::vector<FilePath> directoryPaths;
|
||||
directoryPaths.push_back(FilePath(L"./data/FileSystemTestSuite/src"));
|
||||
|
||||
std::vector<FileInfo> files = FileSystem::getFileInfosFromPaths(directoryPaths, { L".h", L".hpp", L".cpp" }, false);
|
||||
|
||||
REQUIRE(files.size() == 2);
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.cpp"));
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.h"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("find file infos with symlinks")
|
||||
{
|
||||
#ifndef _WIN32
|
||||
std::vector<FilePath> directoryPaths;
|
||||
directoryPaths.push_back(FilePath(L"./data/FileSystemTestSuite/src"));
|
||||
|
||||
std::vector<FileInfo> files = FileSystem::getFileInfosFromPaths(directoryPaths, { L".h", L".hpp", L".cpp" }, true);
|
||||
|
||||
REQUIRE(files.size() == 5);
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/Settings/player.h",
|
||||
L"./data/FileSystemTestSuite/player.h"
|
||||
));
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/Settings/sample.cpp",
|
||||
L"./data/FileSystemTestSuite/sample.cpp"
|
||||
));
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/main.cpp",
|
||||
L"./data/FileSystemTestSuite/src/Settings/src/main.cpp"
|
||||
));
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.cpp",
|
||||
L"./data/FileSystemTestSuite/src/Settings/src/test.cpp"
|
||||
));
|
||||
REQUIRE(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.h",
|
||||
L"./data/FileSystemTestSuite/src/Settings/src/test.h"
|
||||
));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("find symlinked directories")
|
||||
{
|
||||
#ifndef _WIN32
|
||||
std::vector<FilePath> directoryPaths;
|
||||
directoryPaths.push_back(FilePath("./data/FileSystemTestSuite/src"));
|
||||
|
||||
std::set<FilePath> dirs = FileSystem::getSymLinkedDirectories(directoryPaths);
|
||||
|
||||
REQUIRE(dirs.size() == 2);
|
||||
#endif
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "utility.h"
|
||||
|
||||
class FileSystemTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_find_cpp_files()
|
||||
{
|
||||
std::vector<std::wstring> cppFiles = utility::convert<FilePath, std::wstring>(
|
||||
FileSystem::getFilePathsFromDirectory(FilePath(L"data/FileSystemTestSuite"), { L".cpp" }),
|
||||
[](const FilePath& filePath){ return filePath.wstr(); }
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(cppFiles.size(), 4);
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/main.cpp"));
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/Settings/sample.cpp"));
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/src/main.cpp"));
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(cppFiles, L"data/FileSystemTestSuite/src/test.cpp"));
|
||||
}
|
||||
|
||||
void test_find_h_files()
|
||||
{
|
||||
std::vector<std::wstring> headerFiles = utility::convert<FilePath, std::wstring>(
|
||||
FileSystem::getFilePathsFromDirectory(FilePath(L"data/FileSystemTestSuite"), { L".h" }),
|
||||
[](const FilePath& filePath){ return filePath.wstr(); }
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(headerFiles.size(), 3);
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(headerFiles, L"data/FileSystemTestSuite/tictactoe.h"));
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(headerFiles, L"data/FileSystemTestSuite/Settings/player.h"));
|
||||
TS_ASSERT(utility::containsElement<std::wstring>(headerFiles, L"data/FileSystemTestSuite/src/test.h"));
|
||||
}
|
||||
|
||||
void test_find_all_source_files()
|
||||
{
|
||||
std::vector<std::wstring> sourceFiles = utility::convert<FilePath, std::wstring>(
|
||||
FileSystem::getFilePathsFromDirectory(FilePath(L"data/FileSystemTestSuite"), { L".h", L".hpp", L".cpp" }),
|
||||
[](const FilePath& filePath){ return filePath.wstr(); }
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(sourceFiles.size(), 8);
|
||||
}
|
||||
|
||||
void test_find_file_infos()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
std::vector<FilePath> directoryPaths;
|
||||
directoryPaths.push_back(FilePath(L"./data/FileSystemTestSuite/src"));
|
||||
|
||||
std::vector<FileInfo> files = FileSystem::getFileInfosFromPaths(directoryPaths, { L".h", L".hpp", L".cpp" }, false);
|
||||
|
||||
TS_ASSERT_EQUALS(files.size(), 2);
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.cpp"));
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.h"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_find_file_infos_with_symlinks()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
std::vector<FilePath> directoryPaths;
|
||||
directoryPaths.push_back(FilePath(L"./data/FileSystemTestSuite/src"));
|
||||
|
||||
std::vector<FileInfo> files = FileSystem::getFileInfosFromPaths(directoryPaths, { L".h", L".hpp", L".cpp" }, true);
|
||||
|
||||
TS_ASSERT_EQUALS(files.size(), 5);
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/Settings/player.h",
|
||||
L"./data/FileSystemTestSuite/player.h"
|
||||
));
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/Settings/sample.cpp",
|
||||
L"./data/FileSystemTestSuite/sample.cpp"
|
||||
));
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/main.cpp",
|
||||
L"./data/FileSystemTestSuite/src/Settings/src/main.cpp"
|
||||
));
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.cpp",
|
||||
L"./data/FileSystemTestSuite/src/Settings/src/test.cpp"
|
||||
));
|
||||
TS_ASSERT(isInFileInfos(files, L"./data/FileSystemTestSuite/src/test.h",
|
||||
L"./data/FileSystemTestSuite/src/Settings/src/test.h"
|
||||
));
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_find_symlinked_directories()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
std::vector<FilePath> directoryPaths;
|
||||
directoryPaths.push_back(FilePath("./data/FileSystemTestSuite/src"));
|
||||
|
||||
std::set<FilePath> dirs = FileSystem::getSymLinkedDirectories(directoryPaths);
|
||||
|
||||
TS_ASSERT_EQUALS(dirs.size(), 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
bool isInFiles(const std::set<FilePath>& files, const FilePath& filename)
|
||||
{
|
||||
return std::end(files) != files.find(filename);
|
||||
}
|
||||
|
||||
bool isInFileInfos(const std::vector<FileInfo>& infos, const std::wstring& filename)
|
||||
{
|
||||
for (const FileInfo& info : infos)
|
||||
{
|
||||
if (info.path.wstr() == filename)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isInFileInfos(const std::vector<FileInfo>& infos, const std::wstring& filename, const std::wstring& filename2)
|
||||
{
|
||||
for (const FileInfo& info : infos)
|
||||
{
|
||||
if (info.path.wstr() == filename || info.path.wstr() == filename2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,341 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "Graph.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestToken : public Token
|
||||
{
|
||||
public:
|
||||
TestToken()
|
||||
:Token(0)
|
||||
{
|
||||
}
|
||||
|
||||
TestToken(const TestToken& other)
|
||||
: Token(other)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isNode() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool isEdge() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void addComponent(std::shared_ptr<TokenComponent> component)
|
||||
{
|
||||
Token::addComponent(component);
|
||||
}
|
||||
|
||||
template<typename ComponentType>
|
||||
std::shared_ptr<ComponentType> removeComponent()
|
||||
{
|
||||
return Token::removeComponent<ComponentType>();
|
||||
}
|
||||
|
||||
virtual std::wstring getReadableTypeString() const
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
};
|
||||
|
||||
class TestComponent : public TokenComponent
|
||||
{
|
||||
public:
|
||||
virtual std::shared_ptr<TokenComponent> copy() const
|
||||
{
|
||||
return std::make_shared<TestComponent>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class Test2Component : public TokenComponent
|
||||
{
|
||||
public:
|
||||
virtual std::shared_ptr<TokenComponent> copy() const
|
||||
{
|
||||
return std::make_shared<Test2Component>(*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("tokens save location ids")
|
||||
{
|
||||
TestToken a;
|
||||
a.addLocationId(23);
|
||||
a.addLocationId(5);
|
||||
|
||||
REQUIRE(a.getLocationIds().size() == 2);
|
||||
REQUIRE(a.getLocationIds()[0] == 23);
|
||||
REQUIRE(a.getLocationIds()[1] == 5);
|
||||
}
|
||||
|
||||
TEST_CASE("tokens remove location ids")
|
||||
{
|
||||
TestToken a;
|
||||
a.addLocationId(23);
|
||||
a.addLocationId(5);
|
||||
a.removeLocationId(42);
|
||||
a.removeLocationId(5);
|
||||
|
||||
REQUIRE(a.getLocationIds().size() == 1);
|
||||
REQUIRE(a.getLocationIds()[0] == 23);
|
||||
}
|
||||
|
||||
TEST_CASE("token saves component")
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
a.addComponent(component);
|
||||
|
||||
REQUIRE(a.getComponent<TestComponent>());
|
||||
REQUIRE(!a.getComponent<Test2Component>());
|
||||
|
||||
REQUIRE(a.getComponent<TestComponent>() == component.get());
|
||||
}
|
||||
|
||||
TEST_CASE("token saves multiple components")
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
|
||||
a.addComponent(component2);
|
||||
a.addComponent(component);
|
||||
|
||||
REQUIRE(a.getComponent<TestComponent>());
|
||||
REQUIRE(a.getComponent<Test2Component>());
|
||||
|
||||
REQUIRE(a.getComponent<TestComponent>() == component.get());
|
||||
REQUIRE(a.getComponent<Test2Component>() == component2.get());
|
||||
}
|
||||
|
||||
TEST_CASE("token removes component")
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
|
||||
a.addComponent(component2);
|
||||
a.addComponent(component);
|
||||
std::shared_ptr<TestComponent> component3 = a.removeComponent<TestComponent>();
|
||||
|
||||
REQUIRE(!a.getComponent<TestComponent>());
|
||||
REQUIRE(a.getComponent<Test2Component>());
|
||||
|
||||
REQUIRE(component3.get() == component.get());
|
||||
REQUIRE(a.getComponent<Test2Component>() == component2.get());
|
||||
}
|
||||
|
||||
TEST_CASE("token copies components when token is copied")
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
|
||||
a.addComponent(component2);
|
||||
a.addComponent(component);
|
||||
|
||||
TestToken b(a);
|
||||
|
||||
REQUIRE(b.getComponent<TestComponent>());
|
||||
REQUIRE(b.getComponent<Test2Component>());
|
||||
|
||||
REQUIRE(b.getComponent<TestComponent>() != component.get());
|
||||
REQUIRE(b.getComponent<Test2Component>() != component2.get());
|
||||
}
|
||||
|
||||
TEST_CASE("nodes are nodes")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
REQUIRE(a.isNode());
|
||||
REQUIRE(!a.isEdge());
|
||||
}
|
||||
|
||||
TEST_CASE("edges are edges")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
|
||||
REQUIRE(!e.isNode());
|
||||
REQUIRE(e.isEdge());
|
||||
}
|
||||
|
||||
TEST_CASE("set type of node from constructor")
|
||||
{
|
||||
Node n(1, NodeType(NodeType::NODE_FUNCTION), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
REQUIRE(NodeType(NodeType::NODE_FUNCTION) == n.getType());
|
||||
}
|
||||
|
||||
TEST_CASE("set type of node from non indexed")
|
||||
{
|
||||
Node n(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
n.setType(NodeType(NodeType::NODE_CLASS));
|
||||
REQUIRE(NodeType(NodeType::NODE_CLASS) == n.getType());
|
||||
}
|
||||
|
||||
TEST_CASE("can not change type of node after it was set")
|
||||
{
|
||||
Node n(3, NodeType(NodeType::NODE_NAMESPACE), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
n.setType(NodeType(NodeType::NODE_CLASS));
|
||||
REQUIRE(NodeType(NodeType::NODE_CLASS) != n.getType());
|
||||
}
|
||||
|
||||
TEST_CASE("node can be copied and keeps same id")
|
||||
{
|
||||
Node n(4, NodeType(NodeType::NODE_NAMESPACE), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node n2(n);
|
||||
|
||||
REQUIRE(&n != &n2);
|
||||
REQUIRE(n.getId() == n2.getId());
|
||||
REQUIRE(n.getName() == n2.getName());
|
||||
REQUIRE(n.getType() == n2.getType());
|
||||
}
|
||||
|
||||
TEST_CASE("node type bit masking")
|
||||
{
|
||||
Node n(1, NodeType(NodeType::NODE_NAMESPACE), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
REQUIRE(n.isType(NodeType::NODE_FUNCTION | NodeType::NODE_NAMESPACE | NodeType::NODE_CLASS));
|
||||
REQUIRE(!n.isType(NodeType::NODE_FUNCTION | NodeType::NODE_METHOD | NodeType::NODE_CLASS));
|
||||
}
|
||||
|
||||
TEST_CASE("get type of edges")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
|
||||
REQUIRE(Edge::EDGE_USAGE == e.getType());
|
||||
}
|
||||
|
||||
TEST_CASE("edge can be copied and keeps same id")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
Edge e2(e, &a, &b);
|
||||
|
||||
REQUIRE(&e != &e2);
|
||||
REQUIRE(e.getId() == e2.getId());
|
||||
REQUIRE(e.getType() == e2.getType());
|
||||
}
|
||||
|
||||
TEST_CASE("edge type bit masking")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
|
||||
REQUIRE(e.isType(Edge::EDGE_MEMBER | Edge::EDGE_CALL | Edge::EDGE_USAGE));
|
||||
REQUIRE(!e.isType(Edge::EDGE_MEMBER | Edge::EDGE_CALL));
|
||||
}
|
||||
|
||||
TEST_CASE("node finds child node")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node c(3, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"C", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(4, Edge::EDGE_MEMBER, &a, &b);
|
||||
Edge e2(5, Edge::EDGE_MEMBER, &a, &c);
|
||||
|
||||
Node* x = a.findChildNode(
|
||||
[](Node* n)
|
||||
{
|
||||
return n->getName() == L"C";
|
||||
}
|
||||
);
|
||||
|
||||
REQUIRE(x == &c);
|
||||
REQUIRE(x != &b);
|
||||
}
|
||||
|
||||
TEST_CASE("node can not find child node")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node c(3, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"C", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(4, Edge::EDGE_MEMBER, &a, &b);
|
||||
Edge e2(5, Edge::EDGE_MEMBER, &a, &c);
|
||||
|
||||
Node* x = a.findChildNode(
|
||||
[](Node* n)
|
||||
{
|
||||
return n->getName() == L"D";
|
||||
}
|
||||
);
|
||||
|
||||
REQUIRE(!x);
|
||||
}
|
||||
|
||||
TEST_CASE("node visits child nodes")
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node c(3, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"C", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(4, Edge::EDGE_MEMBER, &a, &b);
|
||||
Edge e2(5, Edge::EDGE_MEMBER, &a, &c);
|
||||
|
||||
std::vector<Node*> children;
|
||||
a.forEachChildNode(
|
||||
[&children](Node* n)
|
||||
{
|
||||
return children.push_back(n);
|
||||
}
|
||||
);
|
||||
|
||||
REQUIRE(children.size() == 2);
|
||||
REQUIRE(children[0] == &b);
|
||||
REQUIRE(children[1] == &c);
|
||||
}
|
||||
|
||||
TEST_CASE("graph saves nodes")
|
||||
{
|
||||
Graph graph;
|
||||
Node* a = graph.createNode(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node* b = graph.createNode(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
REQUIRE(2 == graph.getNodeCount());
|
||||
REQUIRE(0 == graph.getEdgeCount());
|
||||
|
||||
REQUIRE(graph.getNodeById(a->getId()));
|
||||
REQUIRE(L"A" == graph.getNodeById(a->getId())->getName());
|
||||
|
||||
REQUIRE(graph.getNodeById(b->getId()));
|
||||
REQUIRE(L"B" == graph.getNodeById(b->getId())->getName());
|
||||
|
||||
REQUIRE(!graph.getNodeById(0));
|
||||
}
|
||||
|
||||
TEST_CASE("graph saves edges")
|
||||
{
|
||||
Graph graph;
|
||||
|
||||
Node* a = graph.createNode(1, NodeType(NodeType::NODE_FUNCTION), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node* b = graph.createNode(2, NodeType(NodeType::NODE_FUNCTION), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
Edge* e = graph.createEdge(3, Edge::EDGE_CALL, a, b);
|
||||
|
||||
REQUIRE(2 == graph.getNodeCount());
|
||||
REQUIRE(1 == graph.getEdgeCount());
|
||||
|
||||
REQUIRE(graph.getEdgeById(e->getId()));
|
||||
REQUIRE(Edge::EDGE_CALL == graph.getEdgeById(e->getId())->getType());
|
||||
}
|
||||
|
||||
TEST_CASE("graph removes nodes")
|
||||
{
|
||||
Graph graph;
|
||||
|
||||
Node* a = graph.createNode(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
graph.createNode(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
REQUIRE(2 == graph.getNodeCount());
|
||||
REQUIRE(0 == graph.getEdgeCount());
|
||||
|
||||
graph.removeNode(graph.getNodeById(a->getId()));
|
||||
|
||||
REQUIRE(1 == graph.getNodeCount());
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "Graph.h"
|
||||
|
||||
class GraphTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_tokens_save_location_ids()
|
||||
{
|
||||
TestToken a;
|
||||
a.addLocationId(23);
|
||||
a.addLocationId(5);
|
||||
|
||||
TS_ASSERT_EQUALS(a.getLocationIds().size(), 2);
|
||||
TS_ASSERT_EQUALS(a.getLocationIds()[0], 23);
|
||||
TS_ASSERT_EQUALS(a.getLocationIds()[1], 5);
|
||||
}
|
||||
|
||||
void test_tokens_remove_location_ids()
|
||||
{
|
||||
TestToken a;
|
||||
a.addLocationId(23);
|
||||
a.addLocationId(5);
|
||||
a.removeLocationId(42);
|
||||
a.removeLocationId(5);
|
||||
|
||||
TS_ASSERT_EQUALS(a.getLocationIds().size(), 1);
|
||||
TS_ASSERT_EQUALS(a.getLocationIds()[0], 23);
|
||||
}
|
||||
|
||||
void test_token_saves_component()
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
a.addComponent(component);
|
||||
|
||||
TS_ASSERT(a.getComponent<TestComponent>());
|
||||
TS_ASSERT(!a.getComponent<Test2Component>());
|
||||
|
||||
TS_ASSERT_EQUALS(a.getComponent<TestComponent>(), component.get());
|
||||
}
|
||||
|
||||
void test_token_saves_multiple_components()
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
|
||||
a.addComponent(component2);
|
||||
a.addComponent(component);
|
||||
|
||||
TS_ASSERT(a.getComponent<TestComponent>());
|
||||
TS_ASSERT(a.getComponent<Test2Component>());
|
||||
|
||||
TS_ASSERT_EQUALS(a.getComponent<TestComponent>(), component.get());
|
||||
TS_ASSERT_EQUALS(a.getComponent<Test2Component>(), component2.get());
|
||||
}
|
||||
|
||||
void test_token_removes_component()
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
|
||||
a.addComponent(component2);
|
||||
a.addComponent(component);
|
||||
std::shared_ptr<TestComponent> component3 = a.removeComponent<TestComponent>();
|
||||
|
||||
TS_ASSERT(!a.getComponent<TestComponent>());
|
||||
TS_ASSERT(a.getComponent<Test2Component>());
|
||||
|
||||
TS_ASSERT_EQUALS(component3.get(), component.get());
|
||||
TS_ASSERT_EQUALS(a.getComponent<Test2Component>(), component2.get());
|
||||
}
|
||||
|
||||
void test_token_copies_components_when_token_is_copied()
|
||||
{
|
||||
TestToken a;
|
||||
std::shared_ptr<TestComponent> component = std::make_shared<TestComponent>();
|
||||
std::shared_ptr<Test2Component> component2 = std::make_shared<Test2Component>();
|
||||
a.addComponent(component2);
|
||||
a.addComponent(component);
|
||||
|
||||
TestToken b(a);
|
||||
|
||||
TS_ASSERT(b.getComponent<TestComponent>());
|
||||
TS_ASSERT(b.getComponent<Test2Component>());
|
||||
|
||||
TS_ASSERT_DIFFERS(b.getComponent<TestComponent>(), component.get());
|
||||
TS_ASSERT_DIFFERS(b.getComponent<Test2Component>(), component2.get());
|
||||
}
|
||||
|
||||
void test_nodes_are_nodes()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
TS_ASSERT(a.isNode());
|
||||
TS_ASSERT(!a.isEdge());
|
||||
}
|
||||
|
||||
void test_edges_are_edges()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
|
||||
TS_ASSERT(!e.isNode());
|
||||
TS_ASSERT(e.isEdge());
|
||||
}
|
||||
|
||||
void test_set_type_of_node_from_constructor()
|
||||
{
|
||||
Node n(1, NodeType(NodeType::NODE_FUNCTION), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
TS_ASSERT_EQUALS(NodeType(NodeType::NODE_FUNCTION), n.getType());
|
||||
}
|
||||
|
||||
void test_set_type_of_node_from_non_indexed()
|
||||
{
|
||||
Node n(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
n.setType(NodeType(NodeType::NODE_CLASS));
|
||||
TS_ASSERT_EQUALS(NodeType(NodeType::NODE_CLASS), n.getType());
|
||||
}
|
||||
|
||||
void test_can_not_change_type_of_node_after_it_was_set()
|
||||
{
|
||||
Node n(3, NodeType(NodeType::NODE_NAMESPACE), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
n.setType(NodeType(NodeType::NODE_CLASS));
|
||||
TS_ASSERT_DIFFERS(NodeType(NodeType::NODE_CLASS), n.getType());
|
||||
}
|
||||
|
||||
void test_node_can_be_copied_and_keeps_same_id()
|
||||
{
|
||||
Node n(4, NodeType(NodeType::NODE_NAMESPACE), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node n2(n);
|
||||
|
||||
TS_ASSERT_DIFFERS(&n, &n2);
|
||||
TS_ASSERT_EQUALS(n.getId(), n2.getId());
|
||||
TS_ASSERT_EQUALS(n.getName(), n2.getName());
|
||||
TS_ASSERT_EQUALS(n.getType(), n2.getType());
|
||||
}
|
||||
|
||||
void test_node_type_bit_masking()
|
||||
{
|
||||
Node n(1, NodeType(NodeType::NODE_NAMESPACE), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
TS_ASSERT(n.isType(NodeType::NODE_FUNCTION | NodeType::NODE_NAMESPACE | NodeType::NODE_CLASS));
|
||||
TS_ASSERT(!n.isType(NodeType::NODE_FUNCTION | NodeType::NODE_METHOD | NodeType::NODE_CLASS));
|
||||
}
|
||||
|
||||
void test_get_type_of_edges()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
|
||||
TS_ASSERT_EQUALS(Edge::EDGE_USAGE, e.getType());
|
||||
}
|
||||
|
||||
void test_edge_can_be_copied_and_keeps_same_id()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
Edge e2(e, &a, &b);
|
||||
|
||||
TS_ASSERT_DIFFERS(&e, &e2);
|
||||
TS_ASSERT_EQUALS(e.getId(), e2.getId());
|
||||
TS_ASSERT_EQUALS(e.getType(), e2.getType());
|
||||
}
|
||||
|
||||
void test_edge_type_bit_masking()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(3, Edge::EDGE_USAGE, &a, &b);
|
||||
|
||||
TS_ASSERT(e.isType(Edge::EDGE_MEMBER | Edge::EDGE_CALL | Edge::EDGE_USAGE));
|
||||
TS_ASSERT(!e.isType(Edge::EDGE_MEMBER | Edge::EDGE_CALL));
|
||||
}
|
||||
|
||||
void test_node_finds_child_node()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node c(3, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"C", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(4, Edge::EDGE_MEMBER, &a, &b);
|
||||
Edge e2(5, Edge::EDGE_MEMBER, &a, &c);
|
||||
|
||||
Node* x = a.findChildNode(
|
||||
[](Node* n)
|
||||
{
|
||||
return n->getName() == L"C";
|
||||
}
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(x, &c);
|
||||
TS_ASSERT_DIFFERS(x, &b);
|
||||
}
|
||||
|
||||
void test_node_can_not_find_child_node()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node c(3, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"C", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(4, Edge::EDGE_MEMBER, &a, &b);
|
||||
Edge e2(5, Edge::EDGE_MEMBER, &a, &c);
|
||||
|
||||
Node* x = a.findChildNode(
|
||||
[](Node* n)
|
||||
{
|
||||
return n->getName() == L"D";
|
||||
}
|
||||
);
|
||||
|
||||
TS_ASSERT(!x);
|
||||
}
|
||||
|
||||
void test_node_visits_child_nodes()
|
||||
{
|
||||
Node a(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node b(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node c(3, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"C", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Edge e(4, Edge::EDGE_MEMBER, &a, &b);
|
||||
Edge e2(5, Edge::EDGE_MEMBER, &a, &c);
|
||||
|
||||
std::vector<Node*> children;
|
||||
a.forEachChildNode(
|
||||
[&children](Node* n)
|
||||
{
|
||||
return children.push_back(n);
|
||||
}
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(children.size(), 2);
|
||||
TS_ASSERT_EQUALS(children[0], &b);
|
||||
TS_ASSERT_EQUALS(children[1], &c);
|
||||
}
|
||||
|
||||
void test_graph_saves_nodes()
|
||||
{
|
||||
Graph graph;
|
||||
Node* a = graph.createNode(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node* b = graph.createNode(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
TS_ASSERT_EQUALS(2, graph.getNodeCount());
|
||||
TS_ASSERT_EQUALS(0, graph.getEdgeCount());
|
||||
|
||||
TS_ASSERT(graph.getNodeById(a->getId()));
|
||||
TS_ASSERT_EQUALS(L"A", graph.getNodeById(a->getId())->getName());
|
||||
|
||||
TS_ASSERT(graph.getNodeById(b->getId()));
|
||||
TS_ASSERT_EQUALS(L"B", graph.getNodeById(b->getId())->getName());
|
||||
|
||||
TS_ASSERT(!graph.getNodeById(0));
|
||||
}
|
||||
|
||||
void test_graph_saves_edges()
|
||||
{
|
||||
Graph graph;
|
||||
|
||||
Node* a = graph.createNode(1, NodeType(NodeType::NODE_FUNCTION), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
Node* b = graph.createNode(2, NodeType(NodeType::NODE_FUNCTION), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
Edge* e = graph.createEdge(3, Edge::EDGE_CALL, a, b);
|
||||
|
||||
TS_ASSERT_EQUALS(2, graph.getNodeCount());
|
||||
TS_ASSERT_EQUALS(1, graph.getEdgeCount());
|
||||
|
||||
TS_ASSERT(graph.getEdgeById(e->getId()));
|
||||
TS_ASSERT_EQUALS(Edge::EDGE_CALL, graph.getEdgeById(e->getId())->getType());
|
||||
}
|
||||
|
||||
void test_graph_removes_nodes()
|
||||
{
|
||||
Graph graph;
|
||||
|
||||
Node* a = graph.createNode(1, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"A", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
graph.createNode(2, NodeType(NodeType::NODE_SYMBOL), NameHierarchy(L"B", NAME_DELIMITER_CXX), DEFINITION_EXPLICIT);
|
||||
|
||||
TS_ASSERT_EQUALS(2, graph.getNodeCount());
|
||||
TS_ASSERT_EQUALS(0, graph.getEdgeCount());
|
||||
|
||||
graph.removeNode(graph.getNodeById(a->getId()));
|
||||
|
||||
TS_ASSERT_EQUALS(1, graph.getNodeCount());
|
||||
}
|
||||
|
||||
private:
|
||||
class TestToken: public Token
|
||||
{
|
||||
public:
|
||||
TestToken()
|
||||
:Token(0)
|
||||
{
|
||||
}
|
||||
|
||||
TestToken(const TestToken& other)
|
||||
: Token(other)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isNode() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool isEdge() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void addComponent(std::shared_ptr<TokenComponent> component)
|
||||
{
|
||||
Token::addComponent(component);
|
||||
}
|
||||
|
||||
template<typename ComponentType>
|
||||
std::shared_ptr<ComponentType> removeComponent()
|
||||
{
|
||||
return Token::removeComponent<ComponentType>();
|
||||
}
|
||||
|
||||
virtual std::wstring getReadableTypeString() const
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
};
|
||||
|
||||
class TestComponent: public TokenComponent
|
||||
{
|
||||
public:
|
||||
virtual std::shared_ptr<TokenComponent> copy() const
|
||||
{
|
||||
return std::make_shared<TestComponent>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class Test2Component: public TokenComponent
|
||||
{
|
||||
public:
|
||||
virtual std::shared_ptr<TokenComponent> copy() const
|
||||
{
|
||||
return std::make_shared<Test2Component>(*this);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,289 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "ApplicationSettings.h"
|
||||
#include "FileRegister.h"
|
||||
#include "IndexerCommandJava.h"
|
||||
#include "JavaEnvironmentFactory.h"
|
||||
#include "JavaParser.h"
|
||||
#include "ParserClientImpl.h"
|
||||
#include "TestIntermediateStorage.h"
|
||||
#include "TextAccess.h"
|
||||
#include "TimeStamp.h"
|
||||
#include "utility.h"
|
||||
#include "utilityJava.h"
|
||||
#include "utilityPathDetection.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
#define REQUIRE_MESSAGE(msg, cond) do { INFO(msg); REQUIRE(cond); } while((void)0, 0)
|
||||
|
||||
namespace
|
||||
{
|
||||
const bool updateExpectedOutput = false;
|
||||
const bool trackTime = true;
|
||||
size_t duration;
|
||||
|
||||
void setupJavaEnvironmentFactory()
|
||||
{
|
||||
if (!JavaEnvironmentFactory::getInstance())
|
||||
{
|
||||
std::string errorString;
|
||||
#ifdef _WIN32
|
||||
const std::string separator = ";";
|
||||
#else
|
||||
const std::string separator = ":";
|
||||
#endif
|
||||
std::string classPath = "";
|
||||
{
|
||||
const std::vector<std::wstring> jarNames = utility::getRequiredJarNames();
|
||||
for (size_t i = 0; i < jarNames.size(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
classPath += separator;
|
||||
}
|
||||
classPath += FilePath(L"../app/data/java/lib/").concatenate(jarNames[i]).str();
|
||||
}
|
||||
}
|
||||
|
||||
JavaEnvironmentFactory::createInstance(
|
||||
classPath,
|
||||
errorString
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<TextAccess> parseCode(const FilePath& sourceFilePath, const FilePath& projectDataSrcRoot, const std::vector<FilePath>& classpath)
|
||||
{
|
||||
TestIntermediateStorage storage;
|
||||
JavaParser parser(std::make_shared<ParserClientImpl>(&storage), std::make_shared<IndexerStateInfo>());
|
||||
std::shared_ptr<IndexerCommandJava> command = std::make_shared<IndexerCommandJava>(sourceFilePath, L"8", classpath);
|
||||
|
||||
TimeStamp startTime = TimeStamp::now();
|
||||
parser.buildIndex(command);
|
||||
duration += TimeStamp::now().deltaMS(startTime);
|
||||
|
||||
storage.generateStringLists();
|
||||
|
||||
return TextAccess::createFromLines(storage.m_lines);
|
||||
}
|
||||
|
||||
void processSourceFile(const std::string& projectName, const FilePath& sourceFilePath, const std::vector<FilePath>& classpath)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath("data/JavaIndexSampleProjectsTestSuite/" + projectName);
|
||||
const FilePath projectDataSrcRoot = projectDataRoot.getConcatenated(L"src");
|
||||
const FilePath projectDataExpectedOutputRoot = projectDataRoot.getConcatenated(L"expected_output");
|
||||
|
||||
std::shared_ptr<TextAccess> output = parseCode(projectDataSrcRoot.getConcatenated(sourceFilePath), projectDataSrcRoot, classpath);
|
||||
|
||||
const FilePath expectedOutputFilePath = projectDataExpectedOutputRoot.getConcatenated(utility::replace(sourceFilePath.withoutExtension().wstr() + L".txt", L"/", L"_"));
|
||||
if (updateExpectedOutput || !expectedOutputFilePath.exists())
|
||||
{
|
||||
std::ofstream expectedOutputFile;
|
||||
expectedOutputFile.open(expectedOutputFilePath.str());
|
||||
expectedOutputFile << output->getText();
|
||||
expectedOutputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<TextAccess> expectedOutput = TextAccess::createFromFile(expectedOutputFilePath);
|
||||
REQUIRE_MESSAGE(("Output does not match the expected line count for file " + sourceFilePath.str() + " in project " + projectName).c_str(), expectedOutput->getLineCount() == output->getLineCount());
|
||||
if (expectedOutput->getLineCount() == output->getLineCount())
|
||||
{
|
||||
for (size_t i = 1; i <= expectedOutput->getLineCount(); i++)
|
||||
{
|
||||
REQUIRE(expectedOutput->getLine(i) == output->getLine(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processSourceFiles(const std::string& projectName, const std::vector<FilePath>& sourceFilePaths, const std::vector<FilePath>& classpath)
|
||||
{
|
||||
duration = 0;
|
||||
for (const FilePath& filePath : sourceFilePaths)
|
||||
{
|
||||
processSourceFile(projectName, filePath, classpath);
|
||||
}
|
||||
if (trackTime)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath("data/JavaIndexSampleProjectsTestSuite/" + projectName).makeAbsolute();
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open(FilePath(projectDataRoot.str() + "/" + projectName + ".timing").str(), std::ios_base::app);
|
||||
outfile << TimeStamp::now().toString() << " - " << duration << " ms\n";
|
||||
outfile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("java sample parser can setup environment factory")
|
||||
{
|
||||
std::vector<FilePath> javaPaths = utility::getJavaRuntimePathDetector()->getPaths();
|
||||
if (!javaPaths.empty())
|
||||
{
|
||||
ApplicationSettings::getInstance()->setJavaPath(javaPaths[0]);
|
||||
}
|
||||
|
||||
setupJavaEnvironmentFactory();
|
||||
|
||||
// if this one fails, maybe your java_path in the test settings is wrong.
|
||||
REQUIRE(JavaEnvironmentFactory::getInstance().use_count() >= 1);
|
||||
}
|
||||
|
||||
TEST_CASE("index javasymbolsolver 0 6 0 project")
|
||||
{
|
||||
const std::vector<FilePath>& classpath = {
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/guava-21.0.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/javaparser-core-3.3.0.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/javaslang-2.0.3.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/javassist-3.19.0-GA.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/src/java-symbol-solver-core").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/src/java-symbol-solver-logic").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/src/java-symbol-solver-model").makeAbsolute()
|
||||
};
|
||||
|
||||
processSourceFiles(
|
||||
"JavaSymbolSolver060",
|
||||
{
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/core/resolution/Context.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/core/resolution/ContextHelper.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparser/Navigator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparser/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/InferenceContext.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/ObjectProvider.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/AccessLevel.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/Declaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/EnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/FieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/HasAccessLevel.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/InterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/MethodAmbiguityException.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/MethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/MethodLikeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/TypeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/TypeParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/TypeParametrizable.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ValueDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/methods/MethodUsage.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/UnsolvedSymbolException.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/Value.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/ArrayType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/LambdaConstraintType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/NullType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/PrimitiveType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/ReferenceType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/Type.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/TypeTransformer.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/TypeVariable.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/VoidType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/Wildcard.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametersMap.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParameterValueProvider.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametrized.java")
|
||||
},
|
||||
classpath
|
||||
);
|
||||
}
|
||||
@@ -1,289 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "ApplicationSettings.h"
|
||||
#include "FileRegister.h"
|
||||
#include "IndexerCommandJava.h"
|
||||
#include "JavaEnvironmentFactory.h"
|
||||
#include "JavaParser.h"
|
||||
#include "ParserClientImpl.h"
|
||||
#include "TestIntermediateStorage.h"
|
||||
#include "TextAccess.h"
|
||||
#include "utility.h"
|
||||
#include "utilityJava.h"
|
||||
#include "utilityPathDetection.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
class JavaIndexSampleProjectsTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
static const bool s_updateExpectedOutput = false;
|
||||
static const bool s_trackTime = true;
|
||||
|
||||
void test_java_parser_can_setup_environment_factory()
|
||||
{
|
||||
std::vector<FilePath> javaPaths = utility::getJavaRuntimePathDetector()->getPaths();
|
||||
if (!javaPaths.empty())
|
||||
{
|
||||
ApplicationSettings::getInstance()->setJavaPath(javaPaths[0]);
|
||||
}
|
||||
|
||||
setupJavaEnvironmentFactory();
|
||||
|
||||
// if this one fails, maybe your java_path in the test settings is wrong.
|
||||
TS_ASSERT_LESS_THAN_EQUALS(1, JavaEnvironmentFactory::getInstance().use_count());
|
||||
}
|
||||
|
||||
void test_index_javasymbolsolver_0_6_0_project()
|
||||
{
|
||||
const std::vector<FilePath>& classpath = {
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/guava-21.0.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/javaparser-core-3.3.0.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/javaslang-2.0.3.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/lib/javassist-3.19.0-GA.jar").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/src/java-symbol-solver-core").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/src/java-symbol-solver-logic").makeAbsolute(),
|
||||
FilePath(L"data/JavaIndexSampleProjectsTestSuite/JavaSymbolSolver060/src/java-symbol-solver-model").makeAbsolute()
|
||||
};
|
||||
|
||||
processSourceFiles(
|
||||
"JavaSymbolSolver060",
|
||||
{
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/core/resolution/Context.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/core/resolution/ContextHelper.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparser/Navigator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparser/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/javassistmodel/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-core/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/InferenceContext.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java"),
|
||||
FilePath(L"java-symbol-solver-logic/com/github/javaparser/symbolsolver/logic/ObjectProvider.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/AccessLevel.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ClassDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ConstructorDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/Declaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/EnumDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/FieldDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/HasAccessLevel.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/InterfaceDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/MethodAmbiguityException.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/MethodDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/MethodLikeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/TypeDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/TypeParameterDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/TypeParametrizable.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/declarations/ValueDeclaration.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/methods/MethodUsage.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/UnsolvedSymbolException.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/resolution/Value.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/ArrayType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/LambdaConstraintType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/NullType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/PrimitiveType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/ReferenceType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/Type.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/TypeTransformer.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/TypeVariable.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/VoidType.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/Wildcard.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametersMap.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParameterValueProvider.java"),
|
||||
FilePath(L"java-symbol-solver-model/com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametrized.java")
|
||||
},
|
||||
classpath
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
void setupJavaEnvironmentFactory()
|
||||
{
|
||||
if (!JavaEnvironmentFactory::getInstance())
|
||||
{
|
||||
std::string errorString;
|
||||
#ifdef _WIN32
|
||||
const std::string separator = ";";
|
||||
#else
|
||||
const std::string separator = ":";
|
||||
#endif
|
||||
std::string classPath = "";
|
||||
{
|
||||
const std::vector<std::wstring> jarNames = utility::getRequiredJarNames();
|
||||
for (size_t i = 0; i < jarNames.size(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
classPath += separator;
|
||||
}
|
||||
classPath += FilePath(L"../app/data/java/lib/").concatenate(jarNames[i]).str();
|
||||
}
|
||||
}
|
||||
|
||||
JavaEnvironmentFactory::createInstance(
|
||||
classPath,
|
||||
errorString
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void processSourceFiles(const std::string& projectName, const std::vector<FilePath>& sourceFilePaths, const std::vector<FilePath>& classpath)
|
||||
{
|
||||
m_duration = 0;
|
||||
for (const FilePath& filePath : sourceFilePaths)
|
||||
{
|
||||
processSourceFile(projectName, filePath, classpath);
|
||||
}
|
||||
if (s_trackTime)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath("data/JavaIndexSampleProjectsTestSuite/" + projectName).makeAbsolute();
|
||||
|
||||
std::ofstream outfile;
|
||||
outfile.open(FilePath(projectDataRoot.str() + "/" + projectName + ".timing").str(), std::ios_base::app);
|
||||
outfile << TimeStamp::now().toString() << " - " << m_duration << " ms\n";
|
||||
outfile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void processSourceFile(const std::string& projectName, const FilePath& sourceFilePath, const std::vector<FilePath>& classpath)
|
||||
{
|
||||
const FilePath projectDataRoot = FilePath("data/JavaIndexSampleProjectsTestSuite/" + projectName);
|
||||
const FilePath projectDataSrcRoot = projectDataRoot.getConcatenated(L"src");
|
||||
const FilePath projectDataExpectedOutputRoot = projectDataRoot.getConcatenated(L"expected_output");
|
||||
|
||||
std::shared_ptr<TextAccess> output = parseCode(projectDataSrcRoot.getConcatenated(sourceFilePath), projectDataSrcRoot, classpath);
|
||||
|
||||
const FilePath expectedOutputFilePath = projectDataExpectedOutputRoot.getConcatenated(utility::replace(sourceFilePath.withoutExtension().wstr() + L".txt", L"/", L"_"));
|
||||
if (s_updateExpectedOutput || !expectedOutputFilePath.exists())
|
||||
{
|
||||
std::ofstream expectedOutputFile;
|
||||
expectedOutputFile.open(expectedOutputFilePath.str());
|
||||
expectedOutputFile << output->getText();
|
||||
expectedOutputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<TextAccess> expectedOutput = TextAccess::createFromFile(expectedOutputFilePath);
|
||||
TSM_ASSERT_EQUALS("Output does not match the expected line count for file " + sourceFilePath.str() + " in project " + projectName, expectedOutput->getLineCount(), output->getLineCount());
|
||||
if (expectedOutput->getLineCount() == output->getLineCount())
|
||||
{
|
||||
for (size_t i = 1; i <= expectedOutput->getLineCount(); i++)
|
||||
{
|
||||
TS_ASSERT_EQUALS(expectedOutput->getLine(i), output->getLine(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<TextAccess> parseCode(const FilePath& sourceFilePath, const FilePath& projectDataSrcRoot, const std::vector<FilePath>& classpath)
|
||||
{
|
||||
TestIntermediateStorage storage;
|
||||
JavaParser parser(std::make_shared<ParserClientImpl>(&storage), std::make_shared<IndexerStateInfo>());
|
||||
std::shared_ptr<IndexerCommandJava> command = std::make_shared<IndexerCommandJava>(sourceFilePath, L"8", classpath);
|
||||
|
||||
TimeStamp startTime = TimeStamp::now();
|
||||
parser.buildIndex(command);
|
||||
m_duration += TimeStamp::now().deltaMS(startTime);
|
||||
|
||||
storage.generateStringLists();
|
||||
|
||||
return TextAccess::createFromLines(storage.m_lines);
|
||||
}
|
||||
|
||||
size_t m_duration;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,289 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "LogManagerImplementation.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestLogger : public Logger
|
||||
{
|
||||
public:
|
||||
TestLogger();
|
||||
|
||||
void reset();
|
||||
int getMessageCount() const;
|
||||
int getWarningCount() const;
|
||||
int getErrorCount() const;
|
||||
|
||||
std::wstring getLastInfo() const;
|
||||
std::wstring getLastWarning() const;
|
||||
std::wstring getLastError() const;
|
||||
|
||||
private:
|
||||
void logInfo(const LogMessage& message) override;
|
||||
void logWarning(const LogMessage& message) override;
|
||||
void logError(const LogMessage& message) override;
|
||||
|
||||
int m_logMessageCount;
|
||||
int m_logWarningCount;
|
||||
int m_logErrorCount;
|
||||
|
||||
std::wstring m_lastInfo;
|
||||
std::wstring m_lastWarning;
|
||||
std::wstring m_lastError;
|
||||
};
|
||||
|
||||
TestLogger::TestLogger()
|
||||
: Logger("TestLogger")
|
||||
, m_logMessageCount(0)
|
||||
, m_logWarningCount(0)
|
||||
, m_logErrorCount(0)
|
||||
, m_lastInfo(L"")
|
||||
, m_lastWarning(L"")
|
||||
, m_lastError(L"")
|
||||
{
|
||||
}
|
||||
|
||||
void TestLogger::reset()
|
||||
{
|
||||
m_logMessageCount = 0;
|
||||
m_logWarningCount = 0;
|
||||
m_logErrorCount = 0;
|
||||
}
|
||||
|
||||
int TestLogger::getMessageCount() const
|
||||
{
|
||||
return m_logMessageCount;
|
||||
}
|
||||
|
||||
int TestLogger::getWarningCount() const
|
||||
{
|
||||
return m_logWarningCount;
|
||||
}
|
||||
|
||||
int TestLogger::getErrorCount() const
|
||||
{
|
||||
return m_logErrorCount;
|
||||
}
|
||||
|
||||
std::wstring TestLogger::getLastInfo() const
|
||||
{
|
||||
return m_lastInfo;
|
||||
}
|
||||
|
||||
std::wstring TestLogger::getLastWarning() const
|
||||
{
|
||||
return m_lastWarning;
|
||||
}
|
||||
|
||||
std::wstring TestLogger::getLastError() const
|
||||
{
|
||||
return m_lastError;
|
||||
}
|
||||
|
||||
void TestLogger::logInfo(const LogMessage& message)
|
||||
{
|
||||
m_lastInfo = message.message;
|
||||
m_logMessageCount++;
|
||||
}
|
||||
|
||||
void TestLogger::logWarning(const LogMessage& message)
|
||||
{
|
||||
m_lastWarning = message.message;
|
||||
m_logWarningCount++;
|
||||
}
|
||||
|
||||
void TestLogger::logError(const LogMessage& message)
|
||||
{
|
||||
m_lastError = message.message;
|
||||
m_logErrorCount++;
|
||||
}
|
||||
|
||||
|
||||
void addTestLogger(LogManagerImplementation* logManagerImplementation, const unsigned int loggerCount)
|
||||
{
|
||||
for (unsigned int i = 0; i < loggerCount; i++)
|
||||
{
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
logManagerImplementation->addLogger(logger);
|
||||
}
|
||||
}
|
||||
|
||||
void removeTestLoggers(LogManagerImplementation* logManagerImplementation)
|
||||
{
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
logManagerImplementation->removeLoggersByType(logger->getType());
|
||||
}
|
||||
|
||||
void addAndRemoveTestLogger(LogManagerImplementation* logManagerImplementation, const unsigned int loggerCount)
|
||||
{
|
||||
addTestLogger(logManagerImplementation, loggerCount);
|
||||
removeTestLoggers(logManagerImplementation);
|
||||
}
|
||||
|
||||
void logSomeMessages(
|
||||
LogManagerImplementation* logManagerImplementation,
|
||||
const std::wstring& message,
|
||||
const unsigned int messageCount
|
||||
)
|
||||
{
|
||||
for (unsigned int i = 0; i < messageCount; i++)
|
||||
{
|
||||
logManagerImplementation->logInfo(message, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation->logWarning(message, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation->logError(message, __FILE__, __FUNCTION__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("new logger can be added to manager")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
int countBeforeAdd = logManagerImplementation.getLoggerCount();
|
||||
logManagerImplementation.addLogger(logger);
|
||||
int countAfterAdd = logManagerImplementation.getLoggerCount();
|
||||
logManagerImplementation.removeLogger(logger);
|
||||
|
||||
REQUIRE(1 == countAfterAdd - countBeforeAdd);
|
||||
}
|
||||
|
||||
TEST_CASE("logger can be removed from manager")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
int countBeforeAdd = logManagerImplementation.getLoggerCount();
|
||||
logManagerImplementation.addLogger(logger);
|
||||
logManagerImplementation.removeLogger(logger);
|
||||
int countAfterRemove = logManagerImplementation.getLoggerCount();
|
||||
|
||||
REQUIRE(countBeforeAdd == countAfterRemove);
|
||||
}
|
||||
|
||||
TEST_CASE("logger logs message")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
const std::wstring log = L"test";
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
logManagerImplementation.logInfo(log, __FILE__, __FUNCTION__, __LINE__);
|
||||
const int logCount = logger->getMessageCount();
|
||||
const std::wstring lastLog = logger->getLastInfo();
|
||||
|
||||
REQUIRE(1 == logCount);
|
||||
REQUIRE(log == lastLog);
|
||||
}
|
||||
|
||||
TEST_CASE("logger logs warning")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
const std::wstring log = L"test";
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
logManagerImplementation.logWarning(log, __FILE__, __FUNCTION__, __LINE__);
|
||||
const int logCount = logger->getWarningCount();
|
||||
const std::wstring lastLog = logger->getLastWarning();
|
||||
|
||||
REQUIRE(1 == logCount);
|
||||
REQUIRE(log == lastLog);
|
||||
}
|
||||
|
||||
TEST_CASE("logger logs error")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::wstring log = L"test";
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
logManagerImplementation.logError(log, __FILE__, __FUNCTION__, __LINE__);
|
||||
const int logCount = logger->getErrorCount();
|
||||
const std::wstring lastLog = logger->getLastError();
|
||||
|
||||
REQUIRE(1 == logCount);
|
||||
REQUIRE(log == lastLog);
|
||||
}
|
||||
|
||||
TEST_CASE("logger logs only logs of defined log level")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::wstring info = L"info";
|
||||
std::wstring warning = L"warning";
|
||||
std::wstring error = L"error";
|
||||
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logger->setLogLevel(Logger::LOG_INFOS | Logger::LOG_ERRORS);
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
logManagerImplementation.logInfo(info, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation.logWarning(warning, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation.logError(error, __FILE__, __FUNCTION__, __LINE__);
|
||||
|
||||
REQUIRE(1 == logger->getMessageCount());
|
||||
REQUIRE(0 == logger->getWarningCount());
|
||||
REQUIRE(1 == logger->getErrorCount());
|
||||
|
||||
REQUIRE(info == logger->getLastInfo());
|
||||
REQUIRE(error == logger->getLastError());
|
||||
}
|
||||
|
||||
TEST_CASE("new logger can be added to manager threaded")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
unsigned int loggerCount = 100;
|
||||
|
||||
std::thread thread0(addTestLogger, &logManagerImplementation, loggerCount);
|
||||
std::thread thread1(addTestLogger, &logManagerImplementation, loggerCount);
|
||||
|
||||
thread0.join();
|
||||
thread1.join();
|
||||
|
||||
REQUIRE(loggerCount * 2 == logManagerImplementation.getLoggerCount());
|
||||
}
|
||||
|
||||
TEST_CASE("logger can be removed from manager threaded")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
unsigned int loggerCount = 100;
|
||||
|
||||
std::thread thread0(addAndRemoveTestLogger, &logManagerImplementation, loggerCount);
|
||||
std::thread thread1(addAndRemoveTestLogger, &logManagerImplementation, loggerCount);
|
||||
|
||||
thread0.join();
|
||||
thread1.join();
|
||||
|
||||
REQUIRE(0 == logManagerImplementation.getLoggerCount());
|
||||
}
|
||||
|
||||
TEST_CASE("logger logs threaded")
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::wstring log = L"foo";
|
||||
unsigned int messageCount = 100;
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
std::thread thread0(logSomeMessages, &logManagerImplementation, log, messageCount);
|
||||
std::thread thread1(logSomeMessages, &logManagerImplementation, log, messageCount);
|
||||
|
||||
thread0.join();
|
||||
thread1.join();
|
||||
|
||||
REQUIRE(logger->getLastError() == log);
|
||||
REQUIRE(messageCount * 6 == logger->getErrorCount() + logger->getWarningCount() + logger->getMessageCount());
|
||||
}
|
||||
@@ -1,291 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "LogManagerImplementation.h"
|
||||
|
||||
class LogManagerTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_new_logger_can_be_added_to_manager()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
int countBeforeAdd = logManagerImplementation.getLoggerCount();
|
||||
logManagerImplementation.addLogger(logger);
|
||||
int countAfterAdd = logManagerImplementation.getLoggerCount();
|
||||
logManagerImplementation.removeLogger(logger);
|
||||
|
||||
TS_ASSERT_EQUALS(1, countAfterAdd - countBeforeAdd);
|
||||
}
|
||||
|
||||
void test_logger_can_be_removed_from_manager()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
int countBeforeAdd = logManagerImplementation.getLoggerCount();
|
||||
logManagerImplementation.addLogger(logger);
|
||||
logManagerImplementation.removeLogger(logger);
|
||||
int countAfterRemove = logManagerImplementation.getLoggerCount();
|
||||
|
||||
TS_ASSERT_EQUALS(countBeforeAdd, countAfterRemove);
|
||||
}
|
||||
|
||||
void test_logger_logs_message()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
const std::wstring log = L"test";
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
logManagerImplementation.logInfo(log, __FILE__, __FUNCTION__, __LINE__);
|
||||
const int logCount = logger->getMessageCount();
|
||||
const std::wstring lastLog = logger->getLastInfo();
|
||||
|
||||
TS_ASSERT_EQUALS(1, logCount);
|
||||
TS_ASSERT_EQUALS(log, lastLog);
|
||||
}
|
||||
|
||||
void test_logger_logs_warning()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
const std::wstring log = L"test";
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
logManagerImplementation.logWarning(log, __FILE__, __FUNCTION__, __LINE__);
|
||||
const int logCount = logger->getWarningCount();
|
||||
const std::wstring lastLog = logger->getLastWarning();
|
||||
|
||||
TS_ASSERT_EQUALS(1, logCount);
|
||||
TS_ASSERT_EQUALS(log, lastLog);
|
||||
}
|
||||
|
||||
void test_logger_logs_error()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::wstring log = L"test";
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
logManagerImplementation.logError(log, __FILE__, __FUNCTION__, __LINE__);
|
||||
const int logCount = logger->getErrorCount();
|
||||
const std::wstring lastLog = logger->getLastError();
|
||||
|
||||
TS_ASSERT_EQUALS(1, logCount);
|
||||
TS_ASSERT_EQUALS(log, lastLog);
|
||||
}
|
||||
|
||||
void test_logger_logs_only_logs_of_defined_log_level()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::wstring info = L"info";
|
||||
std::wstring warning = L"warning";
|
||||
std::wstring error = L"error";
|
||||
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
|
||||
logger->setLogLevel(Logger::LOG_INFOS | Logger::LOG_ERRORS);
|
||||
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
logManagerImplementation.logInfo(info, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation.logWarning(warning, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation.logError(error, __FILE__, __FUNCTION__, __LINE__);
|
||||
|
||||
TS_ASSERT_EQUALS(1, logger->getMessageCount());
|
||||
TS_ASSERT_EQUALS(0, logger->getWarningCount());
|
||||
TS_ASSERT_EQUALS(1, logger->getErrorCount());
|
||||
|
||||
TS_ASSERT_EQUALS(info, logger->getLastInfo());
|
||||
TS_ASSERT_EQUALS(error, logger->getLastError());
|
||||
}
|
||||
|
||||
void test_new_logger_can_be_added_to_manager_threaded()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
unsigned int loggerCount = 100;
|
||||
|
||||
std::thread thread0(addTestLogger, &logManagerImplementation, loggerCount);
|
||||
std::thread thread1(addTestLogger, &logManagerImplementation, loggerCount);
|
||||
|
||||
thread0.join();
|
||||
thread1.join();
|
||||
|
||||
TS_ASSERT_EQUALS(loggerCount * 2, logManagerImplementation.getLoggerCount());
|
||||
}
|
||||
|
||||
void test_logger_can_be_removed_from_manager_threaded()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
unsigned int loggerCount = 100;
|
||||
|
||||
std::thread thread0(addAndRemoveTestLogger, &logManagerImplementation, loggerCount);
|
||||
std::thread thread1(addAndRemoveTestLogger, &logManagerImplementation, loggerCount);
|
||||
|
||||
thread0.join();
|
||||
thread1.join();
|
||||
|
||||
TS_ASSERT_EQUALS(0, logManagerImplementation.getLoggerCount());
|
||||
}
|
||||
|
||||
void test_logger_logs_threaded()
|
||||
{
|
||||
LogManagerImplementation logManagerImplementation;
|
||||
|
||||
std::wstring log = L"foo";
|
||||
unsigned int messageCount = 100;
|
||||
std::shared_ptr<TestLogger> logger = std::make_shared<TestLogger>();
|
||||
logManagerImplementation.addLogger(logger);
|
||||
|
||||
std::thread thread0(logSomeMessages, &logManagerImplementation, log, messageCount);
|
||||
std::thread thread1(logSomeMessages, &logManagerImplementation, log, messageCount);
|
||||
|
||||
thread0.join();
|
||||
thread1.join();
|
||||
|
||||
TS_ASSERT_EQUALS(logger->getLastError(), log);
|
||||
TS_ASSERT_EQUALS(messageCount * 6, logger->getErrorCount() + logger->getWarningCount() + logger->getMessageCount());
|
||||
}
|
||||
|
||||
private:
|
||||
static void addTestLogger(LogManagerImplementation* logManagerImplementation, const unsigned int loggerCount)
|
||||
{
|
||||
for(unsigned int i = 0; i < loggerCount; i++)
|
||||
{
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
logManagerImplementation->addLogger(logger);
|
||||
}
|
||||
}
|
||||
|
||||
static void removeTestLoggers(LogManagerImplementation* logManagerImplementation)
|
||||
{
|
||||
std::shared_ptr<Logger> logger = std::make_shared<TestLogger>();
|
||||
logManagerImplementation->removeLoggersByType(logger->getType());
|
||||
}
|
||||
|
||||
static void addAndRemoveTestLogger(LogManagerImplementation* logManagerImplementation, const unsigned int loggerCount)
|
||||
{
|
||||
addTestLogger(logManagerImplementation, loggerCount);
|
||||
removeTestLoggers(logManagerImplementation);
|
||||
}
|
||||
|
||||
static void logSomeMessages(
|
||||
LogManagerImplementation* logManagerImplementation,
|
||||
const std::wstring& message,
|
||||
const unsigned int messageCount
|
||||
)
|
||||
{
|
||||
for(unsigned int i = 0; i < messageCount; i++)
|
||||
{
|
||||
logManagerImplementation->logInfo(message, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation->logWarning(message, __FILE__, __FUNCTION__, __LINE__);
|
||||
logManagerImplementation->logError(message, __FILE__, __FUNCTION__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
class TestLogger: public Logger
|
||||
{
|
||||
public:
|
||||
TestLogger();
|
||||
|
||||
void reset();
|
||||
int getMessageCount() const;
|
||||
int getWarningCount() const;
|
||||
int getErrorCount() const;
|
||||
|
||||
std::wstring getLastInfo() const;
|
||||
std::wstring getLastWarning() const;
|
||||
std::wstring getLastError() const;
|
||||
|
||||
private:
|
||||
void logInfo(const LogMessage& message) override;
|
||||
void logWarning(const LogMessage& message) override;
|
||||
void logError(const LogMessage& message) override;
|
||||
|
||||
int m_logMessageCount;
|
||||
int m_logWarningCount;
|
||||
int m_logErrorCount;
|
||||
|
||||
std::wstring m_lastInfo;
|
||||
std::wstring m_lastWarning;
|
||||
std::wstring m_lastError;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
LogManagerTestSuite::TestLogger::TestLogger()
|
||||
: Logger("TestLogger")
|
||||
, m_logMessageCount(0)
|
||||
, m_logWarningCount(0)
|
||||
, m_logErrorCount(0)
|
||||
, m_lastInfo(L"")
|
||||
, m_lastWarning(L"")
|
||||
, m_lastError(L"")
|
||||
{
|
||||
}
|
||||
|
||||
void LogManagerTestSuite::TestLogger::reset()
|
||||
{
|
||||
m_logMessageCount = 0;
|
||||
m_logWarningCount = 0;
|
||||
m_logErrorCount = 0;
|
||||
}
|
||||
|
||||
int LogManagerTestSuite::TestLogger::getMessageCount() const
|
||||
{
|
||||
return m_logMessageCount;
|
||||
}
|
||||
|
||||
int LogManagerTestSuite::TestLogger::getWarningCount() const
|
||||
{
|
||||
return m_logWarningCount;
|
||||
}
|
||||
|
||||
int LogManagerTestSuite::TestLogger::getErrorCount() const
|
||||
{
|
||||
return m_logErrorCount;
|
||||
}
|
||||
|
||||
std::wstring LogManagerTestSuite::TestLogger::getLastInfo() const
|
||||
{
|
||||
return m_lastInfo;
|
||||
}
|
||||
|
||||
std::wstring LogManagerTestSuite::TestLogger::getLastWarning() const
|
||||
{
|
||||
return m_lastWarning;
|
||||
}
|
||||
|
||||
std::wstring LogManagerTestSuite::TestLogger::getLastError() const
|
||||
{
|
||||
return m_lastError;
|
||||
}
|
||||
|
||||
void LogManagerTestSuite::TestLogger::logInfo(const LogMessage& message)
|
||||
{
|
||||
m_lastInfo = message.message;
|
||||
m_logMessageCount++;
|
||||
}
|
||||
|
||||
void LogManagerTestSuite::TestLogger::logWarning(const LogMessage& message)
|
||||
{
|
||||
m_lastWarning = message.message;
|
||||
m_logWarningCount++;
|
||||
}
|
||||
|
||||
void LogManagerTestSuite::TestLogger::logError(const LogMessage& message)
|
||||
{
|
||||
m_lastError = message.message;
|
||||
m_logErrorCount++;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "LowMemoryStringMap.h"
|
||||
#include "TextAccess.h"
|
||||
#include "types.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
TEST_CASE("roughly everything")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
|
||||
map.add("abcdefg", 2);
|
||||
map.add("abcdefgerlitz", 1);
|
||||
map.add("abcdefghij", 3);
|
||||
map.add("abc", 4);
|
||||
|
||||
// map.print(std::cout);
|
||||
// std::cout << std::endl << map.getByteSize() << " : " << map.getUncompressedByteSize() << std::endl;
|
||||
|
||||
REQUIRE(map.find("abcdefgerlitz") == 1);
|
||||
REQUIRE(map.find("abcdefg") == 2);
|
||||
REQUIRE(map.find("abcdefghij") == 3);
|
||||
REQUIRE(map.find("abc") == 4);
|
||||
REQUIRE(map.find("bc") == 0);
|
||||
REQUIRE(map.find("") == 0);
|
||||
REQUIRE(map.find(";asdfl;kjasd;flkasdf") == 0);
|
||||
|
||||
// TS_ASSERT(map.getByteSize() < map.getUncompressedByteSize());
|
||||
}
|
||||
|
||||
TEST_CASE("cannot find element after creation")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
|
||||
REQUIRE(map.find("a") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("find element")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("a", 1);
|
||||
|
||||
REQUIRE(map.find("a") == 1);
|
||||
REQUIRE(map.find("b") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("find fully different elements")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("a", 1);
|
||||
map.add("b", 2);
|
||||
|
||||
REQUIRE(map.find("a") == 1);
|
||||
REQUIRE(map.find("b") == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("find similar short elements")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("ab", 1);
|
||||
map.add("ac", 2);
|
||||
|
||||
REQUIRE(map.find("ab") == 1);
|
||||
REQUIRE(map.find("ac") == 2);
|
||||
REQUIRE(map.find("bc") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("find similar long elements")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("aaaaabbbbb", 1);
|
||||
map.add("aaaaaccccc", 2);
|
||||
map.add("aaaaccccc", 3);
|
||||
map.add("aaaccccc", 4);
|
||||
|
||||
REQUIRE(map.find("aaaaabbbbb") == 1);
|
||||
REQUIRE(map.find("aaaaaccccc") == 2);
|
||||
REQUIRE(map.find("aaaaacccccc") == 0);
|
||||
REQUIRE(map.find("aacc") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("add twice")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("abba", 1);
|
||||
map.add("abba", 2);
|
||||
|
||||
REQUIRE(map.find("abba") == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("find parent child elements")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("a", 1);
|
||||
map.add("ab", 2);
|
||||
|
||||
REQUIRE(map.find("a") == 1);
|
||||
REQUIRE(map.find("ab") == 2);
|
||||
REQUIRE(map.find("b") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("find long parent child elements")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("ababaaa", 1);
|
||||
map.add("aba", 2);
|
||||
|
||||
REQUIRE(map.find("ababaaa") == 1);
|
||||
REQUIRE(map.find("aba") == 2);
|
||||
REQUIRE(map.find("ab") == 0);
|
||||
REQUIRE(map.find("") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("find long similar prefix elements")
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("ababababaab", 1);
|
||||
map.add("abababababababaccc", 2);
|
||||
map.add("abababababababaer", 3);
|
||||
map.add("abababababababber", 4);
|
||||
map.add("abababababababaaaa", 5);
|
||||
|
||||
// map.print(std::cout);
|
||||
// std::cout << std::endl << map.getByteSize() << " : " << map.getUncompressedByteSize() << std::endl;
|
||||
|
||||
REQUIRE(map.find("ababababaab") == 1);
|
||||
REQUIRE(map.find("abababababababaccc") == 2);
|
||||
REQUIRE(map.find("abababababababaer") == 3);
|
||||
REQUIRE(map.find("abababababababber") == 4);
|
||||
REQUIRE(map.find("abababababababaaaa") == 5);
|
||||
REQUIRE(map.find("abababab") == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("wstring")
|
||||
{
|
||||
LowMemoryStringMap<std::wstring, Id, 0> map;
|
||||
|
||||
FilePath filePath(L"data/LowMemoryStringMapTestSuite/names.txt");
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
std::vector<std::wstring> names;
|
||||
for (std::string line : textAccess->getAllLines())
|
||||
{
|
||||
names.emplace_back(utility::decodeFromUtf8(line.substr(0, line.find("\n"))));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++)
|
||||
{
|
||||
map.add(names[i], i);
|
||||
}
|
||||
|
||||
// map.print(std::wcout);
|
||||
// std::cout << std::endl << map.getByteSize() << " : " << map.getUncompressedByteSize() << std::endl;
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++)
|
||||
{
|
||||
REQUIRE(map.find(names[i]) == i);
|
||||
}
|
||||
|
||||
// TS_ASSERT(map.getByteSize() < map.getUncompressedByteSize());
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "LowMemoryStringMap.h"
|
||||
#include "TextAccess.h"
|
||||
#include "types.h"
|
||||
#include "utilityString.h"
|
||||
|
||||
class LowMemoryStringMapTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_roughly_everything()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
|
||||
map.add("abcdefg", 2);
|
||||
map.add("abcdefgerlitz", 1);
|
||||
map.add("abcdefghij", 3);
|
||||
map.add("abc", 4);
|
||||
|
||||
// map.print(std::cout);
|
||||
// std::cout << std::endl << map.getByteSize() << " : " << map.getUncompressedByteSize() << std::endl;
|
||||
|
||||
TS_ASSERT(map.find("abcdefgerlitz") == 1);
|
||||
TS_ASSERT(map.find("abcdefg") == 2);
|
||||
TS_ASSERT(map.find("abcdefghij") == 3);
|
||||
TS_ASSERT(map.find("abc") == 4);
|
||||
TS_ASSERT(map.find("bc") == 0);
|
||||
TS_ASSERT(map.find("") == 0);
|
||||
TS_ASSERT(map.find(";asdfl;kjasd;flkasdf") == 0);
|
||||
|
||||
// TS_ASSERT(map.getByteSize() < map.getUncompressedByteSize());
|
||||
}
|
||||
|
||||
void test_cannot_find_element_after_creation()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
|
||||
TS_ASSERT(map.find("a") == 0);
|
||||
}
|
||||
|
||||
void test_find_element()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("a", 1);
|
||||
|
||||
TS_ASSERT(map.find("a") == 1);
|
||||
TS_ASSERT(map.find("b") == 0);
|
||||
}
|
||||
|
||||
void test_find_fully_different_elements()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("a", 1);
|
||||
map.add("b", 2);
|
||||
|
||||
TS_ASSERT(map.find("a") == 1);
|
||||
TS_ASSERT(map.find("b") == 2);
|
||||
}
|
||||
|
||||
void test_find_similar_short_elements()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("ab", 1);
|
||||
map.add("ac", 2);
|
||||
|
||||
TS_ASSERT(map.find("ab") == 1);
|
||||
TS_ASSERT(map.find("ac") == 2);
|
||||
TS_ASSERT(map.find("bc") == 0);
|
||||
}
|
||||
|
||||
void test_find_similar_long_elements()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("aaaaabbbbb", 1);
|
||||
map.add("aaaaaccccc", 2);
|
||||
map.add("aaaaccccc", 3);
|
||||
map.add("aaaccccc", 4);
|
||||
|
||||
TS_ASSERT(map.find("aaaaabbbbb") == 1);
|
||||
TS_ASSERT(map.find("aaaaaccccc") == 2);
|
||||
TS_ASSERT(map.find("aaaaacccccc") == 0);
|
||||
TS_ASSERT(map.find("aacc") == 0);
|
||||
}
|
||||
|
||||
void test_add_twice()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("abba", 1);
|
||||
map.add("abba", 2);
|
||||
|
||||
TS_ASSERT(map.find("abba") == 1);
|
||||
}
|
||||
|
||||
void test_find_parent_child_elements()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("a", 1);
|
||||
map.add("ab", 2);
|
||||
|
||||
TS_ASSERT(map.find("a") == 1);
|
||||
TS_ASSERT(map.find("ab") == 2);
|
||||
TS_ASSERT(map.find("b") == 0);
|
||||
}
|
||||
|
||||
void test_find_long_parent_child_elements()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("ababaaa", 1);
|
||||
map.add("aba", 2);
|
||||
|
||||
TS_ASSERT(map.find("ababaaa") == 1);
|
||||
TS_ASSERT(map.find("aba") == 2);
|
||||
TS_ASSERT(map.find("ab") == 0);
|
||||
TS_ASSERT(map.find("") == 0);
|
||||
}
|
||||
|
||||
void test_find_long_similar_prefix_elements()
|
||||
{
|
||||
LowMemoryStringMap<std::string, Id, 0> map;
|
||||
map.add("ababababaab", 1);
|
||||
map.add("abababababababaccc", 2);
|
||||
map.add("abababababababaer", 3);
|
||||
map.add("abababababababber", 4);
|
||||
map.add("abababababababaaaa", 5);
|
||||
|
||||
// map.print(std::cout);
|
||||
// std::cout << std::endl << map.getByteSize() << " : " << map.getUncompressedByteSize() << std::endl;
|
||||
|
||||
TS_ASSERT(map.find("ababababaab") == 1);
|
||||
TS_ASSERT(map.find("abababababababaccc") == 2);
|
||||
TS_ASSERT(map.find("abababababababaer") == 3);
|
||||
TS_ASSERT(map.find("abababababababber") == 4);
|
||||
TS_ASSERT(map.find("abababababababaaaa") == 5);
|
||||
TS_ASSERT(map.find("abababab") == 0);
|
||||
}
|
||||
|
||||
void test_wstring()
|
||||
{
|
||||
LowMemoryStringMap<std::wstring, Id, 0> map;
|
||||
|
||||
FilePath filePath(L"data/LowMemoryStringMapTestSuite/names.txt");
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
std::vector<std::wstring> names;
|
||||
for (std::string line : textAccess->getAllLines())
|
||||
{
|
||||
names.emplace_back(utility::decodeFromUtf8(line.substr(0, line.find("\n"))));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++)
|
||||
{
|
||||
map.add(names[i], i);
|
||||
}
|
||||
|
||||
// map.print(std::wcout);
|
||||
// std::cout << std::endl << map.getByteSize() << " : " << map.getUncompressedByteSize() << std::endl;
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++)
|
||||
{
|
||||
TS_ASSERT(map.find(names[i]) == i);
|
||||
}
|
||||
|
||||
// TS_ASSERT(map.getByteSize() < map.getUncompressedByteSize());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,470 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "MatrixBase.h"
|
||||
#include "VectorBase.h"
|
||||
namespace
|
||||
{
|
||||
/**
|
||||
* C++ functions can't return statically allocated arrays.
|
||||
* I don't want to use dynamically allocated arrays, so here's my work around for that...
|
||||
*
|
||||
* Update: acutally they can... see MatrixBase [] operator (in MatrixBase.cpp)
|
||||
*/
|
||||
template<class T>
|
||||
struct Array3x5
|
||||
{
|
||||
T array[3][5];
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Array5x3
|
||||
{
|
||||
T array[5][3];
|
||||
};
|
||||
|
||||
Array3x5<int> getTestValues3x5()
|
||||
{
|
||||
Array3x5<int> result;
|
||||
|
||||
for (unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < 5; j++)
|
||||
{
|
||||
result.array[i][j] = i + j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array3x5<int> getTestValues3x5_b()
|
||||
{
|
||||
Array3x5<int> result;
|
||||
|
||||
for (unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < 5; j++)
|
||||
{
|
||||
result.array[i][j] = -i - j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array5x3<int> getTestValues5x3()
|
||||
{
|
||||
Array5x3<int> result;
|
||||
|
||||
for (unsigned int i = 0; i < 5; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < 3; j++)
|
||||
{
|
||||
result.array[i][j] = i + j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MatrixBase<int, 3, 5> getTestMatrix3x5()
|
||||
{
|
||||
Array3x5<int> testValues = getTestValues3x5();
|
||||
|
||||
return MatrixBase<int, 3, 5>(testValues.array);
|
||||
}
|
||||
|
||||
MatrixBase<int, 3, 5> getTestMatrix3x5_b()
|
||||
{
|
||||
Array3x5<int> testValues = getTestValues3x5_b();
|
||||
|
||||
return MatrixBase<int, 3, 5>(testValues.array);
|
||||
}
|
||||
|
||||
MatrixBase<int, 5, 3> getTestMatrix5x3()
|
||||
{
|
||||
Array5x3<int> testValues = getTestValues5x3();
|
||||
|
||||
return MatrixBase<int, 5, 3>(testValues.array);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase constructors")
|
||||
{
|
||||
MatrixBase<int, 4, 5> matrix0;
|
||||
|
||||
REQUIRE(4 == matrix0.getColumnsCount());
|
||||
REQUIRE(5 == matrix0.getRowsCount());
|
||||
|
||||
Array3x5<int> testValues = getTestValues3x5();
|
||||
|
||||
MatrixBase<int, 3, 5> matrix1(testValues.array);
|
||||
|
||||
REQUIRE(3 == matrix1.getColumnsCount());
|
||||
REQUIRE(5 == matrix1.getRowsCount());
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(6 == matrix1.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix2(matrix1);
|
||||
|
||||
REQUIRE(0 == matrix2.getValue(0, 0));
|
||||
REQUIRE(6 == matrix2.getValue(2, 4));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase getSetValue")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
|
||||
int value2_2 = matrix0.getValue(2, 2);
|
||||
matrix0.setValue(2, 2, value2_2*2);
|
||||
REQUIRE(value2_2*2 == matrix0.getValue(2, 2));
|
||||
REQUIRE(3 == matrix0.getValue(1, 2));
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase getRowsColumnsCount")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 5, 3> matrix1 = getTestMatrix5x3();
|
||||
|
||||
REQUIRE(3 == matrix0.getColumnsCount());
|
||||
REQUIRE(5 == matrix0.getRowsCount());
|
||||
|
||||
REQUIRE(5 == matrix1.getColumnsCount());
|
||||
REQUIRE(3 == matrix1.getRowsCount());
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase transposed")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
REQUIRE(3 == matrix0.getColumnsCount());
|
||||
REQUIRE(5 == matrix0.getRowsCount());
|
||||
|
||||
MatrixBase<int, 5, 3> matrix1 = matrix0.transposed();
|
||||
REQUIRE(5 == matrix1.getColumnsCount());
|
||||
REQUIRE(3 == matrix1.getRowsCount());
|
||||
|
||||
REQUIRE(matrix0.getValue(0, 0) == matrix1.getValue(0, 0));
|
||||
REQUIRE(matrix0.getValue(0, 1) == matrix1.getValue(1, 0));
|
||||
REQUIRE(matrix0.getValue(0, 4) == matrix1.getValue(4, 0));
|
||||
REQUIRE(matrix0.getValue(1, 4) == matrix1.getValue(4, 1));
|
||||
REQUIRE(matrix0.getValue(2, 4) == matrix1.getValue(4, 2));
|
||||
REQUIRE(matrix0.getValue(0, 3) == matrix1.getValue(3, 0));
|
||||
REQUIRE(matrix0.getValue(1, 3) == matrix1.getValue(3, 1));
|
||||
REQUIRE(matrix0.getValue(2, 3) == matrix1.getValue(3, 2));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase assign")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(2 == matrix0.getValue(1, 1));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(-2 == matrix1.getValue(1, 1));
|
||||
REQUIRE(-4 == matrix1.getValue(2, 2));
|
||||
|
||||
matrix0.assign(matrix1);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(-2 == matrix0.getValue(1, 1));
|
||||
REQUIRE(-4 == matrix0.getValue(2, 2));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase add subtract")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
matrix0.add(matrix1);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(0 == matrix0.getValue(1, 1));
|
||||
REQUIRE(0 == matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.subtract(matrix1);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(2 == matrix0.getValue(1, 1));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase multiplyDivideScalar")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
|
||||
matrix0.scalarMultiplication(2.0f); // float is on porpoise (so is porpoise, womp womp)
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(4 == matrix0.getValue(1, 1));
|
||||
REQUIRE(8 == matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.scalarMultiplication(0.5f);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(2 == matrix0.getValue(1, 1));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.scalarMultiplication(0.5f);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(1 == matrix0.getValue(1, 1));
|
||||
REQUIRE(2 == matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.scalarMultiplication(0.5f);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(0 == matrix0.getValue(1, 1));
|
||||
REQUIRE(1 == matrix0.getValue(2, 2));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase multiplyMatrix")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
MatrixBase<int, 5, 3> matrix1t = matrix1.transposed();
|
||||
|
||||
MatrixBase<int, 5, 5> matrix2 = matrix0.matrixMultiplication(matrix1t);
|
||||
MatrixBase<int, 3, 3> matrix3 = matrix1t.matrixMultiplication(matrix0);
|
||||
|
||||
// expected results
|
||||
// matrix0 * matrix1t
|
||||
/**
|
||||
* -5, -8, -11, -14, -17
|
||||
* -8, -14, -20, -26, -32
|
||||
* -11, -20, -29, -38, -47
|
||||
* -14, -26, -38, -50, -62
|
||||
* -17, -32, -47, -62, -77
|
||||
*/
|
||||
|
||||
// matrix1t * matrix0
|
||||
/**
|
||||
* -30, -40, -50
|
||||
* -40, -55, -70
|
||||
* -50, -70, -90
|
||||
*/
|
||||
|
||||
|
||||
REQUIRE(5 == matrix2.getColumnsCount());
|
||||
REQUIRE(5 == matrix2.getRowsCount());
|
||||
|
||||
REQUIRE(3 == matrix3.getColumnsCount());
|
||||
REQUIRE(3 == matrix3.getRowsCount());
|
||||
|
||||
REQUIRE(-5 == matrix2.getValue(0, 0));
|
||||
REQUIRE(-77 == matrix2.getValue(4, 4));
|
||||
REQUIRE(-29 == matrix2.getValue(2, 2));
|
||||
REQUIRE(-11 == matrix2.getValue(2, 0));
|
||||
REQUIRE(-11 == matrix2.getValue(0, 2));
|
||||
REQUIRE(-38 == matrix2.getValue(3, 2));
|
||||
|
||||
|
||||
REQUIRE(-30 == matrix3.getValue(0, 0));
|
||||
REQUIRE(-90 == matrix3.getValue(2, 2));
|
||||
REQUIRE(-50 == matrix3.getValue(2, 0));
|
||||
REQUIRE(-50 == matrix3.getValue(0, 2));
|
||||
REQUIRE(-55 == matrix3.getValue(1, 1));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase isEqual")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
REQUIRE(true == matrix0.isEqual(matrix0_b));
|
||||
REQUIRE(false == matrix0.isEqual(matrix1));
|
||||
REQUIRE(true == matrix0.isEqual(matrix0));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase isSame")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
REQUIRE(false == matrix0.isSame(matrix0_b));
|
||||
REQUIRE(false == matrix0.isSame(matrix1));
|
||||
REQUIRE(true == matrix0.isSame(matrix0));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase accessOperator")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
|
||||
REQUIRE(0 == matrix0[0][0]);
|
||||
REQUIRE(4 == matrix0[2][2]);
|
||||
REQUIRE(6 == matrix0[2][4]);
|
||||
|
||||
matrix0[0][0] = 42;
|
||||
|
||||
REQUIRE(42 == matrix0[0][0]);
|
||||
REQUIRE(4 == matrix0[2][2]);
|
||||
REQUIRE(6 == matrix0[2][4]);
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase operators")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5_b();
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
REQUIRE(6 == matrix0.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix0_b.getValue(0, 0));
|
||||
REQUIRE(-4 == matrix0_b.getValue(2, 2));
|
||||
REQUIRE(-6 == matrix0_b.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix1 = matrix0 + matrix0_b;
|
||||
MatrixBase<int, 3, 5> matrix2 = matrix0 - matrix0_b;
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(0 == matrix1.getValue(2, 2));
|
||||
REQUIRE(0 == matrix1.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix2.getValue(0, 0));
|
||||
REQUIRE(8 == matrix2.getValue(2, 2));
|
||||
REQUIRE(12 == matrix2.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix3 = matrix0 * 3;
|
||||
MatrixBase<int, 3, 5> matrix4 = matrix0 / 2;
|
||||
MatrixBase<int, 3, 5> matrix5 = matrix0 * 3.3f; // float is on purpose
|
||||
|
||||
REQUIRE(0 == matrix3.getValue(0, 0));
|
||||
REQUIRE(12 == matrix3.getValue(2, 2));
|
||||
REQUIRE(18 == matrix3.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix4.getValue(0, 0));
|
||||
REQUIRE(2 == matrix4.getValue(2, 2));
|
||||
REQUIRE(3 == matrix4.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix5.getValue(0, 0));
|
||||
REQUIRE(13 == matrix5.getValue(2, 2));
|
||||
REQUIRE(19 == matrix5.getValue(2, 4));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase assignOperators")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5_b();
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
REQUIRE(6 == matrix0.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix0_b.getValue(0, 0));
|
||||
REQUIRE(-4 == matrix0_b.getValue(2, 2));
|
||||
REQUIRE(-6 == matrix0_b.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5();
|
||||
matrix1 += matrix0;
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(8 == matrix1.getValue(2, 2));
|
||||
REQUIRE(12 == matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 += matrix0_b;
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(4 == matrix1.getValue(2, 2));
|
||||
REQUIRE(6 == matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 -= matrix0_b;
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(8 == matrix1.getValue(2, 2));
|
||||
REQUIRE(12 == matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 *= 3.3f;
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(26 == matrix1.getValue(2, 2));
|
||||
REQUIRE(39 == matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 /= 3;
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(8 == matrix1.getValue(2, 2));
|
||||
REQUIRE(13 == matrix1.getValue(2, 4));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase comparisonOperators")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5_b();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5();
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
REQUIRE(6 == matrix0.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix0_b.getValue(0, 0));
|
||||
REQUIRE(-4 == matrix0_b.getValue(2, 2));
|
||||
REQUIRE(-6 == matrix0_b.getValue(2, 4));
|
||||
|
||||
REQUIRE(0 == matrix1.getValue(0, 0));
|
||||
REQUIRE(4 == matrix1.getValue(2, 2));
|
||||
REQUIRE(6 == matrix1.getValue(2, 4));
|
||||
|
||||
REQUIRE(true == (matrix0 == matrix0));
|
||||
REQUIRE(true == (matrix0 == matrix1));
|
||||
REQUIRE(true == (matrix0 != matrix0_b));
|
||||
|
||||
REQUIRE(false == (matrix0 != matrix0));
|
||||
REQUIRE(false == (matrix0 != matrix1));
|
||||
REQUIRE(false == (matrix0 == matrix0_b));
|
||||
}
|
||||
|
||||
TEST_CASE("matrixBase vectorMultiplication")
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
VectorBase<int, 3> vector0;
|
||||
|
||||
for(unsigned int i = 0; i < vector0.getDimensions(); i++)
|
||||
{
|
||||
vector0.setValue(i, i+1);
|
||||
}
|
||||
|
||||
VectorBase<int, 5> vector0_r = multiply(matrix0, vector0);
|
||||
|
||||
REQUIRE(8 == vector0_r[0]);
|
||||
REQUIRE(14 == vector0_r[1]);
|
||||
REQUIRE(20 == vector0_r[2]);
|
||||
REQUIRE(26 == vector0_r[3]);
|
||||
REQUIRE(32 == vector0_r[4]);
|
||||
|
||||
MatrixBase<int, 5, 3> matrix1 = getTestMatrix5x3();
|
||||
VectorBase<int, 3> vector1;
|
||||
|
||||
for(unsigned int i = 0; i < vector1.getDimensions(); i++)
|
||||
{
|
||||
vector1.setValue(i, i+1);
|
||||
}
|
||||
|
||||
VectorBase<int, 5> vector1_r = multiply(vector1, matrix1);
|
||||
|
||||
REQUIRE(8 == vector1_r[0]);
|
||||
REQUIRE(14 == vector1_r[1]);
|
||||
REQUIRE(20 == vector1_r[2]);
|
||||
REQUIRE(26 == vector1_r[3]);
|
||||
REQUIRE(32 == vector1_r[4]);
|
||||
|
||||
MatrixBase<int, 3, 5> matrix2 = getTestMatrix3x5();
|
||||
VectorBase<int, 5> vector2;
|
||||
|
||||
for(unsigned int i = 0; i < vector2.getDimensions(); i++)
|
||||
{
|
||||
vector2.setValue(i, i+1);
|
||||
}
|
||||
|
||||
VectorBase<int, 3> vector2_r = multiply(vector2, matrix2);
|
||||
|
||||
REQUIRE(40 == vector2_r[0]);
|
||||
REQUIRE(55 == vector2_r[1]);
|
||||
REQUIRE(70 == vector2_r[2]);
|
||||
}
|
||||
@@ -1,473 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "MatrixBase.h"
|
||||
#include "VectorBase.h"
|
||||
|
||||
class MatrixBaseTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_matrixBase_constructors()
|
||||
{
|
||||
MatrixBase<int, 4, 5> matrix0;
|
||||
|
||||
TS_ASSERT_EQUALS(4, matrix0.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix0.getRowsCount());
|
||||
|
||||
Array3x5<int> testValues = getTestValues3x5();
|
||||
|
||||
MatrixBase<int, 3, 5> matrix1(testValues.array);
|
||||
|
||||
TS_ASSERT_EQUALS(3, matrix1.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix1.getRowsCount());
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(6, matrix1.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix2(matrix1);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix2.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(6, matrix2.getValue(2, 4));
|
||||
}
|
||||
|
||||
void test_matrixBase_getSetValue()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
|
||||
int value2_2 = matrix0.getValue(2, 2);
|
||||
matrix0.setValue(2, 2, value2_2*2);
|
||||
TS_ASSERT_EQUALS(value2_2*2, matrix0.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(3, matrix0.getValue(1, 2));
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
}
|
||||
|
||||
void test_matrixBase_getRowsColumnsCount()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 5, 3> matrix1 = getTestMatrix5x3();
|
||||
|
||||
TS_ASSERT_EQUALS(3, matrix0.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix0.getRowsCount());
|
||||
|
||||
TS_ASSERT_EQUALS(5, matrix1.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(3, matrix1.getRowsCount());
|
||||
}
|
||||
|
||||
void test_matrixBase_transposed()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
TS_ASSERT_EQUALS(3, matrix0.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix0.getRowsCount());
|
||||
|
||||
MatrixBase<int, 5, 3> matrix1 = matrix0.transposed();
|
||||
TS_ASSERT_EQUALS(5, matrix1.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(3, matrix1.getRowsCount());
|
||||
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(0, 0), matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(0, 1), matrix1.getValue(1, 0));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(0, 4), matrix1.getValue(4, 0));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(1, 4), matrix1.getValue(4, 1));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(2, 4), matrix1.getValue(4, 2));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(0, 3), matrix1.getValue(3, 0));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(1, 3), matrix1.getValue(3, 1));
|
||||
TS_ASSERT_EQUALS(matrix0.getValue(2, 3), matrix1.getValue(3, 2));
|
||||
}
|
||||
|
||||
void test_matrixBase_assign()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(2, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-2, matrix1.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(-4, matrix1.getValue(2, 2));
|
||||
|
||||
matrix0.assign(matrix1);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-2, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(-4, matrix0.getValue(2, 2));
|
||||
}
|
||||
|
||||
void test_matrixBase_add_subtract()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
matrix0.add(matrix1);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.subtract(matrix1);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(2, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
}
|
||||
|
||||
void test_matrixBase_multiplyDivideScalar()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
|
||||
matrix0.scalarMultiplication(2.0f); // float is on porpoise (so is porpoise, womp womp)
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(8, matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.scalarMultiplication(0.5f);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(2, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.scalarMultiplication(0.5f);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(1, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(2, matrix0.getValue(2, 2));
|
||||
|
||||
matrix0.scalarMultiplication(0.5f);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(1, 1));
|
||||
TS_ASSERT_EQUALS(1, matrix0.getValue(2, 2));
|
||||
}
|
||||
|
||||
void test_matrixBase_multiplyMatrix()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
MatrixBase<int, 5, 3> matrix1t = matrix1.transposed();
|
||||
|
||||
MatrixBase<int, 5, 5> matrix2 = matrix0.matrixMultiplication(matrix1t);
|
||||
MatrixBase<int, 3, 3> matrix3 = matrix1t.matrixMultiplication(matrix0);
|
||||
|
||||
// expected results
|
||||
// matrix0 * matrix1t
|
||||
/**
|
||||
* -5, -8, -11, -14, -17
|
||||
* -8, -14, -20, -26, -32
|
||||
* -11, -20, -29, -38, -47
|
||||
* -14, -26, -38, -50, -62
|
||||
* -17, -32, -47, -62, -77
|
||||
*/
|
||||
|
||||
// matrix1t * matrix0
|
||||
/**
|
||||
* -30, -40, -50
|
||||
* -40, -55, -70
|
||||
* -50, -70, -90
|
||||
*/
|
||||
|
||||
|
||||
TS_ASSERT_EQUALS(5, matrix2.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix2.getRowsCount());
|
||||
|
||||
TS_ASSERT_EQUALS(3, matrix3.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(3, matrix3.getRowsCount());
|
||||
|
||||
TS_ASSERT_EQUALS(-5, matrix2.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-77, matrix2.getValue(4, 4));
|
||||
TS_ASSERT_EQUALS(-29, matrix2.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(-11, matrix2.getValue(2, 0));
|
||||
TS_ASSERT_EQUALS(-11, matrix2.getValue(0, 2));
|
||||
TS_ASSERT_EQUALS(-38, matrix2.getValue(3, 2));
|
||||
|
||||
|
||||
TS_ASSERT_EQUALS(-30, matrix3.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-90, matrix3.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(-50, matrix3.getValue(2, 0));
|
||||
TS_ASSERT_EQUALS(-50, matrix3.getValue(0, 2));
|
||||
TS_ASSERT_EQUALS(-55, matrix3.getValue(1, 1));
|
||||
}
|
||||
|
||||
void test_matrixBase_isEqual()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
TS_ASSERT_EQUALS(true, matrix0.isEqual(matrix0_b));
|
||||
TS_ASSERT_EQUALS(false, matrix0.isEqual(matrix1));
|
||||
TS_ASSERT_EQUALS(true, matrix0.isEqual(matrix0));
|
||||
}
|
||||
|
||||
void test_matrixBase_isSame()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5_b();
|
||||
|
||||
TS_ASSERT_EQUALS(false, matrix0.isSame(matrix0_b));
|
||||
TS_ASSERT_EQUALS(false, matrix0.isSame(matrix1));
|
||||
TS_ASSERT_EQUALS(true, matrix0.isSame(matrix0));
|
||||
}
|
||||
|
||||
void test_matrixBase_accessOperator()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0[0][0]);
|
||||
TS_ASSERT_EQUALS(4, matrix0[2][2]);
|
||||
TS_ASSERT_EQUALS(6, matrix0[2][4]);
|
||||
|
||||
matrix0[0][0] = 42;
|
||||
|
||||
TS_ASSERT_EQUALS(42, matrix0[0][0]);
|
||||
TS_ASSERT_EQUALS(4, matrix0[2][2]);
|
||||
TS_ASSERT_EQUALS(6, matrix0[2][4]);
|
||||
}
|
||||
|
||||
void test_matrixBase_operators()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5_b();
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(6, matrix0.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0_b.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-4, matrix0_b.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(-6, matrix0_b.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix1 = matrix0 + matrix0_b;
|
||||
MatrixBase<int, 3, 5> matrix2 = matrix0 - matrix0_b;
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix2.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(8, matrix2.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(12, matrix2.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix3 = matrix0 * 3;
|
||||
MatrixBase<int, 3, 5> matrix4 = matrix0 / 2;
|
||||
MatrixBase<int, 3, 5> matrix5 = matrix0 * 3.3f; // float is on purpose
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix3.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(12, matrix3.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(18, matrix3.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix4.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(2, matrix4.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(3, matrix4.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix5.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(13, matrix5.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(19, matrix5.getValue(2, 4));
|
||||
}
|
||||
|
||||
void test_matrixBase_assignOperators()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5_b();
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(6, matrix0.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0_b.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-4, matrix0_b.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(-6, matrix0_b.getValue(2, 4));
|
||||
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5();
|
||||
matrix1 += matrix0;
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(8, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(12, matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 += matrix0_b;
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(6, matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 -= matrix0_b;
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(8, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(12, matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 *= 3.3f;
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(26, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(39, matrix1.getValue(2, 4));
|
||||
|
||||
matrix1 /= 3;
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(8, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(13, matrix1.getValue(2, 4));
|
||||
}
|
||||
|
||||
void test_matrixBase_comparisonOperators()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
MatrixBase<int, 3, 5> matrix0_b = getTestMatrix3x5_b();
|
||||
MatrixBase<int, 3, 5> matrix1 = getTestMatrix3x5();
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(6, matrix0.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0_b.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(-4, matrix0_b.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(-6, matrix0_b.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix1.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix1.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(6, matrix1.getValue(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(true, matrix0 == matrix0);
|
||||
TS_ASSERT_EQUALS(true, matrix0 == matrix1);
|
||||
TS_ASSERT_EQUALS(true, matrix0 != matrix0_b);
|
||||
|
||||
TS_ASSERT_EQUALS(false, matrix0 != matrix0);
|
||||
TS_ASSERT_EQUALS(false, matrix0 != matrix1);
|
||||
TS_ASSERT_EQUALS(false, matrix0 == matrix0_b);
|
||||
}
|
||||
|
||||
void test_matrixBase_vectorMultiplication()
|
||||
{
|
||||
MatrixBase<int, 3, 5> matrix0 = getTestMatrix3x5();
|
||||
VectorBase<int, 3> vector0;
|
||||
|
||||
for(unsigned int i = 0; i < vector0.getDimensions(); i++)
|
||||
{
|
||||
vector0.setValue(i, i+1);
|
||||
}
|
||||
|
||||
VectorBase<int, 5> vector0_r = multiply(matrix0, vector0);
|
||||
|
||||
TS_ASSERT_EQUALS(8, vector0_r[0]);
|
||||
TS_ASSERT_EQUALS(14, vector0_r[1]);
|
||||
TS_ASSERT_EQUALS(20, vector0_r[2]);
|
||||
TS_ASSERT_EQUALS(26, vector0_r[3]);
|
||||
TS_ASSERT_EQUALS(32, vector0_r[4]);
|
||||
|
||||
MatrixBase<int, 5, 3> matrix1 = getTestMatrix5x3();
|
||||
VectorBase<int, 3> vector1;
|
||||
|
||||
for(unsigned int i = 0; i < vector1.getDimensions(); i++)
|
||||
{
|
||||
vector1.setValue(i, i+1);
|
||||
}
|
||||
|
||||
VectorBase<int, 5> vector1_r = multiply(vector1, matrix1);
|
||||
|
||||
TS_ASSERT_EQUALS(8, vector1_r[0]);
|
||||
TS_ASSERT_EQUALS(14, vector1_r[1]);
|
||||
TS_ASSERT_EQUALS(20, vector1_r[2]);
|
||||
TS_ASSERT_EQUALS(26, vector1_r[3]);
|
||||
TS_ASSERT_EQUALS(32, vector1_r[4]);
|
||||
|
||||
MatrixBase<int, 3, 5> matrix2 = getTestMatrix3x5();
|
||||
VectorBase<int, 5> vector2;
|
||||
|
||||
for(unsigned int i = 0; i < vector2.getDimensions(); i++)
|
||||
{
|
||||
vector2.setValue(i, i+1);
|
||||
}
|
||||
|
||||
VectorBase<int, 3> vector2_r = multiply(vector2, matrix2);
|
||||
|
||||
TS_ASSERT_EQUALS(40, vector2_r[0]);
|
||||
TS_ASSERT_EQUALS(55, vector2_r[1]);
|
||||
TS_ASSERT_EQUALS(70, vector2_r[2]);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* C++ functions can't return statically allocated arrays.
|
||||
* I don't want to use dynamically allocated arrays, so here's my work around for that...
|
||||
*
|
||||
* Update: acutally they can... see MatrixBase [] operator (in MatrixBase.cpp)
|
||||
*/
|
||||
template<class T>
|
||||
struct Array3x5
|
||||
{
|
||||
T array[3][5];
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct Array5x3
|
||||
{
|
||||
T array[5][3];
|
||||
};
|
||||
|
||||
Array3x5<int> getTestValues3x5()
|
||||
{
|
||||
Array3x5<int> result;
|
||||
|
||||
for(unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
for(unsigned int j = 0; j < 5; j++)
|
||||
{
|
||||
result.array[i][j] = i + j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array3x5<int> getTestValues3x5_b()
|
||||
{
|
||||
Array3x5<int> result;
|
||||
|
||||
for(unsigned int i = 0; i < 3; i++)
|
||||
{
|
||||
for(unsigned int j = 0; j < 5; j++)
|
||||
{
|
||||
result.array[i][j] = -i - j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Array5x3<int> getTestValues5x3()
|
||||
{
|
||||
Array5x3<int> result;
|
||||
|
||||
for(unsigned int i = 0; i < 5; i++)
|
||||
{
|
||||
for(unsigned int j = 0; j < 3; j++)
|
||||
{
|
||||
result.array[i][j] = i + j;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MatrixBase<int, 3, 5> getTestMatrix3x5()
|
||||
{
|
||||
Array3x5<int> testValues = getTestValues3x5();
|
||||
|
||||
return MatrixBase<int, 3, 5>(testValues.array);
|
||||
}
|
||||
|
||||
MatrixBase<int, 3, 5> getTestMatrix3x5_b()
|
||||
{
|
||||
Array3x5<int> testValues = getTestValues3x5_b();
|
||||
|
||||
return MatrixBase<int, 3, 5>(testValues.array);
|
||||
}
|
||||
|
||||
MatrixBase<int, 5, 3> getTestMatrix5x3()
|
||||
{
|
||||
Array5x3<int> testValues = getTestValues5x3();
|
||||
|
||||
return MatrixBase<int, 5, 3>(testValues.array);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "logging.h"
|
||||
#include "MatrixDynamicBase.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<std::vector<int>> getTestValues(const unsigned int numColumns, const unsigned int numRows)
|
||||
{
|
||||
std::vector<std::vector<int>> testValues;
|
||||
|
||||
for (unsigned int x = 0; x < numColumns; x++)
|
||||
{
|
||||
std::vector<int> row;
|
||||
|
||||
for (unsigned int y = 0; y < numRows; y++)
|
||||
{
|
||||
row.push_back(x + y);
|
||||
}
|
||||
|
||||
testValues.push_back(row);
|
||||
}
|
||||
|
||||
return testValues;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("matrixDynamicBase constructors")
|
||||
{
|
||||
MatrixDynamicBase<int> matrix0;
|
||||
MatrixDynamicBase<int> matrix1(3, 5);
|
||||
|
||||
std::vector<std::vector<int>> testValues = getTestValues(3, 5);
|
||||
MatrixDynamicBase<int> matrix2(testValues);
|
||||
|
||||
REQUIRE(0 == matrix0.getColumnsCount());
|
||||
REQUIRE(0 == matrix0.getRowsCount());
|
||||
REQUIRE(3 == matrix1.getColumnsCount());
|
||||
REQUIRE(5 == matrix1.getRowsCount());
|
||||
REQUIRE(3 == matrix2.getColumnsCount());
|
||||
REQUIRE(5 == matrix2.getRowsCount());
|
||||
}
|
||||
|
||||
TEST_CASE("matrixDynamicBase getValue setValue")
|
||||
{
|
||||
std::vector<std::vector<int>> testValues = getTestValues(3, 5);
|
||||
MatrixDynamicBase<int> matrix0(testValues);
|
||||
|
||||
REQUIRE(0 == matrix0.getValue(0, 0));
|
||||
REQUIRE(4 == matrix0.getValue(2, 2));
|
||||
REQUIRE(6 == matrix0.getValue(2, 4));
|
||||
|
||||
matrix0.setValue(0, 0, 42);
|
||||
matrix0.setValue(2, 2, 84);
|
||||
matrix0.setValue(2, 4, 126);
|
||||
|
||||
REQUIRE(42 == matrix0.getValue(0, 0));
|
||||
REQUIRE(84 == matrix0.getValue(2, 2));
|
||||
REQUIRE(126 == matrix0.getValue(2, 4));
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "TestSuite.h"
|
||||
|
||||
#include "logging.h"
|
||||
#include "MatrixDynamicBase.h"
|
||||
|
||||
class MatrixDynamicBaseTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_matrixDynamicBase_constructors()
|
||||
{
|
||||
MatrixDynamicBase<int> matrix0;
|
||||
MatrixDynamicBase<int> matrix1(3, 5);
|
||||
|
||||
std::vector<std::vector<int>> testValues = getTestValues(3, 5);
|
||||
MatrixDynamicBase<int> matrix2(testValues);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(0, matrix0.getRowsCount());
|
||||
TS_ASSERT_EQUALS(3, matrix1.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix1.getRowsCount());
|
||||
TS_ASSERT_EQUALS(3, matrix2.getColumnsCount());
|
||||
TS_ASSERT_EQUALS(5, matrix2.getRowsCount());
|
||||
}
|
||||
|
||||
void test_matrixDynamicBase_getValue_setValue()
|
||||
{
|
||||
std::vector<std::vector<int>> testValues = getTestValues(3, 5);
|
||||
MatrixDynamicBase<int> matrix0(testValues);
|
||||
|
||||
TS_ASSERT_EQUALS(0, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(4, matrix0.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(6, matrix0.getValue(2, 4));
|
||||
|
||||
matrix0.setValue(0, 0, 42);
|
||||
matrix0.setValue(2, 2, 84);
|
||||
matrix0.setValue(2, 4, 126);
|
||||
|
||||
TS_ASSERT_EQUALS(42, matrix0.getValue(0, 0));
|
||||
TS_ASSERT_EQUALS(84, matrix0.getValue(2, 2));
|
||||
TS_ASSERT_EQUALS(126, matrix0.getValue(2, 4));
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::vector<int>> getTestValues(const unsigned int numColumns, const unsigned int numRows)
|
||||
{
|
||||
std::vector<std::vector<int>> testValues;
|
||||
|
||||
for(unsigned int x = 0; x < numColumns; x++)
|
||||
{
|
||||
std::vector<int> row;
|
||||
|
||||
for(unsigned int y = 0; y < numRows; y++)
|
||||
{
|
||||
row.push_back(x + y);
|
||||
}
|
||||
|
||||
testValues.push_back(row);
|
||||
}
|
||||
|
||||
return testValues;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,246 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "Message.h"
|
||||
#include "MessageListener.h"
|
||||
#include "MessageQueue.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestMessage : public Message<TestMessage>
|
||||
{
|
||||
public:
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "TestMessage";
|
||||
}
|
||||
};
|
||||
|
||||
class Test2Message : public Message<Test2Message>
|
||||
{
|
||||
public:
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "TestMessage2";
|
||||
}
|
||||
};
|
||||
|
||||
class TestMessageListener : public MessageListener<TestMessage>
|
||||
{
|
||||
public:
|
||||
TestMessageListener()
|
||||
: m_messageCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
int m_messageCount;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(TestMessage* message)
|
||||
{
|
||||
m_messageCount++;
|
||||
}
|
||||
};
|
||||
|
||||
class Test2MessageListener : public MessageListener<Test2Message>
|
||||
{
|
||||
public:
|
||||
Test2MessageListener()
|
||||
: m_messageCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
int m_messageCount;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(Test2Message* message)
|
||||
{
|
||||
m_messageCount++;
|
||||
TestMessage().dispatch();
|
||||
}
|
||||
};
|
||||
|
||||
class Test3MessageListener : public MessageListener<Test2Message>
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<TestMessageListener> m_listener;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(Test2Message* message)
|
||||
{
|
||||
m_listener = std::make_shared<TestMessageListener>();
|
||||
}
|
||||
};
|
||||
|
||||
class Test4MessageListener :
|
||||
public MessageListener<TestMessage>,
|
||||
public MessageListener<Test2Message>
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<TestMessageListener> m_listener;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(TestMessage* message)
|
||||
{
|
||||
if (!m_listener)
|
||||
{
|
||||
m_listener = std::make_shared<TestMessageListener>();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void handleMessage(Test2Message* message)
|
||||
{
|
||||
m_listener.reset();
|
||||
}
|
||||
};
|
||||
|
||||
class Test5MessageListener :
|
||||
public MessageListener<TestMessage>
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<TestMessageListener>> m_listeners;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(TestMessage* message)
|
||||
{
|
||||
if (!m_listeners.size())
|
||||
{
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
m_listeners.push_back(std::make_shared<TestMessageListener>());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void waitForThread()
|
||||
{
|
||||
static const int THREAD_WAIT_TIME_MS = 20;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(THREAD_WAIT_TIME_MS));
|
||||
} while (MessageQueue::getInstance()->hasMessagesQueued());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("message loop starts and stops")
|
||||
{
|
||||
REQUIRE(!MessageQueue::getInstance()->loopIsRunning());
|
||||
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
waitForThread();
|
||||
|
||||
REQUIRE(MessageQueue::getInstance()->loopIsRunning());
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
waitForThread();
|
||||
|
||||
REQUIRE(!MessageQueue::getInstance()->loopIsRunning());
|
||||
}
|
||||
|
||||
TEST_CASE("registered listener receives messages")
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
TestMessageListener listener;
|
||||
Test2MessageListener listener2;
|
||||
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
REQUIRE(3 == listener.m_messageCount);
|
||||
REQUIRE(0 == listener2.m_messageCount);
|
||||
}
|
||||
|
||||
TEST_CASE("message dispatching within message handling")
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
TestMessageListener listener;
|
||||
Test2MessageListener listener2;
|
||||
|
||||
Test2Message().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
REQUIRE(1 == listener.m_messageCount);
|
||||
REQUIRE(1 == listener2.m_messageCount);
|
||||
}
|
||||
|
||||
TEST_CASE("listener registration within message handling")
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
Test3MessageListener listener;
|
||||
|
||||
Test2Message().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
REQUIRE(listener.m_listener);
|
||||
if (listener.m_listener)
|
||||
{
|
||||
REQUIRE(1 == listener.m_listener->m_messageCount);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("listener unregistration within message handling")
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
Test4MessageListener listener;
|
||||
|
||||
TestMessage().dispatch();
|
||||
|
||||
Test2Message().dispatch();
|
||||
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
REQUIRE(listener.m_listener);
|
||||
if (listener.m_listener)
|
||||
{
|
||||
REQUIRE(2 == listener.m_listener->m_messageCount);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("listener registration to front and back within message handling")
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
Test5MessageListener listener;
|
||||
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
REQUIRE(5 == listener.m_listeners.size());
|
||||
REQUIRE(2 == listener.m_listeners[0]->m_messageCount);
|
||||
REQUIRE(2 == listener.m_listeners[1]->m_messageCount);
|
||||
REQUIRE(2 == listener.m_listeners[2]->m_messageCount);
|
||||
REQUIRE(2 == listener.m_listeners[3]->m_messageCount);
|
||||
REQUIRE(2 == listener.m_listeners[4]->m_messageCount);
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "Message.h"
|
||||
#include "MessageListener.h"
|
||||
#include "MessageQueue.h"
|
||||
|
||||
class MessageQueueTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_message_loop_starts_and_stops(void)
|
||||
{
|
||||
TS_ASSERT(!MessageQueue::getInstance()->loopIsRunning());
|
||||
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
waitForThread();
|
||||
|
||||
TS_ASSERT(MessageQueue::getInstance()->loopIsRunning());
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
waitForThread();
|
||||
|
||||
TS_ASSERT(!MessageQueue::getInstance()->loopIsRunning());
|
||||
}
|
||||
|
||||
void test_registered_listener_receives_messages(void)
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
TestMessageListener listener;
|
||||
Test2MessageListener listener2;
|
||||
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(3, listener.m_messageCount);
|
||||
TS_ASSERT_EQUALS(0, listener2.m_messageCount);
|
||||
}
|
||||
|
||||
void test_message_dispatching_within_message_handling(void)
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
TestMessageListener listener;
|
||||
Test2MessageListener listener2;
|
||||
|
||||
Test2Message().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(1, listener.m_messageCount);
|
||||
TS_ASSERT_EQUALS(1, listener2.m_messageCount);
|
||||
}
|
||||
|
||||
void test_listener_registration_within_message_handling(void)
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
Test3MessageListener listener;
|
||||
|
||||
Test2Message().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
TS_ASSERT(listener.m_listener);
|
||||
if (listener.m_listener)
|
||||
{
|
||||
TS_ASSERT_EQUALS(1, listener.m_listener->m_messageCount);
|
||||
}
|
||||
}
|
||||
|
||||
void test_listener_unregistration_within_message_handling(void)
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
Test4MessageListener listener;
|
||||
|
||||
TestMessage().dispatch();
|
||||
|
||||
Test2Message().dispatch();
|
||||
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
TS_ASSERT(listener.m_listener);
|
||||
if (listener.m_listener)
|
||||
{
|
||||
TS_ASSERT_EQUALS(2, listener.m_listener->m_messageCount);
|
||||
}
|
||||
}
|
||||
|
||||
void test_listener_registration_to_front_and_back_within_message_handling(void)
|
||||
{
|
||||
MessageQueue::getInstance()->startMessageLoopThreaded();
|
||||
|
||||
Test5MessageListener listener;
|
||||
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
TestMessage().dispatch();
|
||||
|
||||
waitForThread();
|
||||
|
||||
MessageQueue::getInstance()->stopMessageLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(5, listener.m_listeners.size());
|
||||
TS_ASSERT_EQUALS(2, listener.m_listeners[0]->m_messageCount);
|
||||
TS_ASSERT_EQUALS(2, listener.m_listeners[1]->m_messageCount);
|
||||
TS_ASSERT_EQUALS(2, listener.m_listeners[2]->m_messageCount);
|
||||
TS_ASSERT_EQUALS(2, listener.m_listeners[3]->m_messageCount);
|
||||
TS_ASSERT_EQUALS(2, listener.m_listeners[4]->m_messageCount);
|
||||
}
|
||||
|
||||
private:
|
||||
class TestMessage: public Message<TestMessage>
|
||||
{
|
||||
public:
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "TestMessage";
|
||||
}
|
||||
};
|
||||
|
||||
class Test2Message: public Message<Test2Message>
|
||||
{
|
||||
public:
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "TestMessage2";
|
||||
}
|
||||
};
|
||||
|
||||
class TestMessageListener: public MessageListener<TestMessage>
|
||||
{
|
||||
public:
|
||||
TestMessageListener()
|
||||
: m_messageCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
int m_messageCount;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(TestMessage* message)
|
||||
{
|
||||
m_messageCount++;
|
||||
}
|
||||
};
|
||||
|
||||
class Test2MessageListener: public MessageListener<Test2Message>
|
||||
{
|
||||
public:
|
||||
Test2MessageListener()
|
||||
: m_messageCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
int m_messageCount;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(Test2Message* message)
|
||||
{
|
||||
m_messageCount++;
|
||||
TestMessage().dispatch();
|
||||
}
|
||||
};
|
||||
|
||||
class Test3MessageListener: public MessageListener<Test2Message>
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<TestMessageListener> m_listener;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(Test2Message* message)
|
||||
{
|
||||
m_listener = std::make_shared<TestMessageListener>();
|
||||
}
|
||||
};
|
||||
|
||||
class Test4MessageListener:
|
||||
public MessageListener<TestMessage>,
|
||||
public MessageListener<Test2Message>
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<TestMessageListener> m_listener;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(TestMessage* message)
|
||||
{
|
||||
if (!m_listener)
|
||||
{
|
||||
m_listener = std::make_shared<TestMessageListener>();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void handleMessage(Test2Message* message)
|
||||
{
|
||||
m_listener.reset();
|
||||
}
|
||||
};
|
||||
|
||||
class Test5MessageListener:
|
||||
public MessageListener<TestMessage>
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<TestMessageListener>> m_listeners;
|
||||
|
||||
private:
|
||||
virtual void handleMessage(TestMessage* message)
|
||||
{
|
||||
if (!m_listeners.size())
|
||||
{
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
m_listeners.push_back(std::make_shared<TestMessageListener>());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void waitForThread() const
|
||||
{
|
||||
static const int THREAD_WAIT_TIME_MS = 20;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(THREAD_WAIT_TIME_MS));
|
||||
}
|
||||
while (MessageQueue::getInstance()->hasMessagesQueued());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "NetworkProtocolHelper.h"
|
||||
|
||||
TEST_CASE("parse message")
|
||||
{
|
||||
std::wstring type = L"setActiveToken";
|
||||
std::wstring divider = L">>";
|
||||
std::wstring filePath = L"C:/Users/Manuel/imporant/file/location/fileName.cpp";
|
||||
std::wstring endOfMessageToken = L"<EOM>";
|
||||
int row = 1;
|
||||
int column = 2;
|
||||
|
||||
// valid message
|
||||
std::wstringstream message;
|
||||
message << type << divider << filePath << divider << row << divider << column << endOfMessageToken;
|
||||
|
||||
NetworkProtocolHelper::SetActiveTokenMessage networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
REQUIRE(networkMessage.filePath.wstr() == filePath);
|
||||
REQUIRE(networkMessage.row == row);
|
||||
REQUIRE(networkMessage.column == column);
|
||||
REQUIRE(networkMessage.valid == true);
|
||||
|
||||
// invalid type
|
||||
message.str(L"");
|
||||
message << L"foo" << divider << filePath << divider << row << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
REQUIRE(networkMessage.filePath.wstr() == L"");
|
||||
REQUIRE(networkMessage.row == 0);
|
||||
REQUIRE(networkMessage.column == 0);
|
||||
REQUIRE(networkMessage.valid == false);
|
||||
|
||||
// missing divider
|
||||
message.str(L"");
|
||||
message << type << divider << filePath << row << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
REQUIRE(networkMessage.filePath.wstr() == L"");
|
||||
REQUIRE(networkMessage.row == 0);
|
||||
REQUIRE(networkMessage.column == 0);
|
||||
REQUIRE(networkMessage.valid == false);
|
||||
|
||||
// invalid row
|
||||
message.str(L"");
|
||||
message << type << divider << filePath << divider << "potato" << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
REQUIRE(networkMessage.filePath.wstr() == L"");
|
||||
REQUIRE(networkMessage.row == 0);
|
||||
REQUIRE(networkMessage.column == 0);
|
||||
REQUIRE(networkMessage.valid == false);
|
||||
|
||||
// invalid column
|
||||
message.str(L"");
|
||||
message << type << divider << filePath << divider << row << divider << "laz0r" << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
REQUIRE(networkMessage.filePath.wstr() == L"");
|
||||
REQUIRE(networkMessage.row == 0);
|
||||
REQUIRE(networkMessage.column == 0);
|
||||
REQUIRE(networkMessage.valid == false);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "NetworkProtocolHelper.h"
|
||||
|
||||
class NetworkProtocolHelperTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_parse_message(void)
|
||||
{
|
||||
std::wstring type = L"setActiveToken";
|
||||
std::wstring divider = L">>";
|
||||
std::wstring filePath = L"C:/Users/Manuel/imporant/file/location/fileName.cpp";
|
||||
std::wstring endOfMessageToken = L"<EOM>";
|
||||
int row = 1;
|
||||
int column = 2;
|
||||
|
||||
// valid message
|
||||
std::wstringstream message;
|
||||
message << type << divider << filePath << divider << row << divider << column << endOfMessageToken;
|
||||
|
||||
NetworkProtocolHelper::SetActiveTokenMessage networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.filePath.wstr(), filePath);
|
||||
TS_ASSERT_EQUALS(networkMessage.row, row);
|
||||
TS_ASSERT_EQUALS(networkMessage.column, column);
|
||||
TS_ASSERT_EQUALS(networkMessage.valid, true);
|
||||
|
||||
// invalid type
|
||||
message.str(L"");
|
||||
message << L"foo" << divider << filePath << divider << row << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.filePath.wstr(), L"");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.column, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.valid, false);
|
||||
|
||||
// missing divider
|
||||
message.str(L"");
|
||||
message << type << divider << filePath << row << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.filePath.wstr(), L"");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.column, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.valid, false);
|
||||
|
||||
// invalid row
|
||||
message.str(L"");
|
||||
message << type << divider << filePath << divider << "potato" << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.filePath.wstr(), L"");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.column, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.valid, false);
|
||||
|
||||
// invalid column
|
||||
message.str(L"");
|
||||
message << type << divider << filePath << divider << row << divider << "laz0r" << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.filePath.wstr(), L"");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.column, 0);
|
||||
TS_ASSERT_EQUALS(networkMessage.valid, false);
|
||||
}
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "NameHierarchy.h"
|
||||
#include "SearchIndex.h"
|
||||
#include "utility.h"
|
||||
|
||||
TEST_CASE("search index finds id of element added")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
REQUIRE(1 == results.size());
|
||||
REQUIRE(1 == results[0].elementIds.size());
|
||||
REQUIRE(utility::containsElement<Id>(results[0].elementIds, 1));
|
||||
}
|
||||
|
||||
TEST_CASE("search index finds correct indices for query")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
REQUIRE(1 == results.size());
|
||||
REQUIRE(2 == results[0].indices.size());
|
||||
REQUIRE(1 == results[0].indices[0]);
|
||||
REQUIRE(2 == results[0].indices[1]);
|
||||
}
|
||||
|
||||
TEST_CASE("search index finds ids for ambiguous query")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfor\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmfos\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"fo", NodeTypeSet::all(), 0);
|
||||
|
||||
REQUIRE(2 == results.size());
|
||||
REQUIRE(1 == results[0].elementIds.size());
|
||||
REQUIRE(utility::containsElement<Id>(results[0].elementIds, 1));
|
||||
REQUIRE(1 == results[1].elementIds.size());
|
||||
REQUIRE(utility::containsElement<Id>(results[1].elementIds, 2));
|
||||
}
|
||||
|
||||
TEST_CASE("search index does not find anything after clear")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
index.clear();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
REQUIRE(0 == results.size());
|
||||
}
|
||||
|
||||
TEST_CASE("search index does not find all results when max amount is limited")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo1\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmfoo2\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 1);
|
||||
|
||||
REQUIRE(1 == results.size());
|
||||
}
|
||||
|
||||
TEST_CASE("search index query is case insensitive")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo1\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmFOO2\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
REQUIRE(2 == results.size());
|
||||
}
|
||||
|
||||
TEST_CASE("search index rates higher on consecutive letters")
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmoaabbcc\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmocbcabc\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"abc", NodeTypeSet::all(), 0);
|
||||
|
||||
REQUIRE(2 == results.size());
|
||||
REQUIRE(L"ocbcabc" == results[0].text);
|
||||
REQUIRE(L"oaabbcc" == results[1].text);
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "NameHierarchy.h"
|
||||
#include "SearchIndex.h"
|
||||
#include "utility.h"
|
||||
|
||||
class SearchIndexTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
|
||||
void test_search_index_finds_id_of_element_added()
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(1, results.size());
|
||||
TS_ASSERT_EQUALS(1, results[0].elementIds.size());
|
||||
TS_ASSERT(utility::containsElement<Id>(results[0].elementIds, 1));
|
||||
}
|
||||
|
||||
void test_search_index_finds_correct_indices_for_query()
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(1, results.size());
|
||||
TS_ASSERT_EQUALS(2, results[0].indices.size());
|
||||
TS_ASSERT_EQUALS(1, results[0].indices[0]);
|
||||
TS_ASSERT_EQUALS(2, results[0].indices[1]);
|
||||
}
|
||||
|
||||
void test_search_index_finds_ids_for_ambiguous_query()
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfor\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmfos\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"fo", NodeTypeSet::all(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(2, results.size());
|
||||
TS_ASSERT_EQUALS(1, results[0].elementIds.size());
|
||||
TS_ASSERT(utility::containsElement<Id>(results[0].elementIds, 1));
|
||||
TS_ASSERT_EQUALS(1, results[1].elementIds.size());
|
||||
TS_ASSERT(utility::containsElement<Id>(results[1].elementIds, 2));
|
||||
}
|
||||
|
||||
void test_search_index_does_not_find_anything_after_clear()
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
index.clear();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(0, results.size());
|
||||
}
|
||||
|
||||
void test_search_index_does_not_find_all_results_when_max_amount_is_limited()
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo1\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmfoo2\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 1);
|
||||
|
||||
TS_ASSERT_EQUALS(1, results.size());
|
||||
}
|
||||
|
||||
void test_search_index_query_is_case_insensitive()
|
||||
{
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmfoo1\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmFOO2\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"oo", NodeTypeSet::all(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(2, results.size());
|
||||
}
|
||||
|
||||
void test_search_index_rates_higher_on_consecutive_letters()
|
||||
{
|
||||
|
||||
SearchIndex index;
|
||||
index.addNode(1, NameHierarchy::deserialize(L"::\tmoaabbcc\tsvoid\tp() const").getQualifiedName());
|
||||
index.addNode(2, NameHierarchy::deserialize(L"::\tmocbcabc\tsvoid\tp() const").getQualifiedName());
|
||||
index.finishSetup();
|
||||
std::vector<SearchResult> results = index.search(L"abc", NodeTypeSet::all(), 0);
|
||||
|
||||
TS_ASSERT_EQUALS(2, results.size());
|
||||
TS_ASSERT_EQUALS(L"ocbcabc", results[0].text);
|
||||
TS_ASSERT_EQUALS(L"oaabbcc", results[1].text);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,381 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "Settings.h"
|
||||
#include "SettingsMigrator.h"
|
||||
#include "SettingsMigrationLambda.h"
|
||||
#include "SettingsMigrationMoveKey.h"
|
||||
#include "TextAccess.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestSettings
|
||||
: public Settings
|
||||
{
|
||||
public:
|
||||
static TestSettings createFromText(const std::shared_ptr<TextAccess> textAccess)
|
||||
{
|
||||
TestSettings settings;
|
||||
settings.m_config = ConfigManager::createAndLoad(textAccess);
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::string getAsText() const
|
||||
{
|
||||
if (m_config)
|
||||
{
|
||||
return m_config->toString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
TestSettings createSettings(const std::string& text)
|
||||
{
|
||||
return TestSettings::createFromText(TextAccess::createFromString(text));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes nothing without migrations except version")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes name")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes path")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <sub>\n"
|
||||
" <int>2</int>\n"
|
||||
" </sub>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "sub/int"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes group name")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <values>\n"
|
||||
" <value>2</value>\n"
|
||||
" <value>3</value>\n"
|
||||
" <value>4</value>\n"
|
||||
" </values>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <vals>\n"
|
||||
" <value>2</value>\n"
|
||||
" <value>3</value>\n"
|
||||
" <value>4</value>\n"
|
||||
" </vals>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("values/value", "vals/value"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes group element name")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <values>\n"
|
||||
" <value>2</value>\n"
|
||||
" <value>3</value>\n"
|
||||
" <value>4</value>\n"
|
||||
" </values>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <values>\n"
|
||||
" <val>2</val>\n"
|
||||
" <val>3</val>\n"
|
||||
" <val>4</val>\n"
|
||||
" </values>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("values/value", "values/val"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes only up specified version")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int", "val"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes only from specified version")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <val>2</val>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int", "val"));
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes for multiple versions")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <val>2</val>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int", "val"));
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes for multiple migrations")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
" <element>hi there</element>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <val>2</val>\n"
|
||||
" <ele>hi there</ele>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "val"));
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("element", "ele"));
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator changes for multiple versions and migrations")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
" <element>two</element>\n"
|
||||
" <element>three</element>\n"
|
||||
" <element>four</element>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <elements>\n"
|
||||
" <element>two</element>\n"
|
||||
" <element>three</element>\n"
|
||||
" <element>four</element>\n"
|
||||
" </elements>\n"
|
||||
" <version>3</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int/val"));
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("element", "ele"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int/val", "int"));
|
||||
migrator.addMigration(3, std::make_shared<SettingsMigrationMoveKey>("ele", "elements/element"));
|
||||
migrator.migrate(&settingsBefore, 3);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator with lambda")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>4</value>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(
|
||||
1, std::make_shared<SettingsMigrationLambda>(
|
||||
[](const SettingsMigration* migration, Settings* settings)
|
||||
{
|
||||
migration->setValueInSettings<int>(settings, "value", migration->getValueFromSettings<int>(settings, "value", 0) * 2);
|
||||
}
|
||||
));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
TEST_CASE("migrator with multiple lambdas")
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>3</value>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(
|
||||
1, std::make_shared<SettingsMigrationLambda>(
|
||||
[](const SettingsMigration* migration, Settings* settings)
|
||||
{
|
||||
migration->setValueInSettings<int>(settings, "value", migration->getValueFromSettings<int>(settings, "value", 0) * 2);
|
||||
}
|
||||
)
|
||||
);
|
||||
migrator.addMigration(
|
||||
2, std::make_shared<SettingsMigrationLambda>(
|
||||
[](const SettingsMigration* migration, Settings* settings)
|
||||
{
|
||||
migration->setValueInSettings<int>(settings, "value", migration->getValueFromSettings<int>(settings, "value", 0) - 1);
|
||||
}
|
||||
)
|
||||
);
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText());
|
||||
}
|
||||
@@ -1,383 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "Settings.h"
|
||||
#include "SettingsMigrator.h"
|
||||
#include "SettingsMigrationLambda.h"
|
||||
#include "SettingsMigrationMoveKey.h"
|
||||
#include "TextAccess.h"
|
||||
|
||||
class SettingsMigratorTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_migrator_changes_nothing_without_migrations_except_version()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_name()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_path()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <sub>\n"
|
||||
" <int>2</int>\n"
|
||||
" </sub>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "sub/int"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_group_name()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <values>\n"
|
||||
" <value>2</value>\n"
|
||||
" <value>3</value>\n"
|
||||
" <value>4</value>\n"
|
||||
" </values>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <vals>\n"
|
||||
" <value>2</value>\n"
|
||||
" <value>3</value>\n"
|
||||
" <value>4</value>\n"
|
||||
" </vals>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("values/value", "vals/value"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_group_element_name()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <values>\n"
|
||||
" <value>2</value>\n"
|
||||
" <value>3</value>\n"
|
||||
" <value>4</value>\n"
|
||||
" </values>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <values>\n"
|
||||
" <val>2</val>\n"
|
||||
" <val>3</val>\n"
|
||||
" <val>4</val>\n"
|
||||
" </values>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("values/value", "values/val"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_only_up_specified_version()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int", "val"));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_only_from_specified_version()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <val>2</val>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int", "val"));
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_for_multiple_versions()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <val>2</val>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int", "val"));
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_for_multiple_migrations()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
" <element>hi there</element>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <val>2</val>\n"
|
||||
" <ele>hi there</ele>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "val"));
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("element", "ele"));
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_changes_for_multiple_versions_and_migrations()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
" <element>two</element>\n"
|
||||
" <element>three</element>\n"
|
||||
" <element>four</element>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <int>2</int>\n"
|
||||
" <elements>\n"
|
||||
" <element>two</element>\n"
|
||||
" <element>three</element>\n"
|
||||
" <element>four</element>\n"
|
||||
" </elements>\n"
|
||||
" <version>3</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("value", "int/val"));
|
||||
migrator.addMigration(1, std::make_shared<SettingsMigrationMoveKey>("element", "ele"));
|
||||
migrator.addMigration(2, std::make_shared<SettingsMigrationMoveKey>("int/val", "int"));
|
||||
migrator.addMigration(3, std::make_shared<SettingsMigrationMoveKey>("ele", "elements/element"));
|
||||
migrator.migrate(&settingsBefore, 3);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_with_lambda()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>4</value>\n"
|
||||
" <version>1</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(
|
||||
1, std::make_shared<SettingsMigrationLambda>(
|
||||
[](const SettingsMigration* migration, Settings* settings)
|
||||
{
|
||||
migration->setValueInSettings<int>(settings, "value", migration->getValueFromSettings<int>(settings, "value", 0) * 2);
|
||||
}
|
||||
));
|
||||
migrator.migrate(&settingsBefore, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
void test_migrator_with_multiple_lambdas()
|
||||
{
|
||||
TestSettings settingsBefore = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>2</value>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
TestSettings settingsAfter = createSettings(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
" <value>3</value>\n"
|
||||
" <version>2</version>\n"
|
||||
"</config>\n"
|
||||
);
|
||||
|
||||
SettingsMigrator migrator;
|
||||
migrator.addMigration(
|
||||
1, std::make_shared<SettingsMigrationLambda>(
|
||||
[](const SettingsMigration* migration, Settings* settings)
|
||||
{
|
||||
migration->setValueInSettings<int>(settings, "value", migration->getValueFromSettings<int>(settings, "value", 0) * 2);
|
||||
}
|
||||
)
|
||||
);
|
||||
migrator.addMigration(
|
||||
2, std::make_shared<SettingsMigrationLambda>(
|
||||
[](const SettingsMigration* migration, Settings* settings)
|
||||
{
|
||||
migration->setValueInSettings<int>(settings, "value", migration->getValueFromSettings<int>(settings, "value", 0) - 1);
|
||||
}
|
||||
)
|
||||
);
|
||||
migrator.migrate(&settingsBefore, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(settingsBefore.getAsText(), settingsAfter.getAsText());
|
||||
}
|
||||
|
||||
private:
|
||||
class TestSettings
|
||||
: public Settings
|
||||
{
|
||||
public:
|
||||
static TestSettings createFromText(const std::shared_ptr<TextAccess> textAccess)
|
||||
{
|
||||
TestSettings settings;
|
||||
settings.m_config = ConfigManager::createAndLoad(textAccess);
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::string getAsText() const
|
||||
{
|
||||
if (m_config)
|
||||
{
|
||||
return m_config->toString();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
TestSettings createSettings(const std::string& text)
|
||||
{
|
||||
return TestSettings::createFromText(TextAccess::createFromString(text));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,215 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "ProjectSettings.h"
|
||||
#include "Settings.h"
|
||||
#include "SourceGroupSettingsWithCxxPathsAndFlags.h"
|
||||
#include "SourceGroupSettings.h"
|
||||
#include "SourceGroupSettingsWithSourcePaths.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestSettings : public Settings
|
||||
{
|
||||
public:
|
||||
bool getBool() const
|
||||
{
|
||||
return getValue<bool>("Bool", false);
|
||||
}
|
||||
|
||||
bool setBool(bool value)
|
||||
{
|
||||
return setValue<bool>("Bool", value);
|
||||
}
|
||||
|
||||
int getInt() const
|
||||
{
|
||||
return getValue<int>("Int", -1);
|
||||
}
|
||||
|
||||
bool setInt(int value)
|
||||
{
|
||||
return setValue<int>("Int", value);
|
||||
}
|
||||
|
||||
float getFloat() const
|
||||
{
|
||||
return getValue<float>("Float", 0.01f);
|
||||
}
|
||||
|
||||
bool setFloat(float value)
|
||||
{
|
||||
return setValue<float>("Float", value);
|
||||
}
|
||||
|
||||
std::string getString() const
|
||||
{
|
||||
return getValue<std::string>("String", "<empty>");
|
||||
}
|
||||
|
||||
bool setString(const std::string& value)
|
||||
{
|
||||
return setValue<std::string>("String", value);
|
||||
}
|
||||
|
||||
std::wstring getWString() const
|
||||
{
|
||||
return getValue<std::wstring>("WString", L"<empty>");
|
||||
}
|
||||
|
||||
bool setWString(const std::wstring& value)
|
||||
{
|
||||
return setValue<std::wstring>("WString", value);
|
||||
}
|
||||
|
||||
bool getNewBool() const
|
||||
{
|
||||
return getValue<bool>("NewBool", false);
|
||||
}
|
||||
|
||||
bool setNewBool(bool value)
|
||||
{
|
||||
return setValue<bool>("NewBool", value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("settings get loaded from file")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
}
|
||||
|
||||
TEST_CASE("settings get not loaded from file")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(!settings.load(FilePath(L"data/SettingsTestSuite/wrong_settings.xml")));
|
||||
}
|
||||
|
||||
TEST_CASE("settings get loaded value")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
REQUIRE(settings.getBool() == true);
|
||||
REQUIRE(settings.getInt() == 42);
|
||||
REQUIRE(settings.getFloat() == 3.1416f);
|
||||
REQUIRE(settings.getString() == "Hello World!");
|
||||
REQUIRE(settings.getWString() == L"Hello World!");
|
||||
}
|
||||
|
||||
TEST_CASE("settings get default value when not loaded")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(settings.getBool() == false);
|
||||
REQUIRE(settings.getInt() == -1);
|
||||
REQUIRE(settings.getFloat() == 0.01f);
|
||||
REQUIRE(settings.getString() == "<empty>");
|
||||
REQUIRE(settings.getWString() == L"<empty>");
|
||||
}
|
||||
|
||||
TEST_CASE("settings get default value when wrongly loaded")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(!settings.load(FilePath(L"data/SettingsTestSuite/wrong_settings.xml")));
|
||||
|
||||
REQUIRE(settings.getBool() == false);
|
||||
REQUIRE(settings.getInt() == -1);
|
||||
REQUIRE(settings.getFloat() == 0.01f);
|
||||
REQUIRE(settings.getString() == "<empty>");
|
||||
REQUIRE(settings.getWString() == L"<empty>");
|
||||
}
|
||||
|
||||
TEST_CASE("settings get default value after clearing")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
settings.clear();
|
||||
REQUIRE(settings.getBool() == false);
|
||||
REQUIRE(settings.getInt() == -1);
|
||||
REQUIRE(settings.getFloat() == 0.01f);
|
||||
REQUIRE(settings.getString() == "<empty>");
|
||||
REQUIRE(settings.getWString() == L"<empty>");
|
||||
}
|
||||
|
||||
TEST_CASE("settings can be set when not loaded")
|
||||
{
|
||||
TestSettings settings;
|
||||
|
||||
REQUIRE(settings.setBool(false));
|
||||
REQUIRE(settings.getBool() == false);
|
||||
|
||||
REQUIRE(settings.setInt(2));
|
||||
REQUIRE(settings.getInt() == 2);
|
||||
|
||||
REQUIRE(settings.setFloat(2.5f));
|
||||
REQUIRE(settings.getFloat() == 2.5f);
|
||||
|
||||
REQUIRE(settings.setString("foo"));
|
||||
REQUIRE(settings.getString() == "foo");
|
||||
|
||||
REQUIRE(settings.setWString(L"bar"));
|
||||
REQUIRE(settings.getWString() == L"bar");
|
||||
}
|
||||
|
||||
TEST_CASE("settings can be replaced when loaded")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
REQUIRE(settings.setBool(false));
|
||||
REQUIRE(settings.getBool() == false);
|
||||
|
||||
REQUIRE(settings.setInt(2));
|
||||
REQUIRE(settings.getInt() == 2);
|
||||
|
||||
REQUIRE(settings.setFloat(2.5f));
|
||||
REQUIRE(settings.getFloat() == 2.5f);
|
||||
|
||||
REQUIRE(settings.setString("foo"));
|
||||
REQUIRE(settings.getString() == "foo");
|
||||
|
||||
REQUIRE(settings.setWString(L"bar"));
|
||||
REQUIRE(settings.getWString() == L"bar");
|
||||
}
|
||||
|
||||
TEST_CASE("settings can be added when loaded")
|
||||
{
|
||||
TestSettings settings;
|
||||
REQUIRE(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
REQUIRE(settings.getNewBool() == false);
|
||||
REQUIRE(settings.setNewBool(true));
|
||||
REQUIRE(settings.getNewBool() == true);
|
||||
}
|
||||
|
||||
TEST_CASE("load project settings from file")
|
||||
{
|
||||
ProjectSettings settings;
|
||||
REQUIRE(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
}
|
||||
|
||||
TEST_CASE("load source path from file")
|
||||
{
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.load(FilePath(L"data/SettingsTestSuite/settings.xml"));
|
||||
std::shared_ptr<SourceGroupSettingsWithSourcePaths> sourceGroupSettings =
|
||||
std::dynamic_pointer_cast<SourceGroupSettingsWithSourcePaths>(projectSettings.getAllSourceGroupSettings().front());
|
||||
std::vector<FilePath> paths = sourceGroupSettings->getSourcePaths();
|
||||
|
||||
REQUIRE(paths.size() == 1);
|
||||
REQUIRE(paths[0].wstr() == L"data");
|
||||
}
|
||||
|
||||
TEST_CASE("load header search paths from file")
|
||||
{
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.load(FilePath(L"data/SettingsTestSuite/settings.xml"));
|
||||
std::shared_ptr<SourceGroupSettingsWithCxxPathsAndFlags> sourceGroupSettings =
|
||||
std::dynamic_pointer_cast<SourceGroupSettingsWithCxxPathsAndFlags>(projectSettings.getAllSourceGroupSettings().front());
|
||||
std::vector<FilePath> paths = sourceGroupSettings->getHeaderSearchPaths();
|
||||
|
||||
REQUIRE(paths.size() == 2);
|
||||
REQUIRE(paths[0].wstr() == L"data/");
|
||||
REQUIRE(paths[1].wstr() == L"src/");
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "ProjectSettings.h"
|
||||
#include "Settings.h"
|
||||
#include "SourceGroupSettingsWithCxxPathsAndFlags.h"
|
||||
#include "SourceGroupSettingsWithSourcePaths.h"
|
||||
|
||||
class SettingsTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_settings_get_loaded_from_file()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
}
|
||||
|
||||
void test_settings_get_not_loaded_from_file()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(!settings.load(FilePath(L"data/SettingsTestSuite/wrong_settings.xml")));
|
||||
}
|
||||
|
||||
void test_settings_get_loaded_value()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
TS_ASSERT_EQUALS(settings.getBool(), true);
|
||||
TS_ASSERT_EQUALS(settings.getInt(), 42);
|
||||
TS_ASSERT_EQUALS(settings.getFloat(), 3.1416f);
|
||||
TS_ASSERT_EQUALS(settings.getString(), "Hello World!");
|
||||
TS_ASSERT_EQUALS(settings.getWString(), L"Hello World!");
|
||||
}
|
||||
|
||||
void test_settings_get_default_value_when_not_loaded()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT_EQUALS(settings.getBool(), false);
|
||||
TS_ASSERT_EQUALS(settings.getInt(), -1);
|
||||
TS_ASSERT_EQUALS(settings.getFloat(), 0.01f);
|
||||
TS_ASSERT_EQUALS(settings.getString(), "<empty>");
|
||||
TS_ASSERT_EQUALS(settings.getWString(), L"<empty>");
|
||||
}
|
||||
|
||||
void test_settings_get_default_value_when_wrongly_loaded()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(!settings.load(FilePath(L"data/SettingsTestSuite/wrong_settings.xml")));
|
||||
|
||||
TS_ASSERT_EQUALS(settings.getBool(), false);
|
||||
TS_ASSERT_EQUALS(settings.getInt(), -1);
|
||||
TS_ASSERT_EQUALS(settings.getFloat(), 0.01f);
|
||||
TS_ASSERT_EQUALS(settings.getString(), "<empty>");
|
||||
TS_ASSERT_EQUALS(settings.getWString(), L"<empty>");
|
||||
}
|
||||
|
||||
void test_settings_get_default_value_after_clearing()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
settings.clear();
|
||||
TS_ASSERT_EQUALS(settings.getBool(), false);
|
||||
TS_ASSERT_EQUALS(settings.getInt(), -1);
|
||||
TS_ASSERT_EQUALS(settings.getFloat(), 0.01f);
|
||||
TS_ASSERT_EQUALS(settings.getString(), "<empty>");
|
||||
TS_ASSERT_EQUALS(settings.getWString(), L"<empty>");
|
||||
}
|
||||
|
||||
void test_settings_can_be_set_when_not_loaded()
|
||||
{
|
||||
TestSettings settings;
|
||||
|
||||
TS_ASSERT(settings.setBool(false));
|
||||
TS_ASSERT_EQUALS(settings.getBool(), false);
|
||||
|
||||
TS_ASSERT(settings.setInt(2));
|
||||
TS_ASSERT_EQUALS(settings.getInt(), 2);
|
||||
|
||||
TS_ASSERT(settings.setFloat(2.5f));
|
||||
TS_ASSERT_EQUALS(settings.getFloat(), 2.5f);
|
||||
|
||||
TS_ASSERT(settings.setString("foo"));
|
||||
TS_ASSERT_EQUALS(settings.getString(), "foo");
|
||||
|
||||
TS_ASSERT(settings.setWString(L"bar"));
|
||||
TS_ASSERT_EQUALS(settings.getWString(), L"bar");
|
||||
}
|
||||
|
||||
void test_settings_can_be_replaced_when_loaded()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
TS_ASSERT(settings.setBool(false));
|
||||
TS_ASSERT_EQUALS(settings.getBool(), false);
|
||||
|
||||
TS_ASSERT(settings.setInt(2));
|
||||
TS_ASSERT_EQUALS(settings.getInt(), 2);
|
||||
|
||||
TS_ASSERT(settings.setFloat(2.5f));
|
||||
TS_ASSERT_EQUALS(settings.getFloat(), 2.5f);
|
||||
|
||||
TS_ASSERT(settings.setString("foo"));
|
||||
TS_ASSERT_EQUALS(settings.getString(), "foo");
|
||||
|
||||
TS_ASSERT(settings.setWString(L"bar"));
|
||||
TS_ASSERT_EQUALS(settings.getWString(), L"bar");
|
||||
}
|
||||
|
||||
void test_settings_can_be_added_when_loaded()
|
||||
{
|
||||
TestSettings settings;
|
||||
TS_ASSERT(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
|
||||
TS_ASSERT_EQUALS(settings.getNewBool(), false);
|
||||
TS_ASSERT(settings.setNewBool(true));
|
||||
TS_ASSERT_EQUALS(settings.getNewBool(), true);
|
||||
}
|
||||
|
||||
void test_load_project_settings_from_file()
|
||||
{
|
||||
ProjectSettings settings;
|
||||
TS_ASSERT(settings.load(FilePath(L"data/SettingsTestSuite/settings.xml")));
|
||||
}
|
||||
|
||||
void test_load_source_path_from_file()
|
||||
{
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.load(FilePath(L"data/SettingsTestSuite/settings.xml"));
|
||||
std::shared_ptr<SourceGroupSettingsWithSourcePaths> sourceGroupSettings =
|
||||
std::dynamic_pointer_cast<SourceGroupSettingsWithSourcePaths>(projectSettings.getAllSourceGroupSettings().front());
|
||||
std::vector<FilePath> paths = sourceGroupSettings->getSourcePaths();
|
||||
|
||||
TS_ASSERT_EQUALS(paths.size(), 1);
|
||||
TS_ASSERT_EQUALS(paths[0].wstr(), L"data");
|
||||
}
|
||||
|
||||
void test_load_header_search_paths_from_file()
|
||||
{
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.load(FilePath(L"data/SettingsTestSuite/settings.xml"));
|
||||
std::shared_ptr<SourceGroupSettingsWithCxxPathsAndFlags> sourceGroupSettings =
|
||||
std::dynamic_pointer_cast<SourceGroupSettingsWithCxxPathsAndFlags>(projectSettings.getAllSourceGroupSettings().front());
|
||||
std::vector<FilePath> paths = sourceGroupSettings->getHeaderSearchPaths();
|
||||
|
||||
TS_ASSERT_EQUALS(paths.size(), 2);
|
||||
TS_ASSERT_EQUALS(paths[0].wstr(), L"data/");
|
||||
TS_ASSERT_EQUALS(paths[1].wstr(), L"src/");
|
||||
}
|
||||
|
||||
private:
|
||||
class TestSettings
|
||||
: public Settings
|
||||
{
|
||||
public:
|
||||
bool getBool() const
|
||||
{
|
||||
return getValue<bool>("Bool", false);
|
||||
}
|
||||
|
||||
bool setBool(bool value)
|
||||
{
|
||||
return setValue<bool>("Bool", value);
|
||||
}
|
||||
|
||||
int getInt() const
|
||||
{
|
||||
return getValue<int>("Int", -1);
|
||||
}
|
||||
|
||||
bool setInt(int value)
|
||||
{
|
||||
return setValue<int>("Int", value);
|
||||
}
|
||||
|
||||
float getFloat() const
|
||||
{
|
||||
return getValue<float>("Float", 0.01f);
|
||||
}
|
||||
|
||||
bool setFloat(float value)
|
||||
{
|
||||
return setValue<float>("Float", value);
|
||||
}
|
||||
|
||||
std::string getString() const
|
||||
{
|
||||
return getValue<std::string>("String", "<empty>");
|
||||
}
|
||||
|
||||
bool setString(const std::string& value)
|
||||
{
|
||||
return setValue<std::string>("String", value);
|
||||
}
|
||||
|
||||
std::wstring getWString() const
|
||||
{
|
||||
return getValue<std::wstring>("WString", L"<empty>");
|
||||
}
|
||||
|
||||
bool setWString(const std::wstring& value)
|
||||
{
|
||||
return setValue<std::wstring>("WString", value);
|
||||
}
|
||||
|
||||
bool getNewBool() const
|
||||
{
|
||||
return getValue<bool>("NewBool", false);
|
||||
}
|
||||
|
||||
bool setNewBool(bool value)
|
||||
{
|
||||
return setValue<bool>("NewBool", value);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "SharedMemory.h"
|
||||
|
||||
TEST_CASE("shared memory")
|
||||
{
|
||||
SharedMemory memory("memory", 1000, SharedMemory::CREATE_AND_DELETE);
|
||||
|
||||
{
|
||||
SharedMemory::ScopedAccess access(&memory);
|
||||
|
||||
REQUIRE(access.getMemorySize() == 1000);
|
||||
*access.accessValue<int>("count") = 0;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<std::thread>> threads;
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
threads.push_back(std::make_shared<std::thread>(
|
||||
[]()
|
||||
{
|
||||
SharedMemory memory("memory", 0, SharedMemory::OPEN_ONLY);
|
||||
|
||||
SharedMemory::ScopedAccess access(&memory);
|
||||
|
||||
if (access.getMemorySize() < 5000)
|
||||
{
|
||||
access.growMemory(5000 - access.getMemorySize());
|
||||
}
|
||||
|
||||
int* count = access.accessValue<int>("count");
|
||||
*count += 1;
|
||||
|
||||
SharedMemory::String* str = access.accessValueWithAllocator<SharedMemory::String>("string");
|
||||
str->append("hi");
|
||||
|
||||
SharedMemory::Vector<int>* nums = access.accessValueWithAllocator<SharedMemory::Vector<int>>("nums");
|
||||
nums->push_back(nums->size());
|
||||
|
||||
SharedMemory::Vector<SharedMemory::String>* strings =
|
||||
access.accessValueWithAllocator<SharedMemory::Vector<SharedMemory::String>>("strings");
|
||||
strings->push_back(SharedMemory::String("ho", access.getAllocator()));
|
||||
|
||||
SharedMemory::Map<int, int>* vals =
|
||||
access.accessValueWithAllocator<SharedMemory::Map<int, int>>("vals");
|
||||
vals->emplace(vals->size(), vals->size() * vals->size());
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
thread->join();
|
||||
}
|
||||
threads.clear();
|
||||
|
||||
{
|
||||
SharedMemory::ScopedAccess access(&memory);
|
||||
|
||||
REQUIRE(access.getMemorySize() == 5000);
|
||||
REQUIRE(*access.accessValue<int>("count") == 4);
|
||||
const std::string value = access.accessValueWithAllocator<SharedMemory::String>("string")->c_str();
|
||||
REQUIRE(value == "hihihihi");
|
||||
|
||||
SharedMemory::Vector<int>* nums = access.accessValueWithAllocator<SharedMemory::Vector<int>>("nums");
|
||||
REQUIRE(nums->size() == 4);
|
||||
for (int i : *nums)
|
||||
{
|
||||
REQUIRE(i == i);
|
||||
}
|
||||
|
||||
SharedMemory::Vector<SharedMemory::String>* strings =
|
||||
access.accessValueWithAllocator<SharedMemory::Vector<SharedMemory::String>>("strings");
|
||||
REQUIRE(strings->size() == 4);
|
||||
for (SharedMemory::String& str : *strings)
|
||||
{
|
||||
REQUIRE(str == "ho");
|
||||
}
|
||||
|
||||
SharedMemory::Map<int, int>* vals =
|
||||
access.accessValueWithAllocator<SharedMemory::Map<int, int>>("vals");
|
||||
REQUIRE(vals->size() == 4);
|
||||
|
||||
size_t i = 0;
|
||||
for (auto val : *vals)
|
||||
{
|
||||
REQUIRE(val.first == i);
|
||||
REQUIRE(val.second == i * i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "SharedMemory.h"
|
||||
|
||||
class SharedMemoryTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_shared_memory(void)
|
||||
{
|
||||
SharedMemory memory("memory", 1000, SharedMemory::CREATE_AND_DELETE);
|
||||
|
||||
{
|
||||
SharedMemory::ScopedAccess access(&memory);
|
||||
|
||||
TS_ASSERT_EQUALS(access.getMemorySize(), 1000);
|
||||
*access.accessValue<int>("count") = 0;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<std::thread>> threads;
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
threads.push_back(std::make_shared<std::thread>(
|
||||
[]()
|
||||
{
|
||||
SharedMemory memory("memory", 0, SharedMemory::OPEN_ONLY);
|
||||
|
||||
SharedMemory::ScopedAccess access(&memory);
|
||||
|
||||
if (access.getMemorySize() < 5000)
|
||||
{
|
||||
access.growMemory(5000 - access.getMemorySize());
|
||||
}
|
||||
|
||||
int* count = access.accessValue<int>("count");
|
||||
*count += 1;
|
||||
|
||||
SharedMemory::String* str = access.accessValueWithAllocator<SharedMemory::String>("string");
|
||||
str->append("hi");
|
||||
|
||||
SharedMemory::Vector<int>* nums = access.accessValueWithAllocator<SharedMemory::Vector<int>>("nums");
|
||||
nums->push_back(nums->size());
|
||||
|
||||
SharedMemory::Vector<SharedMemory::String>* strings =
|
||||
access.accessValueWithAllocator<SharedMemory::Vector<SharedMemory::String>>("strings");
|
||||
strings->push_back(SharedMemory::String("ho", access.getAllocator()));
|
||||
|
||||
SharedMemory::Map<int, int>* vals =
|
||||
access.accessValueWithAllocator<SharedMemory::Map<int, int>>("vals");
|
||||
vals->emplace(vals->size(), vals->size() * vals->size());
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
thread->join();
|
||||
}
|
||||
threads.clear();
|
||||
|
||||
{
|
||||
SharedMemory::ScopedAccess access(&memory);
|
||||
|
||||
TS_ASSERT_EQUALS(access.getMemorySize(), 5000);
|
||||
TS_ASSERT_EQUALS(*access.accessValue<int>("count"), 4);
|
||||
TS_ASSERT_EQUALS(access.accessValueWithAllocator<SharedMemory::String>("string")->c_str(), "hihihihi");
|
||||
|
||||
SharedMemory::Vector<int>* nums = access.accessValueWithAllocator<SharedMemory::Vector<int>>("nums");
|
||||
TS_ASSERT_EQUALS(nums->size(), 4);
|
||||
for (int i : *nums)
|
||||
{
|
||||
TS_ASSERT_EQUALS(i, i);
|
||||
}
|
||||
|
||||
SharedMemory::Vector<SharedMemory::String>* strings =
|
||||
access.accessValueWithAllocator<SharedMemory::Vector<SharedMemory::String>>("strings");
|
||||
TS_ASSERT_EQUALS(strings->size(), 4);
|
||||
for (SharedMemory::String& str : *strings)
|
||||
{
|
||||
TS_ASSERT_EQUALS(str, "ho");
|
||||
}
|
||||
|
||||
SharedMemory::Map<int, int>* vals =
|
||||
access.accessValueWithAllocator<SharedMemory::Map<int, int>>("vals");
|
||||
TS_ASSERT_EQUALS(vals->size(), 4);
|
||||
|
||||
size_t i = 0;
|
||||
for (auto val : *vals)
|
||||
{
|
||||
TS_ASSERT_EQUALS(val.first, i);
|
||||
TS_ASSERT_EQUALS(val.second, i * i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,619 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "IndexerCommandCustom.h"
|
||||
#include "IndexerCommandCxx.h"
|
||||
#include "IndexerCommandJava.h"
|
||||
#include "JavaEnvironmentFactory.h"
|
||||
#include "SourceGroupCxxEmpty.h"
|
||||
#include "SourceGroupCxxCdb.h"
|
||||
#include "SourceGroupCxxCodeblocks.h"
|
||||
#include "SourceGroupCxxSonargraph.h"
|
||||
#include "SourceGroupCustomCommand.h"
|
||||
#include "SourceGroupJavaEmpty.h"
|
||||
#include "SourceGroupJavaGradle.h"
|
||||
#include "SourceGroupJavaMaven.h"
|
||||
#include "SourceGroupJavaSonargraph.h"
|
||||
#include "SourceGroupSettingsCEmpty.h"
|
||||
#include "SourceGroupSettingsCppEmpty.h"
|
||||
#include "SourceGroupSettingsCxxCdb.h"
|
||||
#include "SourceGroupSettingsCxxCodeblocks.h"
|
||||
#include "SourceGroupSettingsCxxSonargraph.h"
|
||||
#include "SourceGroupSettingsCustomCommand.h"
|
||||
#include "SourceGroupSettingsJavaEmpty.h"
|
||||
#include "SourceGroupSettingsJavaGradle.h"
|
||||
#include "SourceGroupSettingsJavaMaven.h"
|
||||
#include "SourceGroupSettingsJavaSonargraph.h"
|
||||
#include "ProjectSettings.h"
|
||||
#include "ApplicationSettings.h"
|
||||
#include "FileSystem.h"
|
||||
#include "TextAccess.h"
|
||||
#include "AppPath.h"
|
||||
#include "utilityJava.h"
|
||||
#include "utilityPathDetection.h"
|
||||
#include "utilityString.h"
|
||||
#include "Version.h"
|
||||
#include "Application.h"
|
||||
|
||||
#define REQUIRE_MESSAGE(msg, cond) do { INFO(msg); REQUIRE(cond); } while((void)0, 0)
|
||||
|
||||
namespace
|
||||
{
|
||||
const bool updateExpectedOutput = false;
|
||||
|
||||
static FilePath getInputDirectoryPath(const std::wstring& projectName)
|
||||
{
|
||||
return FilePath(L"data/SourceGroupTestSuite/" + projectName + L"/input").makeAbsolute().makeCanonical();
|
||||
}
|
||||
|
||||
static FilePath getOutputDirectoryPath(const std::wstring& projectName)
|
||||
{
|
||||
return FilePath(L"data/SourceGroupTestSuite/" + projectName + L"/expected_output").makeAbsolute().makeCanonical();
|
||||
}
|
||||
|
||||
std::string setupJavaEnvironmentFactory()
|
||||
{
|
||||
if (!JavaEnvironmentFactory::getInstance())
|
||||
{
|
||||
std::string errorString;
|
||||
#ifdef _WIN32
|
||||
const std::string separator = ";";
|
||||
#else
|
||||
const std::string separator = ":";
|
||||
#endif
|
||||
std::string classPath = "";
|
||||
{
|
||||
const std::vector<std::wstring> jarNames = utility::getRequiredJarNames();
|
||||
for (size_t i = 0; i < jarNames.size(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
classPath += separator;
|
||||
}
|
||||
classPath += FilePath(L"../app/data/java/lib/").concatenate(jarNames[i]).str();
|
||||
}
|
||||
}
|
||||
|
||||
JavaEnvironmentFactory::createInstance(
|
||||
classPath,
|
||||
errorString
|
||||
);
|
||||
|
||||
return errorString;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::wstring indexerCommandCxxToString(std::shared_ptr<const IndexerCommandCxx> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
std::wstring result;
|
||||
result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
for (const FilePath& indexedPath : indexerCommand->getIndexedPaths())
|
||||
{
|
||||
result += L"\tIndexedPath: \"" + indexedPath.getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
}
|
||||
for (std::wstring compilerFlag : indexerCommand->getCompilerFlags())
|
||||
{
|
||||
FilePath flagAsPath(compilerFlag);
|
||||
if (flagAsPath.exists())
|
||||
{
|
||||
compilerFlag = flagAsPath.getRelativeTo(baseDirectory).wstr();
|
||||
}
|
||||
result += L"\tCompilerFlag: \"" + compilerFlag + L"\"\n";
|
||||
}
|
||||
for (const FilePathFilter& filter : indexerCommand->getExcludeFilters())
|
||||
{
|
||||
result += L"\tExcludeFilter: \"" + filter.wstr() + L"\"\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring indexerCommandJavaToString(std::shared_ptr<const IndexerCommandJava> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
std::wstring result;
|
||||
result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
result += L"\tLanguageStandard: \"" + indexerCommand->getLanguageStandard() + L"\"\n";
|
||||
for (const FilePath& classPathItem : indexerCommand->getClassPath())
|
||||
{
|
||||
result += L"\tClassPathItem: \"" + classPathItem.getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring indexerCommandCustomToString(std::shared_ptr<const IndexerCommandCustom> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
std::wstring result;
|
||||
result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
result += L"\tCustom Command: \"" + indexerCommand->getCustomCommand() + L"\"\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring indexerCommandToString(std::shared_ptr<IndexerCommand> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
if (indexerCommand)
|
||||
{
|
||||
if (std::shared_ptr<const IndexerCommandCxx> indexerCommandCxx = std::dynamic_pointer_cast<const IndexerCommandCxx>(indexerCommand))
|
||||
{
|
||||
return indexerCommandCxxToString(indexerCommandCxx, baseDirectory);
|
||||
}
|
||||
if (std::shared_ptr<const IndexerCommandJava> indexerCommandJava = std::dynamic_pointer_cast<const IndexerCommandJava>(indexerCommand))
|
||||
{
|
||||
return indexerCommandJavaToString(indexerCommandJava, baseDirectory);
|
||||
}
|
||||
if (std::shared_ptr<const IndexerCommandCustom> indexerCommandCustom = std::dynamic_pointer_cast<const IndexerCommandCustom>(indexerCommand))
|
||||
{
|
||||
return indexerCommandCustomToString(indexerCommandCustom, baseDirectory);
|
||||
}
|
||||
return L"Unsupported indexer command type: " + utility::decodeFromUtf8(indexerCommandTypeToString(indexerCommand->getIndexerCommandType()));
|
||||
}
|
||||
return L"No IndexerCommand provided.";
|
||||
}
|
||||
|
||||
std::shared_ptr<TextAccess> generateExpectedOutput(
|
||||
std::wstring projectName,
|
||||
std::shared_ptr<const SourceGroup> sourceGroup)
|
||||
{
|
||||
const FilePath projectDataRoot = getInputDirectoryPath(projectName).makeAbsolute();
|
||||
|
||||
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands = sourceGroup->getIndexerCommands(sourceGroup->getAllSourceFilePaths());
|
||||
|
||||
std::sort(
|
||||
indexerCommands.begin(),
|
||||
indexerCommands.end(),
|
||||
[](std::shared_ptr<IndexerCommand> a, std::shared_ptr<IndexerCommand> b)
|
||||
{
|
||||
return a->getSourceFilePath().wstr() < b->getSourceFilePath().wstr();
|
||||
}
|
||||
);
|
||||
|
||||
std::wstring outputString;
|
||||
for (std::shared_ptr<IndexerCommand> indexerCommand : indexerCommands)
|
||||
{
|
||||
outputString += indexerCommandToString(indexerCommand, projectDataRoot);
|
||||
}
|
||||
|
||||
return TextAccess::createFromString(utility::encodeToUtf8(outputString));
|
||||
}
|
||||
|
||||
void generateAndCompareExpectedOutput(
|
||||
std::wstring projectName,
|
||||
std::shared_ptr<const SourceGroup> sourceGroup)
|
||||
{
|
||||
const std::shared_ptr<const TextAccess> output = generateExpectedOutput(projectName, sourceGroup);
|
||||
#ifdef WIN32
|
||||
const std::wstring expectedOutputFileName = L"output_windows.txt";
|
||||
#else
|
||||
const std::wstring expectedOutputFileName = L"output_unix.txt";
|
||||
#endif
|
||||
const FilePath expectedOutputFilePath = getOutputDirectoryPath(projectName).concatenate(expectedOutputFileName);
|
||||
if (updateExpectedOutput || !expectedOutputFilePath.exists())
|
||||
{
|
||||
std::ofstream expectedOutputFile;
|
||||
expectedOutputFile.open(expectedOutputFilePath.str());
|
||||
expectedOutputFile << output->getText();
|
||||
expectedOutputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::shared_ptr<const TextAccess> expectedOutput = TextAccess::createFromFile(expectedOutputFilePath);
|
||||
REQUIRE_MESSAGE(("Output does not match the expected line count for project \"" + utility::encodeToUtf8(projectName) + "\".").c_str(), expectedOutput->getLineCount() == output->getLineCount());
|
||||
if (expectedOutput->getLineCount() == output->getLineCount())
|
||||
{
|
||||
for (size_t i = 1; i <= expectedOutput->getLineCount(); i++)
|
||||
{
|
||||
REQUIRE(expectedOutput->getLine(i) == output->getLine(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("finds all jar dependencies")
|
||||
{
|
||||
for (const std::wstring& jarName : utility::getRequiredJarNames())
|
||||
{
|
||||
FilePath jarPath = FilePath(L"../app/data/java/lib/").concatenate(jarName);
|
||||
REQUIRE_MESSAGE("Jar dependency path does not exist: " + jarPath.str(), jarPath.exists());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("can setup environment factory")
|
||||
{
|
||||
std::vector<FilePath> javaPaths = utility::getJavaRuntimePathDetector()->getPaths();
|
||||
if (!javaPaths.empty())
|
||||
{
|
||||
ApplicationSettings::getInstance()->setJavaPath(javaPaths[0]);
|
||||
}
|
||||
const std::string errorString = setupJavaEnvironmentFactory();
|
||||
|
||||
REQUIRE("" == errorString);
|
||||
|
||||
// if this one fails, maybe your java_path in the test settings is wrong.
|
||||
REQUIRE(JavaEnvironmentFactory::getInstance().use_count() >= 1);
|
||||
}
|
||||
|
||||
TEST_CASE("can create application instance")
|
||||
{
|
||||
// required to query in SourceGroup for dialog view... this is not a very elegant solution. should be refactored to pass dialog view to SourceGroup on creation.
|
||||
Application::createInstance(Version(), nullptr, nullptr);
|
||||
REQUIRE(Application::getInstance().use_count() >= 1);
|
||||
}
|
||||
|
||||
TEST_CASE("source group cxx c empty generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_c_empty";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCEmpty> sourceGroupSettings = std::make_shared<SourceGroupSettingsCEmpty>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"src") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".c" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setTargetOptionsEnabled(true);
|
||||
sourceGroupSettings->setTargetArch(L"test_arch");
|
||||
sourceGroupSettings->setTargetVendor(L"test_vendor");
|
||||
sourceGroupSettings->setTargetSys(L"test_sys");
|
||||
sourceGroupSettings->setTargetAbi(L"test_abi");
|
||||
sourceGroupSettings->setCStandard(L"c11");
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxEmpty>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("source group cxx cpp empty generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_cpp_empty";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCppEmpty> sourceGroupSettings = std::make_shared<SourceGroupSettingsCppEmpty>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"/src") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".cpp" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setTargetOptionsEnabled(true);
|
||||
sourceGroupSettings->setTargetArch(L"test_arch");
|
||||
sourceGroupSettings->setTargetVendor(L"test_vendor");
|
||||
sourceGroupSettings->setTargetSys(L"test_sys");
|
||||
sourceGroupSettings->setTargetAbi(L"test_abi");
|
||||
sourceGroupSettings->setCppStandard(L"c++11");
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxEmpty>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("source group cxx codeblocks generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_codeblocks";
|
||||
const FilePath cbpPath = getInputDirectoryPath(projectName).concatenate(L"project.cbp");
|
||||
const FilePath sourceCbpPath = getInputDirectoryPath(projectName).concatenate(L"project.cbp.in");
|
||||
|
||||
FileSystem::remove(cbpPath);
|
||||
|
||||
{
|
||||
std::ofstream fileStream;
|
||||
fileStream.open(cbpPath.str(), std::ios::app);
|
||||
fileStream << utility::replace(
|
||||
TextAccess::createFromFile(sourceCbpPath)->getText(), "<source_path>", getInputDirectoryPath(projectName).concatenate(L"src").getAbsolute().str()
|
||||
);
|
||||
fileStream.close();
|
||||
}
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxCodeblocks> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxCodeblocks>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setCodeblocksProjectPath(cbpPath);
|
||||
sourceGroupSettings->setCppStandard(L"c++11");
|
||||
sourceGroupSettings->setCStandard(L"c11");
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".cpp", L".c" });
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxCodeblocks>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
|
||||
FileSystem::remove(cbpPath);
|
||||
}
|
||||
|
||||
TEST_CASE("source group cxx cdb generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_cdb";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxCdb> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxCdb>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setCompilationDatabasePath(getInputDirectoryPath(projectName).concatenate(L"compile_commands.json"));
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxCdb>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("source group cxx sonargraph with cmake json modules generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_sonargraph_cmake_json";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setSonargraphProjectPath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxSonargraph>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("source group cxx sonargraph with cpp manual modules generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_sonargraph_cpp_manual";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setSonargraphProjectPath(getInputDirectoryPath(projectName).concatenate(L"/sonargraph/system.sonargraph"));
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxSonargraph>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("sourcegroup java empty generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"java_empty";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaEmpty> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaEmpty>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourceExtensions({ L".java" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/Foo.java" });
|
||||
sourceGroupSettings->setJavaStandard({ L"10" });
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"src") });
|
||||
sourceGroupSettings->setUseJreSystemLibrary(true);
|
||||
sourceGroupSettings->setClasspath({
|
||||
getInputDirectoryPath(projectName).concatenate(L"lib/dependency.jar"), getInputDirectoryPath(projectName).concatenate(L"classpath_dir")
|
||||
});
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaEmpty>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("sourcegroup java gradle generates expected output")
|
||||
{
|
||||
#ifndef __linux__
|
||||
const std::wstring projectName = L"java_gradle";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaGradle> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaGradle>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourceExtensions({ L".java" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/HelloWorld.java" });
|
||||
sourceGroupSettings->setJavaStandard({ L"10" });
|
||||
sourceGroupSettings->setGradleProjectFilePath({ getInputDirectoryPath(projectName).concatenate(L"build.gradle") });
|
||||
sourceGroupSettings->setShouldIndexGradleTests(true);
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
const FilePath storedAppPath = AppPath::getAppPath();
|
||||
AppPath::setAppPath(storedAppPath.getConcatenated(L"../app").makeAbsolute());
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaGradle>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
AppPath::setAppPath(storedAppPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("sourcegroup java maven generates expected output")
|
||||
{
|
||||
std::vector<FilePath> mavenPaths = utility::getMavenExecutablePathDetector()->getPaths();
|
||||
|
||||
REQUIRE(!mavenPaths.empty());
|
||||
|
||||
if (!mavenPaths.empty())
|
||||
{
|
||||
ApplicationSettings::getInstance()->setMavenPath(mavenPaths.front());
|
||||
}
|
||||
|
||||
const std::wstring projectName = L"java_maven";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaMaven> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaMaven>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourceExtensions({ L".java" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/Foo.java" });
|
||||
sourceGroupSettings->setJavaStandard({ L"10" });
|
||||
sourceGroupSettings->setMavenProjectFilePath({ getInputDirectoryPath(projectName).concatenate(L"my-app/pom.xml") });
|
||||
sourceGroupSettings->setShouldIndexMavenTests(true);
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaMaven>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("sourcegroup java sonargraph with java modules generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"java_sonargraph";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaSonargraph> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setUseJreSystemLibrary(true);
|
||||
sourceGroupSettings->setClasspath({
|
||||
FilePath(L"test/classpath/file.jar"), FilePath(L"test/classpath/dir")
|
||||
});
|
||||
sourceGroupSettings->setSonargraphProjectPath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaSonargraph>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
}
|
||||
|
||||
TEST_CASE("source group custom command generates expected output")
|
||||
{
|
||||
const std::wstring projectName = L"custom_command";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCustomCommand> sourceGroupSettings = std::make_shared<SourceGroupSettingsCustomCommand>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setCustomCommand(L"echo \"Hello World\"");
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"/src") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".txt" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCustomCommand>(sourceGroupSettings));
|
||||
}
|
||||
|
||||
// Special Tests
|
||||
|
||||
TEST_CASE("sourcegroup java sonargraph with cpp modules does not generate output")
|
||||
{
|
||||
const std::wstring projectName = L"cxx_sonargraph_cpp_manual";
|
||||
const FilePath sonargraphProjectFilePath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
REQUIRE(sonargraphProjectFilePath.exists());
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsJavaSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSonargraphProjectPath(sonargraphProjectFilePath);
|
||||
|
||||
std::shared_ptr<TextAccess> output = generateExpectedOutput(projectName, std::make_shared<SourceGroupJavaSonargraph>(sourceGroupSettings));
|
||||
|
||||
REQUIRE(0 == output->getLineCount());
|
||||
}
|
||||
|
||||
TEST_CASE("sourcegroup cxx sonargraph with java modules does not generate output")
|
||||
{
|
||||
const std::wstring projectName = L"java_sonargraph";
|
||||
const FilePath sonargraphProjectFilePath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
REQUIRE(sonargraphProjectFilePath.exists());
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSonargraphProjectPath(sonargraphProjectFilePath);
|
||||
|
||||
std::shared_ptr<TextAccess> output = generateExpectedOutput(projectName, std::make_shared<SourceGroupCxxSonargraph>(sourceGroupSettings));
|
||||
|
||||
REQUIRE(0 == output->getLineCount());
|
||||
}
|
||||
|
||||
TEST_CASE("can destroy application instance")
|
||||
{
|
||||
Application::destroyInstance();
|
||||
REQUIRE(0 == Application::getInstance().use_count());
|
||||
}
|
||||
@@ -1,622 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "IndexerCommandCustom.h"
|
||||
#include "IndexerCommandCxx.h"
|
||||
#include "IndexerCommandJava.h"
|
||||
#include "JavaEnvironmentFactory.h"
|
||||
#include "SourceGroupCxxEmpty.h"
|
||||
#include "SourceGroupCxxCdb.h"
|
||||
#include "SourceGroupCxxCodeblocks.h"
|
||||
#include "SourceGroupCxxSonargraph.h"
|
||||
#include "SourceGroupCustomCommand.h"
|
||||
#include "SourceGroupJavaEmpty.h"
|
||||
#include "SourceGroupJavaGradle.h"
|
||||
#include "SourceGroupJavaMaven.h"
|
||||
#include "SourceGroupJavaSonargraph.h"
|
||||
#include "SourceGroupSettingsCEmpty.h"
|
||||
#include "SourceGroupSettingsCppEmpty.h"
|
||||
#include "SourceGroupSettingsCxxCdb.h"
|
||||
#include "SourceGroupSettingsCxxCodeblocks.h"
|
||||
#include "SourceGroupSettingsCxxSonargraph.h"
|
||||
#include "SourceGroupSettingsCustomCommand.h"
|
||||
#include "SourceGroupSettingsJavaEmpty.h"
|
||||
#include "SourceGroupSettingsJavaGradle.h"
|
||||
#include "SourceGroupSettingsJavaMaven.h"
|
||||
#include "SourceGroupSettingsJavaSonargraph.h"
|
||||
#include "ProjectSettings.h"
|
||||
#include "ApplicationSettings.h"
|
||||
#include "FileSystem.h"
|
||||
#include "TextAccess.h"
|
||||
#include "AppPath.h"
|
||||
#include "utilityJava.h"
|
||||
#include "utilityPathDetection.h"
|
||||
#include "utilityString.h"
|
||||
#include "Version.h"
|
||||
#include "Application.h"
|
||||
|
||||
class SourceGroupTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
static const bool s_updateExpectedOutput = false;
|
||||
|
||||
void test_finds_all_jar_dependencies()
|
||||
{
|
||||
for (const std::wstring& jarName : utility::getRequiredJarNames())
|
||||
{
|
||||
FilePath jarPath = FilePath(L"../app/data/java/lib/").concatenate(jarName);
|
||||
TSM_ASSERT(L"Jar dependency path does not exist: " + jarPath.wstr(), jarPath.exists());
|
||||
}
|
||||
}
|
||||
|
||||
void test_can_setup_environment_factory()
|
||||
{
|
||||
std::vector<FilePath> javaPaths = utility::getJavaRuntimePathDetector()->getPaths();
|
||||
if (!javaPaths.empty())
|
||||
{
|
||||
ApplicationSettings::getInstance()->setJavaPath(javaPaths[0]);
|
||||
}
|
||||
|
||||
const std::string errorString = setupJavaEnvironmentFactory();
|
||||
|
||||
TS_ASSERT_EQUALS("", errorString);
|
||||
|
||||
// if this one fails, maybe your java_path in the test settings is wrong.
|
||||
TS_ASSERT_LESS_THAN_EQUALS(1, JavaEnvironmentFactory::getInstance().use_count());
|
||||
}
|
||||
|
||||
void test_can_create_application_instance()
|
||||
{
|
||||
// required to query in SourceGroup for dialog view... this is not a very elegant solution. should be refactored to pass dialog view to SourceGroup on creation.
|
||||
Application::createInstance(Version(), nullptr, nullptr);
|
||||
TS_ASSERT_LESS_THAN_EQUALS(1, Application::getInstance().use_count());
|
||||
}
|
||||
|
||||
void test_source_group_cxx_c_empty_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_c_empty";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCEmpty> sourceGroupSettings = std::make_shared<SourceGroupSettingsCEmpty>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"src") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".c" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setTargetOptionsEnabled(true);
|
||||
sourceGroupSettings->setTargetArch(L"test_arch");
|
||||
sourceGroupSettings->setTargetVendor(L"test_vendor");
|
||||
sourceGroupSettings->setTargetSys(L"test_sys");
|
||||
sourceGroupSettings->setTargetAbi(L"test_abi");
|
||||
sourceGroupSettings->setCStandard(L"c11");
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxEmpty>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
void test_source_group_cxx_cpp_empty_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_cpp_empty";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCppEmpty> sourceGroupSettings = std::make_shared<SourceGroupSettingsCppEmpty>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"/src") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".cpp" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setTargetOptionsEnabled(true);
|
||||
sourceGroupSettings->setTargetArch(L"test_arch");
|
||||
sourceGroupSettings->setTargetVendor(L"test_vendor");
|
||||
sourceGroupSettings->setTargetSys(L"test_sys");
|
||||
sourceGroupSettings->setTargetAbi(L"test_abi");
|
||||
sourceGroupSettings->setCppStandard(L"c++11");
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxEmpty>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
void test_source_group_cxx_codeblocks_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_codeblocks";
|
||||
const FilePath cbpPath = getInputDirectoryPath(projectName).concatenate(L"project.cbp");
|
||||
const FilePath sourceCbpPath = getInputDirectoryPath(projectName).concatenate(L"project.cbp.in");
|
||||
|
||||
FileSystem::remove(cbpPath);
|
||||
|
||||
{
|
||||
std::ofstream fileStream;
|
||||
fileStream.open(cbpPath.str(), std::ios::app);
|
||||
fileStream << utility::replace(
|
||||
TextAccess::createFromFile(sourceCbpPath)->getText(), "<source_path>", getInputDirectoryPath(projectName).concatenate(L"src").getAbsolute().str()
|
||||
);
|
||||
fileStream.close();
|
||||
}
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxCodeblocks> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxCodeblocks>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setCodeblocksProjectPath(cbpPath);
|
||||
sourceGroupSettings->setCppStandard(L"c++11");
|
||||
sourceGroupSettings->setCStandard(L"c11");
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".cpp", L".c" });
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxCodeblocks>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
|
||||
FileSystem::remove(cbpPath);
|
||||
}
|
||||
|
||||
void test_source_group_cxx_cdb_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_cdb";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxCdb> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxCdb>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setCompilationDatabasePath(getInputDirectoryPath(projectName).concatenate(L"compile_commands.json"));
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
sourceGroupSettings->setHeaderSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"header_search/local") });
|
||||
sourceGroupSettings->setFrameworkSearchPaths({ getInputDirectoryPath(projectName).concatenate(L"framework_search/local") });
|
||||
sourceGroupSettings->setCompilerFlags({ L"-local-flag" });
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxCdb>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
void test_source_group_cxx_sonargraph_with_cmake_json_modules_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_sonargraph_cmake_json";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setSonargraphProjectPath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxSonargraph>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
void test_source_group_cxx_sonargraph_with_cpp_manual_modules_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_sonargraph_cpp_manual";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setIndexedHeaderPaths({ FilePath(L"test/indexed/header/path") });
|
||||
sourceGroupSettings->setSonargraphProjectPath(getInputDirectoryPath(projectName).concatenate(L"/sonargraph/system.sonargraph"));
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedHeaderSearchPaths = applicationSettings->getHeaderSearchPaths();
|
||||
std::vector<FilePath> storedFrameworkSearchPaths = applicationSettings->getFrameworkSearchPaths();
|
||||
|
||||
applicationSettings->setHeaderSearchPaths({ FilePath(L"test/header/search/path") });
|
||||
applicationSettings->setFrameworkSearchPaths({ FilePath(L"test/framework/search/path") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCxxSonargraph>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setHeaderSearchPaths(storedHeaderSearchPaths);
|
||||
applicationSettings->setFrameworkSearchPaths(storedFrameworkSearchPaths);
|
||||
}
|
||||
|
||||
void test_sourcegroup_java_empty_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"java_empty";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaEmpty> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaEmpty>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourceExtensions({ L".java" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/Foo.java" });
|
||||
sourceGroupSettings->setJavaStandard({ L"10" });
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"src") });
|
||||
sourceGroupSettings->setUseJreSystemLibrary(true);
|
||||
sourceGroupSettings->setClasspath({
|
||||
getInputDirectoryPath(projectName).concatenate(L"lib/dependency.jar"), getInputDirectoryPath(projectName).concatenate(L"classpath_dir")
|
||||
});
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaEmpty>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
}
|
||||
|
||||
void test_sourcegroup_java_gradle_generates_expected_output()
|
||||
{
|
||||
#ifndef __linux__
|
||||
const std::wstring projectName = L"java_gradle";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaGradle> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaGradle>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourceExtensions({ L".java" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/HelloWorld.java" });
|
||||
sourceGroupSettings->setJavaStandard({ L"10" });
|
||||
sourceGroupSettings->setGradleProjectFilePath({ getInputDirectoryPath(projectName).concatenate(L"build.gradle") });
|
||||
sourceGroupSettings->setShouldIndexGradleTests(true);
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
const FilePath storedAppPath = AppPath::getAppPath();
|
||||
AppPath::setAppPath(storedAppPath.getConcatenated(L"../app").makeAbsolute());
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaGradle>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
AppPath::setAppPath(storedAppPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_sourcegroup_java_maven_generates_expected_output()
|
||||
{
|
||||
std::vector<FilePath> mavenPaths = utility::getMavenExecutablePathDetector()->getPaths();
|
||||
|
||||
TS_ASSERT(!mavenPaths.empty());
|
||||
|
||||
if (!mavenPaths.empty())
|
||||
{
|
||||
ApplicationSettings::getInstance()->setMavenPath(mavenPaths.front());
|
||||
}
|
||||
|
||||
const std::wstring projectName = L"java_maven";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaMaven> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaMaven>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSourceExtensions({ L".java" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/Foo.java" });
|
||||
sourceGroupSettings->setJavaStandard({ L"10" });
|
||||
sourceGroupSettings->setMavenProjectFilePath({ getInputDirectoryPath(projectName).concatenate(L"my-app/pom.xml") });
|
||||
sourceGroupSettings->setShouldIndexMavenTests(true);
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaMaven>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
}
|
||||
|
||||
void test_sourcegroup_java_sonargraph_with_java_modules_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"java_sonargraph";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaSonargraph> sourceGroupSettings =
|
||||
std::make_shared<SourceGroupSettingsJavaSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setUseJreSystemLibrary(true);
|
||||
sourceGroupSettings->setClasspath({
|
||||
FilePath(L"test/classpath/file.jar"), FilePath(L"test/classpath/dir")
|
||||
});
|
||||
sourceGroupSettings->setSonargraphProjectPath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
std::shared_ptr<ApplicationSettings> applicationSettings = ApplicationSettings::getInstance();
|
||||
|
||||
std::vector<FilePath> storedJreSystemLibraryPaths = applicationSettings->getJreSystemLibraryPaths();
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths({ FilePath(L"test/jre/system/library/path.jar") });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupJavaSonargraph>(sourceGroupSettings));
|
||||
|
||||
applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths);
|
||||
}
|
||||
|
||||
void test_source_group_custom_command_generates_expected_output()
|
||||
{
|
||||
const std::wstring projectName = L"custom_command";
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCustomCommand> sourceGroupSettings = std::make_shared<SourceGroupSettingsCustomCommand>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setCustomCommand(L"echo \"Hello World\"");
|
||||
sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"/src") });
|
||||
sourceGroupSettings->setSourceExtensions({ L".txt" });
|
||||
sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" });
|
||||
|
||||
generateAndCompareExpectedOutput(projectName, std::make_shared<SourceGroupCustomCommand>(sourceGroupSettings));
|
||||
}
|
||||
|
||||
// Special Tests
|
||||
|
||||
void test_sourcegroup_java_sonargraph_with_cpp_modules_does_not_generate_output()
|
||||
{
|
||||
const std::wstring projectName = L"cxx_sonargraph_cpp_manual";
|
||||
const FilePath sonargraphProjectFilePath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
TS_ASSERT(sonargraphProjectFilePath.exists());
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsJavaSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsJavaSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSonargraphProjectPath(sonargraphProjectFilePath);
|
||||
|
||||
std::shared_ptr<TextAccess> output = generateExpectedOutput(projectName, std::make_shared<SourceGroupJavaSonargraph>(sourceGroupSettings));
|
||||
|
||||
TS_ASSERT_EQUALS(0, output->getLineCount());
|
||||
}
|
||||
|
||||
void test_sourcegroup_cxx_sonargraph_with_java_modules_does_not_generate_output()
|
||||
{
|
||||
const std::wstring projectName = L"java_sonargraph";
|
||||
const FilePath sonargraphProjectFilePath(getInputDirectoryPath(projectName).concatenate(L"sonargraph/system.sonargraph"));
|
||||
|
||||
TS_ASSERT(sonargraphProjectFilePath.exists());
|
||||
|
||||
ProjectSettings projectSettings;
|
||||
projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName));
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsCxxSonargraph> sourceGroupSettings = std::make_shared<SourceGroupSettingsCxxSonargraph>("fake_id", &projectSettings);
|
||||
sourceGroupSettings->setSonargraphProjectPath(sonargraphProjectFilePath);
|
||||
|
||||
std::shared_ptr<TextAccess> output = generateExpectedOutput(projectName, std::make_shared<SourceGroupCxxSonargraph>(sourceGroupSettings));
|
||||
|
||||
TS_ASSERT_EQUALS(0, output->getLineCount());
|
||||
}
|
||||
|
||||
void test_can_destroy_application_instance()
|
||||
{
|
||||
Application::destroyInstance();
|
||||
TS_ASSERT_EQUALS(0, Application::getInstance().use_count());
|
||||
}
|
||||
|
||||
// Utility
|
||||
|
||||
private:
|
||||
static FilePath getInputDirectoryPath(const std::wstring& projectName)
|
||||
{
|
||||
return FilePath(L"data/SourceGroupTestSuite/" + projectName + L"/input").makeAbsolute().makeCanonical();
|
||||
}
|
||||
|
||||
static FilePath getOutputDirectoryPath(const std::wstring& projectName)
|
||||
{
|
||||
return FilePath(L"data/SourceGroupTestSuite/" + projectName + L"/expected_output").makeAbsolute().makeCanonical();
|
||||
}
|
||||
|
||||
std::string setupJavaEnvironmentFactory()
|
||||
{
|
||||
if (!JavaEnvironmentFactory::getInstance())
|
||||
{
|
||||
std::string errorString;
|
||||
#ifdef _WIN32
|
||||
const std::string separator = ";";
|
||||
#else
|
||||
const std::string separator = ":";
|
||||
#endif
|
||||
std::string classPath = "";
|
||||
{
|
||||
const std::vector<std::wstring> jarNames = utility::getRequiredJarNames();
|
||||
for (size_t i = 0; i < jarNames.size(); i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
classPath += separator;
|
||||
}
|
||||
classPath += FilePath(L"../app/data/java/lib/").concatenate(jarNames[i]).str();
|
||||
}
|
||||
}
|
||||
|
||||
JavaEnvironmentFactory::createInstance(
|
||||
classPath,
|
||||
errorString
|
||||
);
|
||||
|
||||
return errorString;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void generateAndCompareExpectedOutput(
|
||||
std::wstring projectName,
|
||||
std::shared_ptr<const SourceGroup> sourceGroup)
|
||||
{
|
||||
const std::shared_ptr<const TextAccess> output = generateExpectedOutput(projectName, sourceGroup);
|
||||
#ifdef WIN32
|
||||
const std::wstring expectedOutputFileName = L"output_windows.txt";
|
||||
#else
|
||||
const std::wstring expectedOutputFileName = L"output_unix.txt";
|
||||
#endif
|
||||
const FilePath expectedOutputFilePath = getOutputDirectoryPath(projectName).concatenate(expectedOutputFileName);
|
||||
if (s_updateExpectedOutput || !expectedOutputFilePath.exists())
|
||||
{
|
||||
std::ofstream expectedOutputFile;
|
||||
expectedOutputFile.open(expectedOutputFilePath.str());
|
||||
expectedOutputFile << output->getText();
|
||||
expectedOutputFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::shared_ptr<const TextAccess> expectedOutput = TextAccess::createFromFile(expectedOutputFilePath);
|
||||
TSM_ASSERT_EQUALS(L"Output does not match the expected line count for project \"" + projectName + L"\".", expectedOutput->getLineCount(), output->getLineCount());
|
||||
if (expectedOutput->getLineCount() == output->getLineCount())
|
||||
{
|
||||
for (size_t i = 1; i <= expectedOutput->getLineCount(); i++)
|
||||
{
|
||||
TS_ASSERT_EQUALS(expectedOutput->getLine(i), output->getLine(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<TextAccess> generateExpectedOutput(
|
||||
std::wstring projectName,
|
||||
std::shared_ptr<const SourceGroup> sourceGroup)
|
||||
{
|
||||
const FilePath projectDataRoot = getInputDirectoryPath(projectName).makeAbsolute();
|
||||
|
||||
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands = sourceGroup->getIndexerCommands(sourceGroup->getAllSourceFilePaths());
|
||||
|
||||
std::sort(
|
||||
indexerCommands.begin(),
|
||||
indexerCommands.end(),
|
||||
[](std::shared_ptr<IndexerCommand> a, std::shared_ptr<IndexerCommand> b)
|
||||
{
|
||||
return a->getSourceFilePath().wstr() < b->getSourceFilePath().wstr();
|
||||
}
|
||||
);
|
||||
|
||||
std::wstring outputString;
|
||||
for (std::shared_ptr<IndexerCommand> indexerCommand : indexerCommands)
|
||||
{
|
||||
outputString += indexerCommandToString(indexerCommand, projectDataRoot);
|
||||
}
|
||||
|
||||
return TextAccess::createFromString(utility::encodeToUtf8(outputString));
|
||||
}
|
||||
|
||||
std::wstring indexerCommandToString(std::shared_ptr<IndexerCommand> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
if (indexerCommand)
|
||||
{
|
||||
if (std::shared_ptr<const IndexerCommandCxx> indexerCommandCxx = std::dynamic_pointer_cast<const IndexerCommandCxx>(indexerCommand))
|
||||
{
|
||||
return indexerCommandCxxToString(indexerCommandCxx, baseDirectory);
|
||||
}
|
||||
if (std::shared_ptr<const IndexerCommandJava> indexerCommandJava = std::dynamic_pointer_cast<const IndexerCommandJava>(indexerCommand))
|
||||
{
|
||||
return indexerCommandJavaToString(indexerCommandJava, baseDirectory);
|
||||
}
|
||||
if (std::shared_ptr<const IndexerCommandCustom> indexerCommandCustom = std::dynamic_pointer_cast<const IndexerCommandCustom>(indexerCommand))
|
||||
{
|
||||
return indexerCommandCustomToString(indexerCommandCustom, baseDirectory);
|
||||
}
|
||||
return L"Unsupported indexer command type: " + utility::decodeFromUtf8(indexerCommandTypeToString(indexerCommand->getIndexerCommandType()));
|
||||
}
|
||||
return L"No IndexerCommand provided.";
|
||||
}
|
||||
|
||||
std::wstring indexerCommandCxxToString(std::shared_ptr<const IndexerCommandCxx> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
std::wstring result;
|
||||
result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
for (const FilePath& indexedPath : indexerCommand->getIndexedPaths())
|
||||
{
|
||||
result += L"\tIndexedPath: \"" + indexedPath.getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
}
|
||||
for (std::wstring compilerFlag : indexerCommand->getCompilerFlags())
|
||||
{
|
||||
FilePath flagAsPath(compilerFlag);
|
||||
if (flagAsPath.exists())
|
||||
{
|
||||
compilerFlag = flagAsPath.getRelativeTo(baseDirectory).wstr();
|
||||
}
|
||||
result += L"\tCompilerFlag: \"" + compilerFlag + L"\"\n";
|
||||
}
|
||||
for (const FilePathFilter& filter : indexerCommand->getExcludeFilters())
|
||||
{
|
||||
result += L"\tExcludeFilter: \"" + filter.wstr() + L"\"\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring indexerCommandJavaToString(std::shared_ptr<const IndexerCommandJava> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
std::wstring result;
|
||||
result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
result += L"\tLanguageStandard: \"" + indexerCommand->getLanguageStandard() + L"\"\n";
|
||||
for (const FilePath& classPathItem : indexerCommand->getClassPath())
|
||||
{
|
||||
result += L"\tClassPathItem: \"" + classPathItem.getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring indexerCommandCustomToString(std::shared_ptr<const IndexerCommandCustom> indexerCommand, const FilePath& baseDirectory)
|
||||
{
|
||||
std::wstring result;
|
||||
result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n";
|
||||
result += L"\tCustom Command: \"" + indexerCommand->getCustomCommand() + L"\"\n";
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "SourceLocation.h"
|
||||
#include "SourceLocationCollection.h"
|
||||
#include "SourceLocationFile.h"
|
||||
|
||||
TEST_CASE("source locations get created with other end")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
const SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
|
||||
REQUIRE(a);
|
||||
REQUIRE(a->isStartLocation());
|
||||
REQUIRE(!a->isEndLocation());
|
||||
|
||||
const SourceLocation* b = a->getOtherLocation();
|
||||
|
||||
REQUIRE(b);
|
||||
REQUIRE(!b->isStartLocation());
|
||||
REQUIRE(b->isEndLocation());
|
||||
|
||||
REQUIRE(a == b->getOtherLocation());
|
||||
REQUIRE(a == b->getStartLocation());
|
||||
REQUIRE(a == a->getStartLocation());
|
||||
REQUIRE(b == a->getEndLocation());
|
||||
REQUIRE(b == b->getEndLocation());
|
||||
}
|
||||
|
||||
TEST_CASE("source locations do not get created with wrong input")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 2, 1);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {1}, FilePath(L"file.c"), 4, 1, 1, 10);
|
||||
|
||||
REQUIRE(!a);
|
||||
REQUIRE(!b);
|
||||
}
|
||||
|
||||
TEST_CASE("source locations get unique id but both ends have the same")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 1, 1, 1, 1);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {2}, FilePath(L"file.c"), 1, 1, 1, 1);
|
||||
SourceLocation* c = collection.addSourceLocation(LOCATION_TOKEN, 3, {3}, FilePath(L"file.c"), 1, 1, 1, 1);
|
||||
|
||||
REQUIRE(1 == collection.getSourceLocationFileCount());
|
||||
REQUIRE(3 == collection.getSourceLocationCount());
|
||||
|
||||
REQUIRE(a->getLocationId() == 1);
|
||||
REQUIRE(b->getLocationId() == 2);
|
||||
REQUIRE(c->getLocationId() == 3);
|
||||
|
||||
REQUIRE(a->getLocationId() != b->getLocationId());
|
||||
REQUIRE(b->getLocationId() != c->getLocationId());
|
||||
REQUIRE(c->getLocationId() != a->getLocationId());
|
||||
|
||||
REQUIRE(a->getLocationId() == a->getOtherLocation()->getLocationId());
|
||||
REQUIRE(b->getLocationId() == b->getOtherLocation()->getLocationId());
|
||||
REQUIRE(c->getLocationId() == c->getOtherLocation()->getLocationId());
|
||||
}
|
||||
|
||||
TEST_CASE("source locations have right file path line column and token id")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
|
||||
REQUIRE(1 == a->getTokenIds()[0]);
|
||||
REQUIRE(2 == a->getLineNumber());
|
||||
REQUIRE(3 == a->getColumnNumber());
|
||||
REQUIRE(4 == a->getOtherLocation()->getLineNumber());
|
||||
REQUIRE(5 == a->getOtherLocation()->getColumnNumber());
|
||||
REQUIRE(L"file.c" == a->getFilePath().wstr());
|
||||
}
|
||||
|
||||
TEST_CASE("finding source locations by id")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {6}, FilePath(L"file.c"), 7, 8, 9, 10);
|
||||
|
||||
REQUIRE(a == collection.getSourceLocationById(a->getLocationId()));
|
||||
REQUIRE(b == collection.getSourceLocationById(b->getLocationId()));
|
||||
}
|
||||
|
||||
TEST_CASE("creating plain copy of all locations in line range")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {1}, FilePath(L"file.c"), 3, 3, 4, 5);
|
||||
SourceLocation* c = collection.addSourceLocation(LOCATION_TOKEN, 3, {1}, FilePath(L"file.c"), 1, 3, 5, 5);
|
||||
SourceLocation* d = collection.addSourceLocation(LOCATION_TOKEN, 4, {1}, FilePath(L"file.c"), 1, 5, 4, 5);
|
||||
|
||||
Id ida = a->getLocationId();
|
||||
Id idb = b->getLocationId();
|
||||
Id idc = c->getLocationId();
|
||||
Id idd = d->getLocationId();
|
||||
|
||||
unsigned int fromLine = 2;
|
||||
unsigned int toLine = 4;
|
||||
|
||||
SourceLocationCollection copy;
|
||||
SourceLocation* x = collection.getSourceLocationById(ida);
|
||||
|
||||
x->getSourceLocationFile()->forEachSourceLocation(
|
||||
[©, fromLine, toLine](SourceLocation* location)
|
||||
{
|
||||
if (location->getLineNumber() >= fromLine && location->getLineNumber() <= toLine)
|
||||
{
|
||||
copy.addSourceLocationCopy(location);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
REQUIRE(1 == copy.getSourceLocationFileCount());
|
||||
REQUIRE(3 == copy.getSourceLocationCount());
|
||||
|
||||
REQUIRE(copy.getSourceLocationById(ida));
|
||||
REQUIRE(copy.getSourceLocationById(idb));
|
||||
REQUIRE(!copy.getSourceLocationById(idc));
|
||||
REQUIRE(copy.getSourceLocationById(idd));
|
||||
|
||||
REQUIRE(a != copy.getSourceLocationById(ida));
|
||||
REQUIRE(d != copy.getSourceLocationById(idd));
|
||||
|
||||
REQUIRE(copy.getSourceLocationById(ida)->getStartLocation());
|
||||
REQUIRE(copy.getSourceLocationById(ida)->getEndLocation());
|
||||
|
||||
REQUIRE(!copy.getSourceLocationById(idd)->getStartLocation());
|
||||
REQUIRE(copy.getSourceLocationById(idd)->getEndLocation());
|
||||
}
|
||||
|
||||
TEST_CASE("get source locations filtered by lines")
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 1, 3, 1, 5);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {1}, FilePath(L"file.c"), 1, 3, 2, 5);
|
||||
SourceLocation* c = collection.addSourceLocation(LOCATION_TOKEN, 3, {1}, FilePath(L"file.c"), 2, 3, 2, 5);
|
||||
SourceLocation* d = collection.addSourceLocation(LOCATION_TOKEN, 4, {1}, FilePath(L"file.c"), 3, 3, 4, 5);
|
||||
SourceLocation* e = collection.addSourceLocation(LOCATION_TOKEN, 5, {1}, FilePath(L"file.c"), 3, 5, 5, 5);
|
||||
SourceLocation* f = collection.addSourceLocation(LOCATION_TOKEN, 6, {1}, FilePath(L"file.c"), 1, 5, 5, 5);
|
||||
SourceLocation* g = collection.addSourceLocation(LOCATION_TOKEN, 7, {1}, FilePath(L"file.c"), 5, 5, 5, 5);
|
||||
|
||||
SourceLocationCollection copy;
|
||||
copy.addSourceLocationFile(
|
||||
collection.getSourceLocationById(a->getLocationId())->getSourceLocationFile()->getFilteredByLines(2, 4));
|
||||
|
||||
REQUIRE(1 == copy.getSourceLocationFileCount());
|
||||
REQUIRE(4 == copy.getSourceLocationCount());
|
||||
|
||||
REQUIRE(!copy.getSourceLocationById(a->getLocationId()));
|
||||
REQUIRE(copy.getSourceLocationById(b->getLocationId()));
|
||||
REQUIRE(copy.getSourceLocationById(c->getLocationId()));
|
||||
REQUIRE(copy.getSourceLocationById(d->getLocationId()));
|
||||
REQUIRE(copy.getSourceLocationById(e->getLocationId()));
|
||||
REQUIRE(!copy.getSourceLocationById(f->getLocationId()));
|
||||
REQUIRE(!copy.getSourceLocationById(g->getLocationId()));
|
||||
|
||||
REQUIRE(b != copy.getSourceLocationById(b->getLocationId()));
|
||||
REQUIRE(c != copy.getSourceLocationById(c->getLocationId()));
|
||||
|
||||
REQUIRE(!copy.getSourceLocationById(b->getLocationId())->getStartLocation());
|
||||
REQUIRE(copy.getSourceLocationById(b->getLocationId())->getEndLocation());
|
||||
|
||||
REQUIRE(copy.getSourceLocationById(e->getLocationId())->getStartLocation());
|
||||
REQUIRE(!copy.getSourceLocationById(e->getLocationId())->getEndLocation());
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "SourceLocation.h"
|
||||
#include "SourceLocationCollection.h"
|
||||
#include "SourceLocationFile.h"
|
||||
|
||||
class SourceLocationCollectionTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_source_locations_get_created_with_other_end()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
const SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
|
||||
TS_ASSERT(a);
|
||||
TS_ASSERT(a->isStartLocation());
|
||||
TS_ASSERT(!a->isEndLocation());
|
||||
|
||||
const SourceLocation* b = a->getOtherLocation();
|
||||
|
||||
TS_ASSERT(b);
|
||||
TS_ASSERT(!b->isStartLocation());
|
||||
TS_ASSERT(b->isEndLocation());
|
||||
|
||||
TS_ASSERT_EQUALS(a, b->getOtherLocation());
|
||||
TS_ASSERT_EQUALS(a, b->getStartLocation());
|
||||
TS_ASSERT_EQUALS(a, a->getStartLocation());
|
||||
TS_ASSERT_EQUALS(b, a->getEndLocation());
|
||||
TS_ASSERT_EQUALS(b, b->getEndLocation());
|
||||
}
|
||||
|
||||
void test_source_locations_do_not_get_created_with_wrong_input()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 2, 1);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {1}, FilePath(L"file.c"), 4, 1, 1, 10);
|
||||
|
||||
TS_ASSERT(!a);
|
||||
TS_ASSERT(!b);
|
||||
}
|
||||
|
||||
void test_source_locations_get_unique_id_but_both_ends_have_the_same()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 1, 1, 1, 1);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {2}, FilePath(L"file.c"), 1, 1, 1, 1);
|
||||
SourceLocation* c = collection.addSourceLocation(LOCATION_TOKEN, 3, {3}, FilePath(L"file.c"), 1, 1, 1, 1);
|
||||
|
||||
TS_ASSERT_EQUALS(1, collection.getSourceLocationFileCount());
|
||||
TS_ASSERT_EQUALS(3, collection.getSourceLocationCount());
|
||||
|
||||
TS_ASSERT_EQUALS(a->getLocationId(), 1);
|
||||
TS_ASSERT_EQUALS(b->getLocationId(), 2);
|
||||
TS_ASSERT_EQUALS(c->getLocationId(), 3);
|
||||
|
||||
TS_ASSERT_DIFFERS(a->getLocationId(), b->getLocationId());
|
||||
TS_ASSERT_DIFFERS(b->getLocationId(), c->getLocationId());
|
||||
TS_ASSERT_DIFFERS(c->getLocationId(), a->getLocationId());
|
||||
|
||||
TS_ASSERT_EQUALS(a->getLocationId(), a->getOtherLocation()->getLocationId());
|
||||
TS_ASSERT_EQUALS(b->getLocationId(), b->getOtherLocation()->getLocationId());
|
||||
TS_ASSERT_EQUALS(c->getLocationId(), c->getOtherLocation()->getLocationId());
|
||||
}
|
||||
|
||||
void test_source_locations_have_right_file_path_line_column_and_token_id()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
|
||||
TS_ASSERT_EQUALS(1, a->getTokenIds()[0]);
|
||||
TS_ASSERT_EQUALS(2, a->getLineNumber());
|
||||
TS_ASSERT_EQUALS(3, a->getColumnNumber());
|
||||
TS_ASSERT_EQUALS(4, a->getOtherLocation()->getLineNumber());
|
||||
TS_ASSERT_EQUALS(5, a->getOtherLocation()->getColumnNumber());
|
||||
TS_ASSERT_EQUALS(L"file.c", a->getFilePath().wstr());
|
||||
}
|
||||
|
||||
void test_finding_source_locations_by_id()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {6}, FilePath(L"file.c"), 7, 8, 9, 10);
|
||||
|
||||
TS_ASSERT_EQUALS(a, collection.getSourceLocationById(a->getLocationId()));
|
||||
TS_ASSERT_EQUALS(b, collection.getSourceLocationById(b->getLocationId()));
|
||||
}
|
||||
|
||||
void test_creating_plain_copy_of_all_locations_in_line_range()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 2, 3, 4, 5);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {1}, FilePath(L"file.c"), 3, 3, 4, 5);
|
||||
SourceLocation* c = collection.addSourceLocation(LOCATION_TOKEN, 3, {1}, FilePath(L"file.c"), 1, 3, 5, 5);
|
||||
SourceLocation* d = collection.addSourceLocation(LOCATION_TOKEN, 4, {1}, FilePath(L"file.c"), 1, 5, 4, 5);
|
||||
|
||||
Id ida = a->getLocationId();
|
||||
Id idb = b->getLocationId();
|
||||
Id idc = c->getLocationId();
|
||||
Id idd = d->getLocationId();
|
||||
|
||||
unsigned int fromLine = 2;
|
||||
unsigned int toLine = 4;
|
||||
|
||||
SourceLocationCollection copy;
|
||||
SourceLocation* x = collection.getSourceLocationById(ida);
|
||||
|
||||
x->getSourceLocationFile()->forEachSourceLocation(
|
||||
[©, fromLine, toLine](SourceLocation* location)
|
||||
{
|
||||
if (location->getLineNumber() >= fromLine && location->getLineNumber() <= toLine)
|
||||
{
|
||||
copy.addSourceLocationCopy(location);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(1, copy.getSourceLocationFileCount());
|
||||
TS_ASSERT_EQUALS(3, copy.getSourceLocationCount());
|
||||
|
||||
TS_ASSERT(copy.getSourceLocationById(ida));
|
||||
TS_ASSERT(copy.getSourceLocationById(idb));
|
||||
TS_ASSERT(!copy.getSourceLocationById(idc));
|
||||
TS_ASSERT(copy.getSourceLocationById(idd));
|
||||
|
||||
TS_ASSERT_DIFFERS(a, copy.getSourceLocationById(ida));
|
||||
TS_ASSERT_DIFFERS(d, copy.getSourceLocationById(idd));
|
||||
|
||||
TS_ASSERT(copy.getSourceLocationById(ida)->getStartLocation());
|
||||
TS_ASSERT(copy.getSourceLocationById(ida)->getEndLocation());
|
||||
|
||||
TS_ASSERT(!copy.getSourceLocationById(idd)->getStartLocation());
|
||||
TS_ASSERT(copy.getSourceLocationById(idd)->getEndLocation());
|
||||
}
|
||||
|
||||
void test_get_source_locations_filtered_by_lines()
|
||||
{
|
||||
SourceLocationCollection collection;
|
||||
SourceLocation* a = collection.addSourceLocation(LOCATION_TOKEN, 1, {1}, FilePath(L"file.c"), 1, 3, 1, 5);
|
||||
SourceLocation* b = collection.addSourceLocation(LOCATION_TOKEN, 2, {1}, FilePath(L"file.c"), 1, 3, 2, 5);
|
||||
SourceLocation* c = collection.addSourceLocation(LOCATION_TOKEN, 3, {1}, FilePath(L"file.c"), 2, 3, 2, 5);
|
||||
SourceLocation* d = collection.addSourceLocation(LOCATION_TOKEN, 4, {1}, FilePath(L"file.c"), 3, 3, 4, 5);
|
||||
SourceLocation* e = collection.addSourceLocation(LOCATION_TOKEN, 5, {1}, FilePath(L"file.c"), 3, 5, 5, 5);
|
||||
SourceLocation* f = collection.addSourceLocation(LOCATION_TOKEN, 6, {1}, FilePath(L"file.c"), 1, 5, 5, 5);
|
||||
SourceLocation* g = collection.addSourceLocation(LOCATION_TOKEN, 7, {1}, FilePath(L"file.c"), 5, 5, 5, 5);
|
||||
|
||||
SourceLocationCollection copy;
|
||||
copy.addSourceLocationFile(
|
||||
collection.getSourceLocationById(a->getLocationId())->getSourceLocationFile()->getFilteredByLines(2, 4));
|
||||
|
||||
TS_ASSERT_EQUALS(1, copy.getSourceLocationFileCount());
|
||||
TS_ASSERT_EQUALS(4, copy.getSourceLocationCount());
|
||||
|
||||
TS_ASSERT(!copy.getSourceLocationById(a->getLocationId()));
|
||||
TS_ASSERT(copy.getSourceLocationById(b->getLocationId()));
|
||||
TS_ASSERT(copy.getSourceLocationById(c->getLocationId()));
|
||||
TS_ASSERT(copy.getSourceLocationById(d->getLocationId()));
|
||||
TS_ASSERT(copy.getSourceLocationById(e->getLocationId()));
|
||||
TS_ASSERT(!copy.getSourceLocationById(f->getLocationId()));
|
||||
TS_ASSERT(!copy.getSourceLocationById(g->getLocationId()));
|
||||
|
||||
TS_ASSERT_DIFFERS(b, copy.getSourceLocationById(b->getLocationId()));
|
||||
TS_ASSERT_DIFFERS(c, copy.getSourceLocationById(c->getLocationId()));
|
||||
|
||||
TS_ASSERT(!copy.getSourceLocationById(b->getLocationId())->getStartLocation());
|
||||
TS_ASSERT(copy.getSourceLocationById(b->getLocationId())->getEndLocation());
|
||||
|
||||
TS_ASSERT(copy.getSourceLocationById(e->getLocationId())->getStartLocation());
|
||||
TS_ASSERT(!copy.getSourceLocationById(e->getLocationId())->getEndLocation());
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "SqliteBookmarkStorage.h"
|
||||
|
||||
TEST_CASE("add bookmarks")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
size_t bookmarkCount = 4;
|
||||
int result = -1;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
for (size_t i = 0; i < bookmarkCount; i++)
|
||||
{
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId));
|
||||
}
|
||||
|
||||
result = storage.getAllBookmarks().size();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(result == bookmarkCount);
|
||||
}
|
||||
|
||||
TEST_CASE("add bookmarked node")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
size_t bookmarkCount = 4;
|
||||
int result = -1;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
const Id bookmarkId = storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId)).id;
|
||||
|
||||
for (size_t i = 0; i < bookmarkCount; i++)
|
||||
{
|
||||
storage.addBookmarkedNode(StorageBookmarkedNodeData(bookmarkId, L"test name"));
|
||||
}
|
||||
|
||||
result = storage.getAllBookmarkedNodes().size();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(result == bookmarkCount);
|
||||
}
|
||||
|
||||
TEST_CASE("remove bookmark also removes bookmarked node")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
int result = -1;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
const Id bookmarkId = storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId)).id;
|
||||
storage.addBookmarkedNode(StorageBookmarkedNodeData(bookmarkId, L"test name"));
|
||||
|
||||
storage.removeBookmark(bookmarkId);
|
||||
|
||||
result = storage.getAllBookmarkedNodes().size();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(result == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("edit nodeBookmark")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
|
||||
const std::wstring updatedName = L"updated name";
|
||||
const std::wstring updatedComment = L"updated comment";
|
||||
|
||||
StorageBookmark storageBookmark;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
const Id bookmarkId = storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId)).id;
|
||||
storage.addBookmarkedNode(StorageBookmarkedNodeData(bookmarkId, L"test name"));
|
||||
|
||||
storage.updateBookmark(bookmarkId, updatedName, updatedComment, categoryId);
|
||||
|
||||
storageBookmark = storage.getAllBookmarks().front();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(updatedName == storageBookmark.name);
|
||||
REQUIRE(updatedComment == storageBookmark.comment);
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "SqliteBookmarkStorage.h"
|
||||
|
||||
class SqliteBookmarkStorageTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_add_bookmarks()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
size_t bookmarkCount = 4;
|
||||
int result = -1;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
for (size_t i = 0; i < bookmarkCount; i++)
|
||||
{
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId));
|
||||
}
|
||||
|
||||
result = storage.getAllBookmarks().size();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(result, bookmarkCount);
|
||||
}
|
||||
|
||||
void test_add_bookmarked_node()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
size_t bookmarkCount = 4;
|
||||
int result = -1;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
const Id bookmarkId = storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId)).id;
|
||||
|
||||
for (size_t i = 0; i < bookmarkCount; i++)
|
||||
{
|
||||
storage.addBookmarkedNode(StorageBookmarkedNodeData(bookmarkId, L"test name"));
|
||||
}
|
||||
|
||||
result = storage.getAllBookmarkedNodes().size();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(result, bookmarkCount);
|
||||
}
|
||||
|
||||
void test_remove_bookmark_also_removes_bookmarked_node()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
int result = -1;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
const Id bookmarkId = storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId)).id;
|
||||
storage.addBookmarkedNode(StorageBookmarkedNodeData(bookmarkId, L"test name"));
|
||||
|
||||
storage.removeBookmark(bookmarkId);
|
||||
|
||||
result = storage.getAllBookmarkedNodes().size();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(result, 0);
|
||||
}
|
||||
|
||||
void test_edit_nodeBookmark()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/bookmarkTest.sqlite");
|
||||
|
||||
const std::wstring updatedName = L"updated name";
|
||||
const std::wstring updatedComment = L"updated comment";
|
||||
|
||||
StorageBookmark storageBookmark;
|
||||
{
|
||||
FileSystem::remove(databasePath);
|
||||
SqliteBookmarkStorage storage(databasePath);
|
||||
storage.setup();
|
||||
|
||||
const Id categoryId = storage.addBookmarkCategory(StorageBookmarkCategoryData(L"test category")).id;
|
||||
const Id bookmarkId = storage.addBookmark(StorageBookmarkData(L"test bookmark", L"test comment", TimeStamp::now().toString(), categoryId)).id;
|
||||
storage.addBookmarkedNode(StorageBookmarkedNodeData(bookmarkId, L"test name"));
|
||||
|
||||
storage.updateBookmark(bookmarkId, updatedName, updatedComment, categoryId);
|
||||
|
||||
storageBookmark = storage.getAllBookmarks().front();
|
||||
}
|
||||
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(updatedName, storageBookmark.name);
|
||||
TS_ASSERT_EQUALS(updatedComment, storageBookmark.comment);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "SqliteIndexStorage.h"
|
||||
|
||||
TEST_CASE("storage adds node successfully")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int nodeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
storage.addNode(StorageNodeData(0, L"a"));
|
||||
storage.commitTransaction();
|
||||
nodeCount = storage.getNodeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(1 == nodeCount);
|
||||
}
|
||||
|
||||
TEST_CASE("storage removes node successfully")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int nodeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
int nodeId = storage.addNode(StorageNodeData(0, L"a"));
|
||||
storage.removeElement(nodeId);
|
||||
storage.commitTransaction();
|
||||
nodeCount = storage.getNodeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(0 == nodeCount);
|
||||
}
|
||||
|
||||
TEST_CASE("storage adds edge successfully")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int edgeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
int sourceNodeId = storage.addNode(StorageNodeData(0, L"a"));
|
||||
int targetNodeId = storage.addNode(StorageNodeData(0, L"b"));
|
||||
storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId));
|
||||
storage.commitTransaction();
|
||||
edgeCount = storage.getEdgeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(1 == edgeCount);
|
||||
}
|
||||
|
||||
TEST_CASE("storage removes edge successfully")
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int edgeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
int sourceNodeId = storage.addNode(StorageNodeData(0, L"a"));
|
||||
int targetNodeId = storage.addNode(StorageNodeData(0, L"b"));
|
||||
int edgeId = storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId));
|
||||
storage.removeElement(edgeId);
|
||||
storage.commitTransaction();
|
||||
edgeCount = storage.getEdgeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
REQUIRE(0 == edgeCount);
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "SqliteIndexStorage.h"
|
||||
|
||||
class SqliteIndexStorageTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_storage_adds_node_successfully()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int nodeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
storage.addNode(StorageNodeData(0, L"a"));
|
||||
storage.commitTransaction();
|
||||
nodeCount = storage.getNodeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(1, nodeCount);
|
||||
}
|
||||
|
||||
void test_storage_removes_node_successfully()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int nodeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
int nodeId = storage.addNode(StorageNodeData(0, L"a"));
|
||||
storage.removeElement(nodeId);
|
||||
storage.commitTransaction();
|
||||
nodeCount = storage.getNodeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(0, nodeCount);
|
||||
}
|
||||
|
||||
void test_storage_adds_edge_successfully()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int edgeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
int sourceNodeId = storage.addNode(StorageNodeData(0, L"a"));
|
||||
int targetNodeId = storage.addNode(StorageNodeData(0, L"b"));
|
||||
storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId));
|
||||
storage.commitTransaction();
|
||||
edgeCount = storage.getEdgeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(1, edgeCount);
|
||||
}
|
||||
|
||||
void test_storage_removes_edge_successfully()
|
||||
{
|
||||
FilePath databasePath(L"data/SQLiteTestSuite/test.sqlite");
|
||||
int edgeCount = -1;
|
||||
{
|
||||
SqliteIndexStorage storage(databasePath);
|
||||
storage.setup();
|
||||
storage.beginTransaction();
|
||||
int sourceNodeId = storage.addNode(StorageNodeData(0, L"a"));
|
||||
int targetNodeId = storage.addNode(StorageNodeData(0, L"b"));
|
||||
int edgeId = storage.addEdge(StorageEdgeData(0, sourceNodeId, targetNodeId));
|
||||
storage.removeElement(edgeId);
|
||||
storage.commitTransaction();
|
||||
edgeCount = storage.getEdgeCount();
|
||||
}
|
||||
FileSystem::remove(databasePath);
|
||||
|
||||
TS_ASSERT_EQUALS(0, edgeCount);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,273 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "utilityString.h"
|
||||
|
||||
#include "ParseLocation.h"
|
||||
#include "IntermediateStorage.h"
|
||||
#include "PersistentStorage.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TestStorage : public PersistentStorage
|
||||
{
|
||||
public:
|
||||
TestStorage() : PersistentStorage(FilePath(L"data/test.sqlite"), FilePath(L"data/testBookmarks.sqlite"))
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//const size_t getNodeCount() const
|
||||
//{
|
||||
// return getGraph().getNodeCount();
|
||||
//}
|
||||
|
||||
//const size_t getEdgeCount() const
|
||||
//{
|
||||
// return getGraph().getEdgeCount();
|
||||
//}
|
||||
};
|
||||
|
||||
ParseLocation validLocation(Id locationId = 0)
|
||||
{
|
||||
return ParseLocation(1, 1, locationId, 1, locationId);
|
||||
}
|
||||
|
||||
NameHierarchy createNameHierarchy(std::wstring s)
|
||||
{
|
||||
NameHierarchy nameHierarchy(NAME_DELIMITER_CXX);
|
||||
for (std::wstring element : utility::splitToVector(s, nameDelimiterTypeToString(NAME_DELIMITER_CXX)))
|
||||
{
|
||||
nameHierarchy.push(element);
|
||||
}
|
||||
return nameHierarchy;
|
||||
}
|
||||
|
||||
NameHierarchy createFunctionNameHierarchy(std::wstring ret, std::wstring name, std::wstring parameters)
|
||||
{
|
||||
NameHierarchy nameHierarchy = createNameHierarchy(name);
|
||||
std::wstring lastName = nameHierarchy.back().getName();
|
||||
nameHierarchy.pop();
|
||||
nameHierarchy.push(NameElement(lastName, ret, parameters));
|
||||
return nameHierarchy;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("storage saves file")
|
||||
{
|
||||
TestStorage storage;
|
||||
|
||||
std::wstring filePath = L"path/to/test.h";
|
||||
|
||||
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
|
||||
Id id = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_FILE), NameHierarchy::serialize(NameHierarchy(filePath, NAME_DELIMITER_FILE)))).first;
|
||||
intermetiateStorage->addFile(StorageFile(id, filePath, L"someLanguage", "someTime", true, true));
|
||||
|
||||
storage.inject(intermetiateStorage.get());
|
||||
|
||||
REQUIRE(storage.getNameHierarchyForNodeId(id).getQualifiedName() == filePath);
|
||||
REQUIRE(storage.getNodeTypeForNodeWithId(id).isFile());
|
||||
}
|
||||
|
||||
TEST_CASE("storage saves node")
|
||||
{
|
||||
NameHierarchy a = createNameHierarchy(L"type");
|
||||
|
||||
TestStorage storage;
|
||||
|
||||
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
|
||||
intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(a)));
|
||||
|
||||
storage.inject(intermetiateStorage.get());
|
||||
|
||||
Id storedId = storage.getNodeIdForNameHierarchy(a);
|
||||
|
||||
REQUIRE(storedId != 0);
|
||||
REQUIRE(storage.getNodeTypeForNodeWithId(storedId).getType() == NodeType::NODE_TYPEDEF);
|
||||
}
|
||||
|
||||
TEST_CASE("storage saves field as member")
|
||||
{
|
||||
NameHierarchy a = createNameHierarchy(L"Struct");
|
||||
NameHierarchy b = createNameHierarchy(L"Struct::m_field");
|
||||
|
||||
TestStorage storage;
|
||||
|
||||
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id aId = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_STRUCT), NameHierarchy::serialize(a))).first;
|
||||
intermetiateStorage->addSymbol(StorageSymbol(aId, DEFINITION_EXPLICIT));
|
||||
|
||||
Id bId = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_FIELD), NameHierarchy::serialize(b))).first;
|
||||
intermetiateStorage->addSymbol(StorageSymbol(bId, DEFINITION_EXPLICIT));
|
||||
intermetiateStorage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_MEMBER), aId, bId));
|
||||
|
||||
storage.inject(intermetiateStorage.get());
|
||||
bool foundEdge = false;
|
||||
|
||||
const Id sourceId = storage.getNodeIdForNameHierarchy(a);
|
||||
const Id targetId = storage.getNodeIdForNameHierarchy(b);
|
||||
for (auto edge : storage.getStorageEdges())
|
||||
{
|
||||
if (edge.sourceNodeId == sourceId && edge.targetNodeId == targetId && edge.type == Edge::typeToInt(Edge::EDGE_MEMBER))
|
||||
{
|
||||
foundEdge = true;
|
||||
}
|
||||
}
|
||||
REQUIRE(foundEdge);
|
||||
}
|
||||
|
||||
TEST_CASE("storage saves method static")
|
||||
{
|
||||
//TestStorage storage;
|
||||
//Id id = storage.onMethodParsed(
|
||||
// validLocation(1),
|
||||
// ParseFunction(typeUsage("void"), createNameHierarchy("isMethod"), parameters("bool"), true),
|
||||
// ParserClient::ACCESS_NONE,
|
||||
// ParserClient::ABSTRACTION_NONE,
|
||||
// validLocation(4)
|
||||
//);
|
||||
|
||||
//Node* node = storage.getNodeWithId(id);
|
||||
//TS_ASSERT(node);
|
||||
//TS_ASSERT_EQUALS(node->getQualifiedNameWithSignature(), "isMethod");
|
||||
//TS_ASSERT_EQUALS(node->getType(), NodeType::NODE_METHOD);
|
||||
//TS_ASSERT(node->getComponent<TokenComponentStatic>());
|
||||
}
|
||||
|
||||
TEST_CASE("storage clears single file data of single file storage")
|
||||
{
|
||||
/*
|
||||
m_filePath = FilePath(L"file.cpp");
|
||||
TestStorage storage;
|
||||
storage.onFunctionParsed(
|
||||
validLocation(), ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"),
|
||||
parameters("char")), validLocation()
|
||||
);
|
||||
|
||||
REQUIRE(storage.getNodeCount() == 3);
|
||||
REQUIRE(storage.getEdgeCount() == 2);
|
||||
REQUIRE(storage.tokenLocationCollection().getTokenLocations().size() == 4);
|
||||
|
||||
std::set<FilePath> files;
|
||||
files.insert(FilePath(m_filePath));
|
||||
storage.clearFileData(files);
|
||||
|
||||
REQUIRE(storage.getNodeCount() == 0);
|
||||
REQUIRE(storage.getEdgeCount() == 0);
|
||||
REQUIRE(storage.tokenLocationCollection().getTokenLocations().size() == 0);;*/
|
||||
}
|
||||
|
||||
TEST_CASE("storage clears unreferenced single file data of multi file storage")
|
||||
{
|
||||
//m_filePath = "file.h";
|
||||
|
||||
//TestStorage storage;
|
||||
|
||||
//ParseFunction isTrue = ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"), parameters("char"));
|
||||
//storage.onFunctionParsed(validLocation(), isTrue, validLocation());
|
||||
|
||||
//m_filePath = "file.cpp";
|
||||
|
||||
//ParseFunction main = ParseFunction(typeUsage("int"), createNameHierarchy("main"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), main, validLocation());
|
||||
|
||||
//storage.onCallParsed(validLocation(), main, isTrue);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 6);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
|
||||
|
||||
//std::set<FilePath> files;
|
||||
//files.insert(FilePath("file.cpp"));
|
||||
//storage.clearFileData(files);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 3);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 2);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 4);*/
|
||||
}
|
||||
|
||||
TEST_CASE("storage clears referenced single file data of multi file storage")
|
||||
{
|
||||
//m_filePath = "file.h";
|
||||
|
||||
//TestStorage storage;
|
||||
|
||||
//ParseFunction isTrue = ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), isTrue, validLocation());
|
||||
|
||||
//m_filePath = "file.cpp";
|
||||
|
||||
//ParseFunction main = ParseFunction(typeUsage("int"), createNameHierarchy("main"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), main, validLocation());
|
||||
|
||||
//storage.onCallParsed(validLocation(), main, isTrue);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
|
||||
|
||||
//std::set<FilePath> files;
|
||||
//files.insert(FilePath("file.h"));
|
||||
//storage.clearFileData(files);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 4);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 3);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 5);
|
||||
}
|
||||
|
||||
TEST_CASE("storage clears multi file data of multi file storage")
|
||||
{
|
||||
//m_filePath = "file.h";
|
||||
|
||||
//TestStorage storage;
|
||||
|
||||
//ParseFunction isTrue = ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), isTrue, validLocation());
|
||||
|
||||
//m_filePath = "file.cpp";
|
||||
|
||||
//ParseFunction main = ParseFunction(typeUsage("int"), createNameHierarchy("main"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), main, validLocation());
|
||||
|
||||
//storage.onCallParsed(validLocation(), main, isTrue);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
|
||||
|
||||
//std::set<FilePath> filePaths;
|
||||
//filePaths.insert(FilePath("file.cpp"));
|
||||
//filePaths.insert(FilePath("file.h"));
|
||||
//storage.clearFileData(filePaths);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 0);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 0);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("storage finds and removes depending file nodes")
|
||||
{
|
||||
//TestStorage storage;
|
||||
|
||||
//Id id1 = storage.onFileParsed("f.h");
|
||||
//Id id2 = storage.onFileParsed("file.h");
|
||||
//Id id3 = storage.onFileParsed("file.cpp");
|
||||
//Id id4 = storage.onFileIncludeParsed(validLocation(), "file.h", "f.h");
|
||||
//Id id5 = storage.onFileIncludeParsed(validLocation(), "file.cpp", "file.h");
|
||||
|
||||
//std::string name1 = storage.getNodeWithId(id2)->getQualifiedNameWithSignature();
|
||||
//std::string name2 = storage.getNodeWithId(id3)->getQualifiedNameWithSignature();
|
||||
|
||||
//std::set<FilePath> filePaths;
|
||||
//filePaths.insert(FilePath(name1));
|
||||
//std::set<FilePath> dependingFilePaths = storage.getDependingFilePathsAndRemoveFileNodes(filePaths);
|
||||
|
||||
//TS_ASSERT_EQUALS(dependingFilePaths.size(), 1);
|
||||
//TS_ASSERT_EQUALS(dependingFilePaths.begin()->str(), name2);
|
||||
|
||||
//TS_ASSERT(storage.getNodeWithId(id1));
|
||||
//TS_ASSERT(!storage.getNodeWithId(id2));
|
||||
//TS_ASSERT(!storage.getNodeWithId(id3));
|
||||
//TS_ASSERT(!storage.getEdgeWithId(id4));
|
||||
//TS_ASSERT(!storage.getEdgeWithId(id5));
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "utilityString.h"
|
||||
|
||||
#include "ParseLocation.h"
|
||||
#include "IntermediateStorage.h"
|
||||
#include "PersistentStorage.h"
|
||||
|
||||
class StorageTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void setUp()
|
||||
{
|
||||
m_filePath = FilePath(L"file.cpp");
|
||||
}
|
||||
|
||||
void test_storage_saves_file()
|
||||
{
|
||||
TestStorage storage;
|
||||
|
||||
std::wstring filePath = L"path/to/test.h";
|
||||
|
||||
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
|
||||
Id id = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_FILE), NameHierarchy::serialize(NameHierarchy(filePath, NAME_DELIMITER_FILE)))).first;
|
||||
intermetiateStorage->addFile(StorageFile(id, filePath, L"someLanguage", "someTime", true, true));
|
||||
|
||||
storage.inject(intermetiateStorage.get());
|
||||
|
||||
TS_ASSERT_EQUALS(storage.getNameHierarchyForNodeId(id).getQualifiedName(), filePath);
|
||||
TS_ASSERT(storage.getNodeTypeForNodeWithId(id).isFile());
|
||||
|
||||
}
|
||||
void test_storage_saves_node()
|
||||
{
|
||||
NameHierarchy a = createNameHierarchy(L"type");
|
||||
|
||||
TestStorage storage;
|
||||
|
||||
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
|
||||
intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(a)));
|
||||
|
||||
storage.inject(intermetiateStorage.get());
|
||||
|
||||
Id storedId = storage.getNodeIdForNameHierarchy(a);
|
||||
|
||||
TS_ASSERT(storedId != 0);
|
||||
TS_ASSERT_EQUALS(storage.getNodeTypeForNodeWithId(storedId).getType(), NodeType::NODE_TYPEDEF);
|
||||
}
|
||||
|
||||
|
||||
void test_storage_saves_field_as_member()
|
||||
{
|
||||
NameHierarchy a = createNameHierarchy(L"Struct");
|
||||
NameHierarchy b = createNameHierarchy(L"Struct::m_field");
|
||||
|
||||
TestStorage storage;
|
||||
|
||||
std::shared_ptr<IntermediateStorage> intermetiateStorage = std::make_shared<IntermediateStorage>();
|
||||
|
||||
Id aId = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_STRUCT), NameHierarchy::serialize(a))).first;
|
||||
intermetiateStorage->addSymbol(StorageSymbol(aId, DEFINITION_EXPLICIT));
|
||||
|
||||
Id bId = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_FIELD), NameHierarchy::serialize(b))).first;
|
||||
intermetiateStorage->addSymbol(StorageSymbol(bId, DEFINITION_EXPLICIT));
|
||||
intermetiateStorage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_MEMBER), aId, bId));
|
||||
|
||||
storage.inject(intermetiateStorage.get());
|
||||
bool foundEdge = false;
|
||||
|
||||
const Id sourceId = storage.getNodeIdForNameHierarchy(a);
|
||||
const Id targetId = storage.getNodeIdForNameHierarchy(b);
|
||||
for (auto edge : storage.getStorageEdges())
|
||||
{
|
||||
if (edge.sourceNodeId == sourceId && edge.targetNodeId == targetId && edge.type == Edge::typeToInt(Edge::EDGE_MEMBER))
|
||||
{
|
||||
foundEdge = true;
|
||||
}
|
||||
}
|
||||
TS_ASSERT(foundEdge);
|
||||
}
|
||||
|
||||
|
||||
void test_storage_saves_method_static()
|
||||
{
|
||||
//TestStorage storage;
|
||||
//Id id = storage.onMethodParsed(
|
||||
// validLocation(1),
|
||||
// ParseFunction(typeUsage("void"), createNameHierarchy("isMethod"), parameters("bool"), true),
|
||||
// ParserClient::ACCESS_NONE,
|
||||
// ParserClient::ABSTRACTION_NONE,
|
||||
// validLocation(4)
|
||||
//);
|
||||
|
||||
//Node* node = storage.getNodeWithId(id);
|
||||
//TS_ASSERT(node);
|
||||
//TS_ASSERT_EQUALS(node->getQualifiedNameWithSignature(), "isMethod");
|
||||
//TS_ASSERT_EQUALS(node->getType(), NodeType::NODE_METHOD);
|
||||
//TS_ASSERT(node->getComponent<TokenComponentStatic>());
|
||||
}
|
||||
|
||||
void test_storage_clears_single_file_data_of_single_file_storage()
|
||||
{
|
||||
/*TestStorage storage;
|
||||
storage.onFunctionParsed(
|
||||
validLocation(), ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"),
|
||||
parameters("char")), validLocation()
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(storage.getNodeCount(), 3);
|
||||
TS_ASSERT_EQUALS(storage.getEdgeCount(), 2);
|
||||
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 4);
|
||||
|
||||
std::set<FilePath> files;
|
||||
files.insert(FilePath(m_filePath));
|
||||
storage.clearFileData(files);
|
||||
|
||||
TS_ASSERT_EQUALS(storage.getNodeCount(), 0);
|
||||
TS_ASSERT_EQUALS(storage.getEdgeCount(), 0);
|
||||
TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 0);*/
|
||||
}
|
||||
|
||||
void test_storage_clears_unreferenced_single_file_data_of_multi_file_storage()
|
||||
{
|
||||
//m_filePath = "file.h";
|
||||
|
||||
//TestStorage storage;
|
||||
|
||||
//ParseFunction isTrue = ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"), parameters("char"));
|
||||
//storage.onFunctionParsed(validLocation(), isTrue, validLocation());
|
||||
|
||||
//m_filePath = "file.cpp";
|
||||
|
||||
//ParseFunction main = ParseFunction(typeUsage("int"), createNameHierarchy("main"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), main, validLocation());
|
||||
|
||||
//storage.onCallParsed(validLocation(), main, isTrue);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 6);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
|
||||
|
||||
//std::set<FilePath> files;
|
||||
//files.insert(FilePath("file.cpp"));
|
||||
//storage.clearFileData(files);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 3);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 2);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 4);*/
|
||||
}
|
||||
|
||||
void test_storage_clears_referenced_single_file_data_of_multi_file_storage()
|
||||
{
|
||||
//m_filePath = "file.h";
|
||||
|
||||
//TestStorage storage;
|
||||
|
||||
//ParseFunction isTrue = ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), isTrue, validLocation());
|
||||
|
||||
//m_filePath = "file.cpp";
|
||||
|
||||
//ParseFunction main = ParseFunction(typeUsage("int"), createNameHierarchy("main"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), main, validLocation());
|
||||
|
||||
//storage.onCallParsed(validLocation(), main, isTrue);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
|
||||
|
||||
//std::set<FilePath> files;
|
||||
//files.insert(FilePath("file.h"));
|
||||
//storage.clearFileData(files);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 4);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 3);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 5);
|
||||
}
|
||||
|
||||
void test_storage_clears_multi_file_data_of_multi_file_storage()
|
||||
{
|
||||
//m_filePath = "file.h";
|
||||
|
||||
//TestStorage storage;
|
||||
|
||||
//ParseFunction isTrue = ParseFunction(typeUsage("bool"), createNameHierarchy("isTrue"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), isTrue, validLocation());
|
||||
|
||||
//m_filePath = "file.cpp";
|
||||
|
||||
//ParseFunction main = ParseFunction(typeUsage("int"), createNameHierarchy("main"), parameters("void"));
|
||||
//storage.onFunctionParsed(validLocation(), main, validLocation());
|
||||
|
||||
//storage.onCallParsed(validLocation(), main, isTrue);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 5);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 9);
|
||||
|
||||
//std::set<FilePath> filePaths;
|
||||
//filePaths.insert(FilePath("file.cpp"));
|
||||
//filePaths.insert(FilePath("file.h"));
|
||||
//storage.clearFileData(filePaths);
|
||||
|
||||
//TS_ASSERT_EQUALS(storage.getNodeCount(), 0);
|
||||
//TS_ASSERT_EQUALS(storage.getEdgeCount(), 0);
|
||||
//TS_ASSERT_EQUALS(storage.tokenLocationCollection().getTokenLocations().size(), 0);
|
||||
}
|
||||
|
||||
void test_storage_finds_and_removes_depending_file_nodes()
|
||||
{
|
||||
//TestStorage storage;
|
||||
|
||||
//Id id1 = storage.onFileParsed("f.h");
|
||||
//Id id2 = storage.onFileParsed("file.h");
|
||||
//Id id3 = storage.onFileParsed("file.cpp");
|
||||
//Id id4 = storage.onFileIncludeParsed(validLocation(), "file.h", "f.h");
|
||||
//Id id5 = storage.onFileIncludeParsed(validLocation(), "file.cpp", "file.h");
|
||||
|
||||
//std::string name1 = storage.getNodeWithId(id2)->getQualifiedNameWithSignature();
|
||||
//std::string name2 = storage.getNodeWithId(id3)->getQualifiedNameWithSignature();
|
||||
|
||||
//std::set<FilePath> filePaths;
|
||||
//filePaths.insert(FilePath(name1));
|
||||
//std::set<FilePath> dependingFilePaths = storage.getDependingFilePathsAndRemoveFileNodes(filePaths);
|
||||
|
||||
//TS_ASSERT_EQUALS(dependingFilePaths.size(), 1);
|
||||
//TS_ASSERT_EQUALS(dependingFilePaths.begin()->str(), name2);
|
||||
|
||||
//TS_ASSERT(storage.getNodeWithId(id1));
|
||||
//TS_ASSERT(!storage.getNodeWithId(id2));
|
||||
//TS_ASSERT(!storage.getNodeWithId(id3));
|
||||
//TS_ASSERT(!storage.getEdgeWithId(id4));
|
||||
//TS_ASSERT(!storage.getEdgeWithId(id5));
|
||||
}
|
||||
|
||||
private:
|
||||
class TestStorage
|
||||
: public PersistentStorage
|
||||
{
|
||||
public:
|
||||
TestStorage()
|
||||
: PersistentStorage(FilePath(L"data/test.sqlite"), FilePath(L"data/testBookmarks.sqlite"))
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//const size_t getNodeCount() const
|
||||
//{
|
||||
// return getGraph().getNodeCount();
|
||||
//}
|
||||
|
||||
//const size_t getEdgeCount() const
|
||||
//{
|
||||
// return getGraph().getEdgeCount();
|
||||
//}
|
||||
};
|
||||
|
||||
ParseLocation validLocation(Id locationId = 0) const
|
||||
{
|
||||
return ParseLocation(1, 1, locationId, 1, locationId);
|
||||
}
|
||||
|
||||
NameHierarchy createFunctionNameHierarchy(std::wstring ret, std::wstring name, std::wstring parameters) const
|
||||
{
|
||||
NameHierarchy nameHierarchy = createNameHierarchy(name);
|
||||
std::wstring lastName = nameHierarchy.back().getName();
|
||||
nameHierarchy.pop();
|
||||
nameHierarchy.push(NameElement(lastName, ret, parameters));
|
||||
return nameHierarchy;
|
||||
}
|
||||
|
||||
NameHierarchy createNameHierarchy(std::wstring s) const
|
||||
{
|
||||
NameHierarchy nameHierarchy(NAME_DELIMITER_CXX);
|
||||
for (std::wstring element: utility::splitToVector(s, nameDelimiterTypeToString(NAME_DELIMITER_CXX)))
|
||||
{
|
||||
nameHierarchy.push(element);
|
||||
}
|
||||
return nameHierarchy;
|
||||
}
|
||||
|
||||
FilePath m_filePath;
|
||||
};
|
||||
@@ -0,0 +1,283 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "Blackboard.h"
|
||||
#include "Task.h"
|
||||
#include "TaskGroupSelector.h"
|
||||
#include "TaskGroupSequence.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
void executeTask(Task& task)
|
||||
{
|
||||
std::shared_ptr<Blackboard> blakboard = std::make_shared<Blackboard>();
|
||||
while (true)
|
||||
{
|
||||
if (task.update(blakboard) != Task::STATE_RUNNING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestTask : public Task
|
||||
{
|
||||
public:
|
||||
TestTask(int* orderCountPtr, int updateCount, TaskState returnState = STATE_SUCCESS)
|
||||
: orderCount(*orderCountPtr)
|
||||
, updateCount(updateCount)
|
||||
, returnState(returnState)
|
||||
, enterCallOrder(0)
|
||||
, updateCallOrder(0)
|
||||
, exitCallOrder(0)
|
||||
, resetCallOrder(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
enterCallOrder = ++orderCount;
|
||||
}
|
||||
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
updateCallOrder = ++orderCount;
|
||||
|
||||
if (updateCount < 0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
return Task::STATE_RUNNING;
|
||||
}
|
||||
|
||||
updateCount--;
|
||||
if (updateCount)
|
||||
{
|
||||
return Task::STATE_RUNNING;
|
||||
}
|
||||
|
||||
return returnState;
|
||||
}
|
||||
|
||||
virtual void doExit(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
exitCallOrder = ++orderCount;
|
||||
}
|
||||
|
||||
virtual void doReset(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
resetCallOrder = ++orderCount;
|
||||
}
|
||||
|
||||
int& orderCount;
|
||||
int updateCount;
|
||||
TaskState returnState;
|
||||
|
||||
int enterCallOrder;
|
||||
int updateCallOrder;
|
||||
int exitCallOrder;
|
||||
int resetCallOrder;
|
||||
};
|
||||
|
||||
class TestTaskDispatch : public TestTask
|
||||
{
|
||||
public:
|
||||
TestTaskDispatch(int* orderCountPtr, int updateCount, TaskScheduler* scheduler)
|
||||
: TestTask(orderCountPtr, updateCount)
|
||||
, scheduler(scheduler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
subTask = std::make_shared<TestTask>(&orderCount, 1);
|
||||
scheduler->pushTask(subTask);
|
||||
|
||||
return TestTask::doUpdate(blakboard);
|
||||
}
|
||||
|
||||
TaskScheduler* scheduler;
|
||||
std::shared_ptr<TestTask> subTask;
|
||||
};
|
||||
|
||||
void waitForThread(TaskScheduler& scheduler)
|
||||
{
|
||||
static const int THREAD_WAIT_TIME_MS = 20;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(THREAD_WAIT_TIME_MS));
|
||||
} while (scheduler.hasTasksQueued());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("scheduler loop starts and stops")
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
REQUIRE(!scheduler.loopIsRunning());
|
||||
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
REQUIRE(scheduler.loopIsRunning());
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
REQUIRE(!scheduler.loopIsRunning());
|
||||
}
|
||||
|
||||
TEST_CASE("tasks get executed without scheduling in correct order")
|
||||
{
|
||||
int order = 0;
|
||||
TestTask task(&order, 1);
|
||||
|
||||
executeTask(task);
|
||||
|
||||
REQUIRE(3 == order);
|
||||
|
||||
REQUIRE(1 == task.enterCallOrder);
|
||||
REQUIRE(2 == task.updateCallOrder);
|
||||
REQUIRE(3 == task.exitCallOrder);
|
||||
}
|
||||
|
||||
TEST_CASE("scheduled tasks get processed with callbacks in correct order")
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task = std::make_shared<TestTask>(&order, 1);
|
||||
|
||||
scheduler.pushTask(task);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
REQUIRE(3 == order);
|
||||
|
||||
REQUIRE(1 == task->enterCallOrder);
|
||||
REQUIRE(2 == task->updateCallOrder);
|
||||
REQUIRE(3 == task->exitCallOrder);
|
||||
}
|
||||
|
||||
TEST_CASE("sequential task group to process tasks in correct order")
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task1 = std::make_shared<TestTask>(&order, 1);
|
||||
std::shared_ptr<TestTask> task2 = std::make_shared<TestTask>(&order, 1);
|
||||
|
||||
std::shared_ptr<TaskGroupSequence> taskGroup = std::make_shared<TaskGroupSequence>();
|
||||
taskGroup->addTask(task1);
|
||||
taskGroup->addTask(task2);
|
||||
|
||||
scheduler.pushTask(taskGroup);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
REQUIRE(6 == order);
|
||||
|
||||
REQUIRE(1 == task1->enterCallOrder);
|
||||
REQUIRE(2 == task1->updateCallOrder);
|
||||
REQUIRE(3 == task1->exitCallOrder);
|
||||
|
||||
REQUIRE(4 == task2->enterCallOrder);
|
||||
REQUIRE(5 == task2->updateCallOrder);
|
||||
REQUIRE(6 == task2->exitCallOrder);
|
||||
}
|
||||
|
||||
TEST_CASE("sequential task group does not evaluate tasks after failure")
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task1 = std::make_shared<TestTask>(&order, 1, Task::STATE_FAILURE);
|
||||
std::shared_ptr<TestTask> task2 = std::make_shared<TestTask>(&order, -1);
|
||||
|
||||
std::shared_ptr<TaskGroupSequence> taskGroup = std::make_shared<TaskGroupSequence>();
|
||||
taskGroup->addTask(task1);
|
||||
taskGroup->addTask(task2);
|
||||
|
||||
scheduler.pushTask(taskGroup);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
REQUIRE(1 == task1->enterCallOrder);
|
||||
REQUIRE(2 == task1->updateCallOrder);
|
||||
REQUIRE(3 == task1->exitCallOrder);
|
||||
|
||||
REQUIRE(0 == task2->enterCallOrder);
|
||||
REQUIRE(0 == task2->updateCallOrder);
|
||||
REQUIRE(0 == task2->exitCallOrder);
|
||||
}
|
||||
|
||||
TEST_CASE("sequential task group does not evaluate tasks after success")
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task1 = std::make_shared<TestTask>(&order, 1, Task::STATE_FAILURE);
|
||||
std::shared_ptr<TestTask> task2 = std::make_shared<TestTask>(&order, 1, Task::STATE_SUCCESS);
|
||||
std::shared_ptr<TestTask> task3 = std::make_shared<TestTask>(&order, -1);
|
||||
|
||||
std::shared_ptr<TaskGroupSelector> taskGroup = std::make_shared<TaskGroupSelector>();
|
||||
taskGroup->addTask(task1);
|
||||
taskGroup->addTask(task2);
|
||||
taskGroup->addTask(task3);
|
||||
|
||||
scheduler.pushTask(taskGroup);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
REQUIRE(1 == task1->enterCallOrder);
|
||||
REQUIRE(2 == task1->updateCallOrder);
|
||||
REQUIRE(3 == task1->exitCallOrder);
|
||||
|
||||
REQUIRE(4 == task2->enterCallOrder);
|
||||
REQUIRE(5 == task2->updateCallOrder);
|
||||
REQUIRE(6 == task2->exitCallOrder);
|
||||
|
||||
REQUIRE(0 == task3->enterCallOrder);
|
||||
REQUIRE(0 == task3->updateCallOrder);
|
||||
REQUIRE(0 == task3->exitCallOrder);
|
||||
}
|
||||
|
||||
TEST_CASE("task scheduling within task processing")
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTaskDispatch> task = std::make_shared<TestTaskDispatch>(&order, 1, &scheduler);
|
||||
|
||||
scheduler.pushTask(task);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
REQUIRE(6 == order);
|
||||
|
||||
REQUIRE(1 == task->enterCallOrder);
|
||||
REQUIRE(2 == task->updateCallOrder);
|
||||
REQUIRE(3 == task->exitCallOrder);
|
||||
|
||||
REQUIRE(4 == task->subTask->enterCallOrder);
|
||||
REQUIRE(5 == task->subTask->updateCallOrder);
|
||||
REQUIRE(6 == task->subTask->exitCallOrder);
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "Blackboard.h"
|
||||
#include "Task.h"
|
||||
#include "TaskGroupSelector.h"
|
||||
#include "TaskGroupSequence.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
class TaskSchedulerTestSuite: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_scheduler_loop_starts_and_stops(void)
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
TS_ASSERT(!scheduler.loopIsRunning());
|
||||
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
TS_ASSERT(scheduler.loopIsRunning());
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
TS_ASSERT(!scheduler.loopIsRunning());
|
||||
}
|
||||
|
||||
void test_tasks_get_executed_without_scheduling_in_correct_order(void)
|
||||
{
|
||||
int order = 0;
|
||||
TestTask task(&order, 1);
|
||||
|
||||
executeTask(task);
|
||||
|
||||
TS_ASSERT_EQUALS(3, order);
|
||||
|
||||
TS_ASSERT_EQUALS(1, task.enterCallOrder);
|
||||
TS_ASSERT_EQUALS(2, task.updateCallOrder);
|
||||
TS_ASSERT_EQUALS(3, task.exitCallOrder);
|
||||
}
|
||||
|
||||
void test_scheduled_tasks_get_processed_with_callbacks_in_correct_order(void)
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task = std::make_shared<TestTask>(&order, 1);
|
||||
|
||||
scheduler.pushTask(task);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(3, order);
|
||||
|
||||
TS_ASSERT_EQUALS(1, task->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(2, task->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(3, task->exitCallOrder);
|
||||
}
|
||||
|
||||
void test_sequential_task_group_to_process_tasks_in_correct_order(void)
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task1 = std::make_shared<TestTask>(&order, 1);
|
||||
std::shared_ptr<TestTask> task2 = std::make_shared<TestTask>(&order, 1);
|
||||
|
||||
std::shared_ptr<TaskGroupSequence> taskGroup = std::make_shared<TaskGroupSequence>();
|
||||
taskGroup->addTask(task1);
|
||||
taskGroup->addTask(task2);
|
||||
|
||||
scheduler.pushTask(taskGroup);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(6, order);
|
||||
|
||||
TS_ASSERT_EQUALS(1, task1->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(2, task1->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(3, task1->exitCallOrder);
|
||||
|
||||
TS_ASSERT_EQUALS(4, task2->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(5, task2->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(6, task2->exitCallOrder);
|
||||
}
|
||||
|
||||
void test_sequential_task_group_does_not_evaluate_tasks_after_failure(void)
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task1 = std::make_shared<TestTask>(&order, 1, Task::STATE_FAILURE);
|
||||
std::shared_ptr<TestTask> task2 = std::make_shared<TestTask>(&order, -1);
|
||||
|
||||
std::shared_ptr<TaskGroupSequence> taskGroup = std::make_shared<TaskGroupSequence>();
|
||||
taskGroup->addTask(task1);
|
||||
taskGroup->addTask(task2);
|
||||
|
||||
scheduler.pushTask(taskGroup);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(1, task1->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(2, task1->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(3, task1->exitCallOrder);
|
||||
|
||||
TS_ASSERT_EQUALS(0, task2->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(0, task2->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(0, task2->exitCallOrder);
|
||||
}
|
||||
|
||||
void test_sequential_task_group_does_not_evaluate_tasks_after_success(void)
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTask> task1 = std::make_shared<TestTask>(&order, 1, Task::STATE_FAILURE);
|
||||
std::shared_ptr<TestTask> task2 = std::make_shared<TestTask>(&order, 1, Task::STATE_SUCCESS);
|
||||
std::shared_ptr<TestTask> task3 = std::make_shared<TestTask>(&order, -1);
|
||||
|
||||
std::shared_ptr<TaskGroupSelector> taskGroup = std::make_shared<TaskGroupSelector>();
|
||||
taskGroup->addTask(task1);
|
||||
taskGroup->addTask(task2);
|
||||
taskGroup->addTask(task3);
|
||||
|
||||
scheduler.pushTask(taskGroup);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(1, task1->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(2, task1->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(3, task1->exitCallOrder);
|
||||
|
||||
TS_ASSERT_EQUALS(4, task2->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(5, task2->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(6, task2->exitCallOrder);
|
||||
|
||||
TS_ASSERT_EQUALS(0, task3->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(0, task3->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(0, task3->exitCallOrder);
|
||||
}
|
||||
|
||||
void test_task_scheduling_within_task_processing()
|
||||
{
|
||||
TaskScheduler scheduler(0);
|
||||
scheduler.startSchedulerLoopThreaded();
|
||||
|
||||
int order = 0;
|
||||
std::shared_ptr<TestTaskDispatch> task = std::make_shared<TestTaskDispatch>(&order, 1, &scheduler);
|
||||
|
||||
scheduler.pushTask(task);
|
||||
|
||||
waitForThread(scheduler);
|
||||
|
||||
scheduler.stopSchedulerLoop();
|
||||
|
||||
TS_ASSERT_EQUALS(6, order);
|
||||
|
||||
TS_ASSERT_EQUALS(1, task->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(2, task->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(3, task->exitCallOrder);
|
||||
|
||||
TS_ASSERT_EQUALS(4, task->subTask->enterCallOrder);
|
||||
TS_ASSERT_EQUALS(5, task->subTask->updateCallOrder);
|
||||
TS_ASSERT_EQUALS(6, task->subTask->exitCallOrder);
|
||||
}
|
||||
|
||||
private:
|
||||
void executeTask(Task& task)
|
||||
{
|
||||
std::shared_ptr<Blackboard> blakboard = std::make_shared<Blackboard>();
|
||||
while (true)
|
||||
{
|
||||
if (task.update(blakboard) != Task::STATE_RUNNING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestTask: public Task
|
||||
{
|
||||
public:
|
||||
TestTask(int* orderCountPtr, int updateCount, TaskState returnState = STATE_SUCCESS)
|
||||
: orderCount(*orderCountPtr)
|
||||
, updateCount(updateCount)
|
||||
, returnState(returnState)
|
||||
, enterCallOrder(0)
|
||||
, updateCallOrder(0)
|
||||
, exitCallOrder(0)
|
||||
, resetCallOrder(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
enterCallOrder = ++orderCount;
|
||||
}
|
||||
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
updateCallOrder = ++orderCount;
|
||||
|
||||
if (updateCount < 0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
return Task::STATE_RUNNING;
|
||||
}
|
||||
|
||||
updateCount--;
|
||||
if (updateCount)
|
||||
{
|
||||
return Task::STATE_RUNNING;
|
||||
}
|
||||
|
||||
return returnState;
|
||||
}
|
||||
|
||||
virtual void doExit(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
exitCallOrder = ++orderCount;
|
||||
}
|
||||
|
||||
virtual void doReset(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
resetCallOrder = ++orderCount;
|
||||
}
|
||||
|
||||
int& orderCount;
|
||||
int updateCount;
|
||||
TaskState returnState;
|
||||
|
||||
int enterCallOrder;
|
||||
int updateCallOrder;
|
||||
int exitCallOrder;
|
||||
int resetCallOrder;
|
||||
};
|
||||
|
||||
class TestTaskDispatch: public TestTask
|
||||
{
|
||||
public:
|
||||
TestTaskDispatch(int* orderCountPtr, int updateCount, TaskScheduler* scheduler)
|
||||
: TestTask(orderCountPtr, updateCount)
|
||||
, scheduler(scheduler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blakboard)
|
||||
{
|
||||
subTask = std::make_shared<TestTask>(&orderCount, 1);
|
||||
scheduler->pushTask(subTask);
|
||||
|
||||
return TestTask::doUpdate(blakboard);
|
||||
}
|
||||
|
||||
TaskScheduler* scheduler;
|
||||
std::shared_ptr<TestTask> subTask;
|
||||
};
|
||||
|
||||
void waitForThread(TaskScheduler& scheduler) const
|
||||
{
|
||||
static const int THREAD_WAIT_TIME_MS = 20;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(THREAD_WAIT_TIME_MS));
|
||||
}
|
||||
while (scheduler.hasTasksQueued());
|
||||
}
|
||||
};
|
||||
@@ -1,46 +0,0 @@
|
||||
#include "TestSuiteFixture.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "ApplicationSettings.h"
|
||||
|
||||
TestSuiteFixture::TestSuiteFixture()
|
||||
{
|
||||
}
|
||||
|
||||
TestSuiteFixture::~TestSuiteFixture()
|
||||
{
|
||||
}
|
||||
|
||||
bool TestSuiteFixture::setUpWorld()
|
||||
{
|
||||
#ifdef __linux__
|
||||
const std::string homedir = getenv("HOME");
|
||||
|
||||
if (!homedir.empty())
|
||||
{
|
||||
if(!ApplicationSettings::getInstance()->load(
|
||||
FilePath(homedir + "/.config/sourcetrail/ApplicationSettings.xml")
|
||||
))
|
||||
{
|
||||
std::cout << "no settings" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "no homedir" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
ApplicationSettings::getInstance()->load(FilePath(L"data/TestSettings.xml"));
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestSuiteFixture::tearDownWorld()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef TEST_SUITE_FIXTURE_H
|
||||
#define TEST_SUITE_FIXTURE_H
|
||||
|
||||
#include <cxxtest/GlobalFixture.h>
|
||||
|
||||
class TestSuiteFixture : public CxxTest::GlobalFixture
|
||||
{
|
||||
public:
|
||||
TestSuiteFixture();
|
||||
virtual ~TestSuiteFixture();
|
||||
|
||||
virtual bool setUpWorld();
|
||||
virtual bool tearDownWorld();
|
||||
};
|
||||
|
||||
// According to the CxxTest Documentation global fixtures are actually supposed to be implemented as global static instances
|
||||
// See http://cxxtest.com/guide.html for more details
|
||||
static TestSuiteFixture testSuiteFixture;
|
||||
|
||||
#endif // TEST_SUITE_FIXTURE_H
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "TextAccess.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string getTestText()
|
||||
{
|
||||
std::string text =
|
||||
"\"But the plans were on display . . .\"\n"
|
||||
"\"On display? I eventually had to go down to the cellar to find them.\"\n"
|
||||
"\"That's the display department.\"\n"
|
||||
"\"With a torch.\"\n"
|
||||
"\"Ah, well the lights had probably gone.\"\n"
|
||||
"\"So had the stairs.\"\n"
|
||||
"\"But look, you found the notice, didn't you?\"\n"
|
||||
"\"Yes,\" said Arthur, \"yes I did. It was on display in the bottom of a locked"
|
||||
" filing cabinet stuck in a disused lavatory with a sign on the door saying"
|
||||
" Beware of the Leopard.\"\n";
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessString constructor")
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
|
||||
REQUIRE(textAccess.get() != nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessString lines count")
|
||||
{
|
||||
std::string text = getTestText();
|
||||
unsigned int lineCount = 8;
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
|
||||
REQUIRE(textAccess->getLineCount() == lineCount);
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessString lines content")
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::vector<std::string> lines = textAccess->getLines(1, 4);
|
||||
|
||||
REQUIRE(lines.size() == 4);
|
||||
REQUIRE(lines[0] == "\"But the plans were on display . . .\"\n");
|
||||
REQUIRE(lines[1] == "\"On display? I eventually had to go down to the cellar to find them.\"\n");
|
||||
REQUIRE(lines[2] == "\"That's the display department.\"\n");
|
||||
REQUIRE(lines[3] == "\"With a torch.\"\n");
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessString lines content error handling")
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::vector<std::string> lines = textAccess->getLines(3, 2);
|
||||
|
||||
REQUIRE(lines.size() == 0);
|
||||
|
||||
lines = textAccess->getLines(10, 3);
|
||||
|
||||
REQUIRE(lines.size() == 0);
|
||||
|
||||
lines = textAccess->getLines(1, 10);
|
||||
|
||||
REQUIRE(lines.size() == 0);
|
||||
|
||||
std::string line = textAccess->getLine(0);
|
||||
|
||||
REQUIRE(line == "");
|
||||
|
||||
lines = textAccess->getLines(0, 2);
|
||||
|
||||
REQUIRE(line == "");
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessString single line content")
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::string line = textAccess->getLine(6);
|
||||
|
||||
REQUIRE(line == "\"So had the stairs.\"\n");
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessString all lines")
|
||||
{
|
||||
std::string text = getTestText();
|
||||
unsigned int lineCount = 8;
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::vector<std::string> lines = textAccess->getAllLines();
|
||||
|
||||
REQUIRE(lines.size() == lineCount);
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessFile constructor")
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
REQUIRE(textAccess.get() != nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessFile lines count")
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
unsigned int lineCount = 7;
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
REQUIRE(textAccess->getLineCount() == lineCount);
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessFile lines content")
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
std::vector<std::string> lines = textAccess->getLines(1, 4);
|
||||
|
||||
REQUIRE(lines.size() == 4);
|
||||
REQUIRE(lines[0] == "\"If you're a researcher on this book thing and you were on Earth, you must have been gathering material on it.\"\n");
|
||||
REQUIRE(lines[1] == "\"Well, I was able to extend the original entry a bit, yes.\"\n");
|
||||
REQUIRE(lines[2] == "\"Let me see what it says in this edition, then. I've got to see it.\"\n");
|
||||
REQUIRE(lines[3] == "... \"What? Harmless! Is that all it's got to say? Harmless! One word! ... Well, for God's sake I hope you managed to recitify that a bit.\"\n");
|
||||
}
|
||||
|
||||
TEST_CASE("textAccessFile get filePath")
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
REQUIRE(textAccess->getFilePath() == filePath);
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "TextAccess.h"
|
||||
|
||||
class TextAccessTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_textAccessString_constructor()
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
|
||||
TS_ASSERT(textAccess.get() != nullptr);
|
||||
}
|
||||
|
||||
void test_textAccessString_lines_count()
|
||||
{
|
||||
std::string text = getTestText();
|
||||
unsigned int lineCount = 8;
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
|
||||
TS_ASSERT_EQUALS(textAccess->getLineCount(), lineCount);
|
||||
}
|
||||
|
||||
void test_textAccessString_lines_content()
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::vector<std::string> lines = textAccess->getLines(1, 4);
|
||||
|
||||
TS_ASSERT_EQUALS(lines.size(), 4);
|
||||
TS_ASSERT_EQUALS(lines[0], "\"But the plans were on display . . .\"\n");
|
||||
TS_ASSERT_EQUALS(lines[1], "\"On display? I eventually had to go down to the cellar to find them.\"\n");
|
||||
TS_ASSERT_EQUALS(lines[2], "\"That's the display department.\"\n");
|
||||
TS_ASSERT_EQUALS(lines[3], "\"With a torch.\"\n");
|
||||
}
|
||||
|
||||
void test_textAccessString_lines_content_error_handling()
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::vector<std::string> lines = textAccess->getLines(3, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(lines.size(), 0);
|
||||
|
||||
lines = textAccess->getLines(10, 3);
|
||||
|
||||
TS_ASSERT_EQUALS(lines.size(), 0);
|
||||
|
||||
lines = textAccess->getLines(1, 10);
|
||||
|
||||
TS_ASSERT_EQUALS(lines.size(), 0);
|
||||
|
||||
std::string line = textAccess->getLine(0);
|
||||
|
||||
TS_ASSERT_EQUALS(line, "");
|
||||
|
||||
lines = textAccess->getLines(0, 2);
|
||||
|
||||
TS_ASSERT_EQUALS(line, "");
|
||||
}
|
||||
|
||||
void test_textAccessString_single_line_content()
|
||||
{
|
||||
std::string text = getTestText();
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::string line = textAccess->getLine(6);
|
||||
|
||||
TS_ASSERT_EQUALS(line, "\"So had the stairs.\"\n");
|
||||
}
|
||||
|
||||
void test_textAccessString_all_lines()
|
||||
{
|
||||
std::string text = getTestText();
|
||||
unsigned int lineCount = 8;
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromString(text);
|
||||
std::vector<std::string> lines = textAccess->getAllLines();
|
||||
|
||||
TS_ASSERT_EQUALS(lines.size(), lineCount);
|
||||
}
|
||||
|
||||
void test_textAccessFile_constructor()
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
TS_ASSERT(textAccess.get() != nullptr);
|
||||
}
|
||||
|
||||
void test_textAccessFile_lines_count()
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
unsigned int lineCount = 7;
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
TS_ASSERT_EQUALS(textAccess->getLineCount(), lineCount);
|
||||
}
|
||||
|
||||
void test_textAccessFile_lines_content()
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
std::vector<std::string> lines = textAccess->getLines(1, 4);
|
||||
|
||||
TS_ASSERT_EQUALS(lines.size(), 4);
|
||||
TS_ASSERT_EQUALS(lines[0], "\"If you're a researcher on this book thing and you were on Earth, you must have been gathering material on it.\"\n");
|
||||
TS_ASSERT_EQUALS(lines[1], "\"Well, I was able to extend the original entry a bit, yes.\"\n");
|
||||
TS_ASSERT_EQUALS(lines[2], "\"Let me see what it says in this edition, then. I've got to see it.\"\n");
|
||||
TS_ASSERT_EQUALS(lines[3], "... \"What? Harmless! Is that all it's got to say? Harmless! One word! ... Well, for God's sake I hope you managed to recitify that a bit.\"\n");
|
||||
}
|
||||
|
||||
void test_textAccessFile_get_filePath()
|
||||
{
|
||||
FilePath filePath(L"data/TextAccessTestSuite/text.txt");
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
TS_ASSERT_EQUALS(textAccess->getFilePath(), filePath);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string getTestText()
|
||||
{
|
||||
std::string text =
|
||||
"\"But the plans were on display . . .\"\n"
|
||||
"\"On display? I eventually had to go down to the cellar to find them.\"\n"
|
||||
"\"That's the display department.\"\n"
|
||||
"\"With a torch.\"\n"
|
||||
"\"Ah, well the lights had probably gone.\"\n"
|
||||
"\"So had the stairs.\"\n"
|
||||
"\"But look, you found the notice, didn't you?\"\n"
|
||||
"\"Yes,\" said Arthur, \"yes I did. It was on display in the bottom of a locked"
|
||||
" filing cabinet stuck in a disused lavatory with a sign on the door saying"
|
||||
" Beware of the Leopard.\"\n";
|
||||
|
||||
return text;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "FilePath.h"
|
||||
#include "utility.h"
|
||||
#include "utilityMaven.h"
|
||||
#include "utilityPathDetection.h"
|
||||
|
||||
TEST_CASE("maven path detector is working")
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
REQUIRE(mavenPathDetector->isWorking());
|
||||
}
|
||||
|
||||
TEST_CASE("maven wrapper detects source directories of simple projects")
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
REQUIRE(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/simple_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), false
|
||||
);
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(!utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("maven wrapper detects source and test directories of simple projects")
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
REQUIRE(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/simple_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), true
|
||||
);
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("maven wrapper detects source directories of nested modules")
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
REQUIRE(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/nested_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), false
|
||||
);
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(!utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/test/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(!utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("maven wrapper detects source and test directories of nested modules")
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
REQUIRE(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/nested_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), true
|
||||
);
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/test/java").makeAbsolute()
|
||||
));
|
||||
|
||||
REQUIRE(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "FilePath.h"
|
||||
#include "utilityMaven.h"
|
||||
#include "utilityPathDetection.h"
|
||||
|
||||
class UtilityMavenTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_maven_path_detector_is_working()
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
TS_ASSERT(mavenPathDetector->isWorking());
|
||||
}
|
||||
|
||||
void test_maven_wrapper_detects_source_directories_of_simple_projects()
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
TS_ASSERT(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/simple_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), false
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(!utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void test_maven_wrapper_detects_source_and_test_directories_of_simple_projects()
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
TS_ASSERT(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/simple_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), true
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/simple_maven_project/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void test_maven_wrapper_detects_source_directories_of_nested_modules()
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
TS_ASSERT(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/nested_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), false
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(!utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/test/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(!utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void test_maven_wrapper_detects_source_and_test_directories_of_nested_modules()
|
||||
{
|
||||
std::shared_ptr<PathDetector> mavenPathDetector = utility::getMavenExecutablePathDetector();
|
||||
TS_ASSERT(!mavenPathDetector->getPaths().empty());
|
||||
|
||||
if (!mavenPathDetector->getPaths().empty())
|
||||
{
|
||||
std::vector<FilePath> result = utility::mavenGetAllDirectoriesFromEffectivePom(
|
||||
mavenPathDetector->getPaths().front(), FilePath(L"data/UtilityMavenTestSuite/nested_maven_project"), FilePath(L"data/UtilityMavenTestSuite").makeAbsolute(), true
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/main/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_1/src/test/java").makeAbsolute()
|
||||
));
|
||||
|
||||
TS_ASSERT(utility::containsElement<FilePath>(
|
||||
result, FilePath(L"data/UtilityMavenTestSuite/nested_maven_project/module_2/src/test/java").makeAbsolute()
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,302 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "utilityString.h"
|
||||
|
||||
TEST_CASE("split with char delimiter")
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A,B,C", ',');
|
||||
|
||||
REQUIRE(result.size() == 3);
|
||||
REQUIRE(result.at(0) == "A");
|
||||
REQUIRE(result.at(1) == "B");
|
||||
REQUIRE(result.at(2) == "C");
|
||||
}
|
||||
|
||||
TEST_CASE("split with string delimiter")
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A->B>C", "->");
|
||||
|
||||
REQUIRE(result.size() == 2);
|
||||
REQUIRE(result.at(0) == "A");
|
||||
REQUIRE(result.at(1) == "B>C");
|
||||
}
|
||||
|
||||
TEST_CASE("split on empty string")
|
||||
{
|
||||
std::deque<std::string> result = utility::split("", "->");
|
||||
|
||||
REQUIRE(result.size() == 1);
|
||||
REQUIRE(result.at(0) == "");
|
||||
}
|
||||
|
||||
TEST_CASE("split with unused delimiter")
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A:B:C", ";");
|
||||
|
||||
REQUIRE(result.size() == 1);
|
||||
REQUIRE(result.at(0) == "A:B:C");
|
||||
}
|
||||
|
||||
TEST_CASE("split with delimiters next to each")
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A::B:C", ':');
|
||||
|
||||
REQUIRE(result.size() == 4);
|
||||
REQUIRE(result.at(0) == "A");
|
||||
REQUIRE(result.at(1) == "");
|
||||
REQUIRE(result.at(2) == "B");
|
||||
REQUIRE(result.at(3) == "C");
|
||||
}
|
||||
|
||||
TEST_CASE("split with delimiter at start")
|
||||
{
|
||||
std::deque<std::string> result = utility::split(":B:C", ':');
|
||||
|
||||
REQUIRE(result.size() == 3);
|
||||
REQUIRE(result.at(0) == "");
|
||||
REQUIRE(result.at(1) == "B");
|
||||
REQUIRE(result.at(2) == "C");
|
||||
}
|
||||
|
||||
TEST_CASE("split with delimiter at end")
|
||||
{
|
||||
std::deque<std::string> result = utility::split("B:C:", ':');
|
||||
|
||||
REQUIRE(result.size() == 3);
|
||||
REQUIRE(result.at(0) == "B");
|
||||
REQUIRE(result.at(1) == "C");
|
||||
REQUIRE(result.at(2) == "");
|
||||
}
|
||||
|
||||
TEST_CASE("join with char delimiter")
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
list.push_back("A");
|
||||
list.push_back("B");
|
||||
list.push_back("C");
|
||||
|
||||
std::string result = utility::join(list, ',');
|
||||
REQUIRE(result == "A,B,C");
|
||||
}
|
||||
|
||||
TEST_CASE("join with string delimiter")
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
list.push_back("A");
|
||||
list.push_back("B");
|
||||
list.push_back("C");
|
||||
|
||||
std::string result = utility::join(list, "==");
|
||||
REQUIRE(result == "A==B==C");
|
||||
}
|
||||
|
||||
TEST_CASE("join on empty list")
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
std::string result = utility::join(list, ',');
|
||||
REQUIRE(result == "");
|
||||
}
|
||||
|
||||
TEST_CASE("join with empty strings in list")
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
list.push_back("A");
|
||||
list.push_back("");
|
||||
list.push_back("");
|
||||
|
||||
std::string result = utility::join(list, ':');
|
||||
REQUIRE(result == "A::");
|
||||
}
|
||||
|
||||
TEST_CASE("tokenize with string")
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("A->B->C", "->");
|
||||
|
||||
REQUIRE(result.size() == 5);
|
||||
REQUIRE(result.at(0) == "A");
|
||||
REQUIRE(result.at(1) == "->");
|
||||
REQUIRE(result.at(2) == "B");
|
||||
REQUIRE(result.at(3) == "->");
|
||||
REQUIRE(result.at(4) == "C");
|
||||
}
|
||||
|
||||
TEST_CASE("tokenize with string and delimiter at start")
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("->B", "->");
|
||||
|
||||
REQUIRE(result.size() == 2);
|
||||
REQUIRE(result.at(0) == "->");
|
||||
REQUIRE(result.at(1) == "B");
|
||||
}
|
||||
|
||||
TEST_CASE("tokenize with string and delimiter at end")
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("C+", '+');
|
||||
|
||||
REQUIRE(result.size() == 2);
|
||||
REQUIRE(result.at(0) == "C");
|
||||
REQUIRE(result.at(1) == "+");
|
||||
}
|
||||
|
||||
TEST_CASE("tokenize with deque")
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("A->B=C->D", "->");
|
||||
result = utility::tokenize(result, "=");
|
||||
|
||||
REQUIRE(result.size() == 7);
|
||||
REQUIRE(result.at(0) == "A");
|
||||
REQUIRE(result.at(1) == "->");
|
||||
REQUIRE(result.at(2) == "B");
|
||||
REQUIRE(result.at(3) == "=");
|
||||
REQUIRE(result.at(4) == "C");
|
||||
REQUIRE(result.at(5) == "->");
|
||||
REQUIRE(result.at(6) == "D");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before first with single delimiter occurence")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeFirst("foo bar", ' ') == "foo");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before first with multiple delimiter occurences")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeFirst("foo bar foo", ' ') == "foo");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before first with no delimiter occurence")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeFirst("foobar", ' ') == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before first with delimiter at start")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeFirst(" foobar", ' ') == "");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before first with delimiter at end")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeFirst("foobar ", ' ') == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before last with single delimiter occurence")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeLast("foo bar", ' ') == "foo");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before last with multiple delimiter occurences")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeLast("foo bar foo", ' ') == "foo bar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before last with no delimiter occurence")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeLast("foobar", ' ') == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before last with delimiter at start")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeLast(" foobar", ' ') == "");
|
||||
}
|
||||
|
||||
TEST_CASE("substr before last with delimiter at end")
|
||||
{
|
||||
REQUIRE(utility::substrBeforeLast("foobar ", ' ') == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr after with single delimiter occurence")
|
||||
{
|
||||
REQUIRE(utility::substrAfter("foo bar", ' ') == "bar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr after with multiple delimiter occurences")
|
||||
{
|
||||
REQUIRE(utility::substrAfter("foo bar foo", ' ') == "bar foo");
|
||||
}
|
||||
|
||||
TEST_CASE("substr after with no delimiter occurence")
|
||||
{
|
||||
REQUIRE(utility::substrAfter("foobar", ' ') == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr after with delimiter at start")
|
||||
{
|
||||
REQUIRE(utility::substrAfter(" foobar", ' ') == "foobar");
|
||||
}
|
||||
|
||||
TEST_CASE("substr after with delimiter at end")
|
||||
{
|
||||
REQUIRE(utility::substrAfter("foobar ", ' ') == "");
|
||||
}
|
||||
|
||||
TEST_CASE("empty string is detected as prefix of any other string")
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
|
||||
REQUIRE(utility::isPrefix<std::string>("", foo));
|
||||
}
|
||||
|
||||
TEST_CASE("prefix of bigger text is detected as prefix")
|
||||
{
|
||||
const std::string foobar = "foobar";
|
||||
const std::string foo = "foo";
|
||||
|
||||
REQUIRE(utility::isPrefix(foo, foobar));
|
||||
}
|
||||
|
||||
TEST_CASE("prefix is detected as prefix of self")
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
|
||||
REQUIRE(utility::isPrefix(foo, foo));
|
||||
}
|
||||
|
||||
TEST_CASE("different texts are not detected of prefixes of each other")
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
const std::string bar = "bar";
|
||||
|
||||
REQUIRE(!utility::isPrefix(foo, bar));
|
||||
REQUIRE(!utility::isPrefix(bar, foo));
|
||||
}
|
||||
|
||||
TEST_CASE("to lower case")
|
||||
{
|
||||
REQUIRE("foobar" == utility::toLowerCase("FooBar"));
|
||||
REQUIRE("foobar" == utility::toLowerCase("FOOBAR"));
|
||||
REQUIRE("foobar" == utility::toLowerCase("foobar"));
|
||||
}
|
||||
|
||||
TEST_CASE("equals case insensitive with different cases")
|
||||
{
|
||||
const std::string foo = "FooBar";
|
||||
const std::string foo2 = "foobar";
|
||||
|
||||
REQUIRE(utility::equalsCaseInsensitive(foo, foo2));
|
||||
}
|
||||
|
||||
TEST_CASE("equals case insensitive with same cases")
|
||||
{
|
||||
const std::string foo = "foobar";
|
||||
const std::string foo2 = "foobar";
|
||||
|
||||
REQUIRE(utility::equalsCaseInsensitive(foo, foo2));
|
||||
}
|
||||
|
||||
TEST_CASE("equals case insensitive with different strings")
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
const std::string foo2 = "foobar";
|
||||
|
||||
REQUIRE(!utility::equalsCaseInsensitive(foo, foo2));
|
||||
}
|
||||
|
||||
TEST_CASE("replace")
|
||||
{
|
||||
REQUIRE("fubar" == utility::replace("foobar", "oo", "u"));
|
||||
REQUIRE("fuuuubar" == utility::replace("foobar", "o", "uu"));
|
||||
REQUIRE("bar" == utility::replace("foobar", "foo", ""));
|
||||
REQUIRE("foobar" == utility::replace("foobar", "", "i"));
|
||||
REQUIRE("foobar" == utility::replace("foobar", "", ""));
|
||||
REQUIRE("" == utility::replace("", "foo", "bar"));
|
||||
REQUIRE("foobar" == utility::replace("foobar", "ba", "ba"));
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "utilityString.h"
|
||||
|
||||
class UtilityStringTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_split_with_char_delimiter()
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A,B,C", ',');
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 3);
|
||||
TS_ASSERT_EQUALS(result.at(0), "A");
|
||||
TS_ASSERT_EQUALS(result.at(1), "B");
|
||||
TS_ASSERT_EQUALS(result.at(2), "C");
|
||||
}
|
||||
|
||||
void test_split_with_string_delimiter()
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A->B>C", "->");
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 2);
|
||||
TS_ASSERT_EQUALS(result.at(0), "A");
|
||||
TS_ASSERT_EQUALS(result.at(1), "B>C");
|
||||
}
|
||||
|
||||
void test_split_on_empty_string()
|
||||
{
|
||||
std::deque<std::string> result = utility::split("", "->");
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 1);
|
||||
TS_ASSERT_EQUALS(result.at(0), "");
|
||||
}
|
||||
|
||||
void test_split_with_unused_delimiter()
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A:B:C", ";");
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 1);
|
||||
TS_ASSERT_EQUALS(result.at(0), "A:B:C");
|
||||
}
|
||||
|
||||
void test_split_with_delimiters_next_to_each()
|
||||
{
|
||||
std::deque<std::string> result = utility::split("A::B:C", ':');
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 4);
|
||||
TS_ASSERT_EQUALS(result.at(0), "A");
|
||||
TS_ASSERT_EQUALS(result.at(1), "");
|
||||
TS_ASSERT_EQUALS(result.at(2), "B");
|
||||
TS_ASSERT_EQUALS(result.at(3), "C");
|
||||
}
|
||||
|
||||
void test_split_with_delimiter_at_start()
|
||||
{
|
||||
std::deque<std::string> result = utility::split(":B:C", ':');
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 3);
|
||||
TS_ASSERT_EQUALS(result.at(0), "");
|
||||
TS_ASSERT_EQUALS(result.at(1), "B");
|
||||
TS_ASSERT_EQUALS(result.at(2), "C");
|
||||
}
|
||||
|
||||
void test_split_with_delimiter_at_end()
|
||||
{
|
||||
std::deque<std::string> result = utility::split("B:C:", ':');
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 3);
|
||||
TS_ASSERT_EQUALS(result.at(0), "B");
|
||||
TS_ASSERT_EQUALS(result.at(1), "C");
|
||||
TS_ASSERT_EQUALS(result.at(2), "");
|
||||
}
|
||||
|
||||
void test_join_with_char_delimiter()
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
list.push_back("A");
|
||||
list.push_back("B");
|
||||
list.push_back("C");
|
||||
|
||||
std::string result = utility::join(list, ',');
|
||||
TS_ASSERT_EQUALS(result, "A,B,C");
|
||||
}
|
||||
|
||||
void test_join_with_string_delimiter()
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
list.push_back("A");
|
||||
list.push_back("B");
|
||||
list.push_back("C");
|
||||
|
||||
std::string result = utility::join(list, "==");
|
||||
TS_ASSERT_EQUALS(result, "A==B==C");
|
||||
}
|
||||
|
||||
void test_join_on_empty_list()
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
std::string result = utility::join(list, ',');
|
||||
TS_ASSERT_EQUALS(result, "");
|
||||
}
|
||||
|
||||
void test_join_with_empty_strings_in_list()
|
||||
{
|
||||
std::deque<std::string> list;
|
||||
list.push_back("A");
|
||||
list.push_back("");
|
||||
list.push_back("");
|
||||
|
||||
std::string result = utility::join(list, ':');
|
||||
TS_ASSERT_EQUALS(result, "A::");
|
||||
}
|
||||
|
||||
void test_tokenize_with_string()
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("A->B->C", "->");
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 5);
|
||||
TS_ASSERT_EQUALS(result.at(0), "A");
|
||||
TS_ASSERT_EQUALS(result.at(1), "->");
|
||||
TS_ASSERT_EQUALS(result.at(2), "B");
|
||||
TS_ASSERT_EQUALS(result.at(3), "->");
|
||||
TS_ASSERT_EQUALS(result.at(4), "C");
|
||||
}
|
||||
|
||||
void test_tokenize_with_string_and_delimiter_at_start()
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("->B", "->");
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 2);
|
||||
TS_ASSERT_EQUALS(result.at(0), "->");
|
||||
TS_ASSERT_EQUALS(result.at(1), "B");
|
||||
}
|
||||
|
||||
void test_tokenize_with_string_and_delimiter_at_end()
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("C+", '+');
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 2);
|
||||
TS_ASSERT_EQUALS(result.at(0), "C");
|
||||
TS_ASSERT_EQUALS(result.at(1), "+");
|
||||
}
|
||||
|
||||
void test_tokenize_with_deque()
|
||||
{
|
||||
std::deque<std::string> result = utility::tokenize("A->B=C->D", "->");
|
||||
result = utility::tokenize(result, "=");
|
||||
|
||||
TS_ASSERT_EQUALS(result.size(), 7);
|
||||
TS_ASSERT_EQUALS(result.at(0), "A");
|
||||
TS_ASSERT_EQUALS(result.at(1), "->");
|
||||
TS_ASSERT_EQUALS(result.at(2), "B");
|
||||
TS_ASSERT_EQUALS(result.at(3), "=");
|
||||
TS_ASSERT_EQUALS(result.at(4), "C");
|
||||
TS_ASSERT_EQUALS(result.at(5), "->");
|
||||
TS_ASSERT_EQUALS(result.at(6), "D");
|
||||
}
|
||||
|
||||
void test_substr_before_first_with_single_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foo bar", ' '), "foo");
|
||||
}
|
||||
|
||||
void test_substr_before_first_with_multiple_delimiter_occurences()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foo bar foo", ' '), "foo");
|
||||
}
|
||||
|
||||
void test_substr_before_first_with_no_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foobar", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_before_first_with_delimiter_at_start()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst(" foobar", ' '), "");
|
||||
}
|
||||
|
||||
void test_substr_before_first_with_delimiter_at_end()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foobar ", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_single_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foo bar", ' '), "foo");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_multiple_delimiter_occurences()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foo bar foo", ' '), "foo bar");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_no_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foobar", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_delimiter_at_start()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast(" foobar", ' '), "");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_delimiter_at_end()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foobar ", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_after_with_single_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrAfter("foo bar", ' '), "bar");
|
||||
}
|
||||
|
||||
void test_substr_after_with_multiple_delimiter_occurences()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrAfter("foo bar foo", ' '), "bar foo");
|
||||
}
|
||||
|
||||
void test_substr_after_with_no_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrAfter("foobar", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_after_with_delimiter_at_start()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrAfter(" foobar", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_after_with_delimiter_at_end()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrAfter("foobar ", ' '), "");
|
||||
}
|
||||
|
||||
void test_empty_string_is_detected_as_prefix_of_any_other_string()
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
|
||||
TS_ASSERT(utility::isPrefix<std::string>("", foo));
|
||||
}
|
||||
|
||||
void test_prefix_of_bigger_text_is_detected_as_prefix()
|
||||
{
|
||||
const std::string foobar = "foobar";
|
||||
const std::string foo = "foo";
|
||||
|
||||
TS_ASSERT(utility::isPrefix(foo, foobar));
|
||||
}
|
||||
|
||||
void test_prefix_is_detected_as_prefix_of_self()
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
|
||||
TS_ASSERT(utility::isPrefix(foo, foo));
|
||||
}
|
||||
|
||||
void test_different_texts_are_not_detected_of_prefixes_of_each_other()
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
const std::string bar = "bar";
|
||||
|
||||
TS_ASSERT(!utility::isPrefix(foo, bar));
|
||||
TS_ASSERT(!utility::isPrefix(bar, foo));
|
||||
}
|
||||
|
||||
void test_to_lower_case()
|
||||
{
|
||||
TS_ASSERT_EQUALS("foobar", utility::toLowerCase("FooBar"));
|
||||
TS_ASSERT_EQUALS("foobar", utility::toLowerCase("FOOBAR"));
|
||||
TS_ASSERT_EQUALS("foobar", utility::toLowerCase("foobar"));
|
||||
}
|
||||
|
||||
void test_equals_case_insensitive_with_different_cases()
|
||||
{
|
||||
const std::string foo = "FooBar";
|
||||
const std::string foo2 = "foobar";
|
||||
|
||||
TS_ASSERT(utility::equalsCaseInsensitive(foo, foo2));
|
||||
}
|
||||
|
||||
void test_equals_case_insensitive_with_same_cases()
|
||||
{
|
||||
const std::string foo = "foobar";
|
||||
const std::string foo2 = "foobar";
|
||||
|
||||
TS_ASSERT(utility::equalsCaseInsensitive(foo, foo2));
|
||||
}
|
||||
|
||||
void test_equals_case_insensitive_with_different_strings()
|
||||
{
|
||||
const std::string foo = "foo";
|
||||
const std::string foo2 = "foobar";
|
||||
|
||||
TS_ASSERT(!utility::equalsCaseInsensitive(foo, foo2));
|
||||
}
|
||||
|
||||
void test_replace()
|
||||
{
|
||||
TS_ASSERT_EQUALS("fubar", utility::replace("foobar", "oo", "u"));
|
||||
TS_ASSERT_EQUALS("fuuuubar", utility::replace("foobar", "o", "uu"));
|
||||
TS_ASSERT_EQUALS("bar", utility::replace("foobar", "foo", ""));
|
||||
TS_ASSERT_EQUALS("foobar", utility::replace("foobar", "", "i"));
|
||||
TS_ASSERT_EQUALS("foobar", utility::replace("foobar", "", ""));
|
||||
TS_ASSERT_EQUALS("", utility::replace("", "foo", "bar"));
|
||||
TS_ASSERT_EQUALS("foobar", utility::replace("foobar", "ba", "ba"));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
TEST_CASE("trim blank spaces of string")
|
||||
{
|
||||
REQUIRE(utility::trim(" foo ") == "foo");
|
||||
}
|
||||
|
||||
TEST_CASE("trim blank spaces of wstring")
|
||||
{
|
||||
REQUIRE(utility::trim(L" foo ") == L"foo");
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
class UtilityTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_trim_blank_spaces_of_string()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::trim(" foo "), "foo");
|
||||
}
|
||||
|
||||
void test_trim_blank_spaces_of_wstring()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::trim(L" foo "), L"foo");
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,264 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "Vector2.h"
|
||||
|
||||
TEST_CASE("vec2i constructors")
|
||||
{
|
||||
Vec2i vec0;
|
||||
Vec2i vec1(1, 1);
|
||||
Vec2i vec2(vec1);
|
||||
|
||||
REQUIRE(0 == vec0.x);
|
||||
REQUIRE(0 == vec0.y);
|
||||
|
||||
REQUIRE(1 == vec1.x);
|
||||
REQUIRE(1 == vec1.y);
|
||||
|
||||
REQUIRE(1 == vec2.x);
|
||||
REQUIRE(1 == vec2.y);
|
||||
}
|
||||
|
||||
TEST_CASE("vec2f constructors")
|
||||
{
|
||||
Vec2f vec0;
|
||||
Vec2f vec1(1.0f, 1.0f);
|
||||
Vec2f vec2(vec1);
|
||||
|
||||
REQUIRE(0.0f == vec0.x);
|
||||
REQUIRE(0.0f == vec0.y);
|
||||
|
||||
REQUIRE(1.0f == vec1.x);
|
||||
REQUIRE(1.0f == vec1.y);
|
||||
|
||||
REQUIRE(1.0f == vec2.x);
|
||||
REQUIRE(1.0f == vec2.y);
|
||||
}
|
||||
|
||||
TEST_CASE("vector2 get length")
|
||||
{
|
||||
Vec2f vec0(3.0f, 3.0f);
|
||||
REQUIRE(18.0f == vec0.getLengthSquared());
|
||||
vec0.x = -3.0f;
|
||||
REQUIRE(18.0f == vec0.getLengthSquared());
|
||||
REQUIRE(std::sqrt(18.0f) == vec0.getLength());
|
||||
|
||||
Vec2i vec1(4, 2);
|
||||
REQUIRE(20.0f == vec1.getLengthSquared());
|
||||
REQUIRE(std::sqrt(20.0f) == vec1.getLength());
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("vector2 normalization")
|
||||
{
|
||||
Vec2f vec0(1.0f, 1.0f);
|
||||
|
||||
float targetXY = 1.0f / std::sqrt(2.0f);
|
||||
|
||||
REQUIRE(targetXY == Approx(vec0.normalized().x));
|
||||
REQUIRE(targetXY == Approx(vec0.normalized().y));
|
||||
|
||||
vec0.normalize();
|
||||
REQUIRE(targetXY == Approx(vec0.x));
|
||||
REQUIRE(targetXY == Approx(vec0.y));
|
||||
|
||||
float x = 17.53f;
|
||||
float y = 42.42f;
|
||||
vec0.x = x;
|
||||
vec0.y = y;
|
||||
float targetX = x / std::sqrt(x * x + y * y);
|
||||
float targetY = y / std::sqrt(x * x + y * y);
|
||||
vec0.normalize();
|
||||
REQUIRE(targetX == Approx(vec0.x));
|
||||
REQUIRE(targetY == Approx(vec0.y));
|
||||
}
|
||||
|
||||
TEST_CASE("vector2 comparison")
|
||||
{
|
||||
Vec2i vec0(42, 24);
|
||||
Vec2i vec1(42, 24);
|
||||
Vec2i vec2(69, 96);
|
||||
|
||||
REQUIRE(true == vec0.isEqual(vec1));
|
||||
REQUIRE(false == vec0.isEqual(vec2));
|
||||
REQUIRE(true == vec0.isSame(vec0));
|
||||
REQUIRE(false == vec0.isSame(vec1));
|
||||
|
||||
Vec2f vec3(42.0f, 24.0f);
|
||||
Vec2f vec4(42.0f, 24.0f);
|
||||
Vec2f vec5(69.0f, 96.0f);
|
||||
|
||||
REQUIRE(true == vec3.isEqual(vec4));
|
||||
REQUIRE(false == vec3.isEqual(vec5));
|
||||
REQUIRE(true == vec3.isSame(vec3));
|
||||
REQUIRE(false == vec3.isSame(vec4));
|
||||
}
|
||||
|
||||
TEST_CASE("vector2 comparison operators")
|
||||
{
|
||||
Vec2i vec0(42, 24);
|
||||
Vec2i vec1(42, 24);
|
||||
Vec2i vec2(69, 96);
|
||||
|
||||
REQUIRE(true == (vec0 == vec0));
|
||||
REQUIRE(true == (vec0 == vec1));
|
||||
REQUIRE(false == (vec0 == vec2));
|
||||
REQUIRE(false == (vec0 != vec0));
|
||||
REQUIRE(false == (vec0 != vec1));
|
||||
REQUIRE(true == (vec0 != vec2));
|
||||
|
||||
Vec2f vec3(42.0f, 24.0f);
|
||||
Vec2f vec4(42.0f, 24.0f);
|
||||
Vec2f vec5(69.0f, 96.0f);
|
||||
|
||||
REQUIRE(true == (vec3 == vec3));
|
||||
REQUIRE(true == (vec3 == vec4));
|
||||
REQUIRE(false == (vec3 == vec5));
|
||||
REQUIRE(false == (vec3 != vec3));
|
||||
REQUIRE(false == (vec3 != vec4));
|
||||
REQUIRE(true == (vec3 != vec5));
|
||||
}
|
||||
|
||||
TEST_CASE("assignment operator")
|
||||
{
|
||||
Vec2i vec0(42, 24);
|
||||
Vec2i vec1(69, 96);
|
||||
|
||||
vec1 = vec0;
|
||||
REQUIRE(42 == vec1.x);
|
||||
REQUIRE(24 == vec1.y);
|
||||
REQUIRE(true == vec0.isEqual(vec1));
|
||||
REQUIRE(false == vec0.isSame(vec1));
|
||||
|
||||
Vec2i vec2(42, 24);
|
||||
Vec2i vec3(69, 96);
|
||||
|
||||
vec2 = vec3;
|
||||
REQUIRE(69 == vec2.x);
|
||||
REQUIRE(96 == vec2.y);
|
||||
REQUIRE(true == vec3.isEqual(vec2));
|
||||
REQUIRE(false == vec3.isSame(vec2));
|
||||
}
|
||||
|
||||
TEST_CASE("addition operators")
|
||||
{
|
||||
Vec2i vec0(-2, 2);
|
||||
Vec2i vec1(3, -3);
|
||||
Vec2i vec2 = vec0 + vec1;
|
||||
|
||||
REQUIRE(1 == vec2.x);
|
||||
REQUIRE(-1 == vec2.y);
|
||||
|
||||
REQUIRE(-2 == vec0.x);
|
||||
REQUIRE(2 == vec0.y);
|
||||
REQUIRE(3 == vec1.x);
|
||||
REQUIRE(-3 == vec1.y);
|
||||
|
||||
vec0 += vec1;
|
||||
REQUIRE(1 == vec0.x);
|
||||
REQUIRE(-1 == vec0.y);
|
||||
}
|
||||
|
||||
TEST_CASE("subtraction operators")
|
||||
{
|
||||
Vec2f vec0(-2.0f, 2.0f);
|
||||
Vec2f vec1(3.0f, -3.0f);
|
||||
Vec2f vec2 = vec0 - vec1;
|
||||
|
||||
REQUIRE(-5.0f == vec2.x);
|
||||
REQUIRE(5.0f == vec2.y);
|
||||
|
||||
REQUIRE(-2.0f == vec0.x);
|
||||
REQUIRE(2.0f == vec0.y);
|
||||
REQUIRE(3.0f == vec1.x);
|
||||
REQUIRE(-3.0f == vec1.y);
|
||||
|
||||
vec0 -= vec1;
|
||||
REQUIRE(-5.0f == vec0.x);
|
||||
REQUIRE(5.0f == vec0.y);
|
||||
}
|
||||
|
||||
TEST_CASE("scalar multiplication operators")
|
||||
{
|
||||
Vec2f vec0(-2.0f, 2.0f);
|
||||
Vec2f vec1 = vec0 * 42.0f;
|
||||
|
||||
REQUIRE(-84.0f == vec1.x);
|
||||
REQUIRE(84.0f == vec1.y);
|
||||
|
||||
REQUIRE(-2.0f == vec0.x);
|
||||
REQUIRE(2.0f == vec0.y);
|
||||
|
||||
vec0 *= 42.0f;
|
||||
|
||||
REQUIRE(-84.0f == vec0.x);
|
||||
REQUIRE(84.0f == vec0.y);
|
||||
|
||||
Vec2i vec2(-2, 2);
|
||||
Vec2i vec3 = vec2 * 42.4f;
|
||||
|
||||
REQUIRE(-84 == (int)vec3.x);
|
||||
REQUIRE(84 == (int)vec3.y);
|
||||
|
||||
Vec2i vec3b = vec2 * 42.5f;
|
||||
|
||||
REQUIRE(-85 == (int)vec3b.x);
|
||||
REQUIRE(85 == (int)vec3b.y);
|
||||
|
||||
REQUIRE(-2 == vec2.x);
|
||||
REQUIRE(2 == vec2.y);
|
||||
|
||||
vec2 *= 42;
|
||||
REQUIRE(-84 == vec2.x);
|
||||
REQUIRE(84 == vec2.y);
|
||||
|
||||
vec2 *= 0.5f;
|
||||
REQUIRE(-42 == vec2.x);
|
||||
REQUIRE(42 == vec2.y);
|
||||
}
|
||||
|
||||
TEST_CASE("dot product operator")
|
||||
{
|
||||
Vec2f vec0(2.0f, 4.0f);
|
||||
Vec2f vec1(3.0f, 6.0f);
|
||||
Vec2f vec2(-2.0f, -1.0f);
|
||||
|
||||
REQUIRE(30.0f == vec0.dotProduct(vec1));
|
||||
REQUIRE(-8.0f == vec0.dotProduct(vec2));
|
||||
|
||||
Vec2f vec3(2, 4);
|
||||
Vec2f vec4(3, 6);
|
||||
Vec2f vec5(-2, -1);
|
||||
|
||||
REQUIRE(30 == vec3.dotProduct(vec4));
|
||||
REQUIRE(-8 == vec3.dotProduct(vec5));
|
||||
}
|
||||
|
||||
TEST_CASE("scalar division operators")
|
||||
{
|
||||
Vec2f vec0(42.0f, 24.0f);
|
||||
Vec2f vec1 = vec0 / 2.0f;
|
||||
Vec2f vec2 = vec0 / 0.5f;
|
||||
|
||||
REQUIRE(42.0f == vec0.x);
|
||||
REQUIRE(24.0f == vec0.y);
|
||||
REQUIRE(21.0f == vec1.x);
|
||||
REQUIRE(12.0f == vec1.y);
|
||||
REQUIRE(84.0f == vec2.x);
|
||||
REQUIRE(48.0f == vec2.y);
|
||||
|
||||
vec0 /= 2.0f;
|
||||
REQUIRE(21.0f == vec0.x);
|
||||
REQUIRE(12.0f == vec0.y);
|
||||
|
||||
Vec2i vec3(42, 24);
|
||||
Vec2i vec4 = vec3 / 2;
|
||||
|
||||
REQUIRE(42 == vec3.x);
|
||||
REQUIRE(24 == vec3.y);
|
||||
REQUIRE(21 == vec4.x);
|
||||
REQUIRE(12 == vec4.y);
|
||||
|
||||
vec3 /= 2;
|
||||
REQUIRE(21 == vec3.x);
|
||||
REQUIRE(12 == vec3.y);
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "Vector2.h"
|
||||
|
||||
class Vector2TestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_vec2i_constructors()
|
||||
{
|
||||
Vec2i vec0;
|
||||
Vec2i vec1(1, 1);
|
||||
Vec2i vec2(vec1);
|
||||
|
||||
TS_ASSERT_EQUALS(0, vec0.x);
|
||||
TS_ASSERT_EQUALS(0, vec0.y);
|
||||
|
||||
TS_ASSERT_EQUALS(1, vec1.x);
|
||||
TS_ASSERT_EQUALS(1, vec1.y);
|
||||
|
||||
TS_ASSERT_EQUALS(1, vec2.x);
|
||||
TS_ASSERT_EQUALS(1, vec2.y);
|
||||
}
|
||||
|
||||
void test_vec2f_constructors()
|
||||
{
|
||||
Vec2f vec0;
|
||||
Vec2f vec1(1.0f, 1.0f);
|
||||
Vec2f vec2(vec1);
|
||||
|
||||
TS_ASSERT_EQUALS(0.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(0.0f, vec0.y);
|
||||
|
||||
TS_ASSERT_EQUALS(1.0f, vec1.x);
|
||||
TS_ASSERT_EQUALS(1.0f, vec1.y);
|
||||
|
||||
TS_ASSERT_EQUALS(1.0f, vec2.x);
|
||||
TS_ASSERT_EQUALS(1.0f, vec2.y);
|
||||
}
|
||||
|
||||
void test_vector2_get_length()
|
||||
{
|
||||
Vec2f vec0(3.0f, 3.0f);
|
||||
TS_ASSERT_EQUALS(18.0f, vec0.getLengthSquared());
|
||||
vec0.x = -3.0f;
|
||||
TS_ASSERT_EQUALS(18.0f, vec0.getLengthSquared());
|
||||
TS_ASSERT_EQUALS(std::sqrt(18.0f), vec0.getLength());
|
||||
|
||||
Vec2i vec1(4, 2);
|
||||
TS_ASSERT_EQUALS(20.0f, vec1.getLengthSquared());
|
||||
TS_ASSERT_EQUALS(std::sqrt(20.0f), vec1.getLength());
|
||||
}
|
||||
|
||||
|
||||
void test_vector2_normalization()
|
||||
{
|
||||
Vec2f vec0(1.0f, 1.0f);
|
||||
|
||||
float targetXY = 1.0f / std::sqrt(2.0f);
|
||||
|
||||
TS_ASSERT_DELTA(targetXY, vec0.normalized().x, 1e-7);
|
||||
TS_ASSERT_DELTA(targetXY, vec0.normalized().y, 1e-7);
|
||||
|
||||
vec0.normalize();
|
||||
TS_ASSERT_DELTA(targetXY, vec0.x, 1e-7);
|
||||
TS_ASSERT_DELTA(targetXY, vec0.y, 1e-7);
|
||||
|
||||
float x = 17.53f;
|
||||
float y = 42.42f;
|
||||
vec0.x = x;
|
||||
vec0.y = y;
|
||||
float targetX = x / std::sqrt(x * x + y * y);
|
||||
float targetY = y / std::sqrt(x * x + y * y);
|
||||
vec0.normalize();
|
||||
TS_ASSERT_DELTA(targetX, vec0.x, 1e-7);
|
||||
TS_ASSERT_DELTA(targetY, vec0.y, 1e-7);
|
||||
}
|
||||
|
||||
void test_vector2_comparison()
|
||||
{
|
||||
Vec2i vec0(42, 24);
|
||||
Vec2i vec1(42, 24);
|
||||
Vec2i vec2(69, 96);
|
||||
|
||||
TS_ASSERT_EQUALS(true, vec0.isEqual(vec1));
|
||||
TS_ASSERT_EQUALS(false, vec0.isEqual(vec2));
|
||||
TS_ASSERT_EQUALS(true, vec0.isSame(vec0));
|
||||
TS_ASSERT_EQUALS(false, vec0.isSame(vec1));
|
||||
|
||||
Vec2f vec3(42.0f, 24.0f);
|
||||
Vec2f vec4(42.0f, 24.0f);
|
||||
Vec2f vec5(69.0f, 96.0f);
|
||||
|
||||
TS_ASSERT_EQUALS(true, vec3.isEqual(vec4));
|
||||
TS_ASSERT_EQUALS(false, vec3.isEqual(vec5));
|
||||
TS_ASSERT_EQUALS(true, vec3.isSame(vec3));
|
||||
TS_ASSERT_EQUALS(false, vec3.isSame(vec4));
|
||||
}
|
||||
|
||||
void test_vector2_comparison_operators()
|
||||
{
|
||||
Vec2i vec0(42, 24);
|
||||
Vec2i vec1(42, 24);
|
||||
Vec2i vec2(69, 96);
|
||||
|
||||
TS_ASSERT_EQUALS(true, vec0 == vec0);
|
||||
TS_ASSERT_EQUALS(true, vec0 == vec1);
|
||||
TS_ASSERT_EQUALS(false, vec0 == vec2);
|
||||
TS_ASSERT_EQUALS(false, vec0 != vec0);
|
||||
TS_ASSERT_EQUALS(false, vec0 != vec1);
|
||||
TS_ASSERT_EQUALS(true, vec0 != vec2);
|
||||
|
||||
Vec2f vec3(42.0f, 24.0f);
|
||||
Vec2f vec4(42.0f, 24.0f);
|
||||
Vec2f vec5(69.0f, 96.0f);
|
||||
|
||||
TS_ASSERT_EQUALS(true, vec3 == vec3);
|
||||
TS_ASSERT_EQUALS(true, vec3 == vec4);
|
||||
TS_ASSERT_EQUALS(false, vec3 == vec5);
|
||||
TS_ASSERT_EQUALS(false, vec3 != vec3);
|
||||
TS_ASSERT_EQUALS(false, vec3 != vec4);
|
||||
TS_ASSERT_EQUALS(true, vec3 != vec5);
|
||||
}
|
||||
|
||||
void test_assignment_operator()
|
||||
{
|
||||
Vec2i vec0(42, 24);
|
||||
Vec2i vec1(69, 96);
|
||||
|
||||
vec1 = vec0;
|
||||
TS_ASSERT_EQUALS(42, vec1.x);
|
||||
TS_ASSERT_EQUALS(24, vec1.y);
|
||||
TS_ASSERT_EQUALS(true, vec0.isEqual(vec1));
|
||||
TS_ASSERT_EQUALS(false, vec0.isSame(vec1));
|
||||
|
||||
Vec2i vec2(42, 24);
|
||||
Vec2i vec3(69, 96);
|
||||
|
||||
vec2 = vec3;
|
||||
TS_ASSERT_EQUALS(69, vec2.x);
|
||||
TS_ASSERT_EQUALS(96, vec2.y);
|
||||
TS_ASSERT_EQUALS(true, vec3.isEqual(vec2));
|
||||
TS_ASSERT_EQUALS(false, vec3.isSame(vec2));
|
||||
}
|
||||
|
||||
void test_addition_operators()
|
||||
{
|
||||
Vec2i vec0(-2, 2);
|
||||
Vec2i vec1(3, -3);
|
||||
Vec2i vec2 = vec0 + vec1;
|
||||
|
||||
TS_ASSERT_EQUALS(1, vec2.x);
|
||||
TS_ASSERT_EQUALS(-1, vec2.y);
|
||||
|
||||
TS_ASSERT_EQUALS(-2, vec0.x);
|
||||
TS_ASSERT_EQUALS(2, vec0.y);
|
||||
TS_ASSERT_EQUALS(3, vec1.x);
|
||||
TS_ASSERT_EQUALS(-3, vec1.y);
|
||||
|
||||
vec0 += vec1;
|
||||
TS_ASSERT_EQUALS(1, vec0.x);
|
||||
TS_ASSERT_EQUALS(-1, vec0.y);
|
||||
}
|
||||
|
||||
void test_subtraction_operators()
|
||||
{
|
||||
Vec2f vec0(-2.0f, 2.0f);
|
||||
Vec2f vec1(3.0f, -3.0f);
|
||||
Vec2f vec2 = vec0 - vec1;
|
||||
|
||||
TS_ASSERT_EQUALS(-5.0f, vec2.x);
|
||||
TS_ASSERT_EQUALS(5.0f, vec2.y);
|
||||
|
||||
TS_ASSERT_EQUALS(-2.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(2.0f, vec0.y);
|
||||
TS_ASSERT_EQUALS(3.0f, vec1.x);
|
||||
TS_ASSERT_EQUALS(-3.0f, vec1.y);
|
||||
|
||||
vec0 -= vec1;
|
||||
TS_ASSERT_EQUALS(-5.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(5.0f, vec0.y);
|
||||
}
|
||||
|
||||
void test_scalar_multiplication_operators()
|
||||
{
|
||||
Vec2f vec0(-2.0f, 2.0f);
|
||||
Vec2f vec1 = vec0 * 42.0f;
|
||||
|
||||
TS_ASSERT_EQUALS(-84.0f, vec1.x);
|
||||
TS_ASSERT_EQUALS(84.0f, vec1.y);
|
||||
|
||||
TS_ASSERT_EQUALS(-2.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(2.0f, vec0.y);
|
||||
|
||||
vec0 *= 42.0f;
|
||||
|
||||
TS_ASSERT_EQUALS(-84.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(84.0f, vec0.y);
|
||||
|
||||
Vec2i vec2(-2, 2);
|
||||
Vec2i vec3 = vec2 * 42.4f;
|
||||
|
||||
TS_ASSERT_EQUALS(-84, (int)vec3.x);
|
||||
TS_ASSERT_EQUALS(84, (int)vec3.y);
|
||||
|
||||
Vec2i vec3b = vec2 * 42.5f;
|
||||
|
||||
TS_ASSERT_EQUALS(-85, (int)vec3b.x);
|
||||
TS_ASSERT_EQUALS(85, (int)vec3b.y);
|
||||
|
||||
TS_ASSERT_EQUALS(-2, vec2.x);
|
||||
TS_ASSERT_EQUALS(2, vec2.y);
|
||||
|
||||
vec2 *= 42;
|
||||
TS_ASSERT_EQUALS(-84, vec2.x);
|
||||
TS_ASSERT_EQUALS(84, vec2.y);
|
||||
|
||||
vec2 *= 0.5f;
|
||||
TS_ASSERT_EQUALS(-42, vec2.x);
|
||||
TS_ASSERT_EQUALS(42, vec2.y);
|
||||
}
|
||||
|
||||
void test_dot_product_operator()
|
||||
{
|
||||
Vec2f vec0(2.0f, 4.0f);
|
||||
Vec2f vec1(3.0f, 6.0f);
|
||||
Vec2f vec2(-2.0f, -1.0f);
|
||||
|
||||
TS_ASSERT_EQUALS(30.0f, vec0.dotProduct(vec1));
|
||||
TS_ASSERT_EQUALS(-8.0f, vec0.dotProduct(vec2));
|
||||
|
||||
Vec2f vec3(2, 4);
|
||||
Vec2f vec4(3, 6);
|
||||
Vec2f vec5(-2, -1);
|
||||
|
||||
TS_ASSERT_EQUALS(30, vec3.dotProduct(vec4));
|
||||
TS_ASSERT_EQUALS(-8, vec3.dotProduct(vec5));
|
||||
}
|
||||
|
||||
void test_scalar_division_operators()
|
||||
{
|
||||
Vec2f vec0(42.0f, 24.0f);
|
||||
Vec2f vec1 = vec0 / 2.0f;
|
||||
Vec2f vec2 = vec0 / 0.5f;
|
||||
|
||||
TS_ASSERT_EQUALS(42.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(24.0f, vec0.y);
|
||||
TS_ASSERT_EQUALS(21.0f, vec1.x);
|
||||
TS_ASSERT_EQUALS(12.0f, vec1.y);
|
||||
TS_ASSERT_EQUALS(84.0f, vec2.x);
|
||||
TS_ASSERT_EQUALS(48.0f, vec2.y);
|
||||
|
||||
vec0 /= 2.0f;
|
||||
TS_ASSERT_EQUALS(21.0f, vec0.x);
|
||||
TS_ASSERT_EQUALS(12.0f, vec0.y);
|
||||
|
||||
Vec2i vec3(42, 24);
|
||||
Vec2i vec4 = vec3 / 2;
|
||||
|
||||
TS_ASSERT_EQUALS(42, vec3.x);
|
||||
TS_ASSERT_EQUALS(24, vec3.y);
|
||||
TS_ASSERT_EQUALS(21, vec4.x);
|
||||
TS_ASSERT_EQUALS(12, vec4.y);
|
||||
|
||||
vec3 /= 2;
|
||||
TS_ASSERT_EQUALS(21, vec3.x);
|
||||
TS_ASSERT_EQUALS(12, vec3.y);
|
||||
}
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
---------
|
||||
Debugging
|
||||
---------
|
||||
To debug unit tests remove the post-build event, set the execution directory for 'Coati_test' to '.../Coati/bin/test' and run 'Coati_test' as startup project
|
||||
|
||||
|
||||
Post build event (if you manage to delete it without saving it somewhere):
|
||||
|
||||
setlocal
|
||||
cd $(ProjectDir)../../bin/test/
|
||||
$(OutDir)$(TargetName)$(TargetExt)
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd
|
||||
@@ -0,0 +1,39 @@
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() function
|
||||
|
||||
#include "catch.hpp"
|
||||
// IMPORTANT NOTE: removed signal listener for "EXCEPTION_ACCESS_VIOLATION" from catch source code because it interferes with the jni interface that emits such a signal on purpose
|
||||
|
||||
#include "ApplicationSettings.h"
|
||||
|
||||
struct EventListener : Catch::TestEventListenerBase
|
||||
{
|
||||
using TestEventListenerBase::TestEventListenerBase; // inherit constructor
|
||||
|
||||
void testRunStarting(const Catch::TestRunInfo& testRunInfo) override
|
||||
{
|
||||
#ifdef __linux__
|
||||
const std::string homedir = getenv("HOME");
|
||||
|
||||
if (!homedir.empty())
|
||||
{
|
||||
if(!ApplicationSettings::getInstance()->load(
|
||||
FilePath(homedir + "/.config/sourcetrail/ApplicationSettings.xml")
|
||||
))
|
||||
{
|
||||
std::cout << "no settings" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "no homedir" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
ApplicationSettings::getInstance()->load(FilePath(L"data/TestSettings.xml"));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
CATCH_REGISTER_LISTENER(EventListener)
|
||||
Reference in New Issue
Block a user