From 5eb31ebae0455e36b7f4c69020ce0d7434b87c45 Mon Sep 17 00:00:00 2001
From: Rodrigo Braz Monteiro <zeratul@cellosoft.com>
Date: Mon, 10 Nov 2008 03:37:15 +0000
Subject: [PATCH] More unit tests.

Originally committed to SVN as r2448.
---
 athenasub/src/athenastring.cpp          |  12 ++-
 athenasub/src/athenatime.cpp            |  41 +++++++-
 unit_test/src/athenasub/test_string.cpp | 123 ++++++++++++++++++++++++
 unit_test/src/athenasub/test_time.cpp   |  18 +++-
 unit_test/unit_test.vcproj              |   4 +
 5 files changed, 194 insertions(+), 4 deletions(-)
 create mode 100644 unit_test/src/athenasub/test_string.cpp

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<len;i++) {
+		if (data[i] == ' ') continue;
 		chr = (int)(data[i])-(int)'0';
 		if (chr >= 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 <iostream>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#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 @@
 		<Filter
 			Name="Athenasub"
 			>
+			<File
+				RelativePath=".\src\athenasub\test_string.cpp"
+				>
+			</File>
 			<File
 				RelativePath=".\src\athenasub\test_time.cpp"
 				>
-- 
GitLab