lib: unit tests: improve / better coverage

This commit is contained in:
Dirk-Jan C. Binnema 2023-09-13 23:02:53 +03:00
parent 7c16d080d2
commit 9dcbe1d96c
15 changed files with 304 additions and 147 deletions

View File

@ -79,6 +79,16 @@ test_basic()
} }
} }
static void
test_read_only()
{
MemDb db{true/*read-only*/};
Config conf_db{db};
auto res = conf_db.set<Config::Id::MaxMessageSize>(12345);
g_assert_false(!!res);
}
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
@ -86,6 +96,7 @@ main(int argc, char* argv[])
g_test_add_func("/config-db/props", test_props); g_test_add_func("/config-db/props", test_props);
g_test_add_func("/config-db/basic", test_basic); g_test_add_func("/config-db/basic", test_basic);
g_test_add_func("/config-db/read-only", test_read_only);
return g_test_run(); return g_test_run();
} }

View File

@ -32,10 +32,13 @@
#include <chrono> #include <chrono>
using namespace std::chrono_literals; using namespace std::chrono_literals;
#include "mu-store.hh"
#include "mu-scanner.hh" #include "mu-scanner.hh"
#include "utils/mu-async-queue.hh" #include "utils/mu-async-queue.hh"
#include "utils/mu-error.hh" #include "utils/mu-error.hh"
#include "../mu-store.hh"
#include "utils/mu-utils-file.hh"
using namespace Mu; using namespace Mu;
@ -544,12 +547,106 @@ test_index_basic()
} }
} }
static void
test_index_lazy()
{
allow_warnings();
TempDir tdir;
auto store = Store::make_new(tdir.path(), MU_TESTMAILDIR2);
assert_valid_result(store);
g_assert_true(store->empty());
Indexer& idx{store->indexer()};
Indexer::Config conf{};
conf.lazy_check = true;
conf.ignore_noupdate = false;
const auto start{time({})};
g_assert_true(idx.start(conf));
while (idx.is_running())
g_usleep(10000);
g_assert_false(idx.is_running());
g_assert_true(idx.stop());
g_assert_cmpuint(idx.completed() - start, <, 3);
const auto& prog{idx.progress()};
g_assert_false(prog.running);
g_assert_cmpuint(prog.checked,==, 6);
g_assert_cmpuint(prog.updated,==, 6);
g_assert_cmpuint(prog.removed,==, 0);
g_assert_cmpuint(store->size(),==, 6);
}
static void
test_index_cleanup()
{
allow_warnings();
TempDir tdir;
auto mdir = join_paths(tdir.path(), "Test");
{
auto res = run_command({"cp", "-r", MU_TESTMAILDIR2, mdir});
assert_valid_result(res);
g_assert_cmpuint(res->exit_code,==, 0);
}
auto store = Store::make_new(tdir.path(), mdir);
assert_valid_result(store);
g_assert_true(store->empty());
Indexer& idx{store->indexer()};
Indexer::Config conf{};
conf.ignore_noupdate = true;
g_assert_true(idx.start(conf));
while (idx.is_running())
g_usleep(10000);
g_assert_false(idx.is_running());
g_assert_true(idx.stop());
g_assert_cmpuint(store->size(),==, 14);
// remove a message
{
auto mpath = join_paths(mdir, "bar", "cur", "mail6");
auto res = run_command({"rm", mpath});
assert_valid_result(res);
g_assert_cmpuint(res->exit_code,==, 0);
}
// no cleanup, # stays the same
conf.cleanup = false;
g_assert_true(idx.start(conf));
while (idx.is_running())
g_usleep(10000);
g_assert_false(idx.is_running());
g_assert_true(idx.stop());
g_assert_cmpuint(store->size(),==, 14);
// cleanup, message is gone from store.
conf.cleanup = true;
g_assert_true(idx.start(conf));
while (idx.is_running())
g_usleep(10000);
g_assert_false(idx.is_running());
g_assert_true(idx.stop());
g_assert_cmpuint(store->size(),==, 13);
}
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
mu_test_init(&argc, &argv); mu_test_init(&argc, &argv);
g_test_add_func("/index/basic", test_index_basic); g_test_add_func("/index/basic", test_index_basic);
g_test_add_func("/index/lazy", test_index_lazy);
g_test_add_func("/index/cleanup", test_index_cleanup);
return g_test_run(); return g_test_run();

View File

@ -205,23 +205,20 @@ clear_links(const std::string& path, DIR* dir)
switch(d_type) { switch(d_type) {
case DT_LNK: case DT_LNK:
if (::unlink(fullpath.c_str()) != 0) { if (::unlink(fullpath.c_str()) != 0) {
mu_warning("error unlinking {}: {}", mu_warning("error unlinking {}: {}", fullpath, g_strerror(errno));
fullpath, g_strerror(errno));
res = false; res = false;
} }
break; break;
case DT_DIR: { case DT_DIR: {
DIR* subdir{::opendir(fullpath.c_str())}; DIR* subdir{::opendir(fullpath.c_str())};
if (!subdir) { if (!subdir) {
mu_warning("failed to open dir {}: {}", fullpath, mu_warning("error opening dir {}: {}", fullpath, g_strerror(errno));
g_strerror(errno));
res = false; res = false;
} }
if (!clear_links(fullpath, subdir)) if (!clear_links(fullpath, subdir))
res = false; res = false;
::closedir(subdir); ::closedir(subdir);
} } break;
break;
default: default:
break; break;
} }
@ -289,7 +286,7 @@ msg_move_g_file(const std::string& src, const std::string& dst)
else else
return Err(Error::Code::File, &err, "error moving {} -> {}", src, dst); return Err(Error::Code::File, &err, "error moving {} -> {}", src, dst);
} }
/* LCOV_EXCL_STOPT*/ /* LCOV_EXCL_STOP*/
/* use mv to move files; this is slower than rename() so only use this when /* use mv to move files; this is slower than rename() so only use this when
* needed: when moving across filesystems */ * needed: when moving across filesystems */
@ -323,10 +320,11 @@ msg_move(const std::string& src, const std::string& dst, bool assume_remote)
if (::rename(src.c_str(), dst.c_str()) == 0) /* seems it worked; double-check */ if (::rename(src.c_str(), dst.c_str()) == 0) /* seems it worked; double-check */
return msg_move_verify(src, dst); return msg_move_verify(src, dst);
/* LCOV_EXCL_START*/
if (errno != EXDEV) /* some unrecoverable error occurred */ if (errno != EXDEV) /* some unrecoverable error occurred */
return Err(Error{Error::Code::File, "error moving {} -> {}: {}", return Err(Error{Error::Code::File, "error moving {} -> {}: {}",
src, dst, strerror(errno)}); src, dst, strerror(errno)});
/* LCOV_EXCL_STOP*/
} }
/* the EXDEV / assume-remote case -- source and target live on different /* the EXDEV / assume-remote case -- source and target live on different
@ -461,12 +459,7 @@ Mu::maildir_determine_target(const std::string& old_path,
const auto dst_file{determine_dst_filename(src_file, newflags, new_name)}; const auto dst_file{determine_dst_filename(src_file, newflags, new_name)};
/* and the complete path name. */ /* and the complete path name. */
const auto subdir = std::invoke([&]()->std::string { const std::string subdir{(none_of(newflags & Flags::New)) ? "cur" : "new"};
if (none_of(newflags & Flags::New))
return "cur";
else
return "new";
});
return join_paths(dst_mdir, subdir,dst_file); return join_paths(dst_mdir, subdir,dst_file);
} }

View File

@ -264,14 +264,12 @@ parse_basic(const Field &field, Sexp &&vals, Mu::ParserFlags flags)
if (auto&& finfo{flag_info(val)}; finfo) if (auto&& finfo{flag_info(val)}; finfo)
return Xapian::Query{field.xapian_term(finfo->shortcut_lower())}; return Xapian::Query{field.xapian_term(finfo->shortcut_lower())};
else else
return Err(Error::Code::InvalidArgument, return Err(Error::Code::InvalidArgument, "invalid flag '{}'", val);
"invalid flag '{}'", val);
case Field::Id::Priority: case Field::Id::Priority:
if (auto&& prio{priority_from_name(val)}; prio) if (auto&& prio{priority_from_name(val)}; prio)
return Xapian::Query{field.xapian_term(to_char(*prio))}; return Xapian::Query{field.xapian_term(to_char(*prio))};
else else
return Err(Error::Code::InvalidArgument, return Err(Error::Code::InvalidArgument, "invalid priority '{}'", val);
"invalid priority '{}'", val);
default: { default: {
auto q{Xapian::Query{field.xapian_term(val)}}; auto q{Xapian::Query{field.xapian_term(val)}};
if (ngrams) { // special case: cjk; see if we can create an expanded query. if (ngrams) { // special case: cjk; see if we can create an expanded query.
@ -328,8 +326,7 @@ parse(const Store& store, Sexp&& s, Mu::ParserFlags flags)
return parse_field_matcher(store, *field, return parse_field_matcher(store, *field,
*match_sym, std::move(*args)); *match_sym, std::move(*args));
} }
return Err(Error::Code::InvalidArgument, return Err(Error::Code::InvalidArgument, "unexpected sexp {}", s.to_string());
"unexpected sexp {}", s.to_string());
} }
/* LCOV_EXCL_START */ /* LCOV_EXCL_START */

View File

@ -250,14 +250,12 @@ Scanner::Private::start()
{ {
const auto mode{F_OK | R_OK}; const auto mode{F_OK | R_OK};
if (G_UNLIKELY(::access(root_dir_.c_str(), mode) != 0)) if (G_UNLIKELY(::access(root_dir_.c_str(), mode) != 0))
return Err(Error::Code::File, return Err(Error::Code::File, "'{}' is not readable: {}", root_dir_,
"'{}' is not readable: {}", root_dir_,
g_strerror(errno)); g_strerror(errno));
struct stat statbuf {}; struct stat statbuf {};
if (G_UNLIKELY(::stat(root_dir_.c_str(), &statbuf) != 0)) if (G_UNLIKELY(::stat(root_dir_.c_str(), &statbuf) != 0))
return Err(Error::Code::File, return Err(Error::Code::File, "'{}' is not stat'able: {}",
"'{}' is not stat'able: {}",
root_dir_, g_strerror(errno)); root_dir_, g_strerror(errno));
if (G_UNLIKELY(!S_ISDIR(statbuf.st_mode))) if (G_UNLIKELY(!S_ISDIR(statbuf.st_mode)))
@ -322,6 +320,7 @@ Scanner::is_running() const
#if BUILD_TESTS #if BUILD_TESTS
/* LCOV_EXCL_START*/
#include "mu-test-utils.hh" #include "mu-test-utils.hh"
static void static void
@ -334,11 +333,15 @@ test_scan_maildirs()
MU_TESTMAILDIR, MU_TESTMAILDIR,
[&](const std::string& fullpath, const struct stat* statbuf, auto&& htype) -> bool { [&](const std::string& fullpath, const struct stat* statbuf, auto&& htype) -> bool {
++count; ++count;
g_usleep(10000);
return true; return true;
}}; }};
g_assert_true(scanner.start()); assert_valid_result(scanner.start());
scanner.stop();
count = 0;
assert_valid_result(scanner.start());
while (scanner.is_running()) { g_usleep(1000); } while (scanner.is_running()) { g_usleep(100000); }
// very rudimentary test... // very rudimentary test...
g_assert_cmpuint(count,==,23); g_assert_cmpuint(count,==,23);
@ -356,7 +359,7 @@ test_count_maildirs()
dirs.emplace_back(basename(fullpath)); dirs.emplace_back(basename(fullpath));
return true; return true;
}, Scanner::Mode::MaildirsOnly}; }, Scanner::Mode::MaildirsOnly};
g_assert_true(scanner.start()); assert_valid_result(scanner.start());
while (scanner.is_running()) { g_usleep(1000); } while (scanner.is_running()) { g_usleep(1000); }
@ -366,14 +369,27 @@ test_count_maildirs()
g_assert_true(seq_find_if(dirs, [](auto& p){return p == "wom_bat";}) != dirs.end()); g_assert_true(seq_find_if(dirs, [](auto& p){return p == "wom_bat";}) != dirs.end());
} }
static void
test_fail_nonexistent()
{
allow_warnings();
Scanner scanner{"/foo/bar/non-existent",
[&](auto&& a1, auto&& a2, auto&& a3){ return false; }};
g_assert_false(scanner.is_running());
g_assert_false(!!scanner.start());
g_assert_false(scanner.is_running());
}
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
mu_test_init(&argc, &argv); mu_test_init(&argc, &argv);
g_test_add_func("/index/scan-maildirs", test_scan_maildirs); g_test_add_func("/scanner/scan-maildirs", test_scan_maildirs);
g_test_add_func("/index/count-maildirs", test_count_maildirs); g_test_add_func("/scanner/count-maildirs", test_count_maildirs);
g_test_add_func("/scanner/fail-nonexistent", test_fail_nonexistent);
return g_test_run(); return g_test_run();
} }
@ -402,4 +418,5 @@ main (int argc, char *argv[])
return 0; return 0;
} }
/* LCOV_EXCL_STOP*/
#endif /*BUILD_LIST_MAILDIRS*/ #endif /*BUILD_LIST_MAILDIRS*/

View File

@ -285,7 +285,6 @@ public:
DupFlags = 1 << 1, /**< Update flags for duplicate messages too*/ DupFlags = 1 << 1, /**< Update flags for duplicate messages too*/
}; };
/** /**
* Move a message both in the filesystem and in the store. After a * Move a message both in the filesystem and in the store. After a
* successful move, the message is updated. * successful move, the message is updated.

View File

@ -111,6 +111,13 @@ struct MetadataIface {
/// In-memory db /// In-memory db
struct MemDb: public MetadataIface { struct MemDb: public MetadataIface {
/**
* Create a new memdb
*
* @param readonly read-only? (for testing)
*/
MemDb(bool readonly=false):read_only_{readonly} {}
/** /**
* Set some metadata * Set some metadata
* *
@ -141,7 +148,7 @@ struct MemDb: public MetadataIface {
* *
* @return true or false * @return true or false
*/ */
bool read_only() const override { return false; } bool read_only() const override { return read_only_; }
/** /**
@ -157,6 +164,7 @@ struct MemDb: public MetadataIface {
private: private:
std::unordered_map<std::string, std::string> map_; std::unordered_map<std::string, std::string> map_;
const bool read_only_;
}; };
/** /**
@ -171,8 +179,8 @@ public:
* *
*/ */
enum struct Flavor { enum struct Flavor {
ReadOnly, /**< Read-only database */ ReadOnly, /**< Read-only database */
Open, /**< Open existing read-write */ Open, /**< Open existing read-write */
CreateOverwrite, /**< Create new or overwrite existing */ CreateOverwrite, /**< Create new or overwrite existing */
}; };

View File

@ -363,8 +363,9 @@ test_maildir_get_new_path_02(void)
} }
} }
static void static void
test_maildir_get_new_path_custom(void) test_maildir_get_new_path_custom_real(bool change_name)
{ {
struct { struct {
std::string oldpath; std::string oldpath;
@ -393,12 +394,30 @@ test_maildir_get_new_path_custom(void)
paths[1].root_maildir, paths[1].root_maildir,
paths[i].targetdir, paths[i].targetdir,
paths[i].flags, paths[i].flags,
false)}; change_name)};
assert_valid_result(newpath); assert_valid_result(newpath);
assert_equal(*newpath, paths[i].newpath); if (change_name)
g_assert_true(*newpath != paths[i].newpath); // weak test
else
assert_equal(*newpath, paths[i].newpath);
} }
} }
static void
test_maildir_get_new_path_custom(void)
{
return test_maildir_get_new_path_custom_real(false);
}
static void
test_maildir_get_new_path_custom_change_name(void)
{
return test_maildir_get_new_path_custom_real(true);
}
static void static void
test_maildir_from_path(void) test_maildir_from_path(void)
{ {
@ -506,32 +525,30 @@ test_maildir_move_gio()
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
g_test_init(&argc, &argv, NULL); mu_test_init(&argc, &argv);
/* mu_util_maildir_mkmdir */ /* mu_util_maildir_mkmdir */
g_test_add_func("/mu-maildir/mu-maildir-mkdir-01", test_maildir_mkdir_01); g_test_add_func("/maildir/mkdir-01", test_maildir_mkdir_01);
g_test_add_func("/mu-maildir/mu-maildir-mkdir-02", test_maildir_mkdir_02); g_test_add_func("/maildir/mkdir-02", test_maildir_mkdir_02);
g_test_add_func("/mu-maildir/mu-maildir-mkdir-03", test_maildir_mkdir_03); g_test_add_func("/maildir/mkdir-03", test_maildir_mkdir_03);
g_test_add_func("/mu-maildir/mu-maildir-mkdir-04", test_maildir_mkdir_04); g_test_add_func("/maildir/mkdir-04", test_maildir_mkdir_04);
g_test_add_func("/mu-maildir/mu-maildir-mkdir-05", test_maildir_mkdir_05); g_test_add_func("/maildir/mkdir-05", test_maildir_mkdir_05);
g_test_add_func("/mu-maildir/mu-maildir-determine-target-ok", g_test_add_func("/maildir/determine-target-ok", test_determine_target_ok);
test_determine_target_ok); g_test_add_func("/maildir/determine-target-fail", test_determine_target_fail);
g_test_add_func("/mu-maildir/mu-maildir-determine-target-fail",
test_determine_target_fail);
// /* get/set flags */ // /* get/set flags */
g_test_add_func("/mu-maildir/mu-maildir-get-new-path-01", test_maildir_get_new_path_01); g_test_add_func("/maildir/get-new-path-01", test_maildir_get_new_path_01);
g_test_add_func("/mu-maildir/mu-maildir-get-new-path-02", test_maildir_get_new_path_02); g_test_add_func("/maildir/get-new-path-02", test_maildir_get_new_path_02);
g_test_add_func("/mu-maildir/mu-maildir-get-new-path-custom", g_test_add_func("/maildir/get-new-path-custom", test_maildir_get_new_path_custom);
test_maildir_get_new_path_custom); g_test_add_func("/maildir/get-new-path-custom-change-name",
g_test_add_func("/mu-maildir/mu-maildir-from-path", test_maildir_get_new_path_custom_change_name);
test_maildir_from_path);
g_test_add_func("/mu-maildir/mu-maildir-link", test_maildir_link); g_test_add_func("/maildir/from-path", test_maildir_from_path);
g_test_add_func("/mu-maildir/mu-maildir-move-vanilla", test_maildir_move_vanilla); g_test_add_func("/maildir/link", test_maildir_link);
g_test_add_func("/mu-maildir/mu-maildir-move-gio", test_maildir_move_gio); g_test_add_func("/maildir/move-vanilla", test_maildir_move_vanilla);
g_test_add_func("/maildir/aildir-move-gio", test_maildir_move_gio);
return g_test_run(); return g_test_run();
} }

View File

@ -505,6 +505,26 @@ test_store_circular_symlink(void)
remove_directory(testhome); remove_directory(testhome);
} }
static void
test_store_maildirs()
{
allow_warnings();
TempDir tdir;
auto store = Store::make_new(tdir.path(), MU_TESTMAILDIR2);
assert_valid_result(store);
g_assert_true(store->empty());
const auto mdirs = store->maildirs();
g_assert_cmpuint(mdirs.size(), ==, 3);
g_assert(seq_some(mdirs, [](auto&& m){return m == "/Foo";}));
g_assert(seq_some(mdirs, [](auto&& m){return m == "/bar";}));
g_assert(seq_some(mdirs, [](auto&& m){return m == "/wom_bat";}));
}
static void static void
test_store_fail() test_store_fail()
@ -521,6 +541,7 @@ test_store_fail()
} }
} }
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
@ -534,8 +555,12 @@ main(int argc, char* argv[])
g_test_add_func("/store/message/attachments", g_test_add_func("/store/message/attachments",
test_message_attachments); test_message_attachments);
g_test_add_func("/store/move-dups", test_store_move_dups); g_test_add_func("/store/move-dups", test_store_move_dups);
g_test_add_func("/store/maildirs", test_store_maildirs);
g_test_add_func("/store/index/index-move", test_index_move); g_test_add_func("/store/index/index-move", test_index_move);
g_test_add_func("/store/index/circular-symlink", test_store_circular_symlink); g_test_add_func("/store/index/circular-symlink", test_store_circular_symlink);
g_test_add_func("/store/index/fail", test_store_fail); g_test_add_func("/store/index/fail", test_store_fail);
return g_test_run(); return g_test_run();

View File

@ -87,6 +87,12 @@ test('test-logger',
cpp_args: ['-DBUILD_TESTS'], cpp_args: ['-DBUILD_TESTS'],
dependencies: [glib_dep, lib_mu_utils_dep, thread_dep ])) dependencies: [glib_dep, lib_mu_utils_dep, thread_dep ]))
test('test-option',
executable('test-option', 'mu-option.cc',
install: false,
cpp_args: ['-DBUILD_TESTS'],
dependencies: [glib_dep, lib_mu_utils_dep ]))
test('test-lang-detector', test('test-lang-detector',
executable('test-lang-detector', 'mu-lang-detector.cc', executable('test-lang-detector', 'mu-lang-detector.cc',
install: false, install: false,

View File

@ -30,3 +30,77 @@ Mu::to_string_opt_gchar(gchar*&& str)
return res; return res;
} }
#if BUILD_TESTS
#include "mu-test-utils.hh"
static Option<int>
get_opt_int(bool b)
{
if (b)
return Some(123);
else
return Nothing;
}
static void
test_option()
{
{
const auto oi{get_opt_int(true)};
g_assert_true(!!oi);
g_assert_cmpint(oi.value(), ==, 123);
}
{
const auto oi{get_opt_int(false)};
g_assert_false(!!oi);
g_assert_false(oi.has_value());
g_assert_cmpint(oi.value_or(456), ==, 456);
}
}
static void
test_unwrap()
{
{
auto&& oi{get_opt_int(true)};
g_assert_cmpint(unwrap(std::move(oi)), ==, 123);
}
auto ex{0};
try {
auto&& oi{get_opt_int(false)};
unwrap(std::move(oi));
} catch(...) {
ex = 1;
}
g_assert_cmpuint(ex, ==, 1);
}
static void
test_opt_gchar()
{
auto o1{to_string_opt_gchar(g_strdup("boo!"))};
auto o2{to_string_opt_gchar(nullptr)};
g_assert_false(!!o2);
g_assert_true(o1.value() == "boo!");
}
int
main(int argc, char* argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/option/option", test_option);
g_test_add_func("/option/unwrap", test_unwrap);
g_test_add_func("/option/opt-gchar", test_opt_gchar);
return g_test_run();
}
#endif /*BUILD_TESTS*/

View File

@ -22,8 +22,6 @@
using namespace Mu; using namespace Mu;
// LCOV_EXCL_STOP
#if BUILD_TESTS #if BUILD_TESTS
#include "mu-test-utils.hh" #include "mu-test-utils.hh"
@ -75,17 +73,14 @@ test_regex_replace()
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
try { {
mu_test_init(&argc, &argv); mu_test_init(&argc, &argv);
g_test_add_func("/regex/match", test_regex_match); g_test_add_func("/regex/match", test_regex_match);
g_test_add_func("/regex/match2", test_regex_match2); g_test_add_func("/regex/match2", test_regex_match2);
g_test_add_func("/regex/replace", test_regex_replace); g_test_add_func("/regex/replace", test_regex_replace);
return g_test_run();
} catch (const std::runtime_error& re) { return g_test_run();
mu_printerrln("{}", re.what());
return 1;
} }
#endif /*BUILD_TESTS*/ #endif /*BUILD_TESTS*/

View File

@ -1,4 +1,4 @@
## Copyright (C) 2021 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ## Copyright (C) 2021-2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
## ##
## This program is free software; you can redistribute it and/or modify ## 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 ## it under the terms of the GNU General Public License as published by
@ -17,12 +17,7 @@
################################################################################ ################################################################################
# tests # tests
#
test('test-option',
executable('test-option',
'test-option.cc',
install: false,
dependencies: [glib_dep, lib_mu_utils_dep]))
test('test-mu-utils', test('test-mu-utils',
executable('test-mu-utils', executable('test-mu-utils',
'test-utils.cc', 'test-utils.cc',

View File

@ -1,59 +0,0 @@
/*
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public License
** as published by the Free Software Foundation; either version 2.1
** of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free
** Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
** 02110-1301, USA.
*/
#include "mu-utils.hh"
#include "mu-option.hh"
using namespace Mu;
static Option<int>
get_opt_int(bool b)
{
if (b)
return Some(123);
else
return Nothing;
}
static void
test_option()
{
{
const auto oi{get_opt_int(true)};
g_assert_true(!!oi);
g_assert_cmpint(oi.value(), ==, 123);
}
{
const auto oi{get_opt_int(false)};
g_assert_false(!!oi);
g_assert_false(oi.has_value());
g_assert_cmpint(oi.value_or(456), ==, 456);
}
}
int
main(int argc, char* argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/option/option", test_option);
return g_test_run();
}

View File

@ -1,18 +0,0 @@
/*
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** 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 3, 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, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/