From a016c11d41b3f4f6cdb51eedd5fd652ee8303c8d Mon Sep 17 00:00:00 2001
From: Mark Pilgrim <mark@diveintopython.org>
Date: Thu, 8 Oct 2015 13:03:41 -0700
Subject: add test suite
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

 Add test suite, extracted from the “Dive Into Python” book (package
 diveintopython).
Origin: upstream
Last-Update: 2012-05-05

Patch-Name: tests.diff
---
 tests/romantest.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)
 create mode 100644 tests/romantest.py

diff --git a/tests/romantest.py b/tests/romantest.py
new file mode 100644
index 0000000..a20cef2
--- /dev/null
+++ b/tests/romantest.py
@@ -0,0 +1,153 @@
+"""Unit test for roman.py
+
+This program is part of "Dive Into Python", a free Python book for
+experienced programmers.  Visit http://diveintopython.org/ for the
+latest version.
+"""
+
+__author__ = "Mark Pilgrim (mark@diveintopython.org)"
+__version__ = "$Revision: 1.2 $"
+__date__ = "$Date: 2004/05/05 21:57:19 $"
+__copyright__ = "Copyright (c) 2001 Mark Pilgrim"
+__license__ = "Python"
+
+import roman
+import unittest
+
+class KnownValues(unittest.TestCase):
+	knownValues = ( (1, 'I'),
+					(2, 'II'),
+					(3, 'III'),
+					(4, 'IV'),
+					(5, 'V'),
+					(6, 'VI'),
+					(7, 'VII'),
+					(8, 'VIII'),
+					(9, 'IX'),
+					(10, 'X'),
+					(50, 'L'),
+					(100, 'C'),
+					(500, 'D'),
+					(1000, 'M'),
+					(31, 'XXXI'),
+					(148, 'CXLVIII'),
+					(294, 'CCXCIV'),
+					(312, 'CCCXII'),
+					(421, 'CDXXI'),
+					(528, 'DXXVIII'),
+					(621, 'DCXXI'),
+					(782, 'DCCLXXXII'),
+					(870, 'DCCCLXX'),
+					(941, 'CMXLI'),
+					(1043, 'MXLIII'),
+					(1110, 'MCX'),
+					(1226, 'MCCXXVI'),
+					(1301, 'MCCCI'),
+					(1485, 'MCDLXXXV'),
+					(1509, 'MDIX'),
+					(1607, 'MDCVII'),
+					(1754, 'MDCCLIV'),
+					(1832, 'MDCCCXXXII'),
+					(1993, 'MCMXCIII'),
+					(2074, 'MMLXXIV'),
+					(2152, 'MMCLII'),
+					(2212, 'MMCCXII'),
+					(2343, 'MMCCCXLIII'),
+					(2499, 'MMCDXCIX'),
+					(2574, 'MMDLXXIV'),
+					(2646, 'MMDCXLVI'),
+					(2723, 'MMDCCXXIII'),
+					(2892, 'MMDCCCXCII'),
+					(2975, 'MMCMLXXV'),
+					(3051, 'MMMLI'),
+					(3185, 'MMMCLXXXV'),
+					(3250, 'MMMCCL'),
+					(3313, 'MMMCCCXIII'),
+					(3408, 'MMMCDVIII'),
+					(3501, 'MMMDI'),
+					(3610, 'MMMDCX'),
+					(3743, 'MMMDCCXLIII'),
+					(3844, 'MMMDCCCXLIV'),
+					(3888, 'MMMDCCCLXXXVIII'),
+					(3940, 'MMMCMXL'),
+					(3999, 'MMMCMXCIX'),
+					(4000, 'MMMM'),
+					(4500, 'MMMMD'),
+					(4888, 'MMMMDCCCLXXXVIII'),
+					(4999, 'MMMMCMXCIX'))
+
+	def testToRomanKnownValues(self):
+		"""toRoman should give known result with known input"""
+		for integer, numeral in self.knownValues:
+			result = roman.toRoman(integer)
+			self.assertEqual(numeral, result)
+
+	def testFromRomanKnownValues(self):
+		"""fromRoman should give known result with known input"""
+		for integer, numeral in self.knownValues:
+			result = roman.fromRoman(numeral)
+			self.assertEqual(integer, result)
+
+class ToRomanBadInput(unittest.TestCase):
+	def testTooLarge(self):
+		"""toRoman should fail with large input"""
+		self.assertRaises(roman.OutOfRangeError, roman.toRoman, 5000)
+
+	def testZero(self):
+		"""toRoman should fail with 0 input"""
+		self.assertRaises(roman.OutOfRangeError, roman.toRoman, 0)
+
+	def testNegative(self):
+		"""toRoman should fail with negative input"""
+		self.assertRaises(roman.OutOfRangeError, roman.toRoman, -1)
+
+	def testDecimal(self):
+		"""toRoman should fail with non-integer input"""
+		self.assertRaises(roman.NotIntegerError, roman.toRoman, 0.5)
+
+class FromRomanBadInput(unittest.TestCase):
+	def testTooManyRepeatedNumerals(self):
+		"""fromRoman should fail with too many repeated numerals"""
+		for s in ('MMMMM', 'DD', 'CCCC', 'LL', 'XXXX', 'VV', 'IIII'):
+			self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s)
+
+	def testRepeatedPairs(self):
+		"""fromRoman should fail with repeated pairs of numerals"""
+		for s in ('CMCM', 'CDCD', 'XCXC', 'XLXL', 'IXIX', 'IVIV'):
+			self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s)
+
+	def testMalformedAntecedent(self):
+		"""fromRoman should fail with malformed antecedents"""
+		for s in ('IIMXCC', 'VX', 'DCM', 'CMM', 'IXIV',
+				  'MCMC', 'XCX', 'IVI', 'LM', 'LD', 'LC'):
+			self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, s)
+
+	def testBlank(self):
+		"""fromRoman should fail with blank string"""
+		self.assertRaises(roman.InvalidRomanNumeralError, roman.fromRoman, "")
+
+class SanityCheck(unittest.TestCase):
+	def testSanity(self):
+		"""fromRoman(toRoman(n))==n for all n"""
+		for integer in range(1, 5000):
+			numeral = roman.toRoman(integer)
+			result = roman.fromRoman(numeral)
+			self.assertEqual(integer, result)
+
+class CaseCheck(unittest.TestCase):
+	def testToRomanCase(self):
+		"""toRoman should always return uppercase"""
+		for integer in range(1, 5000):
+			numeral = roman.toRoman(integer)
+			self.assertEqual(numeral, numeral.upper())
+
+	def testFromRomanCase(self):
+		"""fromRoman should only accept uppercase input"""
+		for integer in range(1, 5000):
+			numeral = roman.toRoman(integer)
+			roman.fromRoman(numeral.upper())
+			self.assertRaises(roman.InvalidRomanNumeralError,
+							  roman.fromRoman, numeral.lower())
+
+if __name__ == "__main__":
+	unittest.main()
