1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#include <tests/import/utils.h>
#include <libglom/utils.h>
#include <glibmm/convert.h>
#include <glibmm/fileutils.h>
#include <glibmm/main.h>
namespace ImportTests
{
//The result just shows whether it finished before the timeout.
static bool finished_parsing = true;
bool check(const std::string& name, bool test, std::stringstream& report)
{
if(!test)
report << name << ": FAILED" << std::endl;
return test;
}
// Returns the file URI of the temporary created file, which will contain the buffer's contents.
static Glib::ustring create_file_from_buffer(const char* input, guint input_size)
{
const auto file_uri = Glom::Utils::get_temp_file_uri("glom_import_testdata");
if(file_uri.empty())
{
std::cerr << G_STRFUNC << ": file_uri was empty." << std::endl;
return std::string();
}
Glib::RefPtr<Gio::File> file = Gio::File::create_for_uri(file_uri);
gssize result = 0;
try
{
result = file->append_to()->write(input, input_size);
g_return_val_if_fail(-1 < result, "");
}
catch(const Gio::Error& ex)
{
std::cerr << G_STRFUNC << ": Gio::File::write() failed: " << ex.what() << std::endl;
return std::string();
}
return file_uri;
}
static void on_mainloop_killed_by_watchdog(const Glib::RefPtr<Glib::MainLoop>& mainloop)
{
finished_parsing = false;
//Quit the mainloop that we ran because the parser uses an idle handler.
mainloop->quit();
}
static void on_parser_encoding_error(const Glib::RefPtr<Glib::MainLoop>& mainloop)
{
finished_parsing = true;
//Quit the mainloop that we ran because the parser uses an idle handler.
mainloop->quit();
}
static void on_parser_finished(const Glib::RefPtr<Glib::MainLoop>& mainloop)
{
finished_parsing = true;
//Quit the mainloop that we ran because the parser uses an idle handler.
mainloop->quit();
}
static void on_file_read_error(const std::string& /*unused*/, const Glib::RefPtr<Glib::MainLoop>& mainloop)
{
finished_parsing = true;
//Quit the mainloop that we ran because the parser uses an idle handler.
mainloop->quit();
}
bool run_parser_from_buffer(const FuncConnectParserSignals& connect_parser_signals, const std::string& input)
{
return run_parser_from_buffer(connect_parser_signals, input.data(), input.size());
}
bool run_parser_from_buffer(const FuncConnectParserSignals& connect_parser_signals, const char* input, guint input_size)
{
finished_parsing = true;
//Start a mainloop because the parser uses an idle handler.
//TODO: Stop the parser from doing that.
Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create();
Glom::CsvParser parser("UTF-8");
parser.signal_encoding_error().connect(sigc::bind(&on_parser_encoding_error, mainloop));
parser.signal_finished_parsing().connect(sigc::bind(&on_parser_finished, mainloop));
// Install a watchdog for the mainloop. No test should need longer than 300
// seconds. Also, we need to avoid being stuck in the mainloop.
// Infinitely running tests are useless.
mainloop->get_context()->signal_timeout().connect_seconds_once(sigc::bind(&on_mainloop_killed_by_watchdog, mainloop), 300);
connect_parser_signals(parser);
const auto file_uri = create_file_from_buffer(input, input_size);
parser.set_file_and_start_parsing(file_uri);
if(Glom::CsvParser::State::PARSING != parser.get_state())
return false;
mainloop->run();
Glib::RefPtr<Gio::File> file = Gio::File::create_for_uri(file_uri);
try
{
const auto removed = file->remove();
g_assert(removed);
}
catch(const Gio::Error& ex)
{
std::cerr << G_STRFUNC << ": Gio::File::remove() failed: " << ex.what() << std::endl;
return false;
}
return finished_parsing;
}
bool run_parser_on_file(const FuncConnectParserSignals& connect_parser_signals, const std::string &uri)
{
finished_parsing = true;
//Start a mainloop because the parser uses an idle handler.
//TODO: Stop the parser from doing that.
Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create();
Glom::CsvParser parser("UTF-8");
parser.signal_encoding_error().connect(sigc::bind(&on_parser_encoding_error, mainloop));
parser.signal_finished_parsing().connect(sigc::bind(&on_parser_finished, mainloop));
parser.signal_file_read_error().connect(sigc::bind(&on_file_read_error, mainloop));
// Install a watchdog for the mainloop. No test should need longer than 300
// seconds. Also, we need to avoid being stuck in the mainloop.
// Infinitely running tests are useless.
mainloop->get_context()->signal_timeout().connect_seconds_once(sigc::bind(&on_mainloop_killed_by_watchdog, mainloop), 300);
connect_parser_signals(parser);
parser.set_file_and_start_parsing(uri);
if(Glom::CsvParser::State::PARSING != parser.get_state())
return false;
mainloop->run();
return finished_parsing;
}
} //namespace ImportTests
|