diff --git a/include/wx/numformatter.h b/include/wx/numformatter.h index 13b47b210b..24ab702ab7 100644 --- a/include/wx/numformatter.h +++ b/include/wx/numformatter.h @@ -34,6 +34,8 @@ public: static wxString ToString(wxLongLong_t val, int style = Style_WithThousandsSep); #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + static wxString ToString(wxULongLong_t val, + int style = Style_WithThousandsSep); static wxString ToString(double val, int precision, int style = Style_WithThousandsSep); @@ -46,6 +48,7 @@ public: #ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG static bool FromString(wxString s, wxLongLong_t *val); #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + static bool FromString(wxString s, wxULongLong_t *val); static bool FromString(wxString s, double *val); diff --git a/include/wx/valnum.h b/include/wx/valnum.h index ba684c1ab3..6c94f53613 100644 --- a/include/wx/valnum.h +++ b/include/wx/valnum.h @@ -79,11 +79,6 @@ protected: // bits of our style to the corresponding wxNumberFormatter::Style values. int GetFormatFlags() const; - // Return true if pressing a '-' key is acceptable for the current control - // contents and insertion point. This is meant to be called from the - // derived class IsCharOk() implementation. - bool IsMinusOk(const wxString& val, int pos) const; - // Return the string which would result from inserting the given character // at the specified position. wxString GetValueAfterInsertingChar(wxString val, int pos, wxChar ch) const @@ -92,6 +87,11 @@ protected: return val; } + // Return true if this control allows negative numbers in it. + // + // If it doesn't, we don't allow entering "-" at all. + virtual bool CanBeNegative() const = 0; + private: // Check whether the specified character can be inserted in the control at // the given position in the string representing the current controls @@ -114,6 +114,11 @@ private: // Determine the current insertion point and text in the associated control. void GetCurrentValueAndInsertionPoint(wxString& val, int& pos) const; + // Return true if pressing a '-' key is acceptable for the current control + // contents and insertion point. This is used by OnChar() to handle '-' and + // relies on CanBeNegative() implementation in the derived class. + bool IsMinusOk(const wxString& val, int pos) const; + // Combination of wxVAL_NUM_XXX values. int m_style; @@ -154,22 +159,22 @@ public: void SetMin(ValueType min) { - this->DoSetMin(static_cast(min)); + m_min = min; } ValueType GetMin() const { - return static_cast(this->DoGetMin()); + return m_min; } void SetMax(ValueType max) { - this->DoSetMax(static_cast(max)); + m_max = max; } ValueType GetMax() const { - return static_cast(this->DoGetMax()); + return m_max; } void SetRange(ValueType min, ValueType max) @@ -238,6 +243,9 @@ protected: : wxString(); } + virtual bool CanBeNegative() const wxOVERRIDE { return m_min < 0; } + + // This member is protected because it can be useful to the derived classes // in their Transfer{From,To}Window() implementations. ValueType * const m_value; @@ -261,6 +269,8 @@ private: return s; } + // Minimal and maximal values accepted (inclusive). + ValueType m_min, m_max; wxDECLARE_NO_ASSIGN_CLASS(wxNumValidator); }; @@ -283,8 +293,10 @@ protected: // on it. #ifdef wxLongLong_t typedef wxLongLong_t LongestValueType; + typedef wxULongLong_t ULongestValueType; #else typedef long LongestValueType; + typedef unsigned long ULongestValueType; #endif wxIntegerValidatorBase(int style) @@ -294,34 +306,18 @@ protected: "This style doesn't make sense for integers." ); } - wxIntegerValidatorBase(const wxIntegerValidatorBase& other) - : wxNumValidatorBase(other) - { - m_min = other.m_min; - m_max = other.m_max; - } + // Default copy ctor is ok. // Provide methods for wxNumValidator use. wxString ToString(LongestValueType value) const; - static bool FromString(const wxString& s, LongestValueType *value); + bool FromString(const wxString& s, LongestValueType *value) const; - void DoSetMin(LongestValueType min) { m_min = min; } - LongestValueType DoGetMin() const { return m_min; } - void DoSetMax(LongestValueType max) { m_max = max; } - LongestValueType DoGetMax() const { return m_max; } - - bool IsInRange(LongestValueType value) const - { - return m_min <= value && value <= m_max; - } + virtual bool IsInRange(LongestValueType value) const = 0; // Implement wxNumValidatorBase pure virtual method. virtual bool IsCharOk(const wxString& val, int pos, wxChar ch) const wxOVERRIDE; private: - // Minimal and maximal values accepted (inclusive). - LongestValueType m_min, m_max; - wxDECLARE_NO_ASSIGN_CLASS(wxIntegerValidatorBase); }; @@ -337,6 +333,8 @@ public: typedef wxPrivate::wxNumValidator Base; + typedef + wxIntegerValidatorBase::LongestValueType LongestValueType; // Ctor for an integer validator. // @@ -345,12 +343,30 @@ public: wxIntegerValidator(ValueType *value = NULL, int style = wxNUM_VAL_DEFAULT) : Base(value, style) { - this->DoSetMin(std::numeric_limits::min()); - this->DoSetMax(std::numeric_limits::max()); + this->SetMin(std::numeric_limits::min()); + this->SetMax(std::numeric_limits::max()); } virtual wxObject *Clone() const wxOVERRIDE { return new wxIntegerValidator(*this); } + virtual bool IsInRange(LongestValueType value) const wxOVERRIDE + { + // LongestValueType is used as a container for the values of any type + // which can be used in type-independent wxIntegerValidatorBase code, + // but we need to use the correct type for comparisons, notably for + // comparing unsigned values correctly, so cast to this type and check + // that we don't lose precision while doing it. + const ValueType valueT = static_cast(value); + if ( static_cast(valueT) != value ) + { + // The conversion wasn't lossless, so the value must not be exactly + // representable in this type and so is definitely not in range. + return false; + } + + return this->GetMin() <= valueT && valueT <= this->GetMax(); + } + private: wxDECLARE_NO_ASSIGN_CLASS(wxIntegerValidator); }; @@ -395,29 +411,13 @@ protected: m_factor = 1.0; } - wxFloatingPointValidatorBase(const wxFloatingPointValidatorBase& other) - : wxNumValidatorBase(other) - { - m_precision = other.m_precision; - m_factor = other.m_factor; - - m_min = other.m_min; - m_max = other.m_max; - } + // Default copy ctor is ok. // Provide methods for wxNumValidator use. wxString ToString(LongestValueType value) const; bool FromString(const wxString& s, LongestValueType *value) const; - void DoSetMin(LongestValueType min) { m_min = min; } - LongestValueType DoGetMin() const { return m_min; } - void DoSetMax(LongestValueType max) { m_max = max; } - LongestValueType DoGetMax() const { return m_max; } - - bool IsInRange(LongestValueType value) const - { - return m_min <= value && value <= m_max; - } + virtual bool IsInRange(LongestValueType value) const = 0; // Implement wxNumValidatorBase pure virtual method. virtual bool IsCharOk(const wxString& val, int pos, wxChar ch) const wxOVERRIDE; @@ -429,9 +429,6 @@ private: // Factor applied for the displayed the value. double m_factor; - // Minimal and maximal values accepted (inclusive). - LongestValueType m_min, m_max; - wxDECLARE_NO_ASSIGN_CLASS(wxFloatingPointValidatorBase); }; @@ -444,6 +441,8 @@ class wxFloatingPointValidator public: typedef T ValueType; typedef wxPrivate::wxNumValidator Base; + typedef wxFloatingPointValidatorBase::LongestValueType LongestValueType; + // Ctor using implicit (maximal) precision for this type. wxFloatingPointValidator(ValueType *value = NULL, @@ -471,16 +470,21 @@ public: return new wxFloatingPointValidator(*this); } -private: - typedef typename Base::LongestValueType LongestValueType; + virtual bool IsInRange(LongestValueType value) const wxOVERRIDE + { + const ValueType valueT = static_cast(value); + return this->GetMin() <= valueT && valueT <= this->GetMax(); + } + +private: void DoSetMinMax() { // NB: Do not use min(), it's not the smallest representable value for // the floating point types but rather the smallest representable // positive value. - this->DoSetMin(static_cast(-std::numeric_limits::max())); - this->DoSetMax(static_cast( std::numeric_limits::max())); + this->SetMin(-std::numeric_limits::max()); + this->SetMax( std::numeric_limits::max()); } }; diff --git a/interface/wx/numformatter.h b/interface/wx/numformatter.h index db678d08f5..1479bae1c4 100644 --- a/interface/wx/numformatter.h +++ b/interface/wx/numformatter.h @@ -70,7 +70,11 @@ public: Combination of values from the Style enumeration (except for Style_NoTrailingZeroes which can't be used with this overload). */ + //@{ static wxString ToString(long val, int flags = Style_WithThousandsSep); + static wxString ToString(long long val, int flags = Style_WithThousandsSep); + static wxString ToString(unsigned long long val, int flags = Style_WithThousandsSep); + //@} /** Returns string representation of a floating point number. @@ -94,10 +98,18 @@ public: success they return @true and store the result at the location pointed to by @a val (which can't be @NULL), otherwise @false is returned. + Note that the overload taking unsigned long long value is only + available since wxWidgets 3.1.5. Also, unlike wxString::ToULongLong() + and the standard functions such as @c strtoul(), this overload does + @em not accept, i.e. returns @false, for the strings starting with the + minus sign. + @see wxString::ToLong(), wxString::ToDouble() */ //@{ static bool FromString(wxString s, long *val); + static bool FromString(wxString s, long long *val); + static bool FromString(wxString s, unsigned long long *val); static bool FromString(wxString s, double *val); //@} diff --git a/src/common/numformatter.cpp b/src/common/numformatter.cpp index 1bf8497712..e57ab02335 100644 --- a/src/common/numformatter.cpp +++ b/src/common/numformatter.cpp @@ -198,6 +198,12 @@ wxString wxNumberFormatter::ToString(wxLongLong_t val, int style) #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG +wxString wxNumberFormatter::ToString(wxULongLong_t val, int style) +{ + return PostProcessIntString(wxString::Format("%" wxLongLongFmtSpec "u", val), + style); +} + wxString wxNumberFormatter::ToString(double val, int precision, int style) { wxString s = wxString::FromDouble(val,precision); @@ -300,6 +306,27 @@ bool wxNumberFormatter::FromString(wxString s, wxLongLong_t *val) #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG +bool wxNumberFormatter::FromString(wxString s, wxULongLong_t *val) +{ + RemoveThousandsSeparators(s); + + // wxString::ToULongLong() does accept minus sign for unsigned integers, + // consistently with the standard functions behaviour, e.g. strtoul() does + // the same thing, but here we really want to accept the "true" unsigned + // numbers only, so check for leading minus, possibly preceded by some + // whitespace. + for ( wxString::const_iterator it = s.begin(); it != s.end(); ++it ) + { + if ( *it == '-' ) + return false; + + if ( *it != ' ' && *it != '\t' ) + break; + } + + return s.ToULongLong(val); +} + bool wxNumberFormatter::FromString(wxString s, double *val) { RemoveThousandsSeparators(s); diff --git a/src/common/valnum.cpp b/src/common/valnum.cpp index 33344b185b..563701aadb 100644 --- a/src/common/valnum.cpp +++ b/src/common/valnum.cpp @@ -117,6 +117,10 @@ wxNumValidatorBase::GetCurrentValueAndInsertionPoint(wxString& val, bool wxNumValidatorBase::IsMinusOk(const wxString& val, int pos) const { + // We need to know if we accept negative numbers at all. + if ( !CanBeNegative() ) + return false; + // Minus is only ever accepted in the beginning of the string. if ( pos != 0 ) return false; @@ -125,6 +129,15 @@ bool wxNumValidatorBase::IsMinusOk(const wxString& val, int pos) const if ( !val.empty() && val[0] == '-' ) return false; + // Notice that entering '-' can make our value invalid, for example if + // we're limited to -5..15 range and the current value is 12, then the + // new value would be (invalid) -12. We consider it better to let the + // user do this because perhaps he is going to press Delete key next to + // make it -2 and forcing him to delete 1 first would be unnatural. + // + // TODO: It would be nice to indicate that the current control contents + // is invalid (if it's indeed going to be the case) once + // wxValidator supports doing this non-intrusively. return true; } @@ -165,7 +178,10 @@ void wxNumValidatorBase::OnChar(wxKeyEvent& event) int pos; GetCurrentValueAndInsertionPoint(val, pos); - if ( !IsCharOk(val, pos, ch) ) + // Minus is a special case because we can deal with it directly here, for + // all the rest call the derived class virtual function. + const bool ok = ch == '-' ? IsMinusOk(val, pos) : IsCharOk(val, pos, ch); + if ( !ok ) { if ( !wxValidator::IsSilent() ) wxBell(); @@ -214,33 +230,42 @@ void wxNumValidatorBase::OnKillFocus(wxFocusEvent& event) wxString wxIntegerValidatorBase::ToString(LongestValueType value) const { - return wxNumberFormatter::ToString(value, GetFormatFlags()); + if ( CanBeNegative() ) + { + return wxNumberFormatter::ToString(value, GetFormatFlags()); + } + else + { + ULongestValueType uvalue = static_cast(value); + return wxNumberFormatter::ToString(uvalue, GetFormatFlags()); + } } bool -wxIntegerValidatorBase::FromString(const wxString& s, LongestValueType *value) +wxIntegerValidatorBase::FromString(const wxString& s, + LongestValueType *value) const { - return wxNumberFormatter::FromString(s, value); + if ( CanBeNegative() ) + { + return wxNumberFormatter::FromString(s, value); + } + else + { + // Parse as unsigned to ensure we don't accept minus sign here. + ULongestValueType uvalue; + if ( !wxNumberFormatter::FromString(s, &uvalue) ) + return false; + + // This cast is lossless. + *value = static_cast(uvalue); + + return true; + } } bool wxIntegerValidatorBase::IsCharOk(const wxString& val, int pos, wxChar ch) const { - // We may accept minus sign if we can represent negative numbers at all. - if ( ch == '-' ) - { - // Notice that entering '-' can make our value invalid, for example if - // we're limited to -5..15 range and the current value is 12, then the - // new value would be (invalid) -12. We consider it better to let the - // user do this because perhaps he is going to press Delete key next to - // make it -2 and forcing him to delete 1 first would be unnatural. - // - // TODO: It would be nice to indicate that the current control contents - // is invalid (if it's indeed going to be the case) once - // wxValidator supports doing this non-intrusively. - return m_min < 0 && IsMinusOk(val, pos); - } - // We only accept digits here (remember that '-' is taken care of by the // base class already). if ( ch < '0' || ch > '9' ) @@ -292,10 +317,6 @@ wxFloatingPointValidatorBase::IsCharOk(const wxString& val, int pos, wxChar ch) const { - // We may accept minus sign if we can represent negative numbers at all. - if ( ch == '-' ) - return m_min < 0 && IsMinusOk(val, pos); - const wxChar separator = wxNumberFormatter::GetDecimalSeparator(); if ( ch == separator ) { diff --git a/tests/strings/numformatter.cpp b/tests/strings/numformatter.cpp index 6416a2ddd1..ba0e86ac69 100644 --- a/tests/strings/numformatter.cpp +++ b/tests/strings/numformatter.cpp @@ -20,220 +20,145 @@ // test class // ---------------------------------------------------------------------------- -class NumFormatterTestCase : public CppUnit::TestCase +namespace +{ + +class NumFormatterTestCase { public: - NumFormatterTestCase() { m_locale = NULL; } - - virtual void setUp() wxOVERRIDE - { + NumFormatterTestCase() : // We need to use a locale with known decimal point and which uses the // thousands separator for the tests to make sense. - m_locale = new wxLocale(wxLANGUAGE_ENGLISH_UK, - wxLOCALE_DONT_LOAD_DEFAULT); - if ( !m_locale->IsOk() ) - tearDown(); + m_locale(wxLANGUAGE_ENGLISH_UK, wxLOCALE_DONT_LOAD_DEFAULT) + { } - virtual void tearDown() wxOVERRIDE - { - delete m_locale; - m_locale = NULL; - } +protected: + bool CanRunTest() const { return m_locale.IsOk(); } private: - CPPUNIT_TEST_SUITE( NumFormatterTestCase ); - CPPUNIT_TEST( LongToString ); -#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - CPPUNIT_TEST( LongLongToString ); -#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - CPPUNIT_TEST( DoubleToString ); - CPPUNIT_TEST( NoTrailingZeroes ); - CPPUNIT_TEST( LongFromString ); -#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - CPPUNIT_TEST( LongLongFromString ); -#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - CPPUNIT_TEST( DoubleFromString ); - CPPUNIT_TEST_SUITE_END(); - - void LongToString(); -#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - void LongLongToString(); -#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - void DoubleToString(); - void NoTrailingZeroes(); - void LongFromString(); -#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - void LongLongFromString(); -#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG - void DoubleFromString(); - - wxLocale *m_locale; + 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 ); +// A couple of helpers to avoid writing over long expressions. +wxString ToStringWithoutTrailingZeroes(double val, int precision) +{ + return wxNumberFormatter::ToString + ( + val, + precision, + wxNumberFormatter::Style_NoTrailingZeroes + ); +} -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( NumFormatterTestCase, "NumFormatterTestCase" ); +wxString ToStringWithTrailingZeroes(double val, int precision) +{ + return wxNumberFormatter::ToString + ( + val, + precision, + wxNumberFormatter::Style_None + ); +} + +} // anonymous namespace // ---------------------------------------------------------------------------- // tests themselves // ---------------------------------------------------------------------------- -void NumFormatterTestCase::LongToString() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongToString", "[numformatter]") { - if ( !m_locale ) + if ( !CanRunTest() ) return; - CPPUNIT_ASSERT_EQUAL( "1", wxNumberFormatter::ToString( 1L)); - CPPUNIT_ASSERT_EQUAL( "-1", wxNumberFormatter::ToString( -1L)); - CPPUNIT_ASSERT_EQUAL( "12", wxNumberFormatter::ToString( 12L)); - CPPUNIT_ASSERT_EQUAL( "-12", wxNumberFormatter::ToString( -12L)); - CPPUNIT_ASSERT_EQUAL( "123", wxNumberFormatter::ToString( 123L)); - CPPUNIT_ASSERT_EQUAL( "-123", wxNumberFormatter::ToString( -123L)); - CPPUNIT_ASSERT_EQUAL( "1,234", wxNumberFormatter::ToString( 1234L)); - CPPUNIT_ASSERT_EQUAL( "-1,234", wxNumberFormatter::ToString( -1234L)); - CPPUNIT_ASSERT_EQUAL( "12,345", wxNumberFormatter::ToString( 12345L)); - CPPUNIT_ASSERT_EQUAL( "-12,345", wxNumberFormatter::ToString( -12345L)); - CPPUNIT_ASSERT_EQUAL( "123,456", wxNumberFormatter::ToString( 123456L)); - CPPUNIT_ASSERT_EQUAL( "-123,456", wxNumberFormatter::ToString( -123456L)); - CPPUNIT_ASSERT_EQUAL( "1,234,567", wxNumberFormatter::ToString( 1234567L)); - CPPUNIT_ASSERT_EQUAL( "-1,234,567", wxNumberFormatter::ToString( -1234567L)); - CPPUNIT_ASSERT_EQUAL( "12,345,678", wxNumberFormatter::ToString( 12345678L)); - CPPUNIT_ASSERT_EQUAL("-12,345,678", wxNumberFormatter::ToString( -12345678L)); - CPPUNIT_ASSERT_EQUAL("123,456,789", wxNumberFormatter::ToString( 123456789L)); + CHECK( wxNumberFormatter::ToString( 1L) == "1" ); + CHECK( wxNumberFormatter::ToString( -1L) == "-1" ); + CHECK( wxNumberFormatter::ToString( 12L) == "12" ); + CHECK( wxNumberFormatter::ToString( -12L) == "-12" ); + CHECK( wxNumberFormatter::ToString( 123L) == "123" ); + CHECK( wxNumberFormatter::ToString( -123L) == "-123" ); + CHECK( wxNumberFormatter::ToString( 1234L) == "1,234" ); + CHECK( wxNumberFormatter::ToString( -1234L) == "-1,234" ); + CHECK( wxNumberFormatter::ToString( 12345L) == "12,345" ); + CHECK( wxNumberFormatter::ToString( -12345L) == "-12,345" ); + CHECK( wxNumberFormatter::ToString( 123456L) == "123,456" ); + CHECK( wxNumberFormatter::ToString( -123456L) == "-123,456" ); + CHECK( wxNumberFormatter::ToString( 1234567L) == "1,234,567" ); + CHECK( wxNumberFormatter::ToString( -1234567L) == "-1,234,567" ); + CHECK( wxNumberFormatter::ToString( 12345678L) == "12,345,678" ); + CHECK( wxNumberFormatter::ToString( -12345678L) == "-12,345,678" ); + CHECK( wxNumberFormatter::ToString( 123456789L) == "123,456,789" ); } #ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG -void NumFormatterTestCase::LongLongToString() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongLongToString", "[numformatter]") { - if ( !m_locale ) + if ( !CanRunTest() ) return; - CPPUNIT_ASSERT_EQUAL( "1", wxNumberFormatter::ToString(wxLL( 1))); - CPPUNIT_ASSERT_EQUAL( "12", wxNumberFormatter::ToString(wxLL( 12))); - CPPUNIT_ASSERT_EQUAL( "123", wxNumberFormatter::ToString(wxLL( 123))); - CPPUNIT_ASSERT_EQUAL( "1,234", wxNumberFormatter::ToString(wxLL( 1234))); - CPPUNIT_ASSERT_EQUAL( "12,345", wxNumberFormatter::ToString(wxLL( 12345))); - CPPUNIT_ASSERT_EQUAL( "123,456", wxNumberFormatter::ToString(wxLL( 123456))); - CPPUNIT_ASSERT_EQUAL( "1,234,567", wxNumberFormatter::ToString(wxLL( 1234567))); - CPPUNIT_ASSERT_EQUAL( "12,345,678", wxNumberFormatter::ToString(wxLL( 12345678))); - CPPUNIT_ASSERT_EQUAL("123,456,789", wxNumberFormatter::ToString(wxLL( 123456789))); + CHECK( wxNumberFormatter::ToString(wxLL( 1)) == "1" ); + CHECK( wxNumberFormatter::ToString(wxLL( 12)) == "12" ); + CHECK( wxNumberFormatter::ToString(wxLL( 123)) == "123" ); + CHECK( wxNumberFormatter::ToString(wxLL( 1234)) == "1,234" ); + CHECK( wxNumberFormatter::ToString(wxLL( 12345)) == "12,345" ); + CHECK( wxNumberFormatter::ToString(wxLL( 123456)) == "123,456" ); + CHECK( wxNumberFormatter::ToString(wxLL( 1234567)) == "1,234,567" ); + CHECK( wxNumberFormatter::ToString(wxLL( 12345678)) == "12,345,678" ); + CHECK( wxNumberFormatter::ToString(wxLL( 123456789)) == "123,456,789" ); } #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG -void NumFormatterTestCase::DoubleToString() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::DoubleToString", "[numformatter]") { - if ( !m_locale ) + if ( !CanRunTest() ) 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)); - CPPUNIT_ASSERT_EQUAL("12,345", - wxNumberFormatter::ToString(12345.012, -1)); - CPPUNIT_ASSERT_EQUAL("-123.1230", - wxNumberFormatter::ToString(-123.123, 4, wxNumberFormatter::Style_None)); - CPPUNIT_ASSERT_EQUAL("0.0", - wxNumberFormatter::ToString(0.02, 1, wxNumberFormatter::Style_None)); - CPPUNIT_ASSERT_EQUAL("-0.0", - wxNumberFormatter::ToString(-0.02, 1, wxNumberFormatter::Style_None)); + CHECK( wxNumberFormatter::ToString( 1., 1) == "1.0" ); + CHECK( wxNumberFormatter::ToString( 0.123456, 6) == "0.123456" ); + CHECK( wxNumberFormatter::ToString( 1.234567, 6) == "1.234567" ); + CHECK( wxNumberFormatter::ToString( 12.34567, 5) == "12.34567" ); + CHECK( wxNumberFormatter::ToString( 123.4567, 4) == "123.4567" ); + CHECK( wxNumberFormatter::ToString( 1234.56, 2) == "1,234.56" ); + CHECK( wxNumberFormatter::ToString( 12345.6, 1) == "12,345.6" ); + CHECK( wxNumberFormatter::ToString(123456789.012, 3) == "123,456,789.012" ); + CHECK( wxNumberFormatter::ToString( 12345.012, -1) == "12,345" ); + + CHECK( ToStringWithTrailingZeroes(-123.123, 4) == "-123.1230" ); + CHECK( ToStringWithTrailingZeroes( 0.02, 1) == "0.0" ); + CHECK( ToStringWithTrailingZeroes( -0.02, 1) == "-0.0" ); } -void NumFormatterTestCase::NoTrailingZeroes() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::NoTrailingZeroes", "[numformatter]") { WX_ASSERT_FAILS_WITH_ASSERT ( wxNumberFormatter::ToString(123L, wxNumberFormatter::Style_NoTrailingZeroes) ); - if ( !m_locale ) + if ( !CanRunTest() ) 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) - ); - - CPPUNIT_ASSERT_EQUAL - ( - "123.12", - wxNumberFormatter::ToString(123.123, 2, wxNumberFormatter::Style_NoTrailingZeroes) - ); - - CPPUNIT_ASSERT_EQUAL - ( - "123", - wxNumberFormatter::ToString(123.123, 0, wxNumberFormatter::Style_NoTrailingZeroes) - ); - - CPPUNIT_ASSERT_EQUAL - ( - "0", - wxNumberFormatter::ToString(-0.000123, 3, wxNumberFormatter::Style_NoTrailingZeroes) - ); - - CPPUNIT_ASSERT_EQUAL - ( - "123", - wxNumberFormatter::ToString(123., -1, wxNumberFormatter::Style_NoTrailingZeroes) - ); - - CPPUNIT_ASSERT_EQUAL - ( - "1e-120", - wxNumberFormatter::ToString(1e-120, -1, wxNumberFormatter::Style_NoTrailingZeroes) - ); + CHECK( ToStringWithTrailingZeroes ( 123., 3) == "123.000" ); + CHECK( ToStringWithoutTrailingZeroes( 123., 3) == "123" ); + CHECK( ToStringWithoutTrailingZeroes( 123., 9) == "123" ); + CHECK( ToStringWithoutTrailingZeroes( 123.456, 3) == "123.456" ); + CHECK( ToStringWithTrailingZeroes ( 123.456, 9) == "123.456000000" ); + CHECK( ToStringWithoutTrailingZeroes( 123.456, 9) == "123.456" ); + CHECK( ToStringWithoutTrailingZeroes( 123.123, 2) == "123.12" ); + CHECK( ToStringWithoutTrailingZeroes( 123.123, 0) == "123" ); + CHECK( ToStringWithoutTrailingZeroes( -0.000123, 3) == "0" ); + CHECK( ToStringWithoutTrailingZeroes( 123., -1) == "123" ); + CHECK( ToStringWithoutTrailingZeroes( 1e-120, -1) == "1e-120" ); } -void NumFormatterTestCase::LongFromString() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongFromString", "[numformatter]") { - if ( !m_locale ) + if ( !CanRunTest() ) return; WX_ASSERT_FAILS_WITH_ASSERT @@ -242,34 +167,43 @@ void NumFormatterTestCase::LongFromString() ); long l; - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &l) ); - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("foo", &l) ); - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("1.234", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("foo", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("1.234", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("-", &l) ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &l) ); - CPPUNIT_ASSERT_EQUAL( 123, l ); + CHECK( wxNumberFormatter::FromString("0", &l) ); + CHECK( l == 0 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1234", &l) ); - CPPUNIT_ASSERT_EQUAL( 1234, l ); + CHECK( wxNumberFormatter::FromString("123", &l) ); + CHECK( l == 123 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234", &l) ); - CPPUNIT_ASSERT_EQUAL( 1234, l ); + CHECK( wxNumberFormatter::FromString("1234", &l) ); + CHECK( l == 1234 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345", &l) ); - CPPUNIT_ASSERT_EQUAL( 12345, l ); + CHECK( wxNumberFormatter::FromString("1,234", &l) ); + CHECK( l == 1234 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456", &l) ); - CPPUNIT_ASSERT_EQUAL( 123456, l ); + CHECK( wxNumberFormatter::FromString("12,345", &l) ); + CHECK( l == 12345 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567", &l) ); - CPPUNIT_ASSERT_EQUAL( 1234567, l ); + CHECK( wxNumberFormatter::FromString("123,456", &l) ); + CHECK( l == 123456 ); + + CHECK( wxNumberFormatter::FromString("1,234,567", &l) ); + CHECK( l == 1234567 ); + + CHECK( wxNumberFormatter::FromString("-123", &l) ); + CHECK( l == -123 ); + + CHECK_FALSE( wxNumberFormatter::FromString("9223372036854775808", &l) ); } #ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG -void NumFormatterTestCase::LongLongFromString() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongLongFromString", "[numformatter]") { - if ( !m_locale ) + if ( !CanRunTest() ) return; WX_ASSERT_FAILS_WITH_ASSERT @@ -278,34 +212,97 @@ void NumFormatterTestCase::LongLongFromString() ); wxLongLong_t l; - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &l) ); - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("foo", &l) ); - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("1.234", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("foo", &l) ); + CHECK_FALSE( wxNumberFormatter::FromString("1.234", &l) ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &l) ); - CPPUNIT_ASSERT_EQUAL( 123, l ); + // This somehow succeeds with gcc 4.8.4 under Ubuntu and MinGW 5.3, so + // don't use CHECK() for it. + if ( wxNumberFormatter::FromString("-", &l) ) + { + WARN("Converting \"-\" to long long unexpectedly succeeded, result: " << l); + } - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1234", &l) ); - CPPUNIT_ASSERT_EQUAL( 1234, l ); + CHECK( wxNumberFormatter::FromString("0", &l) ); + CHECK( l == 0 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234", &l) ); - CPPUNIT_ASSERT_EQUAL( 1234, l ); + CHECK( wxNumberFormatter::FromString("123", &l) ); + CHECK( l == 123 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345", &l) ); - CPPUNIT_ASSERT_EQUAL( 12345, l ); + CHECK( wxNumberFormatter::FromString("1234", &l) ); + CHECK( l == 1234 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456", &l) ); - CPPUNIT_ASSERT_EQUAL( 123456, l ); + CHECK( wxNumberFormatter::FromString("1,234", &l) ); + CHECK( l == 1234 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567", &l) ); - CPPUNIT_ASSERT_EQUAL( 1234567, l ); + CHECK( wxNumberFormatter::FromString("12,345", &l) ); + CHECK( l == 12345 ); + + CHECK( wxNumberFormatter::FromString("123,456", &l) ); + CHECK( l == 123456 ); + + CHECK( wxNumberFormatter::FromString("1,234,567", &l) ); + CHECK( l == 1234567 ); + + CHECK( wxNumberFormatter::FromString("-123", &l) ); + CHECK( l == -123 ); + + CHECK( wxNumberFormatter::FromString("9223372036854775807", &l) ); + CHECK( l == wxINT64_MAX ); + + CHECK_FALSE( wxNumberFormatter::FromString("9223372036854775808", &l) ); } #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG -void NumFormatterTestCase::DoubleFromString() +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::ULongLongFromString", "[numformatter]") { - if ( !m_locale ) + if ( !CanRunTest() ) + return; + + wxULongLong_t u; + CHECK_FALSE( wxNumberFormatter::FromString("", &u) ); + CHECK_FALSE( wxNumberFormatter::FromString("bar", &u) ); + CHECK_FALSE( wxNumberFormatter::FromString("1.234", &u) ); + CHECK_FALSE( wxNumberFormatter::FromString("-2", &u) ); + CHECK_FALSE( wxNumberFormatter::FromString("-", &u) ); + + CHECK( wxNumberFormatter::FromString("0", &u) ); + CHECK( u == 0 ); + + CHECK( wxNumberFormatter::FromString("123", &u) ); + CHECK( u == 123 ); + + CHECK( wxNumberFormatter::FromString("1234", &u) ); + CHECK( u == 1234 ); + + CHECK( wxNumberFormatter::FromString("1,234", &u) ); + CHECK( u == 1234 ); + + CHECK( wxNumberFormatter::FromString("12,345", &u) ); + CHECK( u == 12345 ); + + CHECK( wxNumberFormatter::FromString("123,456", &u) ); + CHECK( u == 123456 ); + + CHECK( wxNumberFormatter::FromString("1,234,567", &u) ); + CHECK( u == 1234567 ); + + CHECK( wxNumberFormatter::FromString("9223372036854775807", &u) ); + CHECK( u == static_cast(wxINT64_MAX) ); + + CHECK( wxNumberFormatter::FromString("9223372036854775808", &u) ); + CHECK( u == static_cast(wxINT64_MAX) + 1 ); + + CHECK( wxNumberFormatter::FromString("18446744073709551615", &u) ); + CHECK( u == wxUINT64_MAX ); + + CHECK_FALSE( wxNumberFormatter::FromString("18446744073709551616", &u) ); +} + +TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::DoubleFromString", "[numformatter]") +{ + if ( !CanRunTest() ) return; WX_ASSERT_FAILS_WITH_ASSERT @@ -314,33 +311,33 @@ void NumFormatterTestCase::DoubleFromString() ); double d; - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("", &d) ); - CPPUNIT_ASSERT( !wxNumberFormatter::FromString("bar", &d) ); + CHECK_FALSE( wxNumberFormatter::FromString("", &d) ); + CHECK_FALSE( wxNumberFormatter::FromString("bar", &d) ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123", &d) ); - CPPUNIT_ASSERT_EQUAL( 123., d ); + CHECK( wxNumberFormatter::FromString("123", &d) ); + CHECK( d == 123. ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123.456789012", &d) ); - CPPUNIT_ASSERT_EQUAL( 123.456789012, d ); + CHECK( wxNumberFormatter::FromString("123.456789012", &d) ); + CHECK( d == 123.456789012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234.56789012", &d) ); - CPPUNIT_ASSERT_EQUAL( 1234.56789012, d ); + CHECK( wxNumberFormatter::FromString("1,234.56789012", &d) ); + CHECK( d == 1234.56789012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345.6789012", &d) ); - CPPUNIT_ASSERT_EQUAL( 12345.6789012, d ); + CHECK( wxNumberFormatter::FromString("12,345.6789012", &d) ); + CHECK( d == 12345.6789012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456.789012", &d) ); - CPPUNIT_ASSERT_EQUAL( 123456.789012, d ); + CHECK( wxNumberFormatter::FromString("123,456.789012", &d) ); + CHECK( d == 123456.789012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("1,234,567.89012", &d) ); - CPPUNIT_ASSERT_EQUAL( 1234567.89012, d ); + CHECK( wxNumberFormatter::FromString("1,234,567.89012", &d) ); + CHECK( d == 1234567.89012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("12,345,678.9012", &d) ); - CPPUNIT_ASSERT_EQUAL( 12345678.9012, d ); + CHECK( wxNumberFormatter::FromString("12,345,678.9012", &d) ); + CHECK( d == 12345678.9012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123,456,789.012", &d) ); - CPPUNIT_ASSERT_EQUAL( 123456789.012, d ); + CHECK( wxNumberFormatter::FromString("123,456,789.012", &d) ); + CHECK( d == 123456789.012 ); - CPPUNIT_ASSERT( wxNumberFormatter::FromString("123456789.012", &d) ); - CPPUNIT_ASSERT_EQUAL( 123456789.012, d ); + CHECK( wxNumberFormatter::FromString("123456789.012", &d) ); + CHECK( d == 123456789.012 ); } diff --git a/tests/validators/valnum.cpp b/tests/validators/valnum.cpp index d3a063dab0..b91129359c 100644 --- a/tests/validators/valnum.cpp +++ b/tests/validators/valnum.cpp @@ -20,116 +20,144 @@ #include "asserthelper.h" #include "testableframe.h" + +#include "wx/scopeguard.h" #include "wx/uiaction.h" -class NumValidatorTestCase : public CppUnit::TestCase +class NumValidatorTestCase { public: - NumValidatorTestCase() { } + NumValidatorTestCase(); + ~NumValidatorTestCase(); - void setUp() wxOVERRIDE; - void tearDown() wxOVERRIDE; - -private: - CPPUNIT_TEST_SUITE( NumValidatorTestCase ); - CPPUNIT_TEST( TransferInt ); - CPPUNIT_TEST( TransferUnsigned ); - CPPUNIT_TEST( TransferFloat ); - CPPUNIT_TEST( ZeroAsBlank ); - CPPUNIT_TEST( NoTrailingZeroes ); - WXUISIM_TEST( Interactive ); - CPPUNIT_TEST_SUITE_END(); - - void TransferInt(); - void TransferUnsigned(); - void TransferFloat(); - void ZeroAsBlank(); - void NoTrailingZeroes(); -#if wxUSE_UIACTIONSIMULATOR - void Interactive(); -#endif // wxUSE_UIACTIONSIMULATOR - - wxTextCtrl *m_text; +protected: + wxTextCtrl* const m_text; wxDECLARE_NO_COPY_CLASS(NumValidatorTestCase); }; -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( NumValidatorTestCase ); - -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( NumValidatorTestCase, "NumValidatorTestCase" ); - -void NumValidatorTestCase::setUp() +NumValidatorTestCase::NumValidatorTestCase() + : m_text(new wxTextCtrl(wxTheApp->GetTopWindow(), wxID_ANY)) { - m_text = new wxTextCtrl(wxTheApp->GetTopWindow(), wxID_ANY); } -void NumValidatorTestCase::tearDown() +NumValidatorTestCase::~NumValidatorTestCase() { - wxTheApp->GetTopWindow()->DestroyChildren(); + delete m_text; } -void NumValidatorTestCase::TransferInt() +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::TransferInt", "[valnum]") { int value = 0; wxIntegerValidator valInt(&value); valInt.SetWindow(m_text); - CPPUNIT_ASSERT( valInt.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "0", m_text->GetValue() ); + CHECK( valInt.TransferToWindow() ); + CHECK( m_text->GetValue() == "0" ); value = 17; - CPPUNIT_ASSERT( valInt.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "17", m_text->GetValue() ); + CHECK( valInt.TransferToWindow() ); + CHECK( m_text->GetValue() == "17" ); m_text->ChangeValue("foobar"); - CPPUNIT_ASSERT( !valInt.TransferFromWindow() ); + CHECK( !valInt.TransferFromWindow() ); m_text->ChangeValue("-234"); - CPPUNIT_ASSERT( valInt.TransferFromWindow() ); - CPPUNIT_ASSERT_EQUAL( -234, value ); + CHECK( valInt.TransferFromWindow() ); + CHECK( value == -234 ); m_text->ChangeValue("9223372036854775808"); // == LLONG_MAX + 1 - CPPUNIT_ASSERT( !valInt.TransferFromWindow() ); + CHECK( !valInt.TransferFromWindow() ); m_text->Clear(); - CPPUNIT_ASSERT( !valInt.TransferFromWindow() ); + CHECK( !valInt.TransferFromWindow() ); } -void NumValidatorTestCase::TransferUnsigned() +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::TransferUnsigned", "[valnum]") { unsigned value = 0; wxIntegerValidator valUnsigned(&value); valUnsigned.SetWindow(m_text); - CPPUNIT_ASSERT( valUnsigned.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "0", m_text->GetValue() ); + CHECK( valUnsigned.TransferToWindow() ); + CHECK( m_text->GetValue() == "0" ); value = 17; - CPPUNIT_ASSERT( valUnsigned.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "17", m_text->GetValue() ); + CHECK( valUnsigned.TransferToWindow() ); + CHECK( m_text->GetValue() == "17" ); m_text->ChangeValue("foobar"); - CPPUNIT_ASSERT( !valUnsigned.TransferFromWindow() ); + CHECK( !valUnsigned.TransferFromWindow() ); m_text->ChangeValue("-234"); - CPPUNIT_ASSERT( !valUnsigned.TransferFromWindow() ); + CHECK( !valUnsigned.TransferFromWindow() ); m_text->ChangeValue("234"); - CPPUNIT_ASSERT( valUnsigned.TransferFromWindow() ); - CPPUNIT_ASSERT_EQUAL( 234, value ); + CHECK( valUnsigned.TransferFromWindow() ); + CHECK( value == 234 ); + + m_text->ChangeValue("4294967295"); // == ULONG_MAX in 32 bits + CHECK( valUnsigned.TransferFromWindow() ); + CHECK( value == wxUINT32_MAX ); + CHECK( valUnsigned.TransferToWindow() ); + CHECK( m_text->GetValue() == "4294967295" ); + + m_text->ChangeValue("4294967296"); // == ULONG_MAX + 1 + CHECK( !valUnsigned.TransferFromWindow() ); m_text->ChangeValue("18446744073709551616"); // == ULLONG_MAX + 1 - CPPUNIT_ASSERT( !valUnsigned.TransferFromWindow() ); + CHECK( !valUnsigned.TransferFromWindow() ); m_text->Clear(); - CPPUNIT_ASSERT( !valUnsigned.TransferFromWindow() ); + CHECK( !valUnsigned.TransferFromWindow() ); } -void NumValidatorTestCase::TransferFloat() +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::TransferULL", "[valnum]") +{ + unsigned long long value = 0; + wxIntegerValidator valULL(&value); + valULL.SetWindow(m_text); + + SECTION("LLONG_MAX") + { + m_text->ChangeValue("9223372036854775807"); // == LLONG_MAX + REQUIRE( valULL.TransferFromWindow() ); + CHECK( value == static_cast(wxINT64_MAX) ); + + REQUIRE( valULL.TransferToWindow() ); + CHECK( m_text->GetValue() == "9223372036854775807" ); + } + + SECTION("LLONG_MAX+1") + { + m_text->ChangeValue("9223372036854775808"); // == LLONG_MAX + 1 + REQUIRE( valULL.TransferFromWindow() ); + CHECK( value == static_cast(wxINT64_MAX) + 1 ); + + REQUIRE( valULL.TransferToWindow() ); + CHECK( m_text->GetValue() == "9223372036854775808" ); + } + + SECTION("ULLONG_MAX") + { + m_text->ChangeValue("18446744073709551615"); // == ULLONG_MAX + REQUIRE( valULL.TransferFromWindow() ); + CHECK( value == wxUINT64_MAX ); + + REQUIRE( valULL.TransferToWindow() ); + CHECK( m_text->GetValue() == "18446744073709551615" ); + } + + SECTION("ULLONG_MAX+1") + { + m_text->ChangeValue("18446744073709551616"); // == ULLONG_MAX + 1 + CHECK( !valULL.TransferFromWindow() ); + } +} + +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::TransferFloat", "[valnum]") { // We need a locale with point as decimal separator. wxLocale loc(wxLANGUAGE_ENGLISH_UK, wxLOCALE_DONT_LOAD_DEFAULT); @@ -138,30 +166,30 @@ void NumValidatorTestCase::TransferFloat() wxFloatingPointValidator valFloat(3, &value); valFloat.SetWindow(m_text); - CPPUNIT_ASSERT( valFloat.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "0.000", m_text->GetValue() ); + CHECK( valFloat.TransferToWindow() ); + CHECK( m_text->GetValue() == "0.000" ); value = 1.234f; - CPPUNIT_ASSERT( valFloat.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "1.234", m_text->GetValue() ); + CHECK( valFloat.TransferToWindow() ); + CHECK( m_text->GetValue() == "1.234" ); value = 1.2345678f; - CPPUNIT_ASSERT( valFloat.TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "1.235", m_text->GetValue() ); + CHECK( valFloat.TransferToWindow() ); + CHECK( m_text->GetValue() == "1.235" ); m_text->ChangeValue("foobar"); - CPPUNIT_ASSERT( !valFloat.TransferFromWindow() ); + CHECK( !valFloat.TransferFromWindow() ); m_text->ChangeValue("-234.567"); - CPPUNIT_ASSERT( valFloat.TransferFromWindow() ); - CPPUNIT_ASSERT_EQUAL( -234.567f, value ); + CHECK( valFloat.TransferFromWindow() ); + CHECK( value == -234.567f ); m_text->Clear(); - CPPUNIT_ASSERT( !valFloat.TransferFromWindow() ); + CHECK( !valFloat.TransferFromWindow() ); } -void NumValidatorTestCase::ZeroAsBlank() +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::ZeroAsBlank", "[valnum]") { long value = 0; m_text->SetValidator( @@ -169,15 +197,15 @@ void NumValidatorTestCase::ZeroAsBlank() wxValidator * const val = m_text->GetValidator(); - CPPUNIT_ASSERT( val->TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "", m_text->GetValue() ); + CHECK( val->TransferToWindow() ); + CHECK( m_text->GetValue() == "" ); value++; - CPPUNIT_ASSERT( val->TransferFromWindow() ); - CPPUNIT_ASSERT_EQUAL( 0, value ); + CHECK( val->TransferFromWindow() ); + CHECK( value == 0 ); } -void NumValidatorTestCase::NoTrailingZeroes() +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::NoTrailingZeroes", "[valnum]") { // We need a locale with point as decimal separator. wxLocale loc(wxLANGUAGE_ENGLISH_UK, wxLOCALE_DONT_LOAD_DEFAULT); @@ -188,17 +216,17 @@ void NumValidatorTestCase::NoTrailingZeroes() wxValidator * const val = m_text->GetValidator(); - CPPUNIT_ASSERT( val->TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "1.2", m_text->GetValue() ); + CHECK( val->TransferToWindow() ); + CHECK( m_text->GetValue() == "1.2" ); value = 1.234; - CPPUNIT_ASSERT( val->TransferToWindow() ); - CPPUNIT_ASSERT_EQUAL( "1.234", m_text->GetValue() ); + CHECK( val->TransferToWindow() ); + CHECK( m_text->GetValue() == "1.234" ); } #if wxUSE_UIACTIONSIMULATOR -void NumValidatorTestCase::Interactive() +TEST_CASE_METHOD(NumValidatorTestCase, "ValNum::Interactive", "[valnum]") { #ifdef __WXMSW__ // FIXME: This test fails on MSW buildbot slaves although works fine on @@ -217,6 +245,7 @@ void NumValidatorTestCase::Interactive() // Create a sibling text control to be able to switch focus and thus // trigger the control validation/normalization. wxTextCtrl * const text2 = new wxTextCtrl(m_text->GetParent(), wxID_ANY); + wxON_BLOCK_EXIT_OBJ0( *text2, wxWindow::Destroy ); text2->Move(10, 80); // Just to see it better while debugging... wxFloatingPointValidator valFloat(3); valFloat.SetRange(-10., 10.); @@ -228,12 +257,12 @@ void NumValidatorTestCase::Interactive() m_text->SetFocus(); sim.Char('-'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "", m_text->GetValue() ); + CHECK( m_text->GetValue() == "" ); // Neither is entering '.' or any non-digit character. sim.Text(".a+/"); wxYield(); - CPPUNIT_ASSERT_EQUAL( "", m_text->GetValue() ); + CHECK( m_text->GetValue() == "" ); // Entering digits should work though and after leaving the control the // contents should be normalized. @@ -242,43 +271,43 @@ void NumValidatorTestCase::Interactive() text2->SetFocus(); wxYield(); if ( loc.IsOk() ) - CPPUNIT_ASSERT_EQUAL( "1,234,567", m_text->GetValue() ); + CHECK( m_text->GetValue() == "1,234,567" ); else - CPPUNIT_ASSERT_EQUAL( "1234567", m_text->GetValue() ); + CHECK( m_text->GetValue() == "1234567" ); // Entering both '-' and '.' in this control should work but only in the // correct order. sim.Char('-'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "-", text2->GetValue() ); + CHECK( text2->GetValue() == "-" ); text2->SetInsertionPoint(0); sim.Char('.'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "-", text2->GetValue() ); + CHECK( text2->GetValue() == "-" ); text2->SetInsertionPointEnd(); sim.Char('.'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "-.", text2->GetValue() ); + CHECK( text2->GetValue() == "-." ); // Adding up to three digits after the point should work. sim.Text("987"); wxYield(); - CPPUNIT_ASSERT_EQUAL( "-.987", text2->GetValue() ); + CHECK( text2->GetValue() == "-.987" ); // But no more. sim.Text("654"); wxYield(); - CPPUNIT_ASSERT_EQUAL( "-.987", text2->GetValue() ); + CHECK( text2->GetValue() == "-.987" ); // We can remove one digit and another one though. sim.Char(WXK_BACK); sim.Char(WXK_BACK); sim.Char('6'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "-.96", text2->GetValue() ); + CHECK( text2->GetValue() == "-.96" ); // Also test the range constraint. @@ -286,11 +315,11 @@ void NumValidatorTestCase::Interactive() sim.Char('9'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "9", text2->GetValue() ); + CHECK( text2->GetValue() == "9" ); sim.Char('9'); wxYield(); - CPPUNIT_ASSERT_EQUAL( "9", text2->GetValue() ); + CHECK( text2->GetValue() == "9" ); } #endif // wxUSE_UIACTIONSIMULATOR