X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/72ddfce0ddea31ba493cf7af6ad428ab7c2bca4f..a9e994615409e36d441135e4fa0761cf0398a2aa:/tests/regex/wxregextest.cpp diff --git a/tests/regex/wxregextest.cpp b/tests/regex/wxregextest.cpp new file mode 100644 index 0000000000..fd8f19251f --- /dev/null +++ b/tests/regex/wxregextest.cpp @@ -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 + +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