]> git.saurik.com Git - wxWidgets.git/commitdiff
moved wxRegEx test from console to testsuite (patch 938995)
authorVáclav Slavík <vslavik@fastmail.fm>
Wed, 21 Apr 2004 20:17:18 +0000 (20:17 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Wed, 21 Apr 2004 20:17:18 +0000 (20:17 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26906 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

13 files changed:
samples/console/console.cpp
tests/Makefile.in
tests/makefile.bcc
tests/makefile.gcc
tests/makefile.vc
tests/makefile.wat
tests/regex/regex.cpp
tests/regex/regex.inc
tests/regex/regex.pl
tests/regex/wxregex.cpp [new file with mode: 0644]
tests/test.bkl
tests/test.cpp
tests/test.dsp

index b18744999c6c43972205d0caf604e64e5aba5e4e..40c664bb0833ac449e9211538eb6aeca9de2bbff 100644 (file)
@@ -2287,163 +2287,6 @@ static void TestPathList()
 
 #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()
 {
     wxPuts(_T("*** Testing RE interactively ***"));
@@ -6156,19 +5999,9 @@ int main(int argc, char **argv)
     TestRegConfRead();
 #endif // TEST_REGCONF
 
-#ifdef TEST_REGEX
-    // TODO: write a real test using src/regex/tests file
-    #if TEST_ALL
-        TestRegExCompile();
-        TestRegExMatch();
-        TestRegExSubmatch();
-        TestRegExReplacement();
-
-        #if TEST_INTERACTIVE
-            TestRegExInteractive();
-        #endif
-    #endif
-#endif // TEST_REGEX
+#if defined TEST_REGEX && TEST_INTERACTIVE
+    TestRegExInteractive();
+#endif // defined TEST_REGEX && TEST_INTERACTIVE
 
 #ifdef TEST_REGISTRY
     TestRegistryRead();
index 27f4878c3358d1e1d85dce78c59bfa555f02a474..c00b28af80d599b6580cbcfe213eaf6c56eea29d 100644 (file)
@@ -40,6 +40,7 @@ TEST_OBJECTS =  \
        test_main.o \
        test_formatconverter.o \
        test_regex.o \
+       test_wxregex.o \
        test_filesys.o \
        test_arrays.o \
        test_longlong.o \
@@ -123,6 +124,9 @@ test_formatconverter.o: $(srcdir)/formatconverter/formatconverter.cpp
 test_regex.o: $(srcdir)/regex/regex.cpp
        $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $<
 
+test_wxregex.o: $(srcdir)/regex/wxregex.cpp
+       $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $<
+
 test_filesys.o: $(srcdir)/filesys/filesys.cpp
        $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $<
 
index 0ed5ea706a186d72c1f6eacada0479494bfc75a1..1aaea9790f68b989c0faccddeea64542c6162bb5 100644 (file)
@@ -34,6 +34,7 @@ TEST_OBJECTS =  \
        $(OBJS)\test_main.obj \
        $(OBJS)\test_formatconverter.obj \
        $(OBJS)\test_regex.obj \
+       $(OBJS)\test_wxregex.obj \
        $(OBJS)\test_filesys.obj \
        $(OBJS)\test_arrays.obj \
        $(OBJS)\test_longlong.obj \
@@ -174,6 +175,9 @@ $(OBJS)\test_formatconverter.obj: .\formatconverter\formatconverter.cpp
 $(OBJS)\test_regex.obj: .\regex\regex.cpp
        $(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
        $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) $**
 
index 99f1ca299ab159a00cd8af0d6c51ea325738df3f..a47b49d489e64996a1fe82cb6f1b80a5ec9964d9 100644 (file)
@@ -25,6 +25,7 @@ TEST_OBJECTS =  \
        $(OBJS)\test_main.o \
        $(OBJS)\test_formatconverter.o \
        $(OBJS)\test_regex.o \
+       $(OBJS)\test_wxregex.o \
        $(OBJS)\test_filesys.o \
        $(OBJS)\test_arrays.o \
        $(OBJS)\test_longlong.o \
@@ -168,6 +169,9 @@ $(OBJS)\test_formatconverter.o: ./formatconverter/formatconverter.cpp
 $(OBJS)\test_regex.o: ./regex/regex.cpp
        $(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
 
+$(OBJS)\test_wxregex.o: ./regex/wxregex.cpp
+       $(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
+
 $(OBJS)\test_filesys.o: ./filesys/filesys.cpp
        $(CXX) -c -o $@ $(TEST_CXXFLAGS) $<
 
index a2f6040190afb1bf357155286c2de51ff486ff96..9cb9c9e2e75f99b0091726be62a3f7101d21fe4a 100644 (file)
@@ -27,6 +27,7 @@ TEST_OBJECTS =  \
        $(OBJS)\test_main.obj \
        $(OBJS)\test_formatconverter.obj \
        $(OBJS)\test_regex.obj \
+       $(OBJS)\test_wxregex.obj \
        $(OBJS)\test_filesys.obj \
        $(OBJS)\test_arrays.obj \
        $(OBJS)\test_longlong.obj \
@@ -230,6 +231,9 @@ $(OBJS)\test_formatconverter.obj: .\formatconverter\formatconverter.cpp
 $(OBJS)\test_regex.obj: .\regex\regex.cpp
        $(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
        $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) $**
 
index 963bf1520f38107a8628337d96ee608460faddc2..2d5cc67571bffd5bcca9c6685ee3e9f105e0a9f4 100644 (file)
@@ -175,6 +175,7 @@ TEST_OBJECTS =  &
        $(OBJS)\test_main.obj &
        $(OBJS)\test_formatconverter.obj &
        $(OBJS)\test_regex.obj &
+       $(OBJS)\test_wxregex.obj &
        $(OBJS)\test_filesys.obj &
        $(OBJS)\test_arrays.obj &
        $(OBJS)\test_longlong.obj &
@@ -224,6 +225,9 @@ $(OBJS)\test_formatconverter.obj :  .AUTODEPEND .\formatconverter\formatconverte
 $(OBJS)\test_regex.obj :  .AUTODEPEND .\regex\regex.cpp
        $(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
        $(CXX) -zq -fo=$^@ $(TEST_CXXFLAGS) $<
 
index 3905dcdcc5ce53aa82b6aa924faf427c4c1d3d3e..d2eb0d4056525477c8669393dbd2f2c6b0a55823 100644 (file)
 //  test --verbose regex
 // 
 // 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
 // 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'.
 // 
 
-#if defined(__GNUG__) && !defined(__APPLE__)
-    #pragma implementation
-    #pragma interface
-#endif
-
 // For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"
 
@@ -48,7 +43,6 @@
 
 #include "wx/regex.h"
 #include "wx/cppunit.h"
-#include <iomanip>
 #include <stdexcept>
 
 using namespace std;
@@ -85,7 +79,6 @@ private:
     wxString Conv(const char *str);
     void parseFlags(const wxString& flags);
     void doTest(int flavor);
-    static size_t matchCount(const wxString& expr, int flags);
     static wxString quote(const wxString& arg);
     const wxChar *convError() const { return _T("<cannot convert>"); }
 
@@ -225,9 +218,8 @@ void RegExTestCase::doTest(int flavor)
     wxRegEx re(m_pattern, m_compileFlags | flavor);
 
     // 'e' - test that the pattern fails to compile
-    if (m_mode == 'e')
-    {
-        failIf(re.IsValid(), _T("compile suceeded (should fail)"));
+    if (m_mode == 'e') {
+        failIf(re.IsValid(), _T("compile succeeded (should fail)"));
         return;
     }
     failIf(!re.IsValid(), _T("compile failed"));
@@ -235,20 +227,21 @@ void RegExTestCase::doTest(int flavor)
     bool matches = re.Matches(m_data, m_matchFlags);
 
     // 'f' or 'p' - test that the pattern does not match
-    if (m_mode == 'f' || m_mode == 'p')
-    {
-        failIf(matches, _T("match suceeded (should fail)"));
+    if (m_mode == 'f' || m_mode == 'p') {
+        failIf(matches, _T("match succeeded (should fail)"));
         return;
     }
 
     // otherwise 'm' or 'i' - test the pattern does match
     failIf(!matches, _T("match failed"));
 
-    // Check that wxRegEx is going to allocate a large enough array for the
-    // results we are supposed to get
-    failIf(m_expected.size() > matchCount(m_pattern, m_compileFlags | flavor),
-           _T("wxRegEx has not allocated a large enough array for the ")
-           _T("number of results expected"));
+    if (m_compileFlags & wxRE_NOSUB)
+        return;
+
+    // check wxRegEx has correctly counted the number of subexpressions
+    failIf(m_expected.size() != re.GetMatchCount(),
+           wxString::Format(_T("GetMatchCount() == %d, expected %d"),
+                            re.GetMatchCount(), m_expected.size()));
 
     wxString result;
     size_t start, len;
@@ -323,37 +316,6 @@ wxString RegExTestCase::quote(const wxString& arg)
         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
index e53d36451abf6c7a274ab7d05f5ef4008ce9647d..2276f90f079553296a9bc0b34823237c1e6350aa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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.
  *   wxreg.test: Copyright (c) 2004 Mike Wetherell.
@@ -1186,13 +1186,13 @@ Test *regextest_extra_1::suite()
 {
     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 505048", "-", "\\A\\s*[^<]*\\s*<([^>]+)>", "a<a>", NULL);
-    suite->add("m", "Bug 505048", "-", "\\A\\s*([^b]*)b", "ab", NULL);
-    suite->add("m", "Bug 505048", "-", "\\A\\s*[^b]*(b)", "ab", NULL);
-    suite->add("m", "Bug 505048", "-", "\\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*[^<]*\\s*<([^>]+)>", "a<a>", NULL);
+    suite->add("m", "Bug 505048", "o", "\\A\\s*([^b]*)b", "ab", NULL);
+    suite->add("m", "Bug 505048", "o", "\\A\\s*[^b]*(b)", "ab", NULL);
+    suite->add("m", "Bug 505048", "o", "\\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("i", "Bug 505048", "-", "\\A\\s*[^b]*b", "ab", "0 1", NULL);
 
index cf2ba46d59be6e888b8f94eab472f66f44a7efb7..2402864171cdbb4ab3cb0b3c23841f1cfc47deba 100755 (executable)
@@ -426,7 +426,7 @@ for (@input)
         my $results = $opts =~ /-inline/ && $test ne 'f' ? $extras[$i+2] : '';
 
         # 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;
         handle_test @args;
     }
diff --git a/tests/regex/wxregex.cpp b/tests/regex/wxregex.cpp
new file mode 100644 (file)
index 0000000..fd8f192
--- /dev/null
@@ -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
index 76e17e2514e9849da40afc6b431859391b8ffefe..56e4e9314e5cadd5052e0936582bb653efff9f21 100644 (file)
@@ -12,6 +12,7 @@
             mbconv/main.cpp
             formatconverter/formatconverter.cpp
             regex/regex.cpp
+            regex/wxregex.cpp
             filesys/filesys.cpp
             arrays/arrays.cpp
             longlong/longlong.cpp
index d54a53583f569d467647a24c432ee995a67f2cec..2ed648499314b2cd1cb12d8cf84bf45628e55f7b 100644 (file)
@@ -143,7 +143,7 @@ void TestApp::List(Test *test, const string& parent /*=""*/) const
     TestSuite *suite = dynamic_cast<TestSuite*>(test);
     string name;
 
-    if (suite || m_longlist) {
+    if (suite) {
         // take the last component of the name and append to the parent
         name = test->getName();
         string::size_type i = name.find_last_of(".:");
@@ -156,9 +156,7 @@ void TestApp::List(Test *test, const string& parent /*=""*/) const
                 cout << "  ";
             cout << "  " << name.substr(i + 1) << "\n";
         }
-    }
 
-    if (suite) {
         typedef const vector<Test*> Tests;
         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)
             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";
+    }
 }
index 2fc12e1c66032744cfe7f0e984a731a419392f5c..6e44c44fbffdd956251e223bf286a76b7c6a083f 100644 (file)
@@ -483,6 +483,10 @@ SOURCE=.\test.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\regex\wxregex.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\streams\zlibstream.cpp
 # End Source File
 # End Group