mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 22:26:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			374 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			374 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <components/settings/parser.hpp>
 | |
| 
 | |
| #include <fstream>
 | |
| 
 | |
| #include <gtest/gtest.h>
 | |
| 
 | |
| #include "../testing_util.hpp"
 | |
| 
 | |
| namespace
 | |
| {
 | |
|     using namespace testing;
 | |
|     using namespace Settings;
 | |
| 
 | |
|     struct SettingsFileParserTest : Test
 | |
|     {
 | |
|         SettingsFileParser mLoader;
 | |
|         SettingsFileParser mSaver;
 | |
| 
 | |
|         template <typename F>
 | |
|         void withSettingsFile(const std::string& content, F&& f)
 | |
|         {
 | |
|             auto path = TestingOpenMW::outputFilePath(
 | |
|                 std::string(UnitTest::GetInstance()->current_test_info()->name()) + ".cfg");
 | |
| 
 | |
|             {
 | |
|                 std::ofstream stream(path);
 | |
|                 stream << content;
 | |
|                 stream.close();
 | |
|             }
 | |
| 
 | |
|             f(path);
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, load_empty_file)
 | |
|     {
 | |
|         const std::string content;
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap());
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_single_empty_section)
 | |
|     {
 | |
|         const std::string content = "[Section]\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap());
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_single_section_and_key)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key = value\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), "value" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_single_section_and_key_and_line_comments)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "# foo\n"
 | |
|               "[Section]\n"
 | |
|               "# bar\n"
 | |
|               "key = value\n"
 | |
|               "# baz\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), "value" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_single_section_and_key_file_and_inline_section_comment)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section] # foo\n"
 | |
|               "key = value\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             EXPECT_THROW(mLoader.loadSettingsFile(path, map), std::runtime_error);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_single_section_and_key_and_inline_key_comment)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key = value # foo\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), "value # foo" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_single_section_and_key_and_whitespaces)
 | |
|     {
 | |
|         const std::string content
 | |
|             = " [ Section ] \n"
 | |
|               " key = value \n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), "value" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_quoted_string_value)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               R"(key = "value")";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), R"("value")" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_quoted_string_value_and_eol)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               R"(key = "value"\n)";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), R"("value"\n)" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_empty_value)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key =\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), "" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_empty_key)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "=\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", ""), "" } }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_multiple_keys)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key1 = value1\n"
 | |
|               "key2 = value2\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map,
 | |
|                 CategorySettingValueMap({
 | |
|                     { CategorySetting("Section", "key1"), "value1" },
 | |
|                     { CategorySetting("Section", "key2"), "value2" },
 | |
|                 }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_multiple_sections)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section1]\n"
 | |
|               "key1 = value1\n"
 | |
|               "[Section2]\n"
 | |
|               "key2 = value2\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map,
 | |
|                 CategorySettingValueMap({
 | |
|                     { CategorySetting("Section1", "key1"), "value1" },
 | |
|                     { CategorySetting("Section2", "key2"), "value2" },
 | |
|                 }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_multiple_sections_and_keys)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section1]\n"
 | |
|               "key1 = value1\n"
 | |
|               "key2 = value2\n"
 | |
|               "[Section2]\n"
 | |
|               "key3 = value3\n"
 | |
|               "key4 = value4\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map,
 | |
|                 CategorySettingValueMap({
 | |
|                     { CategorySetting("Section1", "key1"), "value1" },
 | |
|                     { CategorySetting("Section1", "key2"), "value2" },
 | |
|                     { CategorySetting("Section2", "key3"), "value3" },
 | |
|                     { CategorySetting("Section2", "key4"), "value4" },
 | |
|                 }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_repeated_sections)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key1 = value1\n"
 | |
|               "[Section]\n"
 | |
|               "key2 = value2\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map,
 | |
|                 CategorySettingValueMap({
 | |
|                     { CategorySetting("Section", "key1"), "value1" },
 | |
|                     { CategorySetting("Section", "key2"), "value2" },
 | |
|                 }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_repeated_keys)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key = value\n"
 | |
|               "key = value\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             EXPECT_THROW(mLoader.loadSettingsFile(path, map), std::runtime_error);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_repeated_keys_in_differrent_sections)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section1]\n"
 | |
|               "key = value\n"
 | |
|               "[Section2]\n"
 | |
|               "key = value\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map,
 | |
|                 CategorySettingValueMap({
 | |
|                     { CategorySetting("Section1", "key"), "value" },
 | |
|                     { CategorySetting("Section2", "key"), "value" },
 | |
|                 }));
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_unterminated_section)
 | |
|     {
 | |
|         const std::string content = "[Section";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             EXPECT_THROW(mLoader.loadSettingsFile(path, map), std::runtime_error);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_single_empty_section_name)
 | |
|     {
 | |
|         const std::string content = "[]\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap());
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_key_and_without_section)
 | |
|     {
 | |
|         const std::string content = "key = value\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             EXPECT_THROW(mLoader.loadSettingsFile(path, map), std::runtime_error);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_key_in_empty_name_section)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[]"
 | |
|               "key = value\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             EXPECT_THROW(mLoader.loadSettingsFile(path, map), std::runtime_error);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_unterminated_key)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "[Section]\n"
 | |
|               "key\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             EXPECT_THROW(mLoader.loadSettingsFile(path, map), std::runtime_error);
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     TEST_F(SettingsFileParserTest, file_with_empty_lines)
 | |
|     {
 | |
|         const std::string content
 | |
|             = "\n"
 | |
|               "[Section]\n"
 | |
|               "\n"
 | |
|               "key = value\n"
 | |
|               "\n";
 | |
| 
 | |
|         withSettingsFile(content, [this](const auto& path) {
 | |
|             CategorySettingValueMap map;
 | |
|             mLoader.loadSettingsFile(path, map);
 | |
| 
 | |
|             EXPECT_EQ(map, CategorySettingValueMap({ { CategorySetting("Section", "key"), "value" } }));
 | |
|         });
 | |
|     }
 | |
| }
 |