git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33401 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			340 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			340 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // 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 "testprec.h"
 | |
| 
 | |
| #ifdef __BORLANDC__
 | |
| #   pragma hdrstop
 | |
| #endif
 | |
| 
 | |
| #ifndef WX_PRECOMP
 | |
| #   include "wx/wx.h"
 | |
| #endif
 | |
| 
 | |
| #if wxUSE_REGEX
 | |
| 
 | |
| #include "wx/regex.h"
 | |
| #include "wx/tokenzr.h"
 | |
| #include <string>
 | |
| 
 | |
| using CppUnit::Test;
 | |
| using CppUnit::TestCase;
 | |
| using CppUnit::TestSuite;
 | |
| using std::string;
 | |
| 
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // 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());
 | |
| 
 | |
|             CPPUNIT_ASSERT_MESSAGE((const char*)msgstr.mb_str(),
 | |
|                                    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());
 | |
|     CPPUNIT_ASSERT_MESSAGE((const char*)msgstr.mb_str(), text == m_expected);
 | |
| 
 | |
|     msgstr.Printf(_T("matches %d times (expected %d)"), (int)nRepl, (int)m_count);
 | |
|     CPPUNIT_ASSERT_MESSAGE((const char*)msgstr.mb_str(), 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
 |