Commit 96a546be authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Started cunit tester

parent a71461d4
......@@ -16,12 +16,54 @@ AC_PROG_CXX
CXXFLAGS="$CXXFLAGS -std=c++11 -Wall -Werror"
# Checks for libraries.
dnl Check for xxd
dnl ##################################################
dnl # Check for XXD
dnl ##################################################
AC_CHECK_PROG(xxd_found, xxd, yes)
if test "$xxd_found" != yes ;then
AC_MSG_ERROR("xxd is required (provided by vim package)")
fi
dnl ##################################################
dnl # Check for CUnit
dnl ##################################################
PKG_CHECK_MODULES(CUNIT, cunit, [found_cunit=yes],[found_cunit=no])
if test "$found_cunit" = "no" ; then
AC_CHECK_HEADERS(CUnit/CUnit.h,
[
AC_CHECK_LIB(cunit,CU_add_suite,[
found_cunit=yes
CUNIT_LIBS+=" -lcunit"
])
])
fi
case "$target_os" in
*darwin*)
#hack for macport
CUNIT_LIBS+=" -lncurses"
;;
*mingw*)
CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0501"
LIBS="$LIBS -lws2_32 -liphlpapi"
LDFLAGS="$LDFLAGS -Wl,--export-all-symbols"
;;
esac
if test "$found_cunit" = "no" ; then
AC_MSG_WARN([Could not find cunit framework, tests are not compiled.])
else
AC_CHECK_LIB(cunit,CU_get_suite,[
AC_DEFINE(HAVE_CU_GET_SUITE,1,[defined when CU_get_suite is available])
],[foo=bar],[$CUNIT_LIBS])
AC_CHECK_LIB(cunit,CU_curses_run_tests,[
AC_DEFINE(HAVE_CU_CURSES,1,[defined when CU_curses_run_tests is available])
],[foo=bar],[$CUNIT_LIBS])
fi
AM_CONDITIONAL(BUILD_TESTS,test x$found_cunit = xyes)
# Checks for header files.
......
......@@ -2,6 +2,9 @@
#define belcard_generic_hpp
#include <belr/parser-impl.cc>
#include <belr/grammarbuilder.hh>
#include <belr/abnf.hh>
#include "belcard/vcard_grammar.hpp"
#include <string>
#include <list>
......@@ -28,6 +31,15 @@ namespace belcard {
return make_shared<BelCardParam>();
}
static shared_ptr<BelCardParam> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("any-param", input, NULL);
return dynamic_pointer_cast<BelCardParam>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("any-param", make_fn(&BelCardParam::create))
->setCollector("param-name", make_sfn(&BelCardParam::setName))
......@@ -64,6 +76,7 @@ namespace belcard {
string _name;
string _value;
list<shared_ptr<BelCardParam>> _params;
public:
static shared_ptr<BelCardProperty> create() {
return make_shared<BelCardProperty>();
......
......@@ -2,6 +2,8 @@
#define belcard_identification_hpp
#include "belcard_generic.hpp"
#include <belr/grammarbuilder.hh>
#include <belr/abnf.hh>
#include <string>
#include <list>
......@@ -18,8 +20,14 @@ namespace belcard {
return make_shared<BelCardFN>();
}
BelCardFN() : BelCardProperty() {
setName("FN");
static shared_ptr<BelCardFN> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("FN", input, NULL);
return dynamic_pointer_cast<BelCardFN>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
......@@ -29,6 +37,10 @@ namespace belcard {
->setCollector("FN-value", make_sfn(&BelCardFN::setValue));
}
BelCardFN() : BelCardProperty() {
setName("FN");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
......@@ -46,6 +58,16 @@ namespace belcard {
return make_shared<BelCardN>();
}
static shared_ptr<BelCardN> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("N", input, NULL);
return dynamic_pointer_cast<BelCardN>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("N", make_fn(&BelCardN::create))
->setCollector("group", make_sfn(&BelCardN::setGroup))
......@@ -120,6 +142,16 @@ namespace belcard {
return make_shared<BelCardNickname>();
}
static shared_ptr<BelCardNickname> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("NICKNAME", input, NULL);
return dynamic_pointer_cast<BelCardNickname>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("NICKNAME", make_fn(&BelCardNickname::create))
->setCollector("group", make_sfn(&BelCardNickname::setGroup))
......@@ -142,6 +174,16 @@ namespace belcard {
return make_shared<BelCardBirthday>();
}
static shared_ptr<BelCardBirthday> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("BDAY", input, NULL);
return dynamic_pointer_cast<BelCardBirthday>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("BDAY", make_fn(&BelCardBirthday::create))
->setCollector("group", make_sfn(&BelCardBirthday::setGroup))
......@@ -164,6 +206,16 @@ namespace belcard {
return make_shared<BelCardAnniversary>();
}
static shared_ptr<BelCardAnniversary> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("ANNIVERSARY", input, NULL);
return dynamic_pointer_cast<BelCardAnniversary>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("ANNIVERSARY", make_fn(&BelCardAnniversary::create))
->setCollector("group", make_sfn(&BelCardAnniversary::setGroup))
......@@ -186,6 +238,16 @@ namespace belcard {
return make_shared<BelCardGender>();
}
static shared_ptr<BelCardGender> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("GENDER", input, NULL);
return dynamic_pointer_cast<BelCardGender>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("GENDER", make_fn(&BelCardGender::create))
->setCollector("group", make_sfn(&BelCardGender::setGroup))
......@@ -208,6 +270,16 @@ namespace belcard {
return make_shared<BelCardPhoto>();
}
static shared_ptr<BelCardPhoto> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("PHOTO", input, NULL);
return dynamic_pointer_cast<BelCardPhoto>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("PHOTO", make_fn(&BelCardPhoto::create))
->setCollector("group", make_sfn(&BelCardPhoto::setGroup))
......
#include "belcard/belcard_parser.hpp"
#include "belcard/belcard.hpp"
#include "belcard/vcard_grammar.hpp"
using namespace::std;
using namespace::belr;
......
bin_PROGRAMS=belcard-folder belcard-unfolder belcard-tester
EXTRA_DIST=vcards/vcard.vcf vcards/unfoldtest.vcf vcards/foldtest.vcf
belcard_tester_SOURCES=belcard-tester.cpp
belcard_tester_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
bin_PROGRAMS=belcard-folder belcard-unfolder
if BUILD_TESTS
noinst_PROGRAMS=belcard-tester
belcard_tester_SOURCES=belcard-tester.cpp belcard-tester.hpp common/bc_tester_utils.c common/bc_tester_utils.h belcard-identification-tester.cpp
belcard_tester_LDADD=$(top_builddir)/src/libbelcard.la -lbelr $(CUNIT_LIBS)
endif # BUILD_TESTS
belcard_folder_SOURCES=belcard-folder.cpp
belcard_folder_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
......@@ -9,4 +16,6 @@ belcard_folder_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
belcard_unfolder_SOURCES=belcard-unfolder.cpp
belcard_unfolder_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
AM_CPPFLAGS=-I$(top_srcdir)/include
AM_CPPFLAGS=-I$(top_srcdir)/include \
-I$(top_srcdir)/tester \
-I$(top_srcdir)/tester/common
#include "belcard/belcard.hpp"
#include "common/bc_tester_utils.h"
#include <sstream>
using namespace::std;
using namespace::belcard;
static int tester_before_all(void) {
return 0;
}
static int tester_after_all(void) {
return 0;
}
static void fn_property(void) {
string input = "FN:Sylvain Berfini\r\n";
shared_ptr<BelCardFN> fn = BelCardFN::parse(input);
stringstream sstream;
sstream << *fn;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
}
static void n_property(void) {
string input = "N:Berfini;Sylvain;Pascal;;\r\n";
shared_ptr<BelCardN> n = BelCardN::parse(input);
stringstream sstream;
sstream << *n;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
}
static void nickname_property(void) {
string input = "NICKNAME;TYPE=home:Viish\r\n";
shared_ptr<BelCardNickname> nickname = BelCardNickname::parse(input);
stringstream sstream;
sstream << *nickname;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
}
static void bday_property(void) {
string input = "BDAY:19891001\r\n";
shared_ptr<BelCardBirthday> bday = BelCardBirthday::parse(input);
stringstream sstream;
sstream << *bday;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
}
static void anniversary_property(void) {
string input = "ANNIVERSARY:20140621\r\n";
shared_ptr<BelCardAnniversary> anniversary = BelCardAnniversary::parse(input);
stringstream sstream;
sstream << *anniversary;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
}
static void gender_property(void) {
string input = "GENDER:M\r\n";
shared_ptr<BelCardGender> gender = BelCardGender::parse(input);
stringstream sstream;
sstream << *gender;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
}
static void photo_property(void) {
string input = "PHOTO;VALUE=URL;MEDIATYPE=image/png:http://www.belledonne-communications.com/uploads/images/belledonne-communications.png\r\n";
shared_ptr<BelCardPhoto> photo = BelCardPhoto::parse(input);
stringstream sstream;
sstream << *photo;
BC_ASSERT_TRUE(input.compare(sstream.str()) == 0);
input = "PHOTO:data:image/jpeg;base64,data:image/png;base64,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\r\n";
photo = BelCardPhoto::parse(input);
stringstream sstream2;
sstream2 << *photo;
BC_ASSERT_TRUE(input.compare(sstream2.str()) == 0);
}
static test_t tests[] = {
{ "Full name", fn_property },
{ "Name", n_property },
{ "Nickname", nickname_property },
{ "Birthday", bday_property },
{ "Anniversary", anniversary_property },
{ "Gender", gender_property },
{ "Photo", photo_property },
};
test_suite_t vcard_identification_properties_test_suite = {
"Identification",
tester_before_all,
tester_after_all,
NULL,
NULL,
sizeof(tests) / sizeof(tests[0]),
tests
};
\ No newline at end of file
#include "belcard/belcard_parser.hpp"
#include "belcard-tester.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace::belr;
using namespace::belcard;
#define MESSAGE 1<<1
#define WARNING 1<<2
#define ERROR 1<<3
int main(int argc, char *argv[]) {
const char *file = NULL;
if (argc < 2) {
cerr << argv[0] << " <file to parse> - parse the content of a file" << endl;
return -1;
}
file = argv[1];
int i;
int ret;
belcard_tester_init(NULL);
ifstream istr(file);
if (!istr.is_open()) {
return -1;
if (strstr(argv[0], ".libs")) {
int prefix_length = strstr(argv[0], ".libs") - argv[0] + 1;
char prefix[200];
sprintf(prefix, "%s%.*s", argv[0][0] == '/' ? "" : "./", prefix_length, argv[0]);
bc_tester_set_resource_dir_prefix(prefix);
bc_tester_set_writable_dir_prefix(prefix);
}
stringstream vcardStream;
vcardStream << istr.rdbuf();
string vcard = vcardStream.str();
BelCardParser *parser = new BelCardParser();
shared_ptr<BelCard> belCard = parser->parse(vcard);
if (belCard) {
cout << (*belCard) << endl;
} else {
cerr << "Error: returned pointer is null" << endl;
for(i = 1; i < argc; ++i) {
int ret = bc_tester_parse_args(argc, argv, i);
if (ret>0) {
i += ret - 1;
continue;
} else if (ret<0) {
bc_tester_helper(argv[0], "");
}
return ret;
}
ret = bc_tester_start(argv[0]);
belcard_tester_uninit();
return ret;
}
static void log_handler(int lev, const char *fmt, va_list args) {
#ifdef _WIN32
vfprintf(lev == ERROR ? stderr : stdout, fmt, args);
fprintf(lev == ERROR ? stderr : stdout, "\n");
#else
va_list cap;
va_copy(cap,args);
/* Otherwise, we must use stdio to avoid log formatting (for autocompletion etc.) */
vfprintf(lev == ERROR ? stderr : stdout, fmt, cap);
fprintf(lev == ERROR ? stderr : stdout, "\n");
va_end(cap);
#endif
}
void belcard_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) {
if (ftester_printf == NULL) ftester_printf = log_handler;
bc_tester_init(ftester_printf, MESSAGE, ERROR);
delete parser;
return 0;
bc_tester_add_suite(&vcard_identification_properties_test_suite);
}
void belcard_tester_uninit(void) {
bc_tester_uninit();
}
\ No newline at end of file
#ifndef belcard_tester_hpp
#define belcard_tester_hpp
#include "common/bc_tester_utils.h"
#ifdef __cplusplus
extern "C" {
#endif
extern test_suite_t vcard_identification_properties_test_suite;
void belcard_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args));
void belcard_tester_uninit(void);
#ifdef __cplusplus
};
#endif
#endif
This diff is collapsed.
This diff is collapsed.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment