mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 05:26:39 +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" } }));
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 |