From 99c2c5e4395a92dff6da76b6cdac2b218f8e2e4b Mon Sep 17 00:00:00 2001 From: John Ralls Date: Tue, 11 Feb 2020 13:35:27 -0800 Subject: [PATCH] GncOptionUIItem from the GncOptionVariant classes to GncOption. Separating the UI from the data model. Note that the GncOptionVariant classes still have a GncOptionUIType member to ensure that a GncOptionUIItem of the right type is attached. --- libgnucash/app-utils/gnc-option-impl.hpp | 111 ++++++------------ libgnucash/app-utils/gnc-option-ui.hpp | 93 +++++++++++++++ libgnucash/app-utils/gnc-option.cpp | 54 +++++++-- libgnucash/app-utils/gnc-option.hpp | 10 +- libgnucash/app-utils/gnc-optiondb.cpp | 1 + libgnucash/app-utils/gnc-optiondb.hpp | 1 + libgnucash/app-utils/gnc-optiondb.i | 4 + .../app-utils/test/gtest-gnc-option.cpp | 50 ++++++-- .../app-utils/test/gtest-gnc-optiondb.cpp | 2 + 9 files changed, 225 insertions(+), 101 deletions(-) create mode 100644 libgnucash/app-utils/gnc-option-ui.hpp diff --git a/libgnucash/app-utils/gnc-option-impl.hpp b/libgnucash/app-utils/gnc-option-impl.hpp index 71e9d49245..adc47a40fa 100644 --- a/libgnucash/app-utils/gnc-option-impl.hpp +++ b/libgnucash/app-utils/gnc-option-impl.hpp @@ -1,5 +1,5 @@ /********************************************************************\ - * gnc-option-impl.hpp -- Application options system * + * gnc-option-impl.hpp -- Application options system * * Copyright (C) 2019 John Ralls * * * * This program is free software; you can redistribute it and/or * @@ -107,62 +107,12 @@ struct OptionClassifier std::string m_doc_string; }; -class GncOptionUIItem; - -/** - * Holds a pointer to the UI item which will control the option and an enum - * representing the type of the option for dispatch purposes; all of that - * happens in gnucash/gnome-utils/dialog-options and - * gnucash/gnome/business-option-gnome. - * - * This class takes no ownership responsibility, so calling code is responsible - * for ensuring that the UI_Item is alive. For convenience the public - * clear_ui_item function can be used as a weak_ptr's destruction callback to - * ensure that the ptr will be nulled if the ui_item is destroyed elsewhere. - */ -class OptionUIItem -{ -public: - GncOptionUIType get_ui_type() const { return m_ui_type; } - GncOptionUIItem* const get_ui_item() const {return m_ui_item; } - void clear_ui_item() { m_ui_item = nullptr; } - void set_ui_item(GncOptionUIItem* ui_item) - { - if (m_ui_type == GncOptionUIType::INTERNAL) - { - std::string error{"INTERNAL option, setting the UI item forbidden."}; - throw std::logic_error(std::move(error)); - } - m_ui_item = ui_item; - } - void make_internal() - { - if (m_ui_item != nullptr) - { - std::string error("Option has a UI Element, can't be INTERNAL."); - throw std::logic_error(std::move(error)); - } - m_ui_type = GncOptionUIType::INTERNAL; - } -protected: - OptionUIItem(GncOptionUIType ui_type) : - m_ui_item{nullptr}, m_ui_type{ui_type} {} - OptionUIItem(const OptionUIItem&) = default; - OptionUIItem(OptionUIItem&&) = default; - ~OptionUIItem() = default; - OptionUIItem& operator=(const OptionUIItem&) = default; - OptionUIItem& operator=(OptionUIItem&&) = default; -private: - GncOptionUIItem* m_ui_item; - GncOptionUIType m_ui_type; -}; - #ifndef SWIG auto constexpr size_t_max = std::numeric_limits::max(); #endif template -class GncOptionValue : public OptionClassifier, public OptionUIItem +class GncOptionValue : public OptionClassifier { public: GncOptionValue(const char* section, const char* name, @@ -170,8 +120,7 @@ public: ValueType value, GncOptionUIType ui_type = GncOptionUIType::INTERNAL) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(ui_type), - m_value{value}, m_default_value{value} {} + m_ui_type(ui_type), m_value{value}, m_default_value{value} {} GncOptionValue(const GncOptionValue&) = default; GncOptionValue(GncOptionValue&&) = default; GncOptionValue& operator=(const GncOptionValue&) = default; @@ -180,13 +129,16 @@ public: ValueType get_default_value() const { return m_default_value; } void set_value(ValueType new_value) { m_value = new_value; } bool is_changed() const noexcept { return m_value != m_default_value; } + GncOptionUIType get_ui_type() const noexcept { return m_ui_type; } + void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; } private: + GncOptionUIType m_ui_type; ValueType m_value; ValueType m_default_value; }; template -class GncOptionValidatedValue : public OptionClassifier, public OptionUIItem +class GncOptionValidatedValue : public OptionClassifier { public: GncOptionValidatedValue() = delete; @@ -197,8 +149,8 @@ public: GncOptionUIType ui_type = GncOptionUIType::INTERNAL ) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem{ui_type}, - m_value{value}, m_default_value{value}, m_validator{validator} + m_ui_type{ui_type}, m_value{value}, m_default_value{value}, + m_validator{validator} { if (!this->validate(value)) throw std::invalid_argument("Attempt to create GncValidatedOption with bad value."); @@ -209,7 +161,7 @@ public: std::functionvalidator, ValueType val_data) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem{GncOptionUIType::INTERNAL}, m_value{value}, + m_ui_type{GncOptionUIType::INTERNAL}, m_value{value}, m_default_value{value}, m_validator{validator}, m_validation_data{val_data} { if (!this->validate(value)) @@ -232,7 +184,10 @@ public: bool is_changed() const noexcept { return m_value != m_default_value; } std::ostream& to_scheme(std::ostream&) const; std::istream& from_scheme(std::istream&); + GncOptionUIType get_ui_type() const noexcept { return m_ui_type; } + void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; } private: + GncOptionUIType m_ui_type; ValueType m_value; ValueType m_default_value; std::function m_validator; //11 @@ -419,8 +374,7 @@ gnc_option_from_scheme (std::istream& iss, OptType& opt) */ template -class GncOptionRangeValue : - public OptionClassifier, public OptionUIItem +class GncOptionRangeValue : public OptionClassifier { public: GncOptionRangeValue(const char* section, const char* name, @@ -428,7 +382,6 @@ public: ValueType value, ValueType min, ValueType max, ValueType step) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(GncOptionUIType::NUMBER_RANGE), m_value{value >= min && value <= max ? value : min}, m_default_value{value >= min && value <= max ? value : min}, m_min{min}, m_max{max}, m_step{step} {} @@ -448,7 +401,10 @@ public: throw std::invalid_argument("Validation failed, value not set."); } bool is_changed() const noexcept { return m_value != m_default_value; } + GncOptionUIType get_ui_type() const noexcept { return m_ui_type; } + void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; } private: + GncOptionUIType m_ui_type = GncOptionUIType::NUMBER_RANGE; ValueType m_value; ValueType m_default_value; ValueType m_min; @@ -471,8 +427,7 @@ using GncMultiChoiceOptionChoices = std::vector; * */ -class GncOptionMultichoiceValue : - public OptionClassifier, public OptionUIItem +class GncOptionMultichoiceValue : public OptionClassifier { public: GncOptionMultichoiceValue(const char* section, const char* name, @@ -481,7 +436,7 @@ public: GncMultiChoiceOptionChoices&& choices, GncOptionUIType ui_type = GncOptionUIType::MULTICHOICE) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(ui_type), + m_ui_type{ui_type}, m_value{}, m_default_value{}, m_choices{std::move(choices)} { if (value) { @@ -543,6 +498,8 @@ public: return std::get<2>(m_choices.at(index)); } bool is_changed() const noexcept { return m_value != m_default_value; } + GncOptionUIType get_ui_type() const noexcept { return m_ui_type; } + void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; } private: std::size_t find_key (const std::string& key) const noexcept { @@ -555,6 +512,7 @@ private: return size_t_max; } + GncOptionUIType m_ui_type; std::size_t m_value; std::size_t m_default_value; GncMultiChoiceOptionChoices m_choices; @@ -581,31 +539,28 @@ using GncOptionAccountTypeList = std::vector; */ -class GncOptionAccountValue : - public OptionClassifier, public OptionUIItem +class GncOptionAccountValue : public OptionClassifier { public: GncOptionAccountValue(const char* section, const char* name, const char* key, const char* doc_string, GncOptionUIType ui_type) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(ui_type), m_value{}, m_default_value{}, m_allowed{} {} + m_ui_type{ui_type}, m_value{}, m_default_value{}, m_allowed{} {} GncOptionAccountValue(const char* section, const char* name, const char* key, const char* doc_string, GncOptionUIType ui_type, const GncOptionAccountList& value) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(ui_type), - m_value{value}, + m_ui_type{ui_type}, m_value{value}, m_default_value{std::move(value)}, m_allowed{} {} GncOptionAccountValue(const char* section, const char* name, const char* key, const char* doc_string, GncOptionUIType ui_type, GncOptionAccountTypeList&& allowed) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(ui_type), - m_value{}, + m_ui_type{ui_type}, m_value{}, m_default_value{}, m_allowed{std::move(allowed)} {} GncOptionAccountValue(const char* section, const char* name, const char* key, const char* doc_string, @@ -613,8 +568,7 @@ public: const GncOptionAccountList& value, GncOptionAccountTypeList&& allowed) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(ui_type), - m_value{}, + m_ui_type{ui_type}, m_value{}, m_default_value{}, m_allowed{std::move(allowed)} { if (!validate(value)) throw std::invalid_argument("Supplied Value not in allowed set."); @@ -631,7 +585,10 @@ public: m_value = values; } bool is_changed() const noexcept { return m_value != m_default_value; } + GncOptionUIType get_ui_type() const noexcept { return m_ui_type; } + void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; } private: + GncOptionUIType m_ui_type; GncOptionAccountList m_value; GncOptionAccountList m_default_value; GncOptionAccountTypeList m_allowed; @@ -727,13 +684,12 @@ gnc-date-option-absolute-time m_type == DateTyupe::Absolute gnc-date-option-relative-time m_type != DateTyupe::Absolute */ -class GncOptionDateValue : public OptionClassifier, public OptionUIItem +class GncOptionDateValue : public OptionClassifier { public: GncOptionDateValue(const char* section, const char* name, const char* key, const char* doc_string) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(GncOptionUIType::DATE), m_period{RelativeDatePeriod::END_ACCOUNTING_PERIOD}, m_date{INT64_MAX}, m_default_period{RelativeDatePeriod::END_ACCOUNTING_PERIOD}, @@ -742,14 +698,12 @@ public: const char* key, const char* doc_string, time64 time) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(GncOptionUIType::DATE), m_period{RelativeDatePeriod::ABSOLUTE}, m_date{time}, m_default_period{RelativeDatePeriod::ABSOLUTE}, m_default_date{time} {} GncOptionDateValue(const char* section, const char* name, const char* key, const char* doc_string, const RelativeDatePeriod period) : OptionClassifier{section, name, key, doc_string}, - OptionUIItem(GncOptionUIType::DATE), m_period{period}, m_date{INT64_MAX}, m_default_period{period}, m_default_date{INT64_MAX} {} GncOptionDateValue(const GncOptionDateValue&) = default; @@ -770,7 +724,10 @@ public: } bool is_changed() const noexcept { return m_period != m_default_period && m_date != m_default_date; } + GncOptionUIType get_ui_type() const noexcept { return m_ui_type; } + void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; } private: + GncOptionUIType m_ui_type = GncOptionUIType::DATE; RelativeDatePeriod m_period; time64 m_date; RelativeDatePeriod m_default_period; diff --git a/libgnucash/app-utils/gnc-option-ui.hpp b/libgnucash/app-utils/gnc-option-ui.hpp new file mode 100644 index 0000000000..ef2a8a4a5b --- /dev/null +++ b/libgnucash/app-utils/gnc-option-ui.hpp @@ -0,0 +1,93 @@ +/********************************************************************\ + * gnc-option-ui.hpp -- UI association for GncOption * + * Copyright (C) 2019 John Ralls * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * + * Boston, MA 02110-1301, USA gnu@gnu.org * + * * +\********************************************************************/ + +#ifndef GNC_OPTION_UI_HPP_ +#define GNC_OPTION_UI_HPP_ + +#include "gnc-option-uitype.hpp" +template +class GncUIItem +{ +public: + GncUIItem(UIType* widget) : m_widget{widget} {} + UIType* m_widget; +}; + +class GncUIType; +using OptionUIItem = GncUIItem; +using OptionSyncFunc = std::function; +/** + * Holds a pointer to the UI item which will control the option and an enum + * representing the type of the option for dispatch purposes; all of that + * happens in gnucash/gnome-utils/dialog-options and + * gnucash/gnome/business-option-gnome. + * + * This class takes no ownership responsibility, so calling code is responsible + * for ensuring that the UI_Item is alive. For convenience the public + * clear_ui_item function can be used as a weak_ptr's destruction callback to + * ensure that the ptr will be nulled if the ui_item is destroyed elsewhere. + */ +class GncOptionUIItem +{ +public: + GncOptionUIItem(OptionUIItem&& ui_item, GncOptionUIType type, + OptionSyncFunc to_ui, OptionSyncFunc from_ui) : + m_ui_item{std::move(ui_item)}, m_ui_type{type}, + m_set_ui_item_from_option{to_ui}, m_set_option_from_ui_item{from_ui} {} + GncOptionUIItem(GncOptionUIType ui_type) : + m_ui_item{nullptr}, m_ui_type{ui_type} {} + GncOptionUIItem(const GncOptionUIItem&) = default; + GncOptionUIItem(GncOptionUIItem&&) = default; + ~GncOptionUIItem() = default; + GncOptionUIItem& operator=(const GncOptionUIItem&) = default; + GncOptionUIItem& operator=(GncOptionUIItem&&) = default; + GncOptionUIType get_ui_type() const { return m_ui_type; } + const OptionUIItem& get_ui_item() const {return m_ui_item; } + void clear_ui_item() { m_ui_item = nullptr; } + void set_ui_item(OptionUIItem&& ui_item) + { + if (m_ui_type == GncOptionUIType::INTERNAL) + { + std::string error{"INTERNAL option, setting the UI item forbidden."}; + throw std::logic_error(std::move(error)); + } + m_ui_item = std::move(ui_item); + } + void set_ui_item_from_option(GncOption& option) + { + m_set_ui_item_from_option(m_ui_item, option); + } + void set_option_from_ui_item(GncOption& option) + { + m_set_option_from_ui_item(m_ui_item, option); + } +private: + OptionUIItem m_ui_item; + GncOptionUIType m_ui_type; + OptionSyncFunc m_set_ui_item_from_option; + OptionSyncFunc m_set_option_from_ui_item; +}; + +using GncOptionUIItemPtr = std::unique_ptr; + +#endif //GNC_OPTION_UI_HPP__ diff --git a/libgnucash/app-utils/gnc-option.cpp b/libgnucash/app-utils/gnc-option.cpp index 4218262711..4bedeb4a2a 100644 --- a/libgnucash/app-utils/gnc-option.cpp +++ b/libgnucash/app-utils/gnc-option.cpp @@ -24,6 +24,14 @@ #include "gnc-option.hpp" #include "gnc-option-impl.hpp" #include "gnc-option-uitype.hpp" +#include "gnc-option-ui.hpp" + +static const char* log_module{"gnc.app-utils.gnc-option"}; + +extern "C" +{ +#include +} template GncOption::GncOption(const char* section, const char* name, @@ -103,11 +111,21 @@ GncOption::get_docstring() const } void -GncOption::set_ui_item(GncOptionUIItem* ui_elem) +GncOption::set_ui_item(GncOptionUIItemPtr&& ui_item) { - std::visit([ui_elem](auto& option) { - option.set_ui_item(ui_elem); - }, *m_option); + + auto opt_ui_type = std::visit([](const auto& option)->GncOptionUIType { + return option.get_ui_type(); + }, *m_option); + + if (ui_item->get_ui_type() != opt_ui_type) + { + PERR("Setting option %s:%s UI element failed, mismatched UI types.", + get_section().c_str(), get_name().c_str()); + return; + } + + m_ui_item = std::move(ui_item); } const GncOptionUIType @@ -118,17 +136,37 @@ GncOption::get_ui_type() const }, *m_option); } -GncOptionUIItem* const +const GncOptionUIItem* GncOption::get_ui_item() const { - return std::visit([](const auto& option)->GncOptionUIItem* { - return option.get_ui_item(); - }, *m_option); + return m_ui_item.get(); +} + +void +GncOption::set_ui_item_from_option() +{ + if (!m_ui_item) + return; + m_ui_item->set_ui_item_from_option(*this); +} + +void +GncOption::set_option_from_ui_item() +{ + if (!m_ui_item) + return; + m_ui_item->set_option_from_ui_item(*this); } void GncOption::make_internal() { + if (!m_ui_item) + { + PERR("Option %s:%s has a UI Element, can't be INTERNAL.", + get_section().c_str(), get_name().c_str()); + return; + } std::visit([](auto& option) { option.make_internal(); }, *m_option); diff --git a/libgnucash/app-utils/gnc-option.hpp b/libgnucash/app-utils/gnc-option.hpp index 96f0db9844..8a990e3ba4 100644 --- a/libgnucash/app-utils/gnc-option.hpp +++ b/libgnucash/app-utils/gnc-option.hpp @@ -31,6 +31,7 @@ #include "gnc-option-uitype.hpp" class GncOptionUIItem; +using GncOptionUIItemPtr = std::unique_ptr; struct QofInstance_s; using QofInstance = QofInstance_s; template class GncOptionValue; @@ -72,9 +73,11 @@ public: const std::string& get_name() const; const std::string& get_key() const; const std::string& get_docstring() const; - void set_ui_item(GncOptionUIItem* ui_elem); + void set_ui_item(GncOptionUIItemPtr&& ui_elem); const GncOptionUIType get_ui_type() const; - GncOptionUIItem* const get_ui_item() const; + const GncOptionUIItem* get_ui_item() const; + void set_ui_item_from_option(); + void set_option_from_ui_item(); void make_internal(); bool is_changed() const noexcept; template bool validate(ValueType value) const; @@ -87,10 +90,11 @@ public: std::istream& in_stream(std::istream& iss); std::ostream& to_scheme(std::ostream& oss) const; std::istream& from_scheme(std::istream& iss); - GncOptionVariantPtr& _get_option() { return m_option; } + GncOptionVariant* const _get_option() { return m_option.get(); } private: inline static const std::string c_empty_string{""}; GncOptionVariantPtr m_option; + GncOptionUIItemPtr m_ui_item{nullptr}; }; inline std::ostream& diff --git a/libgnucash/app-utils/gnc-optiondb.cpp b/libgnucash/app-utils/gnc-optiondb.cpp index 476ee6ede4..82735a6102 100644 --- a/libgnucash/app-utils/gnc-optiondb.cpp +++ b/libgnucash/app-utils/gnc-optiondb.cpp @@ -27,6 +27,7 @@ #include #include "gnc-optiondb.hpp" #include "gnc-optiondb-impl.hpp" +#include "gnc-option-ui.hpp" auto constexpr stream_max = std::numeric_limits::max(); GncOptionDB::GncOptionDB() : m_default_section{std::nullopt} {} diff --git a/libgnucash/app-utils/gnc-optiondb.hpp b/libgnucash/app-utils/gnc-optiondb.hpp index f29e81774f..eebf933f88 100644 --- a/libgnucash/app-utils/gnc-optiondb.hpp +++ b/libgnucash/app-utils/gnc-optiondb.hpp @@ -206,4 +206,5 @@ void gnc_register_date_interval_option(const GncOptionDBPtr& db, const char* section, const char* name, const char* key, const char* doc_string, RelativeDatePeriod period); + #endif //GNC_OPTIONDB_HPP_ diff --git a/libgnucash/app-utils/gnc-optiondb.i b/libgnucash/app-utils/gnc-optiondb.i index 4aab780759..818dd876d5 100644 --- a/libgnucash/app-utils/gnc-optiondb.i +++ b/libgnucash/app-utils/gnc-optiondb.i @@ -181,6 +181,7 @@ gnc_option_test_book_destroy(QofBook* book) %ignore GncOptionDateValue::operator=(GncOptionDateValue&&); %ignore operator<<(std::ostream&, const GncOption&); %ignore operator>>(std::istream&, GncOption&); +%ignore GncOption::_get_option(); %rename(absolute) RelativeDatePeriod::ABSOLUTE; %rename(today) RelativeDatePeriod::TODAY; @@ -305,6 +306,9 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB); %include "gnc-option-impl.hpp" %include "gnc-optiondb.hpp" %include "gnc-optiondb-impl.hpp" +%inline %{ +#include "gnc-option-ui.hpp" +%} %extend GncOption { SCM get_scm_value() diff --git a/libgnucash/app-utils/test/gtest-gnc-option.cpp b/libgnucash/app-utils/test/gtest-gnc-option.cpp index 08aa941b65..03c4f4dba8 100644 --- a/libgnucash/app-utils/test/gtest-gnc-option.cpp +++ b/libgnucash/app-utils/test/gtest-gnc-option.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include extern "C" { @@ -505,7 +506,7 @@ TEST_F(GncOptionCommodityTest, test_commodity_from_scheme) EXPECT_EQ(QOF_INSTANCE(m_hpe), option.get_value()); } -class GncUIItem +class GncUIType { public: void set_value(const std::string& value) { m_value = value; } @@ -514,20 +515,29 @@ private: std::string m_value; }; -class GncOptionUIItem -{ -public: - GncOptionUIItem(GncUIItem* widget) : m_widget{widget} {} - GncUIItem* m_widget; -}; +using OptionUIItem = GncUIItem; class GncOptionUITest : public ::testing::Test { protected: GncOptionUITest() : + m_widget{}, m_option{"foo", "bar", "baz", "Phony Option", std::string{"waldo"}, - GncOptionUIType::STRING} {} - + GncOptionUIType::STRING} + { + auto to_ui = [](OptionUIItem& ui, GncOption& opt) { + ui.m_widget->set_value(opt.get_value()); + }; + auto from_ui = [](OptionUIItem& ui, GncOption& opt) { + opt.set_value(ui.m_widget->get_value()); + }; + auto ui_item{std::make_unique( + OptionUIItem{&m_widget}, + GncOptionUIType::STRING, + to_ui, from_ui)}; + m_option.set_ui_item(std::move(ui_item)); + } + GncUIType m_widget; GncOption m_option; }; @@ -540,10 +550,24 @@ TEST_F(GncOptionUI, test_option_ui_type) TEST_F(GncOptionUI, test_set_option_ui_item) { - GncUIItem ui_item; - GncOptionUIItem option_ui_item{&ui_item}; - m_option.set_ui_item(&option_ui_item); - EXPECT_EQ(&ui_item, m_option.get_ui_item()->m_widget); + EXPECT_EQ(&m_widget, m_option.get_ui_item()->get_ui_item().m_widget); +} + +TEST_F(GncOptionUI, test_ui_value_from_option) +{ + const char* value{"waldo"}; + + m_option.set_value(value); + m_option.set_ui_item_from_option(); + EXPECT_STREQ(value, m_widget.get_value().c_str()); +} + +TEST_F(GncOptionUI, test_option_value_from_ui) +{ + const char* value{"pepper"}; + m_widget.set_value(value); + m_option.set_option_from_ui_item(); + EXPECT_STREQ(value, m_option.get_value().c_str()); } class GncOptionRangeTest : public ::testing::Test diff --git a/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp b/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp index 1c7ee7de42..e0199c8c9b 100644 --- a/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp +++ b/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include extern "C" { @@ -205,6 +206,7 @@ TEST_F(GncOptionDBTest, test_register_date_interval_option) ASSERT_TRUE(m_db->set_option("foo", "bar", time)); EXPECT_EQ(time, m_db->find_option("foo", "bar")->get().get_value()); } + class GncOptionDBIOTest : public ::testing::Test { protected: