Skip to content
Snippets Groups Projects
Commit cbca941c authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Add phone number cleanup functions, unit tests and panel configuration

parent 7ad45ed7
No related branches found
No related tags found
No related merge requests found
......@@ -311,12 +311,6 @@ AS_IF([test "x$with_speex" != xno],
]
dnl More advanced check in case the libspeexdsp is not installed
AC_SEARCH_LIBS(speex_preprocess_run, speexdsp, HAVE_SPEEXDSP="yes", HAVE_SPEEXDSP="no", [])
if test $HAVE_SPEEXDSP="no"; then
echo $HAVE_SPEEXDSP;
AC_MSG_WARN([The silence detection in speex could not have been enabled])
fi
)
AC_DEFINE([HAVE_SPEEX], test "x$with_speex" = "xyes", [Define if you have libspeex])
......
......@@ -21,7 +21,7 @@
URLHook_Config *_urlhook_config;
GtkWidget *field, *command;
GtkWidget *field, *command, *prefix;
void hooks_load_parameters (URLHook_Config** settings){
......@@ -39,12 +39,16 @@ void hooks_load_parameters (URLHook_Config** settings){
_settings->command = DEFAULT_URL_COMMAND;
_settings->sip_enabled = "0";
_settings->iax2_enabled = "0";
_settings->phone_number_enabled = "0";
_settings->phone_number_prefix = "";
}
else {
_settings->sip_field = (gchar*)(g_hash_table_lookup (_params, URLHOOK_SIP_FIELD));
_settings->command = (gchar*)(g_hash_table_lookup (_params, URLHOOK_COMMAND));
_settings->sip_enabled = (gchar*)(g_hash_table_lookup (_params, URLHOOK_SIP_ENABLED));
_settings->iax2_enabled = (gchar*)(g_hash_table_lookup (_params, URLHOOK_IAX2_ENABLED));
_settings->phone_number_enabled = (gchar*)(g_hash_table_lookup (_params, PHONE_NUMBER_HOOK_ENABLED ));
_settings->phone_number_prefix = (gchar*)(g_hash_table_lookup (_params, PHONE_NUMBER_HOOK_ADD_PREFIX ));
}
*settings = _settings;
......@@ -64,6 +68,10 @@ void hooks_save_parameters (void){
(gpointer)g_strdup(_urlhook_config->sip_enabled));
g_hash_table_replace (params, (gpointer)URLHOOK_IAX2_ENABLED,
(gpointer)g_strdup(_urlhook_config->iax2_enabled));
g_hash_table_replace (params, (gpointer)PHONE_NUMBER_HOOK_ENABLED,
(gpointer)g_strdup(_urlhook_config->phone_number_enabled));
g_hash_table_replace (params, (gpointer)PHONE_NUMBER_HOOK_ADD_PREFIX,
g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(prefix))));
dbus_set_hook_settings (params);
......@@ -94,9 +102,24 @@ static void iax2_enabled_cb (GtkWidget *widget) {
_urlhook_config->iax2_enabled="0";
}
static void phone_number_enabled_cb (GtkWidget *widget) {
guint check;
check = (guint) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget));
if (check){
_urlhook_config->phone_number_enabled="1";
gtk_widget_set_sensitive (GTK_WIDGET (prefix), TRUE);
}else{
_urlhook_config->phone_number_enabled="0";
gtk_widget_set_sensitive (GTK_WIDGET (prefix), FALSE);
}
}
GtkWidget* create_hooks_settings (){
GtkWidget *ret, *url_frame, *table, *label, *widg;
GtkWidget *ret, *frame, *table, *label, *widg;
// Load the user value
hooks_load_parameters (&_urlhook_config);
......@@ -104,15 +127,15 @@ GtkWidget* create_hooks_settings (){
ret = gtk_vbox_new(FALSE, 10);
gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
url_frame = gtk_frame_new(_("URL argument"));
gtk_box_pack_start(GTK_BOX(ret), url_frame, FALSE, FALSE, 0);
gtk_widget_show (url_frame);
frame = gtk_frame_new(_("URL argument"));
gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
table = gtk_table_new ( 5, 3, FALSE/* homogeneous */);
gtk_table_set_row_spacings( GTK_TABLE(table), 10);
gtk_table_set_col_spacings( GTK_TABLE(table), 10);
gtk_widget_show(table);
gtk_container_add( GTK_CONTAINER (url_frame) , table );
gtk_container_add( GTK_CONTAINER (frame) , table );
widg = gtk_check_button_new_with_mnemonic( _("_SIP protocol"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->sip_enabled, "1")==0)?TRUE:FALSE);
......@@ -138,6 +161,29 @@ GtkWidget* create_hooks_settings (){
gtk_entry_set_text(GTK_ENTRY(command), _urlhook_config->command);
gtk_table_attach ( GTK_TABLE( table ), command, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
frame = gtk_frame_new(_("Phone number formatting"));
gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
table = gtk_table_new ( 2, 2, FALSE/* homogeneous */);
gtk_table_set_row_spacings( GTK_TABLE(table), 10);
gtk_table_set_col_spacings( GTK_TABLE(table), 10);
gtk_widget_show(table);
gtk_container_add( GTK_CONTAINER (frame) , table );
widg = gtk_check_button_new_with_mnemonic( _("_Add phone number prefix"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->phone_number_enabled, "1")==0)?TRUE:FALSE);
g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (phone_number_enabled_cb), NULL);
gtk_table_attach ( GTK_TABLE( table ), widg, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
label = gtk_label_new_with_mnemonic (_("_Prepend: "));
gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
prefix = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (label), prefix);
gtk_entry_set_text(GTK_ENTRY(prefix), _urlhook_config->phone_number_prefix);
gtk_widget_set_sensitive (GTK_WIDGET (prefix), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widg)));
gtk_table_attach ( GTK_TABLE( table ), prefix, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
gtk_widget_show_all(ret);
return ret;
......
......@@ -33,6 +33,8 @@ G_BEGIN_DECLS
#define URLHOOK_SIP_FIELD "URLHOOK_SIP_FIELD"
#define URLHOOK_SIP_ENABLED "URLHOOK_SIP_ENABLED"
#define URLHOOK_IAX2_ENABLED "URLHOOK_IAX2_ENABLED"
#define PHONE_NUMBER_HOOK_ENABLED "PHONE_NUMBER_HOOK_ENABLED"
#define PHONE_NUMBER_HOOK_ADD_PREFIX "PHONE_NUMBER_HOOK_ADD_PREFIX"
typedef struct _URLHook_Config {
......@@ -40,6 +42,8 @@ typedef struct _URLHook_Config {
gchar *iax2_enabled;
gchar *sip_field;
gchar *command;
gchar *phone_number_enabled;
gchar *phone_number_prefix;
}URLHook_Config;
/**
......
......@@ -31,6 +31,7 @@ sflphoned_SOURCES = \
sipcall.cpp \
sdp.cpp \
sdpmedia.cpp \
numbercleaner.cpp \
$(IAXSOURCES)
......@@ -71,7 +72,8 @@ noinst_HEADERS = \
call.h \
sipcall.h \
sdp.h \
sdpmedia.h
sdpmedia.h \
numbercleaner.h
libsflphone_la_LIBADD = \
$(src)/libs/stund/libstun.la \
......
......@@ -82,11 +82,14 @@ ManagerImpl::ManagerImpl (void)
, _callAccountMapMutex()
, _callConfigMap()
, _accountMap()
, _cleaner (NULL)
{
// initialize random generator for call id
srand (time(NULL));
_cleaner = new NumberCleaner ();
#ifdef TEST
testAccountMap();
loadAccountMap();
......@@ -102,6 +105,7 @@ ManagerImpl::ManagerImpl (void)
ManagerImpl::~ManagerImpl (void)
{
// terminate();
delete _cleaner; _cleaner=0;
_debug("%s stop correctly.\n", PROGNAME);
}
......@@ -195,23 +199,26 @@ ManagerImpl::switchCall(const CallID& id ) {
bool
ManagerImpl::outgoingCall(const std::string& accountid, const CallID& id, const std::string& to)
{
std::string pattern;
std::string pattern, to_cleaned;
Call::CallConfiguration callConfig;
SIPVoIPLink *siplink;
_debug("ManagerImpl::outgoingCall() method \n");
// stopTone(false);
// playTone();
if (getConfigString (HOOKS, PHONE_NUMBER_HOOK_ENABLED) == "1")
_cleaner->set_phone_number_prefix (getConfigString (HOOKS, PHONE_NUMBER_HOOK_ADD_PREFIX ));
else
_cleaner->set_phone_number_prefix ("");
to_cleaned = _cleaner->clean (to);
/* Check what kind of call we are dealing with */
check_call_configuration (id, to, &callConfig);
check_call_configuration (id, to_cleaned, &callConfig);
if (callConfig == Call::IPtoIP) {
_debug ("Start IP to IP call\n");
/* We need to retrieve the sip voiplink instance */
siplink = SIPVoIPLink::instance("");
if (siplink->new_ip_to_ip_call (id, to)) {
if (siplink->new_ip_to_ip_call (id, to_cleaned)) {
switchCall (id);
return true;
}
......@@ -238,7 +245,7 @@ ManagerImpl::outgoingCall(const std::string& accountid, const CallID& id, const
_debug("- Manager Action: Adding Outgoing Call %s on account %s\n", id.data(), accountid.data());
associateCallToAccount( id, accountid );
if ( getAccountLink(accountid)->newOutgoingCall(id, to) ) {
if ( getAccountLink(accountid)->newOutgoingCall(id, to_cleaned) ) {
switchCall(id);
return true;
} else {
......@@ -1210,6 +1217,8 @@ ManagerImpl::initConfigFile ( bool load_user_value )
fill_config_str (URLHOOK_COMMAND, HOOK_DEFAULT_URL_COMMAND);
fill_config_str (URLHOOK_SIP_ENABLED, NO_STR);
fill_config_str (URLHOOK_IAX2_ENABLED, NO_STR);
fill_config_str (PHONE_NUMBER_HOOK_ENABLED, NO_STR);
fill_config_str (PHONE_NUMBER_HOOK_ADD_PREFIX, "");
// Loads config from ~/.sflphone/sflphonedrc or so..
if (createSettingsPath() == 1 && load_user_value) {
......@@ -2597,6 +2606,8 @@ std::map<std::string, std::string> ManagerImpl::getHookSettings () {
settings.insert (std::pair<std::string, std::string> ("URLHOOK_COMMAND", getConfigString (HOOKS, URLHOOK_COMMAND)) );
settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_ENABLED", getConfigString (HOOKS, URLHOOK_SIP_ENABLED)) );
settings.insert (std::pair<std::string, std::string> ("URLHOOK_IAX2_ENABLED", getConfigString (HOOKS, URLHOOK_IAX2_ENABLED)) );
settings.insert (std::pair<std::string, std::string> ("PHONE_NUMBER_HOOK_ENABLED", getConfigString (HOOKS, PHONE_NUMBER_HOOK_ENABLED)) );
settings.insert (std::pair<std::string, std::string> ("PHONE_NUMBER_HOOK_ADD_PREFIX", getConfigString (HOOKS, PHONE_NUMBER_HOOK_ADD_PREFIX)) );
return settings;
}
......@@ -2607,6 +2618,8 @@ void ManagerImpl::setHookSettings (const std::map<std::string, std::string>& set
setConfig(HOOKS, URLHOOK_COMMAND, (*settings.find("URLHOOK_COMMAND")).second);
setConfig(HOOKS, URLHOOK_SIP_ENABLED, (*settings.find("URLHOOK_SIP_ENABLED")).second);
setConfig(HOOKS, URLHOOK_IAX2_ENABLED, (*settings.find("URLHOOK_IAX2_ENABLED")).second);
setConfig(HOOKS, PHONE_NUMBER_HOOK_ENABLED, (*settings.find("PHONE_NUMBER_HOOK_ENABLED")).second);
setConfig(HOOKS, PHONE_NUMBER_HOOK_ADD_PREFIX, (*settings.find("PHONE_NUMBER_HOOK_ADD_PREFIX")).second);
// Write it to the configuration file
saveConfig ();
......
......@@ -36,6 +36,7 @@
#include "account.h"
#include "call.h"
#include "numbercleaner.h"
#include "audio/tonelist.h" // for Tone::TONEID declaration
#include "audio/audiofile.h"
......@@ -1112,6 +1113,8 @@ private:
// Assignment Operator
ManagerImpl& operator=( const ManagerImpl& rh);
NumberCleaner *_cleaner;
/**
* Check if the call is a classic call or a direct IP-to-IP call
*/
......
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
*
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "numbercleaner.h"
#include <iostream>
NumberCleaner::NumberCleaner (void) : _prefix("") {
}
NumberCleaner::~NumberCleaner (void) {
}
std::string NumberCleaner::clean (std::string to_clean) {
strip_char (" ", &to_clean);
strip_char ("-", &to_clean);
strip_char ("(", &to_clean);
strip_char (")", &to_clean);
return to_clean.insert (0, this->get_phone_number_prefix ());
}
void NumberCleaner::strip_char (std::string to_strip, std::string *num) {
std::size_t pos;
while ( (pos=(*num).find (to_strip)) != std::string::npos) {
*num = (*num).erase (pos, 1);
}
}
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
*
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _NUMBER_CLEANER_H
#define _NUMBER_CLEANER_H
#include <string>
class NumberCleaner {
public:
NumberCleaner (void);
~NumberCleaner (void);
std::string clean (std::string to_clean);
inline void set_phone_number_prefix (std::string prefix) { _prefix = prefix; }
inline std::string get_phone_number_prefix (void) { return _prefix; }
private:
std::string _prefix;
void strip_char(std::string to_strip, std::string *num);
};
#endif
......@@ -84,6 +84,8 @@
#define URLHOOK_COMMAND "Hooks.url_command"
#define URLHOOK_SIP_ENABLED "Hooks.sip_enabled"
#define URLHOOK_IAX2_ENABLED "Hooks.iax2_enabled"
#define PHONE_NUMBER_HOOK_ENABLED "Hooks.phone_number_enabled"
#define PHONE_NUMBER_HOOK_ADD_PREFIX "Hooks.phone_number_add_prefix"
#define EMPTY_FIELD "" /** Default value for empty field */
#define DFT_STUN_SERVER "stun.ekiga.net" /** Default STUN server address */
......
include ../globals.mak
bin_PROGRAMS = pluginmanagerTester hookmanagerTester
bin_PROGRAMS = numbercleanerTester pluginmanagerTester hookmanagerTester
OBJECT_FILES= \
../src/sflphoned-managerimpl.o \
......@@ -19,7 +19,27 @@ OBJECT_FILES= \
../src/plug-in/audiorecorder/audiorecord.o \
../src/sflphoned-samplerateconverter.o \
../src/sflphoned-sdp.o \
../src/sflphoned-sdpmedia.o
../src/sflphoned-sdpmedia.o \
../src/sflphoned-numbercleaner.o
numbercleanerTester_SOURCES = \
numbercleanerTest.h \
numbercleanerTest.cpp \
TestMain.cpp
numbercleanerTester_LDADD = \
../src/libsflphone.la \
$(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) \
@ALSA_LIBS@ \
@PULSEAUDIO_LIBS@ \
@CPPUNIT_LIBS@ \
@CCEXT2_LIBS@ \
@CCGNU2_LIBS@ \
@CCRTP_LIBS@ \
@SAMPLERATE_LIBS@ \
$(PJSIP_LIBS) \
-luuid \
$(OBJECT_FILES)
pluginmanagerTester_SOURCES = \
pluginmanagerTest.h \
......
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <sstream>
#include <dlfcn.h>
#include "numbercleanerTest.h"
#define NUMBER_TEST_1 "514 333 4444"
#define NUMBER_TEST_2 "514-333-4444"
#define NUMBER_TEST_3 "(514) 333 4444"
#define NUMBER_TEST_4 "(514)-333-4444"
#define NUMBER_TEST_5 "(514) 333-4444"
#define NUMBER_TEST_6 "514 333 4444"
#define NUMBER_TEST_7 "ext 136"
#define NUMBER_TEST_8 "514 333 4444 ext. 136"
#define NUMBER_TEST_9 "514 333 4444 ext 136"
#define VALID_NUMBER "5143334444"
#define VALID_PREPENDED_NUMBER "95143334444"
using std::cout;
using std::endl;
void NumberCleanerTest::setUp(){
// Instanciate the cleaner singleton
cleaner = new NumberCleaner ();
}
void NumberCleanerTest::test_format_1 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_1) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_2 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_2) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_3 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_3) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_4 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_4) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_5 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_5) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_6 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_6) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_7 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_7) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_8 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_8) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_9 (void) {
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_9) == VALID_NUMBER);
}
void NumberCleanerTest::test_format_10 (void) {
cleaner->set_phone_number_prefix ("9");
CPPUNIT_ASSERT (cleaner->get_phone_number_prefix () == "9");
CPPUNIT_ASSERT (cleaner->clean (NUMBER_TEST_1) == VALID_PREPENDED_NUMBER);
}
void NumberCleanerTest::tearDown(){
// Delete the cleaner object
delete cleaner; cleaner=0;
}
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* 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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// Cppunit import
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestCase.h>
#include <cppunit/TestSuite.h>
#include <assert.h>
// Application import
#include "numbercleaner.h"
/*
* @file numbercleanerTest.cpp
* @brief Regroups unitary tests related to the phone number cleanup function.
*/
#ifndef _NUMBERCLEANER_TEST_
#define _NUMBERCLEANER_TEST_
class NumberCleanerTest : public CppUnit::TestCase {
/**
* Use cppunit library macros to add unit test the factory
*/
CPPUNIT_TEST_SUITE (NumberCleanerTest);
CPPUNIT_TEST (test_format_1);
CPPUNIT_TEST (test_format_2);
CPPUNIT_TEST (test_format_3);
CPPUNIT_TEST (test_format_4);
CPPUNIT_TEST (test_format_5);
CPPUNIT_TEST (test_format_6);
CPPUNIT_TEST (test_format_7);
CPPUNIT_TEST (test_format_8);
CPPUNIT_TEST (test_format_9);
CPPUNIT_TEST (test_format_10);
CPPUNIT_TEST_SUITE_END ();
public:
NumberCleanerTest() : CppUnit::TestCase("Hook Manager Tests") {}
/*
* Code factoring - Common resources can be initialized here.
* This method is called by unitcpp before each test
*/
void setUp();
void test_format_1 ();
void test_format_2 ();
void test_format_3 ();
void test_format_4 ();
void test_format_5 ();
void test_format_6 ();
void test_format_7 ();
void test_format_8 ();
void test_format_9 ();
void test_format_10 ();
/*
* Code factoring - Common resources can be released here.
* This method is called by unitcpp after each test
*/
inline void tearDown ();
private:
NumberCleaner *cleaner;
};
/* Register our test module */
CPPUNIT_TEST_SUITE_REGISTRATION( NumberCleanerTest );
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment