mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Use GUIDs to represent QofInstances instead of pointers.
Converting them to pointers for Scheme to use. Prevents dangling pointers when the user deletes a QofInstance as long as the Scheme report code re-fetches its pointers from the options when it's regenerated.
This commit is contained in:
parent
a7a643f7f2
commit
d4c3c30b1a
@ -1524,7 +1524,7 @@ create_option_widget<GncOptionUIType::DATE_BOTH>(GncOption& option,
|
||||
documentation, enclosing, packed);
|
||||
}
|
||||
|
||||
using GncOptionAccountList = std::vector<const Account*>;
|
||||
using GncOptionAccountList = std::vector<GncGUID>;
|
||||
|
||||
static void
|
||||
account_select_all_cb(GtkWidget *widget, gpointer data)
|
||||
@ -1604,8 +1604,12 @@ public:
|
||||
GList *acc_list = nullptr;
|
||||
const GncOptionAccountList& accounts =
|
||||
option.get_value<GncOptionAccountList>();
|
||||
for (auto account : accounts)
|
||||
acc_list = g_list_prepend(acc_list, static_cast<void*>(const_cast<Account*>(account)));
|
||||
auto book{gnc_get_current_book()};
|
||||
for (auto guid : accounts)
|
||||
{
|
||||
auto account{xaccAccountLookup(&guid, book)};
|
||||
acc_list = g_list_prepend(acc_list, account);
|
||||
}
|
||||
acc_list = g_list_reverse(acc_list);
|
||||
gnc_tree_view_account_set_selected_accounts(widget, acc_list, TRUE);
|
||||
g_list_free(acc_list);
|
||||
@ -1617,7 +1621,10 @@ public:
|
||||
GncOptionAccountList acc_vec;
|
||||
acc_vec.reserve(g_list_length(acc_list));
|
||||
for (auto node = acc_list; node; node = g_list_next(node))
|
||||
acc_vec.push_back(static_cast<const Account*>(node->data));
|
||||
{
|
||||
auto guid{qof_entity_get_guid(node->data)};
|
||||
acc_vec.push_back(*guid);
|
||||
}
|
||||
g_list_free(acc_list);
|
||||
option.set_value(acc_vec);
|
||||
}
|
||||
|
@ -275,13 +275,20 @@ GncOptionAccountListValue::validate(const GncOptionAccountList& values) const
|
||||
return true;
|
||||
if ((get_ui_type() == GncOptionUIType::ACCOUNT_SEL || !m_multiselect) &&
|
||||
values.size() != 1)
|
||||
{
|
||||
std::cerr << "GncOptionAccountListValue::validate: Multiple values for a non-multiselect option." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (m_allowed.empty())
|
||||
return true;
|
||||
for(auto account : values) {
|
||||
auto book{gnc_get_current_book()};
|
||||
for(auto& guid : values)
|
||||
{
|
||||
if (std::find(m_allowed.begin(), m_allowed.end(),
|
||||
xaccAccountGetType(account)) == m_allowed.end())
|
||||
return false;
|
||||
xaccAccountGetType(xaccAccountLookup(&guid, book))) == m_allowed.end())
|
||||
{
|
||||
std::cerr << "GncOptionAccountListValue::validate: Account " << gnc::GUID(guid).to_string() << " is not of an allowed type" << std::endl;
|
||||
return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -310,17 +317,33 @@ GncOptionAccountListValue::get_default_value() const
|
||||
if (!account_list)
|
||||
return retval;
|
||||
|
||||
auto book{gnc_get_current_book()};
|
||||
for (auto node = account_list; node; node = g_list_next (node))
|
||||
{
|
||||
if (std::find(m_allowed.begin(), m_allowed.end(),
|
||||
xaccAccountGetType(GNC_ACCOUNT(node->data))) != m_allowed.end())
|
||||
{
|
||||
retval.push_back(GNC_ACCOUNT(node->data));
|
||||
retval.push_back(*qof_entity_get_guid(GNC_ACCOUNT(node->data)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_list_free(account_list);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool
|
||||
operator==(const GncGUID& l, const GncGUID& r)
|
||||
{
|
||||
return guid_equal(&l, &r);
|
||||
}
|
||||
|
||||
bool
|
||||
GncOptionAccountListValue::is_changed() const noexcept
|
||||
{
|
||||
return m_value != m_default_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a GList of account types to pass to gnc_account_sel_set_acct_filters.
|
||||
@ -354,15 +377,20 @@ GncOptionAccountSelValue::validate(const Account* value) const
|
||||
const Account*
|
||||
GncOptionAccountSelValue::get_value() const
|
||||
{
|
||||
return m_value ? m_value : get_default_value();
|
||||
auto book{gnc_get_current_book()};
|
||||
return guid_equal(guid_null(), &m_value) ? get_default_value() :
|
||||
xaccAccountLookup(&m_value, book);
|
||||
}
|
||||
|
||||
const Account*
|
||||
GncOptionAccountSelValue::get_default_value() const
|
||||
{
|
||||
|
||||
if (m_default_value)
|
||||
return m_default_value;
|
||||
if (!guid_equal(guid_null(), &m_default_value))
|
||||
{
|
||||
auto book{gnc_get_current_book()};
|
||||
return xaccAccountLookup(&m_default_value, book);
|
||||
}
|
||||
|
||||
/* If no default has been set and there's an allowed set then find the first
|
||||
* account that matches one of the allowed account types.
|
||||
@ -713,7 +741,7 @@ GncOptionAccountListValue::serialize() const noexcept
|
||||
if (!first)
|
||||
retval += " ";
|
||||
first = false;
|
||||
retval += qof_instance_to_string(QOF_INSTANCE(val));
|
||||
retval += guid_to_string(&val);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@ -732,8 +760,9 @@ GncOptionAccountListValue::deserialize(const std::string& str) noexcept
|
||||
if (!first)
|
||||
++pos;
|
||||
first = false;
|
||||
auto ptr = qof_instance_from_string(str.substr(pos, pos + GUID_ENCODING_LENGTH), get_ui_type());
|
||||
m_value.push_back(reinterpret_cast<Account*>(ptr));
|
||||
GncGUID guid{};
|
||||
string_to_guid(str.substr(pos, pos + GUID_ENCODING_LENGTH).c_str(), &guid);
|
||||
m_value.push_back(guid);
|
||||
pos += GUID_ENCODING_LENGTH;
|
||||
}
|
||||
return true;
|
||||
@ -743,7 +772,7 @@ std::string
|
||||
GncOptionAccountSelValue::serialize() const noexcept
|
||||
{
|
||||
static const std::string no_value{"No Value"};
|
||||
return m_value ?qof_instance_to_string(QOF_INSTANCE(m_value)) : no_value;
|
||||
return guid_equal(guid_null(), &m_value) ? no_value : guid_to_string(&m_value);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -717,7 +717,7 @@ operator>> <GncOptionMultichoiceValue>(std::istream& iss,
|
||||
}
|
||||
|
||||
|
||||
using GncOptionAccountList = std::vector<const Account*>;
|
||||
using GncOptionAccountList = std::vector<GncGUID>;
|
||||
|
||||
using GncOptionAccountTypeList = std::vector<GNCAccountType>;
|
||||
|
||||
@ -795,7 +795,7 @@ public:
|
||||
}
|
||||
GList* account_type_list() const noexcept;
|
||||
void reset_default_value() { m_value = m_default_value; }
|
||||
bool is_changed() const noexcept { return m_value != m_default_value; }
|
||||
bool is_changed() const noexcept;
|
||||
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
|
||||
void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; }
|
||||
bool is_multiselect() const noexcept { return m_multiselect; }
|
||||
@ -821,7 +821,7 @@ operator<< <GncOptionAccountListValue>(std::ostream& oss,
|
||||
first = false;
|
||||
else
|
||||
oss << " ";
|
||||
oss << qof_instance_to_string(QOF_INSTANCE(value));
|
||||
oss << guid_to_string(&value);
|
||||
}
|
||||
return oss;
|
||||
}
|
||||
@ -836,7 +836,10 @@ operator>> <GncOptionAccountListValue>(std::istream& iss,
|
||||
std::string str;
|
||||
std::getline(iss, str, ' ');
|
||||
if (!str.empty())
|
||||
values.emplace_back((Account*)qof_instance_from_string(str, opt.get_ui_type()));
|
||||
{
|
||||
auto guid{qof_entity_get_guid(qof_instance_from_string(str, opt.get_ui_type()))};
|
||||
values.push_back(*guid);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -856,32 +859,32 @@ public:
|
||||
const char* key, const char* doc_string,
|
||||
GncOptionUIType ui_type) :
|
||||
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
|
||||
m_value{}, m_default_value{}, m_allowed{} {}
|
||||
m_value{*guid_null()}, m_default_value{*guid_null()}, m_allowed{} {}
|
||||
|
||||
GncOptionAccountSelValue(const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
GncOptionUIType ui_type,
|
||||
const Account* value) :
|
||||
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
|
||||
m_value{const_cast<Account*>(value)},
|
||||
m_default_value{const_cast<Account*>(value)}, m_allowed{} {}
|
||||
m_value{*qof_entity_get_guid(value)},
|
||||
m_default_value{*qof_entity_get_guid(value)}, m_allowed{} {}
|
||||
GncOptionAccountSelValue(const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
GncOptionUIType ui_type,
|
||||
GncOptionAccountTypeList&& allowed) :
|
||||
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
|
||||
m_value{}, m_default_value{}, m_allowed{std::move(allowed)} {}
|
||||
m_value{*guid_null()}, m_default_value{*guid_null()},
|
||||
m_allowed{std::move(allowed)} {}
|
||||
GncOptionAccountSelValue(const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
GncOptionUIType ui_type,
|
||||
const Account* value,
|
||||
GncOptionAccountTypeList&& allowed) :
|
||||
OptionClassifier{section, name, key, doc_string}, m_ui_type{ui_type},
|
||||
m_value{}, m_default_value{}, m_allowed{std::move(allowed)} {
|
||||
m_value{*guid_null()}, m_default_value{*guid_null()}, m_allowed{std::move(allowed)} {
|
||||
if (!validate(value))
|
||||
throw std::invalid_argument("Supplied Value not in allowed set.");
|
||||
m_value = const_cast<Account*>(value);
|
||||
m_default_value = const_cast<Account*>(value);
|
||||
m_value = m_default_value = *qof_entity_get_guid(value);
|
||||
}
|
||||
|
||||
const Account* get_value() const;
|
||||
@ -889,25 +892,31 @@ public:
|
||||
bool validate (const Account* value) const;
|
||||
void set_value (const Account* value) {
|
||||
if (validate(value))
|
||||
//throw!
|
||||
m_value = const_cast<Account*>(value);
|
||||
{
|
||||
auto guid{qof_entity_get_guid(value)};
|
||||
m_value = *guid;
|
||||
}
|
||||
//else throw
|
||||
}
|
||||
void set_default_value (const Account* value) {
|
||||
if (validate(value))
|
||||
//throw!
|
||||
m_value = m_default_value = const_cast<Account*>(value);
|
||||
{
|
||||
auto guid{qof_entity_get_guid(value)};
|
||||
m_value = m_default_value = *guid;
|
||||
}
|
||||
//else throw
|
||||
}
|
||||
GList* account_type_list() const noexcept;
|
||||
void reset_default_value() { m_value = m_default_value; }
|
||||
bool is_changed() const noexcept { return m_value != m_default_value; }
|
||||
bool is_changed() const noexcept { return !guid_equal(&m_value, &m_default_value); }
|
||||
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
|
||||
void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; }
|
||||
std::string serialize() const noexcept;
|
||||
bool deserialize(const std::string& str) noexcept;
|
||||
private:
|
||||
GncOptionUIType m_ui_type;
|
||||
Account* m_value;
|
||||
Account* m_default_value;
|
||||
GncGUID m_value;
|
||||
GncGUID m_default_value;
|
||||
GncOptionAccountTypeList m_allowed;
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <sstream>
|
||||
#include <kvp-value.hpp>
|
||||
#include <qofbookslots.h>
|
||||
#include <guid.hpp>
|
||||
#include "gnc-optiondb.h"
|
||||
#include "gnc-optiondb.hpp"
|
||||
#include "gnc-optiondb-impl.hpp"
|
||||
@ -708,6 +709,11 @@ gnc_register_account_list_limited_option(GncOptionDB* db,
|
||||
{
|
||||
try
|
||||
{
|
||||
std::cout << "gnc_register_account_list_limited_option for accounts ";
|
||||
std::for_each(value.begin(), value.end(), [](auto& guid){
|
||||
std::cout << gnc::GUID(guid).to_string() << " ";
|
||||
});
|
||||
std::cout << std::endl;
|
||||
GncOption option{GncOptionAccountListValue{section, name, key, doc_string,
|
||||
GncOptionUIType::ACCOUNT_LIST, value, std::move(allowed)}};
|
||||
db->register_option(section, std::move(option));
|
||||
@ -729,7 +735,7 @@ find_children(Account* account, void* data)
|
||||
const GncOptionAccountTypeList& types = datapair->second;
|
||||
if (std::find(types.begin(), types.end(),
|
||||
xaccAccountGetType(account)) != types.end())
|
||||
list.push_back(account);
|
||||
list.push_back(*qof_entity_get_guid(account));
|
||||
}
|
||||
|
||||
GncOptionAccountList
|
||||
|
@ -54,7 +54,7 @@ extern "C"
|
||||
|
||||
class GncOptionDB;
|
||||
using GncOptionDBPtr = std::unique_ptr<GncOptionDB>;
|
||||
using GncOptionAccountList = std::vector<const Account*>;
|
||||
using GncOptionAccountList = std::vector<GncGUID>;
|
||||
|
||||
using GncOptionAccountTypeList = std::vector<GNCAccountType>;
|
||||
using GncMultichoiceOptionEntry = std::tuple<const std::string,
|
||||
|
@ -428,7 +428,10 @@ scm_to_value<GncOptionAccountList>(SCM new_value)
|
||||
void* account{};
|
||||
SWIG_ConvertPtr(node, &account, SWIGTYPE_p_Account, 0);
|
||||
if (account)
|
||||
retval.push_back(static_cast<Account*>(account));
|
||||
{
|
||||
auto guid{qof_entity_get_guid(static_cast<Account*>(account))};
|
||||
retval.push_back(*guid);
|
||||
}
|
||||
next = scm_cdr(next);
|
||||
if (scm_is_null(next))
|
||||
break;
|
||||
@ -440,9 +443,13 @@ template <>inline SCM
|
||||
scm_from_value<GncOptionAccountList>(GncOptionAccountList value)
|
||||
{
|
||||
SCM s_list = SCM_EOL;
|
||||
for (auto acct : value)
|
||||
auto book{gnc_get_current_book()};
|
||||
for (auto guid : value)
|
||||
{
|
||||
auto acct{xaccAccountLookup(&guid, book)};
|
||||
s_list = scm_cons(SWIG_NewPointerObj(acct, SWIGTYPE_p_Account, 0),
|
||||
s_list);
|
||||
}
|
||||
return scm_reverse(s_list);
|
||||
}
|
||||
|
||||
@ -452,13 +459,14 @@ void gnc_option_test_book_destroy(QofBook*);
|
||||
QofBook*
|
||||
gnc_option_test_book_new()
|
||||
{
|
||||
return static_cast<QofBook*>(g_object_new(QOF_TYPE_BOOK, nullptr));
|
||||
auto session = gnc_get_current_session();
|
||||
return gnc_get_current_book();
|
||||
}
|
||||
|
||||
void
|
||||
gnc_option_test_book_destroy(QofBook* book)
|
||||
{
|
||||
g_object_unref(book);
|
||||
gnc_clear_current_session();
|
||||
}
|
||||
|
||||
%}
|
||||
@ -574,7 +582,8 @@ gnc_option_test_book_destroy(QofBook* book)
|
||||
SCM s_account = scm_list_ref($input, scm_from_size_t(i));
|
||||
Account* acct = (Account*)SWIG_MustGetPtr(s_account,
|
||||
SWIGTYPE_p_Account, 1, 0);
|
||||
$1.push_back(acct);
|
||||
if (acct)
|
||||
$1.push_back(*qof_entity_get_guid(acct));
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,7 +611,7 @@ gnc_option_test_book_destroy(QofBook* book)
|
||||
$1 = &types;
|
||||
}
|
||||
|
||||
%typemap(in) GncOptionAccountList
|
||||
%typemap(in) GncOptionAccountList const & (GncOptionAccountList alist)
|
||||
{
|
||||
auto len = scm_is_true($input) ? scm_to_size_t(scm_length($input)) : 0;
|
||||
for (std::size_t i = 0; i < len; ++i)
|
||||
@ -610,8 +619,10 @@ gnc_option_test_book_destroy(QofBook* book)
|
||||
SCM s_account = scm_list_ref($input, scm_from_size_t(i));
|
||||
Account* acct = (Account*)SWIG_MustGetPtr(s_account,
|
||||
SWIGTYPE_p_Account, 1, 0);
|
||||
$1.push_back(acct);
|
||||
if (acct)
|
||||
alist.push_back(*qof_entity_get_guid(acct));
|
||||
}
|
||||
$1 = &alist;
|
||||
}
|
||||
|
||||
%typemap(in) GncOptionAccountList& (GncOptionAccountList acclist)
|
||||
@ -623,7 +634,7 @@ gnc_option_test_book_destroy(QofBook* book)
|
||||
SCM s_account = scm_list_ref($input, scm_from_size_t(i));
|
||||
Account* acct = (Account*)SWIG_MustGetPtr(s_account,
|
||||
SWIGTYPE_p_Account, 1, 0);
|
||||
acclist.push_back(acct);
|
||||
acclist.push_back(*qof_entity_get_guid(acct));
|
||||
}
|
||||
$1 = &acclist;
|
||||
}
|
||||
@ -631,18 +642,26 @@ gnc_option_test_book_destroy(QofBook* book)
|
||||
%typemap(out) GncOptionAccountList
|
||||
{
|
||||
$result = SCM_EOL;
|
||||
for (auto acct : $1)
|
||||
auto book{gnc_get_current_book()};
|
||||
for (auto guid : $1)
|
||||
{
|
||||
auto acct{xaccAccountLookup(&guid, book)};
|
||||
$result = scm_cons(SWIG_NewPointerObj(acct, SWIGTYPE_p_Account, 0),
|
||||
$result);
|
||||
}
|
||||
$result = scm_reverse($result);
|
||||
}
|
||||
|
||||
%typemap(out) GncOptionAccountList&
|
||||
%typemap(out) const GncOptionAccountList&
|
||||
{
|
||||
$result = SCM_EOL;
|
||||
for (auto acct : *$1)
|
||||
auto book{gnc_get_current_book()};
|
||||
for (auto guid : *$1)
|
||||
{
|
||||
auto acct{xaccAccountLookup(&guid, book)};
|
||||
$result = scm_cons(SWIG_NewPointerObj(acct, SWIGTYPE_p_Account, 0),
|
||||
$result);
|
||||
}
|
||||
$result = scm_reverse ($result)
|
||||
}
|
||||
|
||||
@ -1080,17 +1099,17 @@ inline SCM return_scm_value(ValueType value)
|
||||
GncOptionAccountListValue>)
|
||||
{
|
||||
static const SCM list_format_str{scm_from_utf8_string("'~s")};
|
||||
auto acct_list{option.get_value()};
|
||||
if (acct_list.empty())
|
||||
auto guid_list{option.get_value()};
|
||||
if (guid_list.empty())
|
||||
return no_value;
|
||||
SCM guid_list{SCM_EOL};
|
||||
for(auto acct : acct_list)
|
||||
SCM string_list{SCM_EOL};
|
||||
for(auto guid : guid_list)
|
||||
{
|
||||
auto acct_str{qof_instance_to_string(QOF_INSTANCE(acct))};
|
||||
auto acct_scm{scm_from_utf8_string(acct_str.c_str())};
|
||||
guid_list = scm_cons(acct_scm, guid_list);
|
||||
auto guid_str{guid_to_string(&guid)};
|
||||
auto guid_scm{scm_from_utf8_string(guid_str)};
|
||||
string_list = scm_cons(guid_scm, string_list);
|
||||
}
|
||||
return scm_simple_format(SCM_BOOL_F, list_format_str, scm_list_1(guid_list));
|
||||
return scm_simple_format(SCM_BOOL_F, list_format_str, scm_list_1(string_list));
|
||||
|
||||
}
|
||||
if constexpr (is_QofInstanceValue_v<decltype(option)>)
|
||||
|
@ -515,7 +515,7 @@ find_children(Account* account, void* data)
|
||||
const GncOptionAccountTypeList& types = datapair->second;
|
||||
if (std::find(types.begin(), types.end(),
|
||||
xaccAccountGetType(account)) != types.end())
|
||||
list.push_back(account);
|
||||
list.push_back(*qof_entity_get_guid(account));
|
||||
}
|
||||
|
||||
class GncOptionAccountTest : public ::testing::Test
|
||||
@ -571,6 +571,12 @@ protected:
|
||||
Account* m_root;
|
||||
};
|
||||
|
||||
static bool
|
||||
operator==(const GncGUID& l, const GncGUID& r)
|
||||
{
|
||||
return guid_equal(&l, &r);
|
||||
}
|
||||
|
||||
TEST_F(GncOptionAccountTest, test_test_constructor_and_destructor)
|
||||
{
|
||||
EXPECT_TRUE(m_book != NULL);
|
||||
@ -662,9 +668,9 @@ TEST_F(GncOptionAccountTest, test_account_list_out)
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
acclist}};
|
||||
std::ostringstream oss;
|
||||
std::string acc_guids{gnc::GUID{*qof_instance_get_guid(acclist[0])}.to_string()};
|
||||
std::string acc_guids{gnc::GUID{acclist[0]}.to_string()};
|
||||
acc_guids += " ";
|
||||
acc_guids += gnc::GUID{*qof_instance_get_guid(acclist[1])}.to_string();
|
||||
acc_guids += gnc::GUID{acclist[1]}.to_string();
|
||||
|
||||
oss << option;
|
||||
EXPECT_EQ(acc_guids, oss.str());
|
||||
@ -675,7 +681,7 @@ TEST_F(GncOptionAccountTest, test_account_list_out)
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
accsel,
|
||||
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
|
||||
acc_guids = gnc::GUID{*qof_instance_get_guid(accsel[0])}.to_string();
|
||||
acc_guids = gnc::GUID{accsel[0]}.to_string();
|
||||
|
||||
oss.str("");
|
||||
oss << sel_option;
|
||||
@ -688,9 +694,9 @@ TEST_F(GncOptionAccountTest, test_account_list_in)
|
||||
GncOption option{GncOptionAccountListValue{"foo", "bar", "baz", "Bogus Option",
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
acclist}};
|
||||
std::string acc_guids{gnc::GUID{*qof_instance_get_guid(acclist[0])}.to_string()};
|
||||
std::string acc_guids{gnc::GUID{acclist[0]}.to_string()};
|
||||
acc_guids += " ";
|
||||
acc_guids += gnc::GUID{*qof_instance_get_guid(acclist[1])}.to_string();
|
||||
acc_guids += gnc::GUID{acclist[1]}.to_string();
|
||||
|
||||
std::istringstream iss{acc_guids};
|
||||
iss >> option;
|
||||
@ -703,7 +709,7 @@ TEST_F(GncOptionAccountTest, test_account_list_in)
|
||||
accsel,
|
||||
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
|
||||
GncOptionAccountList acclistbad{list_of_types({ACCT_TYPE_STOCK})};
|
||||
acc_guids = gnc::GUID{*qof_instance_get_guid(acclistbad[1])}.to_string();
|
||||
acc_guids = gnc::GUID{acclistbad[1]}.to_string();
|
||||
acc_guids += " ";
|
||||
|
||||
iss.str(acc_guids);
|
||||
@ -711,7 +717,7 @@ TEST_F(GncOptionAccountTest, test_account_list_in)
|
||||
EXPECT_EQ(accsel, sel_option.get_value<GncOptionAccountList>());
|
||||
|
||||
iss.clear(); //Reset the failedbit from the invalid selection type.
|
||||
acc_guids = gnc::GUID{*qof_instance_get_guid(acclist[1])}.to_string();
|
||||
acc_guids = gnc::GUID{acclist[1]}.to_string();
|
||||
EXPECT_NO_THROW({
|
||||
iss.str(acc_guids);
|
||||
iss >> sel_option;
|
||||
|
@ -86,10 +86,12 @@ TEST_F(GncOptionDBTest, test_register_string_option)
|
||||
*/
|
||||
|
||||
|
||||
struct AccountTestBook
|
||||
struct GncOptionDBAccountTest : public ::testing::Test
|
||||
{
|
||||
AccountTestBook() :
|
||||
m_book{qof_book_new()}, m_root{gnc_account_create_root(m_book)}
|
||||
GncOptionDBAccountTest() :
|
||||
m_sess{gnc_get_current_session()}, m_book{gnc_get_current_book()},
|
||||
m_root{gnc_account_create_root(m_book)},
|
||||
m_db{std::make_unique<GncOptionDB>()}
|
||||
{
|
||||
auto create_account = [this](Account* parent, GNCAccountType type,
|
||||
const char* name)->Account* {
|
||||
@ -117,31 +119,31 @@ struct AccountTestBook
|
||||
create_account(expenses, ACCT_TYPE_EXPENSE, "Gas");
|
||||
create_account(expenses, ACCT_TYPE_EXPENSE, "Rent");
|
||||
}
|
||||
~AccountTestBook()
|
||||
~GncOptionDBAccountTest()
|
||||
{
|
||||
xaccAccountBeginEdit(m_root);
|
||||
xaccAccountDestroy(m_root); //It does the commit
|
||||
qof_book_destroy(m_book);
|
||||
gnc_clear_current_session();
|
||||
}
|
||||
|
||||
QofSession* m_sess;
|
||||
QofBook* m_book;
|
||||
Account* m_root;
|
||||
GncOptionDBPtr m_db;
|
||||
};
|
||||
|
||||
TEST_F(GncOptionDBTest, test_register_account_list_option)
|
||||
TEST_F(GncOptionDBAccountTest, test_register_account_list_option)
|
||||
{
|
||||
AccountTestBook book;
|
||||
auto acclist{gnc_account_list_from_types(book.m_book, {ACCT_TYPE_STOCK})};
|
||||
auto acclist{gnc_account_list_from_types(m_book, {ACCT_TYPE_STOCK})};
|
||||
gnc_register_account_list_option(m_db, "foo", "bar", "baz",
|
||||
"Phony Option", acclist);
|
||||
EXPECT_EQ(4U, m_db->find_option("foo", "bar")->get_value<GncOptionAccountList>().size());
|
||||
EXPECT_EQ(acclist[3], m_db->find_option("foo", "bar")->get_value<GncOptionAccountList>().at(3));
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBTest, test_register_account_list_limited_option)
|
||||
TEST_F(GncOptionDBAccountTest, test_register_account_list_limited_option)
|
||||
{
|
||||
AccountTestBook book;
|
||||
auto acclist{gnc_account_list_from_types(book.m_book, {ACCT_TYPE_STOCK})};
|
||||
auto acclist{gnc_account_list_from_types(m_book, {ACCT_TYPE_STOCK})};
|
||||
gnc_register_account_list_limited_option(m_db, "foo", "bar", "baz",
|
||||
"Phony Option", acclist,
|
||||
{ACCT_TYPE_STOCK});
|
||||
@ -149,10 +151,9 @@ TEST_F(GncOptionDBTest, test_register_account_list_limited_option)
|
||||
EXPECT_EQ(acclist[3], m_db->find_option("foo", "bar")->get_value<GncOptionAccountList>().at(3));
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBTest, test_register_account_sel_limited_option)
|
||||
TEST_F(GncOptionDBAccountTest, test_register_account_sel_limited_option)
|
||||
{
|
||||
AccountTestBook book;
|
||||
auto acclist{gnc_account_list_from_types(book.m_book, {ACCT_TYPE_STOCK})};
|
||||
auto acclist{gnc_account_list_from_types(m_book, {ACCT_TYPE_STOCK})};
|
||||
GncOptionAccountList accsel{acclist[2]};
|
||||
gnc_register_account_list_limited_option(m_db, "foo", "bar", "baz",
|
||||
"Phony Option", accsel,
|
||||
@ -161,10 +162,9 @@ TEST_F(GncOptionDBTest, test_register_account_sel_limited_option)
|
||||
EXPECT_EQ(accsel[0], m_db->find_option("foo", "bar")->get_value<GncOptionAccountList>().at(0));
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBTest, test_register_account_sel_limited_option_fail_construct)
|
||||
TEST_F(GncOptionDBAccountTest, test_register_account_sel_limited_option_fail_construct)
|
||||
{
|
||||
AccountTestBook book;
|
||||
auto acclist{gnc_account_list_from_types(book.m_book, {ACCT_TYPE_STOCK})};
|
||||
auto acclist{gnc_account_list_from_types(m_book, {ACCT_TYPE_STOCK})};
|
||||
GncOptionAccountList accsel{acclist[2]};
|
||||
gnc_register_account_list_limited_option(m_db, "foo", "bar", "baz", "Phony Option",
|
||||
accsel, {ACCT_TYPE_BANK});
|
||||
@ -276,6 +276,12 @@ TEST_F(GncOptionDBTest, test_register_start_date_option)
|
||||
|
||||
}
|
||||
|
||||
static bool
|
||||
operator==(const GncGUID& l, const GncGUID& r)
|
||||
{
|
||||
return guid_equal(&l, &r);
|
||||
}
|
||||
|
||||
class GncOptionDBIOTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
@ -322,7 +328,8 @@ protected:
|
||||
RelativeDatePeriod::START_CURRENT_QUARTER);
|
||||
gnc_register_account_list_option(m_db, "quux", "xyzzy", "second",
|
||||
"Phony AccountList Option",
|
||||
{aapl, hpe});
|
||||
{*qof_entity_get_guid(aapl),
|
||||
*qof_entity_get_guid(hpe)});
|
||||
}
|
||||
|
||||
~GncOptionDBIOTest()
|
||||
|
@ -315,7 +315,7 @@ veritatis et quasi architecto beatae vitae dicta sunt, explicabo.")
|
||||
(test-template test-account-list-output-template)
|
||||
(new-acclist (gnc-account-list-from-types book (list ACCT-TYPE-BANK))))
|
||||
(gnc:option-set-value option new-acclist)
|
||||
(test-equal "account list form"
|
||||
(test-equal "account list form" ;;fails
|
||||
(test-template (GncOption-serialize option))
|
||||
(gnc:generate-restore-forms odb "options"))
|
||||
))
|
||||
@ -338,7 +338,7 @@ veritatis et quasi architecto beatae vitae dicta sunt, explicabo.")
|
||||
(let ((option (gnc:lookup-option odb "foo" "bar"))
|
||||
(test-template test-string-output-template))
|
||||
(gnc:option-set-value option bank)
|
||||
(test-equal "account sel form"
|
||||
(test-equal "account sel form" ;; fails
|
||||
(test-template (GncOption-serialize option))
|
||||
(gnc:generate-restore-forms odb "options"))
|
||||
))
|
||||
|
@ -112,16 +112,16 @@
|
||||
(test-equal (car acctlist) (car acct-list))) )))
|
||||
|
||||
(define (test-make-account-list-limited-option book)
|
||||
(test-group "test-make-account-list-option"
|
||||
(test-group "test-make-account-list-limited-option"
|
||||
(let ((option-db (new-gnc-optiondb))
|
||||
(acctlist (gnc-account-list-from-types book
|
||||
(list ACCT-TYPE-STOCK))))
|
||||
(gnc-register-account-list-limited-option
|
||||
(gnc-register-account-list-limited-option ;; Error not account type twice
|
||||
option-db "foo" "bar" "baz"
|
||||
"Phony Option" acctlist (list ACCT-TYPE-STOCK))
|
||||
(let ((acct-list (gnc-option-value option-db "foo" "bar")))
|
||||
(test-equal (length acctlist) (length acct-list))
|
||||
(test-equal (cadr acctlist) (cadr acct-list)))
|
||||
(test-equal (length acctlist) (length acct-list)) ;; fails acct-list 4 vs #f
|
||||
(test-equal (cadr acctlist) (cadr acct-list))) ;; fails () vs. #f both wrong
|
||||
(gnc-register-account-list-limited-option
|
||||
option-db "waldo" "pepper" "baz"
|
||||
"Phony Option" acctlist (list ACCT-TYPE-BANK))
|
||||
|
Loading…
Reference in New Issue
Block a user