From cf0ec2749f3e86c05fff47999f6384bcf026c1de Mon Sep 17 00:00:00 2001 From: "James C. Owens" Date: Sat, 28 Dec 2024 17:08:08 -0500 Subject: [PATCH] Enhance Fraction class FromString() and add tests --- src/test/util_tests.cpp | 60 ++++++++++++++++++++++++++++++++++++++++- src/util.h | 20 +++++++++++--- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 1c22fb1f26..38c73c4649 100755 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1744,7 +1744,65 @@ BOOST_AUTO_TEST_CASE(util_Fraction_ToString) Fraction fraction(123, 10000); BOOST_CHECK_EQUAL(fraction.IsSimplified(), true); - BOOST_CHECK_EQUAL(fraction.ToString(),"123/10000"); + BOOST_CHECK_EQUAL(fraction.ToString(), "123/10000"); +} + +BOOST_AUTO_TEST_CASE(util_Fraction_FromString) +{ + Fraction fraction = Fraction().FromString("100/567"); + + BOOST_CHECK_EQUAL(fraction.IsSimplified(), true); + BOOST_CHECK(fraction == Fraction(100, 567, true)); + + fraction = Fraction().FromString("-100/567"); + + BOOST_CHECK_EQUAL(fraction.IsSimplified(), true); + BOOST_CHECK(fraction == Fraction(-100, 567, true)); + + fraction = Fraction().FromString("100/-567"); + + BOOST_CHECK_EQUAL(fraction.IsSimplified(), true); + BOOST_CHECK(fraction == Fraction(-100, 567, true)); + + fraction = Fraction().FromString("5"); + + BOOST_CHECK_EQUAL(fraction.IsSimplified(), true); + BOOST_CHECK(fraction == Fraction(5, 1, true)); + + std::string err; + std::string valid_err_message {"fraction input string cannot be parsed to fraction"}; + + try { + Fraction fraction = Fraction().FromString("100/567/300"); + } catch (std::out_of_range& e) { + err = e.what(); + } + + BOOST_CHECK_EQUAL(err, valid_err_message); + + try { + Fraction fraction = Fraction().FromString("100 / 567"); + } catch (std::out_of_range& e) { + err = e.what(); + } + + BOOST_CHECK_EQUAL(err, valid_err_message); + + try { + Fraction fraction = Fraction().FromString("100.1"); + } catch (std::out_of_range& e) { + err = e.what(); + } + + BOOST_CHECK_EQUAL(err, valid_err_message); + + try { + Fraction fraction = Fraction().FromString(""); + } catch (std::out_of_range& e) { + err = e.what(); + } + + BOOST_CHECK_EQUAL(err, valid_err_message); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util.h b/src/util.h index a1cf95490c..db86e1827d 100644 --- a/src/util.h +++ b/src/util.h @@ -344,13 +344,25 @@ class Fraction { { std::vector string_fraction = split(string, "/"); + if (string_fraction.size() > 2 || string_fraction.size() < 1) { + throw std::out_of_range("fraction input string cannot be parsed to fraction"); + } + int64_t numerator; int64_t denominator; - if (string_fraction.size() != 2 - || !ParseInt64(string_fraction[0], &numerator) - || !ParseInt64(string_fraction[1], &denominator)) { - throw std::out_of_range("Fraction input string cannot be parsed to fraction."); + if (string_fraction.size() == 1) { + if (!ParseInt64(string_fraction[0], &numerator)) { + throw std::out_of_range("fraction input string cannot be parsed to fraction"); + } + + denominator = 1; + } else { + // There must be two elements to the string fraction if we are here. + if (!ParseInt64(string_fraction[0], &numerator) + || !ParseInt64(string_fraction[1], &denominator)) { + throw std::out_of_range("fraction input string cannot be parsed to fraction"); + } } return Fraction(numerator, denominator, true);