diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 715ed6177033..8bde75d3642b 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -146,30 +146,30 @@ const PackedStringArray ProjectSettings::_trim_to_supported_features(const Packe #endif // TOOLS_ENABLED String ProjectSettings::localize_path(const String &p_path) const { - if (resource_path.is_empty() || (p_path.is_absolute_path() && !p_path.begins_with(resource_path))) { - return p_path.simplify_path(); + String path = p_path.simplify_path(); + + if (resource_path.is_empty() || (path.is_absolute_path() && !path.begins_with(resource_path))) { + return path; } // Check if we have a special path (like res://) or a protocol identifier. - int p = p_path.find("://"); + int p = path.find("://"); bool found = false; if (p > 0) { found = true; for (int i = 0; i < p; i++) { - if (!is_ascii_alphanumeric_char(p_path[i])) { + if (!is_ascii_alphanumeric_char(path[i])) { found = false; break; } } } if (found) { - return p_path.simplify_path(); + return path; } Ref dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - String path = p_path.replace("\\", "/").simplify_path(); - if (dir->change_dir(path) == OK) { String cwd = dir->get_current_dir(); cwd = cwd.replace("\\", "/"); @@ -187,7 +187,7 @@ String ProjectSettings::localize_path(const String &p_path) const { cwd = cwd.path_join(""); if (!cwd.begins_with(res_path)) { - return p_path; + return path; } return cwd.replace_first(res_path, "res://"); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index b89e6694b0c6..a1f52fa1e0eb 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -43,6 +43,7 @@ class TypedArray; class ProjectSettings : public Object { GDCLASS(ProjectSettings, Object); _THREAD_SAFE_CLASS_ + friend class TestProjectSettingsInternalsAccessor; public: typedef HashMap CustomMap; diff --git a/tests/core/config/test_project_settings.h b/tests/core/config/test_project_settings.h index 1deafccde1a7..9bd072f51112 100644 --- a/tests/core/config/test_project_settings.h +++ b/tests/core/config/test_project_settings.h @@ -32,9 +32,17 @@ #define TEST_PROJECT_SETTINGS_H #include "core/config/project_settings.h" +#include "core/io/dir_access.h" #include "core/variant/variant.h" #include "tests/test_macros.h" +class TestProjectSettingsInternalsAccessor { +public: + static String &resource_path() { + return ProjectSettings::get_singleton()->resource_path; + }; +}; + namespace TestProjectSettings { TEST_CASE("[ProjectSettings] Get existing setting") { @@ -97,6 +105,58 @@ TEST_CASE("[ProjectSettings] Set value should be returned when retrieved") { CHECK(ProjectSettings::get_singleton()->has_setting("my_custom_setting")); } +TEST_CASE("[ProjectSettings] localize_path") { + String old_resource_path = TestProjectSettingsInternalsAccessor::resource_path(); + TestProjectSettingsInternalsAccessor::resource_path() = DirAccess::create(DirAccess::ACCESS_FILESYSTEM)->get_current_dir(); + String root_path = ProjectSettings::get_singleton()->get_resource_path(); +#ifdef WINDOWS_ENABLED + String root_path_win = ProjectSettings::get_singleton()->get_resource_path().replace("/", "\\"); +#endif + + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("filename"), "res://filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("path/filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("path/something/../filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("path/./filename"), "res://path/filename"); +#ifdef WINDOWS_ENABLED + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("path\\filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("path\\something\\..\\filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("path\\.\\filename"), "res://path/filename"); +#endif + + // FIXME?: These checks pass, but that doesn't seems correct + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("../filename"), "res://filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("../path/filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("..\\path\\filename"), "res://path/filename"); + + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("/testroot/filename"), "/testroot/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("/testroot/path/filename"), "/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("/testroot/path/something/../filename"), "/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("/testroot/path/./filename"), "/testroot/path/filename"); +#ifdef WINDOWS_ENABLED + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:/testroot/filename"), "C:/testroot/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:/testroot/path/filename"), "C:/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:/testroot/path/something/../filename"), "C:/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:/testroot/path/./filename"), "C:/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:\\testroot\\filename"), "C:/testroot/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:\\testroot\\path\\filename"), "C:/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:\\testroot\\path\\something\\..\\filename"), "C:/testroot/path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path("C:\\testroot\\path\\.\\filename"), "C:/testroot/path/filename"); +#endif + + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path + "/filename"), "res://filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path + "/path/filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path + "/path/something/../filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path + "/path/./filename"), "res://path/filename"); +#ifdef WINDOWS_ENABLED + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path_win + "\\filename"), "res://filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path_win + "\\path\\filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path_win + "\\path\\something\\..\\filename"), "res://path/filename"); + CHECK_EQ(ProjectSettings::get_singleton()->localize_path(root_path_win + "\\path\\.\\filename"), "res://path/filename"); +#endif + + TestProjectSettingsInternalsAccessor::resource_path() = old_resource_path; +} + } // namespace TestProjectSettings #endif // TEST_PROJECT_SETTINGS_H