src: replaced unit test framework CxxTest with Catch2

This commit is contained in:
mlangkabel
2019-10-29 19:54:16 +01:00
parent 48c4bddc1b
commit 49050e1089
82 changed files with 28319 additions and 14175 deletions
+2
View File
@@ -1,6 +1,8 @@
add_files(
EXTERNAL
catch/catch.hpp
sqlite/CppSQLite3.cpp
sqlite/CppSQLite3.h
+14361
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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);
}
+172
View File
@@ -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());
}
-174
View File
@@ -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);
}
};
+145
View File
@@ -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()
));
}
-149
View File
@@ -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
}
-223
View File
@@ -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
+39
View File
@@ -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());
}
-43
View File
@@ -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());
}
};
+42
View File
@@ -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 (...)
{
}
}
-45
View File
@@ -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 (...)
{
}
}
};
+123
View File
@@ -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")));
}
-127
View File
@@ -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")));
}
};
+212
View File
@@ -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);
}
-216
View File
@@ -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);
}
};
+133
View File
@@ -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
}
-135
View File
@@ -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;
}
};
+341
View File
@@ -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());
}
-343
View File
@@ -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
);
}
-289
View File
@@ -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
+289
View File
@@ -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());
}
-291
View File
@@ -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++;
}
+161
View File
@@ -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());
}
-165
View File
@@ -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());
}
};
+470
View File
@@ -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]);
}
-473
View File
@@ -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);
}
};
+60
View File
@@ -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));
}
-62
View File
@@ -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;
}
};
+246
View File
@@ -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);
}
-249
View File
@@ -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);
}
-68
View File
@@ -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
+91
View File
@@ -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);
}
-97
View File
@@ -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);
}
};
+381
View File
@@ -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());
}
-383
View File
@@ -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));
}
};
+215
View File
@@ -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/");
}
-217
View File
@@ -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);
}
};
};
+95
View File
@@ -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++;
}
}
}
-98
View File
@@ -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++;
}
}
}
};
+619
View File
@@ -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());
}
-622
View File
@@ -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(
[&copy, 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(
[&copy, 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());
}
};
+105
View File
@@ -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);
}
-110
View File
@@ -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);
}
};
+78
View File
@@ -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);
}
-83
View File
@@ -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);
}
};
+273
View File
@@ -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));
}
-284
View File
@@ -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;
};
+283
View File
@@ -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);
}
-286
View File
@@ -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());
}
};
-46
View File
@@ -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;
}
-20
View File
@@ -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
+144
View File
@@ -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);
}
-146
View File
@@ -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;
}
};
+112
View File
@@ -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()
));
}
}
-115
View File
@@ -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()
));
}
}
};
+302
View File
@@ -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"));
}
-306
View File
@@ -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"));
}
};
+13
View File
@@ -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");
}
-17
View File
@@ -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");
}
};
+264
View File
@@ -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);
}
-268
View File
@@ -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);
}
};
-18
View File
@@ -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
+39
View File
@@ -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)