[glom: 3/4] Refactoring Dialog_Import_CSV: created testcase for the CsvParser's signal emission
- From: Michael Hasselmann <mikhas src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glom: 3/4] Refactoring Dialog_Import_CSV: created testcase for the CsvParser's signal emission
- Date: Thu, 17 Sep 2009 17:49:35 +0000 (UTC)
commit b0415320a7e53790f46ffeab28168137a35d03aa
Author: Michael Hasselmann <michaelh openismus com>
Date: Thu Sep 17 18:35:57 2009 +0200
Refactoring Dialog_Import_CSV: created testcase for the CsvParser's signal emission
* Makefile_tests.am: all tests now run within valgrind by default since mem
leaks in testcases are potential mem leaks in the application. Parameters might
need tweaking.
* glom/import_csv.cc (CsvParser::on_idle_parse): Fixed a missing negation in a
conditional, which was wrongfully leading to signal emissions. Found by the
import signals testcase.
* test/import/test_parsing.cc: Fixed a null byte issue when setting the raw
contents of the parser.
* test/import/test_signals.cc: This testcase checks the CsvParser's signal
emission on varying input. The basic idea was to have on testcase for each
code path that leads to a signal emission in glom/import_csv.cc, even if that
leads to overlapping code coverage tests with the parser testcase.
Makefile_tests.am | 11 +++-
glom/import_csv.cc | 6 +-
tests/import/test_parsing.cc | 4 +-
tests/import/test_signals.cc | 165 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 180 insertions(+), 6 deletions(-)
---
diff --git a/Makefile_tests.am b/Makefile_tests.am
index f5760a2..bce76b8 100644
--- a/Makefile_tests.am
+++ b/Makefile_tests.am
@@ -25,14 +25,18 @@ check_PROGRAMS = \
tests/test_parsing_time \
tests/test_signal_reemit \
tests/test_load_python_library\
- tests/import/test_parsing
+ tests/import/test_parsing\
+ tests/import/test_signals
TESTS = tests/test_parsing_time \
tests/test_signal_reemit \
tests/test_load_python_library\
tests/import/test_parsing\
+ tests/import/test_signals\
tests/import.sh
+TESTS_ENVIRONMENT=which valgrind && valgrind --tool=memcheck --leak-check=full --leak-resolution=high --trace-children=yes --num-callers=30
+
tests_ldadd = glom/libglom/libglom-$(GLOM_ABI_VERSION).la $(LIBGLOM_LIBS)
glom_libglom_test_connectionpool_SOURCES = glom/libglom/test_connectionpool.cc
@@ -46,6 +50,10 @@ tests_import_test_parsing_SOURCES = \
glom/import_csv.cc \
glom/import_csv.h \
tests/import/test_parsing.cc
+tests_import_test_signals_SOURCES = \
+ glom/import_csv.cc \
+ glom/import_csv.h \
+ tests/import/test_signals.cc
glom_libglom_test_connectionpool_LDADD = $(tests_ldadd)
glom_libglom_test_document_LDADD = $(tests_ldadd)
@@ -71,3 +79,4 @@ tests_test_parsing_time_LDADD = $(tests_ldadd)
tests_test_signal_reemit_LDADD = $(LIBGLOM_LIBS)
tests_test_load_python_library_LDADD = $(LIBGLOM_LIBS)
tests_import_test_parsing_LDADD = $(LIBGLOM_LIBS)
+tests_import_test_signals_LDADD = $(LIBGLOM_LIBS)
diff --git a/glom/import_csv.cc b/glom/import_csv.cc
index 8844500..b0363c5 100644
--- a/glom/import_csv.cc
+++ b/glom/import_csv.cc
@@ -265,7 +265,7 @@ bool CsvParser::on_idle_parse()
// Found a newline (outside of quotes) that marks the end of the line:
m_current_line.append(prev_line_end, pos - prev_line_end);
- ++(m_line_number);
+ ++m_line_number;
if(!m_current_line.empty())
{
@@ -295,10 +295,10 @@ bool CsvParser::on_idle_parse()
m_current_line.append(prev, outbuf - prev);
if(!m_stream && m_raw.size() == m_input_position)
{
- ++(m_line_number);
+ ++m_line_number;
// Handle last line, if nonempty
- if(m_current_line.empty())
+ if(!m_current_line.empty())
{
signal_line_scanned().emit(m_current_line, m_line_number);
}
diff --git a/tests/import/test_parsing.cc b/tests/import/test_parsing.cc
index 7e784c3..49779fd 100644
--- a/tests/import/test_parsing.cc
+++ b/tests/import/test_parsing.cc
@@ -43,8 +43,8 @@ bool check_tokens(Glib::RefPtr<Glib::Regex> check)
void set_parser_contents(Glom::CsvParser& parser, const char* input, guint size)
{
-
- parser.m_raw = std::vector<char>(input, input + size);
+ // Do not read terminating null byte.
+ parser.m_raw = std::vector<char>(input, input + size -1);
}
void on_line_scanned(const Glib::ustring& line, guint /*line_number*/)
diff --git a/tests/import/test_signals.cc b/tests/import/test_signals.cc
new file mode 100644
index 0000000..61eaf86
--- /dev/null
+++ b/tests/import/test_signals.cc
@@ -0,0 +1,165 @@
+#include <glom/import_csv.h>
+#include <glibmm/regex.h>
+#include <iostream>
+#include <stdexcept>
+#include <cstdlib>
+
+namespace {
+
+typedef std::vector<std::string> Encodings;
+
+void set_parser_contents(Glom::CsvParser& parser, const char* input, guint size)
+{
+ // Do not read terminating null byte.
+ parser.m_raw = std::vector<char>(input, input + size -1);
+}
+
+guint& get_line_scanned_count_instance()
+{
+ static guint line_scanned_count = 0;
+ return line_scanned_count;
+}
+
+guint& get_encoding_error_count_instance()
+{
+ static guint encoding_error_count = 0;
+ return encoding_error_count;
+}
+
+void on_line_scanned()
+{
+ ++(get_line_scanned_count_instance());
+}
+
+void on_encoding_error()
+{
+ ++(get_encoding_error_count_instance());
+}
+
+void reset_signal_counts()
+{
+ get_line_scanned_count_instance() = 0;
+ get_encoding_error_count_instance() = 0;
+}
+
+void print_signal_counts()
+{
+ std::cout << "lines scanned: " << get_line_scanned_count_instance() << std::endl;
+ std::cout << "encoding errors: " << get_encoding_error_count_instance() << std::endl;
+}
+
+} // namespace
+
+// Testcases
+int main()
+{
+ Glom::CsvParser parser("UTF-8");
+ parser.signal_line_scanned().connect(sigc::hide(sigc::hide(&on_line_scanned)));
+ parser.signal_encoding_error().connect(sigc::ptr_fun(&on_encoding_error));
+
+ bool test_ignore_quoted_newlines = false;
+ bool test_ignore_empty_lines = false;
+ bool test_wrong_encoding = false;
+ bool test_incomplete_chars = false;
+
+ std::stringstream results;
+
+ // test_ignore_quoted_newlines
+ {
+ // 2 CSV lines, first one contains newlines inside quotes
+ const char raw[] = "\"some\n quoted\r\n newlines\n\", \"token2\"\n\"token3\"\n";
+ set_parser_contents(parser, raw, sizeof(raw));
+
+ while(parser.on_idle_parse())
+ {}
+
+ results << "test_ignore_quoted_newlines: "
+ << (test_ignore_quoted_newlines = (2 == get_line_scanned_count_instance()))
+ << std::endl;
+
+ reset_signal_counts();
+ parser.clear();
+ }
+
+ // test_ignore_empty_lines
+ {
+ // 5 CSV lines, but only 2 contain data
+ const char raw[] = "token1\n\n\n\ntoken2, token3\n";
+ set_parser_contents(parser, raw, sizeof(raw));
+
+ while(parser.on_idle_parse())
+ {}
+
+ results << "test_ignore_empty_lines: "
+ << (test_ignore_empty_lines = (2 == get_line_scanned_count_instance() &&
+ 0 == get_encoding_error_count_instance()))
+ << std::endl;
+
+ reset_signal_counts();
+ parser.clear();
+ }
+
+ // test_wrong_encoding
+ {
+ const char* const encoding_arr[] = {"UTF-8", "UCS-2"};
+ Encodings encodings(encoding_arr, encoding_arr + G_N_ELEMENTS(encoding_arr));
+
+ // An invalid Unicode sequence.
+ const char raw[] = "\0xc0\0x00\n";
+ set_parser_contents(parser, raw, sizeof(raw));
+
+ for (Encodings::const_iterator iter = encodings.begin();
+ iter != encodings.end();
+ ++iter)
+ {
+ try
+ {
+ while(parser.on_idle_parse())
+ {}
+
+ parser.clear();
+ }
+ catch (Glib::ConvertError& exception)
+ {
+ std::cout << exception.what() << std::endl;
+ }
+
+ parser.set_encoding((*iter).c_str());
+ }
+
+ results << "test_wrong_encoding: "
+ << (test_wrong_encoding = (2 == get_encoding_error_count_instance() &&
+ 0 == get_line_scanned_count_instance()))
+ << std::endl;
+
+ reset_signal_counts();
+ parser.clear();
+ }
+
+ // test_incomplete_chars
+ {
+ // An incomplete Unicode sequence.
+ const char raw[] = "\0xc0\n";
+ set_parser_contents(parser, raw, sizeof(raw));
+
+ while(parser.on_idle_parse())
+ {}
+
+ parser.clear();
+
+ results << "test_incomplete_chars: "
+ << (test_incomplete_chars = (1 == get_encoding_error_count_instance() &&
+ 0 == get_line_scanned_count_instance()))
+ << std::endl;
+
+ reset_signal_counts();
+ parser.clear();
+ }
+
+ std::cout << results.rdbuf();
+ return (test_ignore_quoted_newlines &&
+ test_ignore_empty_lines &&
+ test_wrong_encoding &&
+ test_incomplete_chars
+ ) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]