#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) { 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( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes name") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "int")); migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes path") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " \n" " 2\n" " \n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "sub/int")); migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes group name") { TestSettings settingsBefore = createSettings( "\n" "\n" " \n" " 2\n" " 3\n" " 4\n" " \n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " \n" " 2\n" " 3\n" " 4\n" " \n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("values/value", "vals/value")); migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes group element name") { TestSettings settingsBefore = createSettings( "\n" "\n" " \n" " 2\n" " 3\n" " 4\n" " \n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " \n" " 2\n" " 3\n" " 4\n" " \n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("values/value", "values/val")); migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes only up specified version") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "int")); migrator.addMigration(2, std::make_shared("int", "val")); migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes only from specified version") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" " 1\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " 2\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "int")); migrator.addMigration(2, std::make_shared("int", "val")); migrator.migrate(&settingsBefore, 2); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes for multiple versions") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " 2\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "int")); migrator.addMigration(2, std::make_shared("int", "val")); migrator.migrate(&settingsBefore, 2); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes for multiple migrations") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" " hi there\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " hi there\n" " 2\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "val")); migrator.addMigration(1, std::make_shared("element", "ele")); migrator.migrate(&settingsBefore, 2); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator changes for multiple versions and migrations") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" " two\n" " three\n" " four\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 2\n" " \n" " two\n" " three\n" " four\n" " \n" " 3\n" "\n" ); SettingsMigrator migrator; migrator.addMigration(1, std::make_shared("value", "int/val")); migrator.addMigration(1, std::make_shared("element", "ele")); migrator.addMigration(2, std::make_shared("int/val", "int")); migrator.addMigration(3, std::make_shared("ele", "elements/element")); migrator.migrate(&settingsBefore, 3); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator with lambda") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 4\n" " 1\n" "\n" ); SettingsMigrator migrator; migrator.addMigration( 1, std::make_shared( [](const SettingsMigration* migration, Settings* settings) { migration->setValueInSettings(settings, "value", migration->getValueFromSettings(settings, "value", 0) * 2); } )); migrator.migrate(&settingsBefore, 1); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); } TEST_CASE("migrator with multiple lambdas") { TestSettings settingsBefore = createSettings( "\n" "\n" " 2\n" "\n" ); TestSettings settingsAfter = createSettings( "\n" "\n" " 3\n" " 2\n" "\n" ); SettingsMigrator migrator; migrator.addMigration( 1, std::make_shared( [](const SettingsMigration* migration, Settings* settings) { migration->setValueInSettings(settings, "value", migration->getValueFromSettings(settings, "value", 0) * 2); } ) ); migrator.addMigration( 2, std::make_shared( [](const SettingsMigration* migration, Settings* settings) { migration->setValueInSettings(settings, "value", migration->getValueFromSettings(settings, "value", 0) - 1); } ) ); migrator.migrate(&settingsBefore, 2); REQUIRE(settingsBefore.getAsText() == settingsAfter.getAsText()); }