diff --git a/athenasub/src/athenastring.cpp b/athenasub/src/athenastring.cpp index dff420fba..54261fb0a 100644 --- a/athenasub/src/athenastring.cpp +++ b/athenasub/src/athenastring.cpp @@ -455,13 +455,23 @@ int String::ToInteger() const { size_t len = Length(); int value = 0; + int mult = 1; int chr; + bool firstChar = true; const char *data = c_str(); for (size_t i=0;i= 0 && chr <= 9) value = 10*value+chr; + else if (firstChar && data[i] == '-') mult = -1; + else if (firstChar && data[i] == '+') { + firstChar = false; + continue; + } + else THROW_ATHENA_EXCEPTION(Exception::Out_Of_Range); + firstChar = false; } - return value; + return value * mult; } diff --git a/athenasub/src/athenatime.cpp b/athenasub/src/athenatime.cpp index 5b66456e7..52b8f5732 100644 --- a/athenasub/src/athenatime.cpp +++ b/athenasub/src/athenatime.cpp @@ -80,8 +80,7 @@ int Time::GetMS() const String Time::GetString(int ms_precision,int h_precision) const { // Enforce sanity - ms_precision = Mid(0,ms_precision,3); - h_precision = Max(0,h_precision); + if (ms_precision < 0 || ms_precision > 3 || h_precision < 0) THROW_ATHENA_EXCEPTION(Exception::Out_Of_Range); // Generate values int _ms = GetMS(); @@ -215,3 +214,41 @@ void Time::ParseString(const String &data) // Set SetMS((int)accum); } + + +////////////////// +// Get components +int Time::GetHoursComponent() const +{ + return ms / 3600000; +} + +int Time::GetMinutesComponent() const +{ + int _ms = ms; + int h = _ms / 3600000; + _ms -= h*3600000; + return _ms / 60000; +} + +int Time::GetSecondsComponent() const +{ + int _ms = ms; + int h = _ms / 3600000; + _ms -= h*3600000; + int min = _ms / 60000; + _ms -= min*60000; + return _ms / 1000; +} + +int Time::GetMillisecondsComponent() const +{ + int _ms = ms; + int h = _ms / 3600000; + _ms -= h*3600000; + int min = _ms / 60000; + _ms -= min*60000; + int s = _ms / 1000; + _ms -= s*1000; + return _ms; +} \ No newline at end of file diff --git a/unit_test/src/athenasub/test_string.cpp b/unit_test/src/athenasub/test_string.cpp new file mode 100644 index 000000000..c5a461788 --- /dev/null +++ b/unit_test/src/athenasub/test_string.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2008, Rodrigo Braz Monteiro +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the Aegisub Group nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + +#include "../suites.h" +#if ATHENASUB_TEST == 1 + +#include +#include +#include +#include "../../../athenasub/include/athenasub/athenasub.h" +using namespace Athenasub; + + +class AthenasubStringTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(AthenasubStringTest); + CPPUNIT_TEST(testComparison); + CPPUNIT_TEST(testConcatenation); + CPPUNIT_TEST(testConversion); + CPPUNIT_TEST_SUITE_END(); + +private: + +public: + void setUp() + { + } + + void tearDown() + { + } + + void testComparison() + { + String a; + String b = ""; + String c = "Hello world!"; + String d = "ABC"; + String e = "abc"; + + CPPUNIT_ASSERT(a == ""); + CPPUNIT_ASSERT((a == "lol") == false); + CPPUNIT_ASSERT(a == a); + CPPUNIT_ASSERT(a >= a); + CPPUNIT_ASSERT(a <= a); + CPPUNIT_ASSERT(a == b); + CPPUNIT_ASSERT(a != c); + CPPUNIT_ASSERT(d != e); + CPPUNIT_ASSERT(d < e); + CPPUNIT_ASSERT((e < d) == false); + CPPUNIT_ASSERT(d < c); + CPPUNIT_ASSERT((c < d) == false); + } + + void testConcatenation() + { + String a; + CPPUNIT_ASSERT(a == ""); + a += "Hello"; + CPPUNIT_ASSERT(a == "Hello"); + a += " world!"; + CPPUNIT_ASSERT(a == "Hello world!"); + a += 5; + CPPUNIT_ASSERT(a == "Hello world!5"); + a = ""; + a += 10.32f; + CPPUNIT_ASSERT(a == "10.32"); + a = ""; + a += 10.32; + CPPUNIT_ASSERT(a == "10.32"); + a = "Hello "; + String b("world!"); + CPPUNIT_ASSERT(a+b == "Hello world!"); + a += b; + CPPUNIT_ASSERT(a == "Hello world!"); + } + + void testConversion() + { + CPPUNIT_ASSERT(String("312").ToInteger() == 312); + CPPUNIT_ASSERT(String("+312").ToInteger() == 312); + CPPUNIT_ASSERT(String("-312").ToInteger() == -312); + CPPUNIT_ASSERT(String(" 31 2 ").ToInteger() == 312); + CPPUNIT_ASSERT_THROW(String("312a").ToInteger(),Athenasub::Exception); + CPPUNIT_ASSERT_THROW(String("3-12").ToInteger(),Athenasub::Exception); + CPPUNIT_ASSERT_THROW(String("3+12").ToInteger(),Athenasub::Exception); + } +}; + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(AthenasubStringTest,AegisubSuites::athenasub()); + +#endif diff --git a/unit_test/src/athenasub/test_time.cpp b/unit_test/src/athenasub/test_time.cpp index e2991537f..549069297 100644 --- a/unit_test/src/athenasub/test_time.cpp +++ b/unit_test/src/athenasub/test_time.cpp @@ -51,6 +51,7 @@ class AthenasubTimeTest : public CppUnit::TestFixture { CPPUNIT_TEST(testSetGet); CPPUNIT_TEST(testParse); CPPUNIT_TEST(testToString); + CPPUNIT_TEST(testComponents); CPPUNIT_TEST_SUITE_END(); private: @@ -79,15 +80,17 @@ public: CPPUNIT_ASSERT(a != c); CPPUNIT_ASSERT(b != c); CPPUNIT_ASSERT(a < c); + CPPUNIT_ASSERT((c < a) == false); CPPUNIT_ASSERT(a <= c); CPPUNIT_ASSERT(c > b); + CPPUNIT_ASSERT((b > c) == false); CPPUNIT_ASSERT(c >= b); } void testBounds() { Time a(-500); - CPPUNIT_ASSERT(a.GetMS() >= 0); + CPPUNIT_ASSERT(a.GetMS() == 0); } void testSetGet() @@ -106,6 +109,7 @@ public: CPPUNIT_ASSERT(a + 300 == Time(800)); CPPUNIT_ASSERT(a - 300 == Time(200)); CPPUNIT_ASSERT(a - 600 == Time(0)); + CPPUNIT_ASSERT(a + 500 - 500 == a); } void testParse() @@ -149,6 +153,18 @@ public: CPPUNIT_ASSERT(b.GetString(2,1) == "9:59:59.99"); CPPUNIT_ASSERT(c.GetString(3,2) == "99:59:59.999"); CPPUNIT_ASSERT(c.GetString(3,3) == "111:23:45.678"); + CPPUNIT_ASSERT_THROW(a.GetString(-1),Athenasub::Exception); + CPPUNIT_ASSERT_THROW(a.GetString(4),Athenasub::Exception); + CPPUNIT_ASSERT_THROW(a.GetString(3,-1),Athenasub::Exception); + } + + void testComponents() + { + Time a(1,23,45,678); + CPPUNIT_ASSERT(a.GetHoursComponent() == 1); + CPPUNIT_ASSERT(a.GetMinutesComponent() == 23); + CPPUNIT_ASSERT(a.GetSecondsComponent() == 45); + CPPUNIT_ASSERT(a.GetMillisecondsComponent() == 678); } }; diff --git a/unit_test/unit_test.vcproj b/unit_test/unit_test.vcproj index a66b6df09..d92b9db47 100644 --- a/unit_test/unit_test.vcproj +++ b/unit_test/unit_test.vcproj @@ -180,6 +180,10 @@ + +