From caf2805095a54872c9454bd0348e0ac5d9b390f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jason=20Mar=C3=A9chal?= <45510813+JasonMarechal25@users.noreply.github.com> Date: Tue, 23 Jul 2024 09:41:39 +0200 Subject: [PATCH] [ANT-1890] Properly handle playlist_reset in generaldata.ini (#879) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #864 Properly handle data and avoid exception thrown when reading not numerical values with stoi when reading "playlist_reset" entry in general_data.ini --------- Co-authored-by: Florian Omnès --- .../input_reader/GeneralDataReader.cpp | 46 +++++++++++++++++-- .../lpnamer/input_reader/GeneralDataReader.h | 21 +-------- tests/cpp/lp_namer/CMakeLists.txt | 1 + tests/cpp/lp_namer/GeneralDataReadetTests.cpp | 42 +++++++++++++++++ 4 files changed, 86 insertions(+), 24 deletions(-) create mode 100644 tests/cpp/lp_namer/GeneralDataReadetTests.cpp diff --git a/src/cpp/lpnamer/input_reader/GeneralDataReader.cpp b/src/cpp/lpnamer/input_reader/GeneralDataReader.cpp index 94c8ea7d0..361fe2351 100644 --- a/src/cpp/lpnamer/input_reader/GeneralDataReader.cpp +++ b/src/cpp/lpnamer/input_reader/GeneralDataReader.cpp @@ -1,8 +1,38 @@ #include "GeneralDataReader.h" +#include +#include +#include #include +#include +#include +#include +#include +#include "INIReader.h" #include "LogUtils.h" +#include "ProblemGenerationLogger.h" +#include "StringManip.h" +class IniReaderUtils { + public: + static bool LineIsNotASectionHeader(const std::string& line) { + return StringManip::split(StringManip::trim(line), '=').size() == 2; + } + + static std::string ReadSectionHeader(const std::string& line) { + auto str = StringManip::trim(line); + str.erase(std::remove(str.begin(), str.end(), '['), str.end()); + str.erase(std::remove(str.begin(), str.end(), ']'), str.end()); + return str; + } + + static std::pair GetKeyValFromLine(std::string_view line) { + const auto splitLine = StringManip::split(line, '='); + auto key = StringManip::trim(splitLine[0]); + auto val = std::stoi(StringManip::trim(splitLine[1])); + return {key, val}; + } +}; GeneralDataIniReader::GeneralDataIniReader( const std::filesystem::path& file_path, ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger) @@ -52,7 +82,7 @@ std::vector GeneralDataIniReader::GetActiveYears_() { std::vector GeneralDataIniReader::ActiveYearsFromActiveList() { std::vector active_years; for (auto year = 0; year < mc_years_; year++) { - if (std::find(active_year_list_.begin(), active_year_list_.end(), year) != + if (std::ranges::find(active_year_list_, year) != active_year_list_.end()) { active_years.push_back(year + 1); } @@ -63,7 +93,7 @@ std::vector GeneralDataIniReader::ActiveYearsFromActiveList() { std::vector GeneralDataIniReader::ActiveYearsFromInactiveList() { std::vector active_years; for (auto year = 0; year < mc_years_; year++) { - if (std::find(inactive_year_list_.begin(), inactive_year_list_.end(), + if (std::ranges::find(inactive_year_list_, year) == inactive_year_list_.end()) { active_years.push_back(year + 1); } @@ -79,6 +109,9 @@ GeneralDataIniReader::GetRawPlaylist() { for (const auto& line : file_lines_) { if (IniReaderUtils::LineIsNotASectionHeader(line)) { if (current_section == "playlist") { + if (line.find("playlist_reset") != std::string::npos) { + continue; + } auto [key, val] = IniReaderUtils::GetKeyValFromLine(line); ReadPlaylistVal(key, val); } @@ -104,14 +137,19 @@ std::string GeneralDataIniReader::ReadPlaylist( const std::string& current_section, const std::string& line) { if (IniReaderUtils::LineIsNotASectionHeader(line)) { if (current_section == "playlist") { - auto [key, val] = IniReaderUtils::GetKeyValFromLine(line); - ReadPlaylistVal(key, val); + ReadPlaylist(line); } } else { return IniReaderUtils::ReadSectionHeader(line); } return current_section; } +void GeneralDataIniReader::ReadPlaylist(const std::string& line) { + if (line.find("playlist_reset") == std::string::npos) { + auto [key, val] = IniReaderUtils::GetKeyValFromLine(line); + ReadPlaylistVal(key, val); + } +} void GeneralDataIniReader::ReadPlaylistVal(const std::string& key, int val) { if (key == "playlist_year +") { diff --git a/src/cpp/lpnamer/input_reader/GeneralDataReader.h b/src/cpp/lpnamer/input_reader/GeneralDataReader.h index 18134abf6..eb9d9c552 100644 --- a/src/cpp/lpnamer/input_reader/GeneralDataReader.h +++ b/src/cpp/lpnamer/input_reader/GeneralDataReader.h @@ -18,26 +18,6 @@ class IniFileNotFound : public std::runtime_error { explicit IniFileNotFound(const std::string& msg) : std::runtime_error(msg) {} }; -class IniReaderUtils { - public: - static bool LineIsNotASectionHeader(const std::string& line) { - return StringManip::split(StringManip::trim(line), '=').size() == 2; - } - - static std::string ReadSectionHeader(const std::string& line) { - auto str = StringManip::trim(line); - str.erase(std::remove(str.begin(), str.end(), '['), str.end()); - str.erase(std::remove(str.begin(), str.end(), ']'), str.end()); - return str; - } - - static std::pair GetKeyValFromLine(std::string_view line) { - auto key = StringManip::trim(StringManip::split(line, '=')[0]); - auto val = std::stoi(StringManip::trim(StringManip::split(line, '=')[1])); - return {key, val}; - } -}; - class GeneralDataIniReader { private: ProblemGenerationLog::ProblemGenerationLoggerSharedPointer logger_; @@ -57,6 +37,7 @@ class GeneralDataIniReader { std::string ReadPlaylist(const std::string& current_section, const std::string& line); void ReadPlaylistVal(const std::string& key, int val); + void ReadPlaylist(const std::string& line); public: explicit GeneralDataIniReader( diff --git a/tests/cpp/lp_namer/CMakeLists.txt b/tests/cpp/lp_namer/CMakeLists.txt index 989289c3d..52f5828e9 100644 --- a/tests/cpp/lp_namer/CMakeLists.txt +++ b/tests/cpp/lp_namer/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable (lp_namer_tests WeightsFileReaderTest.cpp LpFilesExtractorTest.cpp MpsTxtWriterTest.cpp + GeneralDataReadetTests.cpp ) target_link_libraries (lp_namer_tests PRIVATE diff --git a/tests/cpp/lp_namer/GeneralDataReadetTests.cpp b/tests/cpp/lp_namer/GeneralDataReadetTests.cpp new file mode 100644 index 000000000..8918e4674 --- /dev/null +++ b/tests/cpp/lp_namer/GeneralDataReadetTests.cpp @@ -0,0 +1,42 @@ +#include + +#include "GeneralDataReader.h" + +//Test for the GeneralDataIniReader class +class GeneralDataIniReaderTests : public testing::TestWithParam { + public: + GeneralDataIniReaderTests() = default; + ~GeneralDataIniReaderTests() override = default; +}; + +INSTANTIATE_TEST_SUITE_P(reset_value, GeneralDataIniReaderTests, + testing::Bool()); +TEST_P(GeneralDataIniReaderTests, ReadPlaylistReset_option) { + auto test_dir = std::filesystem::temp_directory_path() / std::tmpnam(nullptr); + std::filesystem::create_directory(test_dir); + auto ini_file = test_dir / "test.ini"; + std::ofstream file(ini_file); + file << "[general]\n" + "nbyears=10\n" + "user-playlist=true\n" + "[playlist]\n" + "playlist_reset = "; + file << (GetParam() ? "true\n" : "false\n"); + file << "playlist_year += 0\n" + "playlist_year += 5\n" + "playlist_year += 8\n" + "playlist_year -= 1\n" + "playlist_year -= 2\n" + "playlist_year -= 3\n"; + file.close(); + + GeneralDataIniReader reader(ini_file, nullptr); + //GetActiveYears() returns the active years whereas file contains index. year=index+1 + //reset = false => Active playlist (+=) + //rest = true => !inactive playlist (-=) + if (GetParam()) { + EXPECT_EQ(reader.GetActiveYears(), std::vector({1, 5, 6, 7, 8, 9, 10})); + } else { + EXPECT_EQ(reader.GetActiveYears(), std::vector({1, 6, 9})); + } +} \ No newline at end of file