Add wxNumberFormatter class helping to deal with thousands separators.

wxNumberFormatter formats and parses numbers with thousands separators.

Add the class itself as well as documentation and the unit test for it.

See #12166.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66710 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2011-01-19 10:47:40 +00:00
parent 6e91eb1f76
commit 6686fbad16
33 changed files with 822 additions and 4 deletions

View File

@@ -100,6 +100,7 @@ TEST_OBJECTS = \
test_wxregextest.o \
test_scopeguardtest.o \
test_iostream.o \
test_numformatter.o \
test_strings.o \
test_stdstrings.o \
test_tokenizer.o \
@@ -550,6 +551,9 @@ test_scopeguardtest.o: $(srcdir)/scopeguard/scopeguardtest.cpp $(TEST_ODEP)
test_iostream.o: $(srcdir)/strings/iostream.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/strings/iostream.cpp
test_numformatter.o: $(srcdir)/strings/numformatter.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/strings/numformatter.cpp
test_strings.o: $(srcdir)/strings/strings.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/strings/strings.cpp

View File

@@ -84,6 +84,7 @@ TEST_OBJECTS = \
$(OBJS)\test_wxregextest.obj \
$(OBJS)\test_scopeguardtest.obj \
$(OBJS)\test_iostream.obj \
$(OBJS)\test_numformatter.obj \
$(OBJS)\test_strings.obj \
$(OBJS)\test_stdstrings.obj \
$(OBJS)\test_tokenizer.obj \
@@ -593,6 +594,9 @@ $(OBJS)\test_scopeguardtest.obj: .\scopeguard\scopeguardtest.cpp
$(OBJS)\test_iostream.obj: .\strings\iostream.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\strings\iostream.cpp
$(OBJS)\test_numformatter.obj: .\strings\numformatter.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\strings\numformatter.cpp
$(OBJS)\test_strings.obj: .\strings\strings.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\strings\strings.cpp

View File

@@ -76,6 +76,7 @@ TEST_OBJECTS = \
$(OBJS)\test_wxregextest.o \
$(OBJS)\test_scopeguardtest.o \
$(OBJS)\test_iostream.o \
$(OBJS)\test_numformatter.o \
$(OBJS)\test_strings.o \
$(OBJS)\test_stdstrings.o \
$(OBJS)\test_tokenizer.o \
@@ -574,6 +575,9 @@ $(OBJS)\test_scopeguardtest.o: ./scopeguard/scopeguardtest.cpp
$(OBJS)\test_iostream.o: ./strings/iostream.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_numformatter.o: ./strings/numformatter.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_strings.o: ./strings/strings.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<

View File

@@ -78,6 +78,7 @@ TEST_OBJECTS = \
$(OBJS)\test_wxregextest.obj \
$(OBJS)\test_scopeguardtest.obj \
$(OBJS)\test_iostream.obj \
$(OBJS)\test_numformatter.obj \
$(OBJS)\test_strings.obj \
$(OBJS)\test_stdstrings.obj \
$(OBJS)\test_tokenizer.obj \
@@ -719,6 +720,9 @@ $(OBJS)\test_scopeguardtest.obj: .\scopeguard\scopeguardtest.cpp
$(OBJS)\test_iostream.obj: .\strings\iostream.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\strings\iostream.cpp
$(OBJS)\test_numformatter.obj: .\strings\numformatter.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\strings\numformatter.cpp
$(OBJS)\test_strings.obj: .\strings\strings.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\strings\strings.cpp

View File

@@ -319,6 +319,7 @@ TEST_OBJECTS = &
$(OBJS)\test_wxregextest.obj &
$(OBJS)\test_scopeguardtest.obj &
$(OBJS)\test_iostream.obj &
$(OBJS)\test_numformatter.obj &
$(OBJS)\test_strings.obj &
$(OBJS)\test_stdstrings.obj &
$(OBJS)\test_tokenizer.obj &
@@ -632,6 +633,9 @@ $(OBJS)\test_scopeguardtest.obj : .AUTODEPEND .\scopeguard\scopeguardtest.cpp
$(OBJS)\test_iostream.obj : .AUTODEPEND .\strings\iostream.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_numformatter.obj : .AUTODEPEND .\strings\numformatter.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_strings.obj : .AUTODEPEND .\strings\strings.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<

View File

@@ -0,0 +1,239 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/strings/numformat.cpp
// Purpose: wxNumberFormatter unit test
// Author: Vadim Zeitlin
// Created: 2011-01-15
// RCS-ID: $Id$
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/numformatter.h"
#include "wx/intl.h"
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
class NumFormatterTestCase : public CppUnit::TestCase
{
public:
NumFormatterTestCase()
{
// We need to use a locale with known decimal point and which uses the
// thousands separator for the tests to make sense.
wxLanguage lang;
if ( wxLocale::IsAvailable(wxLANGUAGE_ENGLISH_US) )
lang = wxLANGUAGE_ENGLISH_US;
else if ( wxLocale::IsAvailable(wxLANGUAGE_ENGLISH_UK) )
lang = wxLANGUAGE_ENGLISH_UK;
else
{
m_locale = NULL;
return;
}
m_locale = new wxLocale(lang, wxLOCALE_DONT_LOAD_DEFAULT);
}
virtual ~NumFormatterTestCase()
{
delete m_locale;
}
private:
CPPUNIT_TEST_SUITE( NumFormatterTestCase );
CPPUNIT_TEST( LongToString );
CPPUNIT_TEST( DoubleToString );
CPPUNIT_TEST( NoTrailingZeroes );
CPPUNIT_TEST( LongFromString );
CPPUNIT_TEST( DoubleFromString );
CPPUNIT_TEST_SUITE_END();
void LongToString();
void DoubleToString();
void NoTrailingZeroes();
void LongFromString();
void DoubleFromString();
wxLocale *m_locale;
wxDECLARE_NO_COPY_CLASS(NumFormatterTestCase);
};
// register in the unnamed registry so that these tests are run by default
CPPUNIT_TEST_SUITE_REGISTRATION( NumFormatterTestCase );
// also include in it's own registry so that these tests can be run alone
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( NumFormatterTestCase, "NumFormatterTestCase" );
// ----------------------------------------------------------------------------
// tests themselves
// ----------------------------------------------------------------------------
void NumFormatterTestCase::LongToString()
{
if ( !m_locale )
return;
CPPUNIT_ASSERT_EQUAL( "1", wxNumberFormatter::ToString( 1));
CPPUNIT_ASSERT_EQUAL( "12", wxNumberFormatter::ToString( 12));
CPPUNIT_ASSERT_EQUAL( "123", wxNumberFormatter::ToString( 123));
CPPUNIT_ASSERT_EQUAL( "1,234", wxNumberFormatter::ToString( 1234));
CPPUNIT_ASSERT_EQUAL( "12,345", wxNumberFormatter::ToString( 12345));
CPPUNIT_ASSERT_EQUAL( "123,456", wxNumberFormatter::ToString( 123456));
CPPUNIT_ASSERT_EQUAL( "1,234,567", wxNumberFormatter::ToString( 1234567));
CPPUNIT_ASSERT_EQUAL( "12,345,678", wxNumberFormatter::ToString( 12345678));
CPPUNIT_ASSERT_EQUAL("123,456,789", wxNumberFormatter::ToString( 123456789));
}
void NumFormatterTestCase::DoubleToString()
{
if ( !m_locale )
return;
CPPUNIT_ASSERT_EQUAL("1.0", wxNumberFormatter::ToString(1., 1));
CPPUNIT_ASSERT_EQUAL("0.123456", wxNumberFormatter::ToString(0.123456, 6));
CPPUNIT_ASSERT_EQUAL("1.234567", wxNumberFormatter::ToString(1.234567, 6));
CPPUNIT_ASSERT_EQUAL("12.34567", wxNumberFormatter::ToString(12.34567, 5));
CPPUNIT_ASSERT_EQUAL("123.4567", wxNumberFormatter::ToString(123.4567, 4));
CPPUNIT_ASSERT_EQUAL("1,234.56", wxNumberFormatter::ToString(1234.56, 2));
CPPUNIT_ASSERT_EQUAL("12,345.6", wxNumberFormatter::ToString(12345.6, 1));
CPPUNIT_ASSERT_EQUAL("12,345.6", wxNumberFormatter::ToString(12345.6, 1));
CPPUNIT_ASSERT_EQUAL("123,456,789.0",
wxNumberFormatter::ToString(123456789., 1));
CPPUNIT_ASSERT_EQUAL("123,456,789.012",
wxNumberFormatter::ToString(123456789.012, 3));
}
void NumFormatterTestCase::NoTrailingZeroes()
{
WX_ASSERT_FAILS_WITH_ASSERT
(
wxNumberFormatter::ToString(123L, wxNumberFormatter::Style_NoTrailingZeroes)
);
if ( !m_locale )
return;
CPPUNIT_ASSERT_EQUAL
(
"123.000",
wxNumberFormatter::ToString(123., 3)
);
CPPUNIT_ASSERT_EQUAL
(
"123",
wxNumberFormatter::ToString(123., 3, wxNumberFormatter::Style_NoTrailingZeroes)
);
CPPUNIT_ASSERT_EQUAL
(
"123",
wxNumberFormatter::ToString(123., 9, wxNumberFormatter::Style_NoTrailingZeroes)
);
CPPUNIT_ASSERT_EQUAL
(
"123.456",
wxNumberFormatter::ToString(123.456, 3, wxNumberFormatter::Style_NoTrailingZeroes)
);
CPPUNIT_ASSERT_EQUAL
(
"123.456000000",
wxNumberFormatter::ToString(123.456, 9)
);
CPPUNIT_ASSERT_EQUAL
(
"123.456",
wxNumberFormatter::ToString(123.456, 9, wxNumberFormatter::Style_NoTrailingZeroes)
);
}
void NumFormatterTestCase::LongFromString()
{
if ( !m_locale )
return;
WX_ASSERT_FAILS_WITH_ASSERT
(
wxNumberFormatter::FromString("123", static_cast<long *>(0))
);
long l;
CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &l) );
CPPUNIT_ASSERT( !wxNumberFormatter::FromString("foo", &l) );
CPPUNIT_ASSERT( !wxNumberFormatter::FromString("1.234", &l) );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &l) );
CPPUNIT_ASSERT_EQUAL( 123, l );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("1234", &l) );
CPPUNIT_ASSERT_EQUAL( 1234, l );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234", &l) );
CPPUNIT_ASSERT_EQUAL( 1234, l );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345", &l) );
CPPUNIT_ASSERT_EQUAL( 12345, l );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456", &l) );
CPPUNIT_ASSERT_EQUAL( 123456, l );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567", &l) );
CPPUNIT_ASSERT_EQUAL( 1234567, l );
}
void NumFormatterTestCase::DoubleFromString()
{
if ( !m_locale )
return;
WX_ASSERT_FAILS_WITH_ASSERT
(
wxNumberFormatter::FromString("123", static_cast<double *>(0))
);
double d;
CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &d) );
CPPUNIT_ASSERT( !wxNumberFormatter::FromString("bar", &d) );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &d) );
CPPUNIT_ASSERT_EQUAL( 123., d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123.456789012", &d) );
CPPUNIT_ASSERT_EQUAL( 123.456789012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234.56789012", &d) );
CPPUNIT_ASSERT_EQUAL( 1234.56789012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345.6789012", &d) );
CPPUNIT_ASSERT_EQUAL( 12345.6789012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456.789012", &d) );
CPPUNIT_ASSERT_EQUAL( 123456.789012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567.89012", &d) );
CPPUNIT_ASSERT_EQUAL( 1234567.89012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345,678.9012", &d) );
CPPUNIT_ASSERT_EQUAL( 12345678.9012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456,789.012", &d) );
CPPUNIT_ASSERT_EQUAL( 123456789.012, d );
CPPUNIT_ASSERT( wxNumberFormatter::FromString("123456789.012", &d) );
CPPUNIT_ASSERT_EQUAL( 123456789.012, d );
}

View File

@@ -75,6 +75,7 @@
regex/wxregextest.cpp
scopeguard/scopeguardtest.cpp
strings/iostream.cpp
strings/numformatter.cpp
strings/strings.cpp
strings/stdstrings.cpp
strings/tokenizer.cpp

View File

@@ -429,6 +429,10 @@ SOURCE=.\misc\module.cpp
# End Source File
# Begin Source File
SOURCE=.\strings\numformatter.cpp
# End Source File
# Begin Source File
SOURCE=.\interactive\output.cpp
# End Source File
# Begin Source File

View File

@@ -758,6 +758,9 @@
RelativePath=".\misc\module.cpp">
</File>
<File
RelativePath=".\strings\numformatter.cpp">
</File>
<File
RelativePath=".\interactive\output.cpp">
</File>
<File

View File

@@ -1084,6 +1084,10 @@
>
</File>
<File
RelativePath=".\strings\numformatter.cpp"
>
</File>
<File
RelativePath=".\interactive\output.cpp"
>
</File>

View File

@@ -1056,6 +1056,10 @@
>
</File>
<File
RelativePath=".\strings\numformatter.cpp"
>
</File>
<File
RelativePath=".\interactive\output.cpp"
>
</File>