moved wxRegEx test from console to testsuite (patch 938995)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26906 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2004-04-21 20:17:18 +00:00
parent 17aa28a91b
commit bc10103ec8
13 changed files with 395 additions and 231 deletions

View File

@@ -2287,163 +2287,6 @@ static void TestPathList()
#include "wx/regex.h" #include "wx/regex.h"
static void TestRegExCompile()
{
wxPuts(_T("*** Testing RE compilation ***\n"));
static struct RegExCompTestData
{
const wxChar *pattern;
bool correct;
} regExCompTestData[] =
{
{ _T("foo"), true },
{ _T("foo("), false },
{ _T("foo(bar"), false },
{ _T("foo(bar)"), true },
{ _T("foo["), false },
{ _T("foo[bar"), false },
{ _T("foo[bar]"), true },
{ _T("foo{"), true },
{ _T("foo{1"), false },
{ _T("foo{bar"), true },
{ _T("foo{1}"), true },
{ _T("foo{1,2}"), true },
{ _T("foo{bar}"), true },
{ _T("foo*"), true },
{ _T("foo**"), false },
{ _T("foo+"), true },
{ _T("foo++"), false },
{ _T("foo?"), true },
{ _T("foo??"), false },
{ _T("foo?+"), false },
};
wxRegEx re;
for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
{
const RegExCompTestData& data = regExCompTestData[n];
bool ok = re.Compile(data.pattern);
wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
data.pattern,
ok ? wxEmptyString : _T("not "),
ok == data.correct ? _T("ok") : _T("ERROR"));
}
}
static void TestRegExMatch()
{
wxPuts(_T("*** Testing RE matching ***\n"));
static struct RegExMatchTestData
{
const wxChar *pattern;
const wxChar *text;
bool correct;
} regExMatchTestData[] =
{
{ _T("foo"), _T("bar"), false },
{ _T("foo"), _T("foobar"), true },
{ _T("^foo"), _T("foobar"), true },
{ _T("^foo"), _T("barfoo"), false },
{ _T("bar$"), _T("barbar"), true },
{ _T("bar$"), _T("barbar "), false },
};
for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
{
const RegExMatchTestData& data = regExMatchTestData[n];
wxRegEx re(data.pattern);
bool ok = re.Matches(data.text);
wxPrintf(_T("'%s' %s %s (%s)\n"),
data.pattern,
ok ? _T("matches") : _T("doesn't match"),
data.text,
ok == data.correct ? _T("ok") : _T("ERROR"));
}
}
static void TestRegExSubmatch()
{
wxPuts(_T("*** Testing RE subexpressions ***\n"));
wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
if ( !re.IsValid() )
{
wxPuts(_T("ERROR: compilation failed."));
return;
}
wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
if ( !re.Matches(text) )
{
wxPuts(_T("ERROR: match expected."));
}
else
{
wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
re.GetMatch(text, 3).c_str(),
re.GetMatch(text, 2).c_str(),
re.GetMatch(text, 4).c_str(),
re.GetMatch(text, 1).c_str());
}
}
static void TestRegExReplacement()
{
wxPuts(_T("*** Testing RE replacement ***"));
static struct RegExReplTestData
{
const wxChar *text;
const wxChar *repl;
const wxChar *result;
size_t count;
} regExReplTestData[] =
{
{ _T("foo123"), _T("bar"), _T("bar"), 1 },
{ _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
{ _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
{ _T("123foo"), _T("bar"), _T("123foo"), 0 },
{ _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
{ _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
{ _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
};
const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
wxRegEx re(pattern);
wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
{
const RegExReplTestData& data = regExReplTestData[n];
wxString text = data.text;
size_t nRepl = re.Replace(&text, data.repl);
wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
data.text, data.repl,
nRepl, nRepl == 1 ? wxEmptyString : _T("es"),
text.c_str());
if ( text == data.result && nRepl == data.count )
{
wxPuts(_T("ok)"));
}
else
{
wxPrintf(_T("ERROR: should be %u and '%s')\n"),
data.count, data.result);
}
}
}
static void TestRegExInteractive() static void TestRegExInteractive()
{ {
wxPuts(_T("*** Testing RE interactively ***")); wxPuts(_T("*** Testing RE interactively ***"));
@@ -6156,19 +5999,9 @@ int main(int argc, char **argv)
TestRegConfRead(); TestRegConfRead();
#endif // TEST_REGCONF #endif // TEST_REGCONF
#ifdef TEST_REGEX #if defined TEST_REGEX && TEST_INTERACTIVE
// TODO: write a real test using src/regex/tests file
#if TEST_ALL
TestRegExCompile();
TestRegExMatch();
TestRegExSubmatch();
TestRegExReplacement();
#if TEST_INTERACTIVE
TestRegExInteractive(); TestRegExInteractive();
#endif #endif // defined TEST_REGEX && TEST_INTERACTIVE
#endif
#endif // TEST_REGEX
#ifdef TEST_REGISTRY #ifdef TEST_REGISTRY
TestRegistryRead(); TestRegistryRead();

View File

@@ -40,6 +40,7 @@ TEST_OBJECTS = \
test_main.o \ test_main.o \
test_formatconverter.o \ test_formatconverter.o \
test_regex.o \ test_regex.o \
test_wxregex.o \
test_filesys.o \ test_filesys.o \
test_arrays.o \ test_arrays.o \
test_longlong.o \ test_longlong.o \
@@ -123,6 +124,9 @@ test_formatconverter.o: $(srcdir)/formatconverter/formatconverter.cpp
test_regex.o: $(srcdir)/regex/regex.cpp test_regex.o: $(srcdir)/regex/regex.cpp
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $< $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $<
test_wxregex.o: $(srcdir)/regex/wxregex.cpp
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $<
test_filesys.o: $(srcdir)/filesys/filesys.cpp test_filesys.o: $(srcdir)/filesys/filesys.cpp
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $< $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $<

View File

@@ -34,6 +34,7 @@ TEST_OBJECTS = \
$(OBJS)\test_main.obj \ $(OBJS)\test_main.obj \
$(OBJS)\test_formatconverter.obj \ $(OBJS)\test_formatconverter.obj \
$(OBJS)\test_regex.obj \ $(OBJS)\test_regex.obj \
$(OBJS)\test_wxregex.obj \
$(OBJS)\test_filesys.obj \ $(OBJS)\test_filesys.obj \
$(OBJS)\test_arrays.obj \ $(OBJS)\test_arrays.obj \
$(OBJS)\test_longlong.obj \ $(OBJS)\test_longlong.obj \
@@ -174,6 +175,9 @@ $(OBJS)\test_formatconverter.obj: .\formatconverter\formatconverter.cpp
$(OBJS)\test_regex.obj: .\regex\regex.cpp $(OBJS)\test_regex.obj: .\regex\regex.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $** $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
$(OBJS)\test_wxregex.obj: .\regex\wxregex.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
$(OBJS)\test_filesys.obj: .\filesys\filesys.cpp $(OBJS)\test_filesys.obj: .\filesys\filesys.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $** $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**

View File

@@ -25,6 +25,7 @@ TEST_OBJECTS = \
$(OBJS)\test_main.o \ $(OBJS)\test_main.o \
$(OBJS)\test_formatconverter.o \ $(OBJS)\test_formatconverter.o \
$(OBJS)\test_regex.o \ $(OBJS)\test_regex.o \
$(OBJS)\test_wxregex.o \
$(OBJS)\test_filesys.o \ $(OBJS)\test_filesys.o \
$(OBJS)\test_arrays.o \ $(OBJS)\test_arrays.o \
$(OBJS)\test_longlong.o \ $(OBJS)\test_longlong.o \
@@ -168,6 +169,9 @@ $(OBJS)\test_formatconverter.o: ./formatconverter/formatconverter.cpp
$(OBJS)\test_regex.o: ./regex/regex.cpp $(OBJS)\test_regex.o: ./regex/regex.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $< $(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_wxregex.o: ./regex/wxregex.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_filesys.o: ./filesys/filesys.cpp $(OBJS)\test_filesys.o: ./filesys/filesys.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $< $(CXX) -c -o $@ $(TEST_CXXFLAGS) $<

View File

@@ -27,6 +27,7 @@ TEST_OBJECTS = \
$(OBJS)\test_main.obj \ $(OBJS)\test_main.obj \
$(OBJS)\test_formatconverter.obj \ $(OBJS)\test_formatconverter.obj \
$(OBJS)\test_regex.obj \ $(OBJS)\test_regex.obj \
$(OBJS)\test_wxregex.obj \
$(OBJS)\test_filesys.obj \ $(OBJS)\test_filesys.obj \
$(OBJS)\test_arrays.obj \ $(OBJS)\test_arrays.obj \
$(OBJS)\test_longlong.obj \ $(OBJS)\test_longlong.obj \
@@ -230,6 +231,9 @@ $(OBJS)\test_formatconverter.obj: .\formatconverter\formatconverter.cpp
$(OBJS)\test_regex.obj: .\regex\regex.cpp $(OBJS)\test_regex.obj: .\regex\regex.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $** $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
$(OBJS)\test_wxregex.obj: .\regex\wxregex.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
$(OBJS)\test_filesys.obj: .\filesys\filesys.cpp $(OBJS)\test_filesys.obj: .\filesys\filesys.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $** $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**

View File

@@ -175,6 +175,7 @@ TEST_OBJECTS = &
$(OBJS)\test_main.obj & $(OBJS)\test_main.obj &
$(OBJS)\test_formatconverter.obj & $(OBJS)\test_formatconverter.obj &
$(OBJS)\test_regex.obj & $(OBJS)\test_regex.obj &
$(OBJS)\test_wxregex.obj &
$(OBJS)\test_filesys.obj & $(OBJS)\test_filesys.obj &
$(OBJS)\test_arrays.obj & $(OBJS)\test_arrays.obj &
$(OBJS)\test_longlong.obj & $(OBJS)\test_longlong.obj &
@@ -224,6 +225,9 @@ $(OBJS)\test_formatconverter.obj : .AUTODEPEND .\formatconverter\formatconverte
$(OBJS)\test_regex.obj : .AUTODEPEND .\regex\regex.cpp $(OBJS)\test_regex.obj : .AUTODEPEND .\regex\regex.cpp
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $< $(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_wxregex.obj : .AUTODEPEND .\regex\wxregex.cpp
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_filesys.obj : .AUTODEPEND .\filesys\filesys.cpp $(OBJS)\test_filesys.obj : .AUTODEPEND .\filesys\filesys.cpp
$(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $< $(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<

View File

@@ -22,18 +22,13 @@
// test --verbose regex // test --verbose regex
// //
// The tests here are for the builtin library, tests for wxRegEx in general // The tests here are for the builtin library, tests for wxRegEx in general
// should go in another module. // should go in wxregex.cpp
// //
// The tests are generated from Henry Spencer's reg.test, additional test // The tests are generated from Henry Spencer's reg.test, additional test
// can be added in wxreg.test. These test files are then turned into a C++ // can be added in wxreg.test. These test files are then turned into a C++
// include file 'regex.inc' (included below) using a script 'regex.pl'. // include file 'regex.inc' (included below) using a script 'regex.pl'.
// //
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma implementation
#pragma interface
#endif
// For compilers that support precompilation, includes "wx/wx.h". // For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
@@ -48,7 +43,6 @@
#include "wx/regex.h" #include "wx/regex.h"
#include "wx/cppunit.h" #include "wx/cppunit.h"
#include <iomanip>
#include <stdexcept> #include <stdexcept>
using namespace std; using namespace std;
@@ -85,7 +79,6 @@ private:
wxString Conv(const char *str); wxString Conv(const char *str);
void parseFlags(const wxString& flags); void parseFlags(const wxString& flags);
void doTest(int flavor); void doTest(int flavor);
static size_t matchCount(const wxString& expr, int flags);
static wxString quote(const wxString& arg); static wxString quote(const wxString& arg);
const wxChar *convError() const { return _T("<cannot convert>"); } const wxChar *convError() const { return _T("<cannot convert>"); }
@@ -225,9 +218,8 @@ void RegExTestCase::doTest(int flavor)
wxRegEx re(m_pattern, m_compileFlags | flavor); wxRegEx re(m_pattern, m_compileFlags | flavor);
// 'e' - test that the pattern fails to compile // 'e' - test that the pattern fails to compile
if (m_mode == 'e') if (m_mode == 'e') {
{ failIf(re.IsValid(), _T("compile succeeded (should fail)"));
failIf(re.IsValid(), _T("compile suceeded (should fail)"));
return; return;
} }
failIf(!re.IsValid(), _T("compile failed")); failIf(!re.IsValid(), _T("compile failed"));
@@ -235,20 +227,21 @@ void RegExTestCase::doTest(int flavor)
bool matches = re.Matches(m_data, m_matchFlags); bool matches = re.Matches(m_data, m_matchFlags);
// 'f' or 'p' - test that the pattern does not match // 'f' or 'p' - test that the pattern does not match
if (m_mode == 'f' || m_mode == 'p') if (m_mode == 'f' || m_mode == 'p') {
{ failIf(matches, _T("match succeeded (should fail)"));
failIf(matches, _T("match suceeded (should fail)"));
return; return;
} }
// otherwise 'm' or 'i' - test the pattern does match // otherwise 'm' or 'i' - test the pattern does match
failIf(!matches, _T("match failed")); failIf(!matches, _T("match failed"));
// Check that wxRegEx is going to allocate a large enough array for the if (m_compileFlags & wxRE_NOSUB)
// results we are supposed to get return;
failIf(m_expected.size() > matchCount(m_pattern, m_compileFlags | flavor),
_T("wxRegEx has not allocated a large enough array for the ") // check wxRegEx has correctly counted the number of subexpressions
_T("number of results expected")); failIf(m_expected.size() != re.GetMatchCount(),
wxString::Format(_T("GetMatchCount() == %d, expected %d"),
re.GetMatchCount(), m_expected.size()));
wxString result; wxString result;
size_t start, len; size_t start, len;
@@ -323,37 +316,6 @@ wxString RegExTestCase::quote(const wxString& arg)
str : _T("\"") + str + _T("\""); str : _T("\"") + str + _T("\"");
} }
// Count the number of subexpressions (taken from wxRegExImpl::Compile)
//
size_t RegExTestCase::matchCount(const wxString& expr, int flags)
{
// there is always one for the whole expression
size_t nMatches = 1;
// and some more for bracketed subexperessions
for ( const wxChar *cptr = expr; *cptr; cptr++ )
{
if ( *cptr == _T('\\') )
{
// in basic RE syntax groups are inside \(...\)
if ( *++cptr == _T('(') && (flags & wxRE_BASIC) )
{
nMatches++;
}
}
else if ( *cptr == _T('(') && !(flags & wxRE_BASIC) )
{
// we know that the previous character is not an unquoted
// backslash because it would have been eaten above, so we
// have a bar '(' and this indicates a group start for the
// extended syntax
nMatches++;
}
}
return nMatches;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Test suite // Test suite

View File

@@ -1,7 +1,7 @@
/* /*
* Test data for wxRegEx (UTF-8 encoded) * Test data for wxRegEx (UTF-8 encoded)
* *
* Generated Fri Mar 5 21:35:22 2004 by regex.pl from the following files: * Generated Tue Apr 20 20:35:05 2004 by regex.pl from the following files:
* *
* reg.test: Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * reg.test: Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* wxreg.test: Copyright (c) 2004 Mike Wetherell. * wxreg.test: Copyright (c) 2004 Mike Wetherell.
@@ -1186,13 +1186,13 @@ Test *regextest_extra_1::suite()
{ {
RegExTestSuite *suite = new regextest_extra_1; RegExTestSuite *suite = new regextest_extra_1;
suite->add("m", "Bug 230589", "-", "[ ]*(^|[^%])%V", "*%V2", NULL); suite->add("m", "Bug 230589", "o", "[ ]*(^|[^%])%V", "*%V2", NULL);
suite->add("m", "Bug 504785", "-", "([^_.]*)([^.]*)\\.(..)(.).*", "bbcos_001_c01.q1la", "bbcos_001_c01.q1la", "bbcos", "_001_c01", "q1", "l", NULL); suite->add("m", "Bug 504785", "-", "([^_.]*)([^.]*)\\.(..)(.).*", "bbcos_001_c01.q1la", "bbcos_001_c01.q1la", "bbcos", "_001_c01", "q1", "l", NULL);
suite->add("m", "Bug 505048", "-", "\\A\\s*[^<]*\\s*<([^>]+)>", "a<a>", NULL); suite->add("m", "Bug 505048", "o", "\\A\\s*[^<]*\\s*<([^>]+)>", "a<a>", NULL);
suite->add("m", "Bug 505048", "-", "\\A\\s*([^b]*)b", "ab", NULL); suite->add("m", "Bug 505048", "o", "\\A\\s*([^b]*)b", "ab", NULL);
suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*(b)", "ab", NULL); suite->add("m", "Bug 505048", "o", "\\A\\s*[^b]*(b)", "ab", NULL);
suite->add("m", "Bug 505048", "-", "\\A(\\s*)[^b]*(b)", "ab", NULL); suite->add("m", "Bug 505048", "o", "\\A(\\s*)[^b]*(b)", "ab", NULL);
suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", NULL); suite->add("m", "Bug 505048", "o", "\\A\\s*[^b]*b", "ab", NULL);
suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "ab", NULL); suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "ab", NULL);
suite->add("i", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "0 1", NULL); suite->add("i", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "0 1", NULL);

View File

@@ -426,7 +426,7 @@ for (@input)
my $results = $opts =~ /-inline/ && $test ne 'f' ? $extras[$i+2] : ''; my $results = $opts =~ /-inline/ && $test ne 'f' ? $extras[$i+2] : '';
# get them all in the right order and print # get them all in the right order and print
unshift @args, $test, parsetcl($id), '-'; unshift @args, $test, parsetcl($id), $results ? '-' : 'o';
push @args, parsetcl(parsetcl($results)) if $results; push @args, parsetcl(parsetcl($results)) if $results;
handle_test @args; handle_test @args;
} }

340
tests/regex/wxregex.cpp Normal file
View File

@@ -0,0 +1,340 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/regex/wxregex.cpp
// Purpose: Test wxRegEx
// Author: Vadim Zeitlin, Mike Wetherell
// RCS-ID: $Id$
// Copyright: Vadim Zeitlin, Mike Wetherell
// Licence: wxWidgets licence
///////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#ifdef __BORLANDC__
# pragma hdrstop
#endif
#ifndef WX_PRECOMP
# include "wx/wx.h"
#endif
#if wxUSE_REGEX
#include "wx/regex.h"
#include "wx/cppunit.h"
#include "wx/tokenzr.h"
#include <string>
using namespace std;
using namespace CppUnit;
///////////////////////////////////////////////////////////////////////////////
// Compile Test
class RegExCompileTestCase : public TestCase
{
public:
RegExCompileTestCase(const char *name, const wxString& pattern,
bool correct, int flags)
: TestCase(name),
m_pattern(pattern),
m_correct(correct),
m_flags(flags)
{ }
protected:
void runTest();
private:
wxString m_pattern;
bool m_correct;
int m_flags;
};
void RegExCompileTestCase::runTest()
{
wxRegEx re;
bool ok = re.Compile(m_pattern, m_flags);
if (m_correct)
CPPUNIT_ASSERT_MESSAGE("compile failed", ok);
else
CPPUNIT_ASSERT_MESSAGE("compile succeeded (should fail)", !ok);
}
///////////////////////////////////////////////////////////////////////////////
// Match Test
class RegExMatchTestCase : public TestCase
{
public:
RegExMatchTestCase(const char *name, const wxString& pattern,
const wxString& text, const char *expected,
int flags)
: TestCase(name),
m_pattern(pattern),
m_text(text),
m_expected(expected),
m_flags(flags)
{ }
protected:
void runTest();
private:
wxString m_pattern;
wxString m_text;
const char *m_expected;
int m_flags;
};
void RegExMatchTestCase::runTest()
{
int compileFlags = m_flags & ~(wxRE_NOTBOL | wxRE_NOTEOL);
int matchFlags = m_flags & (wxRE_NOTBOL | wxRE_NOTEOL);
wxRegEx re(m_pattern, compileFlags);
CPPUNIT_ASSERT_MESSAGE("compile failed", re.IsValid());
bool ok = re.Matches(m_text, matchFlags);
if (m_expected) {
CPPUNIT_ASSERT_MESSAGE("match failed", ok);
wxStringTokenizer tkz(wxString(m_expected, *wxConvCurrent),
_T("\t"), wxTOKEN_RET_EMPTY);
size_t i;
for (i = 0; i < re.GetMatchCount() && tkz.HasMoreTokens(); i++) {
wxString expected = tkz.GetNextToken();
wxString result = re.GetMatch(m_text, i);
wxString msgstr;
msgstr.Printf(_T("\\%d == '%s' (expected '%s')"),
(int)i, result.c_str(), expected.c_str());
const char *msg = msgstr.mb_str();
CPPUNIT_ASSERT_MESSAGE(msg, result == expected);
}
if ((m_flags & wxRE_NOSUB) == 0)
CPPUNIT_ASSERT(re.GetMatchCount() == i);
}
else {
CPPUNIT_ASSERT_MESSAGE("match succeeded (should fail)", !ok);
}
}
///////////////////////////////////////////////////////////////////////////////
// Replacement Test
class RegExReplaceTestCase : public TestCase
{
public:
RegExReplaceTestCase(const char *name, const wxString& pattern,
const wxString& text, const wxString& repl,
const wxString& expected, size_t count, int flags)
: TestCase(name),
m_pattern(pattern),
m_text(text),
m_repl(repl),
m_expected(expected),
m_count(count),
m_flags(flags)
{ }
protected:
void runTest();
private:
wxString m_pattern;
wxString m_text;
wxString m_repl;
wxString m_expected;
size_t m_count;
int m_flags;
};
void RegExReplaceTestCase::runTest()
{
wxRegEx re(m_pattern, m_flags);
wxString text(m_text);
size_t nRepl = re.Replace(&text, m_repl);
wxString msgstr;
msgstr.Printf(_T("returns '%s' (expected '%s')"), text.c_str(), m_expected.c_str());
const char *msg = msgstr.mb_str();
CPPUNIT_ASSERT_MESSAGE(msg, text == m_expected);
msgstr.Printf(_T("matches %d times (expected %d)"), nRepl, m_count);
msg = msgstr.mb_str();
CPPUNIT_ASSERT_MESSAGE(msg, nRepl == m_count);
}
///////////////////////////////////////////////////////////////////////////////
// The suite
class wxRegExTestSuite : public TestSuite
{
public:
wxRegExTestSuite() : TestSuite("wxRegExTestSuite") { }
static Test *suite();
private:
void add(const char *pattern, bool correct, int flags = wxRE_DEFAULT);
void add(const char *pattern, const char *text,
const char *expected = NULL, int flags = wxRE_DEFAULT);
void add(const char *pattern, const char *text, const char *replacement,
const char *expected, size_t count, int flags = wxRE_DEFAULT);
static wxString FlagStr(int flags);
static wxString Conv(const char *str) { return wxString(str, *wxConvCurrent); }
};
// Build the suite (static)
//
Test *wxRegExTestSuite::suite()
{
wxRegExTestSuite *suite = new wxRegExTestSuite;
// Compile tests
// pattern, expected result
suite->add("foo", true);
suite->add("foo(", false);
suite->add("foo(bar", false);
suite->add("foo(bar)", true);
suite->add("foo[", false);
suite->add("foo[bar", false);
suite->add("foo[bar]", true);
suite->add("foo{1", false);
suite->add("foo{1}", true);
suite->add("foo{1,2}", true);
suite->add("foo*", true);
suite->add("foo+", true);
suite->add("foo?", true);
// Match tests
// pattern, text, expected results (match, followed by submatches
// tab separated, or NULL for no match expected)
suite->add("foo", "bar");
suite->add("foo", "foobar", "foo");
suite->add("^foo", "foobar", "foo");
suite->add("^foo", "barfoo");
suite->add("bar$", "barbar", "bar");
suite->add("bar$", "barbar ");
suite->add("OoBa", "FoObAr", "oObA", wxRE_ICASE);
suite->add("^[A-Z].*$", "AA\nbb\nCC", "AA\nbb\nCC");
suite->add("^[A-Z].*$", "AA\nbb\nCC", "AA", wxRE_NEWLINE);
suite->add("^[a-z].*$", "AA\nbb\nCC", "bb", wxRE_NEWLINE);
suite->add("^[A-Z].*$", "AA\nbb\nCC", "CC", wxRE_NEWLINE | wxRE_NOTBOL);
suite->add("^[A-Z].*$", "AA\nbb\nCC", NULL, wxRE_NEWLINE | wxRE_NOTBOL | wxRE_NOTEOL);
suite->add("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).* ([[:digit:]]+)$",
"Fri Jul 13 18:37:52 CEST 2001",
"Fri Jul 13 18:37:52 CEST 2001\tFri\tJul\t13\t2001");
// Replace tests
// pattern, text, replacement, expected result and number of matches
const char *patn = "([a-z]+)[^0-9]*([0-9]+)";
suite->add(patn, "foo123", "bar", "bar", 1);
suite->add(patn, "foo123", "\\2\\1", "123foo", 1);
suite->add(patn, "foo_123", "\\2\\1", "123foo", 1);
suite->add(patn, "123foo", "bar", "123foo", 0);
suite->add(patn, "123foo456foo", "&&", "123foo456foo456foo", 1);
suite->add(patn, "123foo456foo", "\\0\\0", "123foo456foo456foo", 1);
suite->add(patn, "foo123foo123", "bar", "barbar", 2);
suite->add(patn, "foo123_foo456_foo789", "bar", "bar_bar_bar", 3);
return suite;
}
// Add a compile test
//
void wxRegExTestSuite::add(
const char *pattern,
bool correct,
int flags /*=wxRE_DEFAULT*/)
{
addTest(new RegExCompileTestCase(
(_T("/") + Conv(pattern) + _T("/") + FlagStr(flags)).mb_str(),
Conv(pattern), correct, flags));
}
// Add a match test
//
void wxRegExTestSuite::add(
const char *pattern,
const char *text,
const char *expected /*=NULL*/,
int flags /*=wxRE_DEFAULT*/)
{
wxString name;
name << _T("'") << Conv(text) << _T("' =~ /") << Conv(pattern) << _T("/")
<< FlagStr(flags);
name.Replace(_T("\n"), _T("\\n"));
addTest(new RegExMatchTestCase(name.mb_str(), Conv(pattern),
Conv(text), expected, flags));
}
// Add a replace test
//
void wxRegExTestSuite::add(
const char *pattern,
const char *text,
const char *replacement,
const char *expected,
size_t count,
int flags /*=wxRE_DEFAULT*/)
{
wxString name;
name << _T("'") << Conv(text) << _T("' =~ s/") << Conv(pattern) << _T("/")
<< Conv(replacement) << _T("/g") << FlagStr(flags);
name.Replace(_T("\n"), _T("\\n"));
addTest(new RegExReplaceTestCase(
name.mb_str(), Conv(pattern), Conv(text),
Conv(replacement), Conv(expected), count, flags));
}
// Display string for the flags
//
wxString wxRegExTestSuite::FlagStr(int flags)
{
wxString str;
if (!flags)
return str;
for (int i = 0; (unsigned)flags >> i; i++) {
switch (flags & (1 << i)) {
case 0: break;
#ifdef wxHAS_REGEX_ADVANCED
case wxRE_ADVANCED: str += _T(" | wxRE_ADVANCED"); break;
#endif
case wxRE_BASIC: str += _T(" | wxRE_BASIC"); break;
case wxRE_ICASE: str += _T(" | wxRE_ICASE"); break;
case wxRE_NOSUB: str += _T(" | wxRE_NOSUB"); break;
case wxRE_NEWLINE: str += _T(" | wxRE_NEWLINE"); break;
case wxRE_NOTBOL: str += _T(" | wxRE_NOTBOL"); break;
case wxRE_NOTEOL: str += _T(" | wxRE_NOTEOL"); break;
default: wxFAIL; break;
}
}
return _T(" (") + str.Mid(3) + _T(")");
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION(wxRegExTestSuite);
// also include in it's own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(wxRegExTestSuite, "wxRegExTestSuite");
#endif // wxUSE_REGEX

View File

@@ -12,6 +12,7 @@
mbconv/main.cpp mbconv/main.cpp
formatconverter/formatconverter.cpp formatconverter/formatconverter.cpp
regex/regex.cpp regex/regex.cpp
regex/wxregex.cpp
filesys/filesys.cpp filesys/filesys.cpp
arrays/arrays.cpp arrays/arrays.cpp
longlong/longlong.cpp longlong/longlong.cpp

View File

@@ -143,7 +143,7 @@ void TestApp::List(Test *test, const string& parent /*=""*/) const
TestSuite *suite = dynamic_cast<TestSuite*>(test); TestSuite *suite = dynamic_cast<TestSuite*>(test);
string name; string name;
if (suite || m_longlist) { if (suite) {
// take the last component of the name and append to the parent // take the last component of the name and append to the parent
name = test->getName(); name = test->getName();
string::size_type i = name.find_last_of(".:"); string::size_type i = name.find_last_of(".:");
@@ -156,9 +156,7 @@ void TestApp::List(Test *test, const string& parent /*=""*/) const
cout << " "; cout << " ";
cout << " " << name.substr(i + 1) << "\n"; cout << " " << name.substr(i + 1) << "\n";
} }
}
if (suite) {
typedef const vector<Test*> Tests; typedef const vector<Test*> Tests;
typedef Tests::const_iterator Iter; typedef Tests::const_iterator Iter;
@@ -167,4 +165,10 @@ void TestApp::List(Test *test, const string& parent /*=""*/) const
for (Iter it = tests.begin(); it != tests.end(); ++it) for (Iter it = tests.begin(); it != tests.end(); ++it)
List(*it, name); List(*it, name);
} }
else if (m_longlist) {
string::size_type i = 0;
while ((i = parent.find('.', i + 1)) != string::npos)
cout << " ";
cout << " " << test->getName() << "\n";
}
} }

View File

@@ -483,6 +483,10 @@ SOURCE=.\test.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\regex\wxregex.cpp
# End Source File
# Begin Source File
SOURCE=.\streams\zlibstream.cpp SOURCE=.\streams\zlibstream.cpp
# End Source File # End Source File
# End Group # End Group