[tor-commits] [stem/master] Better organizing unit tests for stem.types

atagar at torproject.org atagar at torproject.org
Sun Nov 6 00:20:59 UTC 2011


commit c4c998f6201dae0123c068c3e081a26d6af8a99b
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Nov 5 14:10:07 2011 -0700

    Better organizing unit tests for stem.types
---
 run_tests.py                       |   12 +-
 test/unit/__init__.py              |    2 +-
 test/unit/message.py               |  189 ------------------------------------
 test/unit/types.py                 |   29 ------
 test/unit/types/__init__.py        |    6 +
 test/unit/types/control_line.py    |   29 ++++++
 test/unit/types/control_message.py |  189 ++++++++++++++++++++++++++++++++++++
 test/unit/types/version.py         |  121 +++++++++++++++++++++++
 test/unit/version.py               |  121 -----------------------
 9 files changed, 352 insertions(+), 346 deletions(-)

diff --git a/run_tests.py b/run_tests.py
index 15a6c92..c0731d9 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -10,9 +10,9 @@ import time
 import getopt
 import unittest
 import test.runner
-import test.unit.message
-import test.unit.version
-import test.unit.types
+import test.unit.types.control_message
+import test.unit.types.control_line
+import test.unit.types.version
 import test.integ.message
 import test.integ.system
 
@@ -23,9 +23,9 @@ OPT_EXPANDED = ["unit", "integ", "config=", "targets=", "help"]
 DIVIDER = "=" * 70
 
 # (name, class) tuples for all of our unit and integration tests
-UNIT_TESTS = (("stem.types.ControlMessage", test.unit.message.TestMessageFunctions),
-              ("stem.types.Version", test.unit.version.TestVerionFunctions),
-              ("stem.types.get_entry", test.unit.types.TestGetEntry),
+UNIT_TESTS = (("stem.types.ControlMessage", test.unit.types.control_message.TestControlMessage),
+              ("stem.types.ControlLine", test.unit.types.control_line.TestGetEntry),
+              ("stem.types.Version", test.unit.types.version.TestVerion),
              )
 
 INTEG_TESTS = (("stem.types.ControlMessage", test.integ.message.TestMessageFunctions),
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
index 52a6924..3c9e3b6 100644
--- a/test/unit/__init__.py
+++ b/test/unit/__init__.py
@@ -2,5 +2,5 @@
 Unit tests for the stem library.
 """
 
-__all__ = ["message", "version"]
+__all__ = []
 
diff --git a/test/unit/message.py b/test/unit/message.py
deleted file mode 100644
index 851b394..0000000
--- a/test/unit/message.py
+++ /dev/null
@@ -1,189 +0,0 @@
-"""
-Unit tests for the types.ControlMessage parsing and class.
-"""
-
-import socket
-import StringIO
-import unittest
-import stem.types
-
-OK_REPLY = "250 OK\r\n"
-
-EVENT_BW = "650 BW 32326 2856\r\n"
-EVENT_CIRC_TIMEOUT = "650 CIRC 5 FAILED PURPOSE=GENERAL REASON=TIMEOUT\r\n"
-EVENT_CIRC_LAUNCHED = "650 CIRC 9 LAUNCHED PURPOSE=GENERAL\r\n"
-EVENT_CIRC_EXTENDED = "650 CIRC 5 EXTENDED $A200F527C82C59A25CCA44884B49D3D65B122652=faktor PURPOSE=MEASURE_TIMEOUT\r\n"
-
-GETINFO_VERSION = """250-version=0.2.2.23-alpha (git-b85eb949b528f4d7)
-250 OK
-""".replace("\n", "\r\n")
-
-GETINFO_INFONAMES = """250+info/names=
-accounting/bytes -- Number of bytes read/written so far in the accounting interval.
-accounting/bytes-left -- Number of bytes left to write/read so far in the accounting interval.
-accounting/enabled -- Is accounting currently enabled?
-accounting/hibernating -- Are we hibernating or awake?
-stream-status -- List of current streams.
-version -- The current version of Tor.
-.
-250 OK
-""".replace("\n", "\r\n")
-
-class TestMessageFunctions(unittest.TestCase):
-  """
-  Tests methods and functions related to 'types.ControlMessage'. This uses
-  StringIO to make 'files' to mock socket input.
-  """
-  
-  def test_ok_response(self):
-    """
-    Checks the basic 'OK' response that we get for most commands.
-    """
-    
-    message = self.assert_message_parses(OK_REPLY)
-    self.assertEquals("OK", str(message))
-    
-    contents = message.content()
-    self.assertEquals(1, len(contents))
-    self.assertEquals(("250", " ", "OK"), contents[0])
-  
-  def test_event_response(self):
-    """
-    Checks parsing of actual events.
-    """
-    
-    # BW event
-    message = self.assert_message_parses(EVENT_BW)
-    self.assertEquals("BW 32326 2856", str(message))
-    
-    contents = message.content()
-    self.assertEquals(1, len(contents))
-    self.assertEquals(("650", " ", "BW 32326 2856"), contents[0])
-    
-    # few types of CIRC events
-    for circ_content in (EVENT_CIRC_TIMEOUT, EVENT_CIRC_LAUNCHED, EVENT_CIRC_EXTENDED):
-      message = self.assert_message_parses(circ_content)
-      self.assertEquals(circ_content[4:-2], str(message))
-      
-      contents = message.content()
-      self.assertEquals(1, len(contents))
-      self.assertEquals(("650", " ", str(message)), contents[0])
-  
-  def test_getinfo_response(self):
-    """
-    Checks parsing of actual GETINFO responses.
-    """
-    
-    # GETINFO version (basic single-line results)
-    message = self.assert_message_parses(GETINFO_VERSION)
-    self.assertEquals(2, len(list(message)))
-    self.assertEquals(2, len(str(message).split("\n")))
-    
-    # manually checks the contents
-    contents = message.content()
-    self.assertEquals(2, len(contents))
-    self.assertEquals(("250", "-", "version=0.2.2.23-alpha (git-b85eb949b528f4d7)"), contents[0])
-    self.assertEquals(("250", " ", "OK"), contents[1])
-    
-    # GETINFO info/names (data entry)
-    message = self.assert_message_parses(GETINFO_INFONAMES)
-    self.assertEquals(2, len(list(message)))
-    self.assertEquals(8, len(str(message).split("\n")))
-    
-    # manually checks the contents
-    contents = message.content()
-    self.assertEquals(2, len(contents))
-    
-    first_entry = (contents[0][0], contents[0][1], contents[0][2][:contents[0][2].find("\n")])
-    self.assertEquals(("250", "+", "info/names="), first_entry)
-    self.assertEquals(("250", " ", "OK"), contents[1])
-  
-  def test_no_crlf(self):
-    """
-    Checks that we get a ProtocolError when we don't have both a carrage
-    returna and newline for line endings. This doesn't really check for
-    newlines (since that's what readline would break on), but not the end of
-    the world.
-    """
-    
-    # Replaces each of the CRLF entries with just LF, confirming that this
-    # causes a parsing error. This should test line endings for both data
-    # entry parsing and non-data.
-    
-    infonames_lines = [line + "\n" for line in GETINFO_INFONAMES.split("\n")[:-1]]
-    
-    for i in range(len(infonames_lines)):
-      # replace the CRLF for the line
-      infonames_lines[i] = infonames_lines[i].rstrip("\r\n") + "\n"
-      test_socket_file = StringIO.StringIO("".join(infonames_lines))
-      self.assertRaises(stem.types.ProtocolError, stem.types.read_message, test_socket_file)
-      
-      # puts the CRLF back
-      infonames_lines[i] = infonames_lines[i].rstrip("\n") + "\r\n"
-    
-    # sanity check the above test isn't broken due to leaving infonames_lines
-    # with invalid data
-    
-    self.assert_message_parses("".join(infonames_lines))
-  
-  def test_malformed_prefix(self):
-    """
-    Checks parsing for responses where the header is missing a digit or divider.
-    """
-    
-    for i in range(len(EVENT_BW)):
-      # makes test input with that character missing or replaced
-      removal_test_input = EVENT_BW[:i] + EVENT_BW[i + 1:]
-      replacement_test_input = EVENT_BW[:i] + "#" + EVENT_BW[i + 1:]
-      
-      if i < 4 or i >= (len(EVENT_BW) - 2):
-        # dropping the character should cause an error if...
-        # - this is part of the message prefix
-        # - this is disrupting the line ending
-        
-        self.assertRaises(stem.types.ProtocolError, stem.types.read_message, StringIO.StringIO(removal_test_input))
-        self.assertRaises(stem.types.ProtocolError, stem.types.read_message, StringIO.StringIO(replacement_test_input))
-      else:
-        # otherwise the data will be malformed, but this goes undetected
-        self.assert_message_parses(removal_test_input)
-        self.assert_message_parses(replacement_test_input)
-  
-  def test_disconnected_socket(self):
-    """
-    Tests when the read function is given a file derived from a disconnected
-    socket.
-    """
-    
-    control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    control_socket_file = control_socket.makefile()
-    self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
-  
-  def assert_message_parses(self, controller_reply):
-    """
-    Performs some basic sanity checks that a reply mirrors its parsed result.
-    
-    Returns:
-      types.ControlMessage for the given input
-    """
-    
-    message = stem.types.read_message(StringIO.StringIO(controller_reply))
-    
-    # checks that the raw_content equals the input value
-    self.assertEqual(controller_reply, message.raw_content())
-    
-    # checks that the contents match the input
-    message_lines = str(message).split("\n")
-    controller_lines = controller_reply.split("\r\n")
-    controller_lines.pop() # the ControlMessage won't have a trailing newline
-    
-    while controller_lines:
-      line = controller_lines.pop(0)
-      
-      # mismatching lines with just a period are probably data termination
-      if line == "." and (not message_lines or line != message_lines[0]):
-        continue
-      
-      self.assertTrue(line.endswith(message_lines.pop(0)))
-    
-    return message
-
diff --git a/test/unit/types.py b/test/unit/types.py
deleted file mode 100644
index 9c06ab2..0000000
--- a/test/unit/types.py
+++ /dev/null
@@ -1,29 +0,0 @@
-"""
-Unit tests for the types.get_entry function.
-"""
-
-import unittest
-import stem.types
-
-class TestGetEntry(unittest.TestCase):
-  """
-  Tests the types.get_entry function.
-  """
-  
-  def test_examples(self):
-    """
-    Checks that the examples from the pydoc are correct.
-    """
-    
-    example_input = 'hello there random person'
-    example_result = (None, "hello", "there random person")
-    self.assertEquals(stem.types.get_entry(example_input), example_result)
-    
-    example_input = 'version="0.1.2.3"'
-    example_result = ("version", "0.1.2.3", "")
-    self.assertEquals(stem.types.get_entry(example_input, True, True), example_result)
-    
-    example_input = r'"this has a \" and \\ in it" foo=bar more_data'
-    example_result = (None, r'this has a " and \ in it', "foo=bar more_data")
-    self.assertEquals(stem.types.get_entry(example_input, False, True, True), example_result)
-
diff --git a/test/unit/types/__init__.py b/test/unit/types/__init__.py
new file mode 100644
index 0000000..d472371
--- /dev/null
+++ b/test/unit/types/__init__.py
@@ -0,0 +1,6 @@
+"""
+Unit tests for stem.types.
+"""
+
+__all__ = ["control_message", "control_line", "version"]
+
diff --git a/test/unit/types/control_line.py b/test/unit/types/control_line.py
new file mode 100644
index 0000000..9c06ab2
--- /dev/null
+++ b/test/unit/types/control_line.py
@@ -0,0 +1,29 @@
+"""
+Unit tests for the types.get_entry function.
+"""
+
+import unittest
+import stem.types
+
+class TestGetEntry(unittest.TestCase):
+  """
+  Tests the types.get_entry function.
+  """
+  
+  def test_examples(self):
+    """
+    Checks that the examples from the pydoc are correct.
+    """
+    
+    example_input = 'hello there random person'
+    example_result = (None, "hello", "there random person")
+    self.assertEquals(stem.types.get_entry(example_input), example_result)
+    
+    example_input = 'version="0.1.2.3"'
+    example_result = ("version", "0.1.2.3", "")
+    self.assertEquals(stem.types.get_entry(example_input, True, True), example_result)
+    
+    example_input = r'"this has a \" and \\ in it" foo=bar more_data'
+    example_result = (None, r'this has a " and \ in it', "foo=bar more_data")
+    self.assertEquals(stem.types.get_entry(example_input, False, True, True), example_result)
+
diff --git a/test/unit/types/control_message.py b/test/unit/types/control_message.py
new file mode 100644
index 0000000..563a0bf
--- /dev/null
+++ b/test/unit/types/control_message.py
@@ -0,0 +1,189 @@
+"""
+Unit tests for the types.ControlMessage parsing and class.
+"""
+
+import socket
+import StringIO
+import unittest
+import stem.types
+
+OK_REPLY = "250 OK\r\n"
+
+EVENT_BW = "650 BW 32326 2856\r\n"
+EVENT_CIRC_TIMEOUT = "650 CIRC 5 FAILED PURPOSE=GENERAL REASON=TIMEOUT\r\n"
+EVENT_CIRC_LAUNCHED = "650 CIRC 9 LAUNCHED PURPOSE=GENERAL\r\n"
+EVENT_CIRC_EXTENDED = "650 CIRC 5 EXTENDED $A200F527C82C59A25CCA44884B49D3D65B122652=faktor PURPOSE=MEASURE_TIMEOUT\r\n"
+
+GETINFO_VERSION = """250-version=0.2.2.23-alpha (git-b85eb949b528f4d7)
+250 OK
+""".replace("\n", "\r\n")
+
+GETINFO_INFONAMES = """250+info/names=
+accounting/bytes -- Number of bytes read/written so far in the accounting interval.
+accounting/bytes-left -- Number of bytes left to write/read so far in the accounting interval.
+accounting/enabled -- Is accounting currently enabled?
+accounting/hibernating -- Are we hibernating or awake?
+stream-status -- List of current streams.
+version -- The current version of Tor.
+.
+250 OK
+""".replace("\n", "\r\n")
+
+class TestControlMessage(unittest.TestCase):
+  """
+  Tests methods and functions related to 'types.ControlMessage'. This uses
+  StringIO to make 'files' to mock socket input.
+  """
+  
+  def test_ok_response(self):
+    """
+    Checks the basic 'OK' response that we get for most commands.
+    """
+    
+    message = self.assert_message_parses(OK_REPLY)
+    self.assertEquals("OK", str(message))
+    
+    contents = message.content()
+    self.assertEquals(1, len(contents))
+    self.assertEquals(("250", " ", "OK"), contents[0])
+  
+  def test_event_response(self):
+    """
+    Checks parsing of actual events.
+    """
+    
+    # BW event
+    message = self.assert_message_parses(EVENT_BW)
+    self.assertEquals("BW 32326 2856", str(message))
+    
+    contents = message.content()
+    self.assertEquals(1, len(contents))
+    self.assertEquals(("650", " ", "BW 32326 2856"), contents[0])
+    
+    # few types of CIRC events
+    for circ_content in (EVENT_CIRC_TIMEOUT, EVENT_CIRC_LAUNCHED, EVENT_CIRC_EXTENDED):
+      message = self.assert_message_parses(circ_content)
+      self.assertEquals(circ_content[4:-2], str(message))
+      
+      contents = message.content()
+      self.assertEquals(1, len(contents))
+      self.assertEquals(("650", " ", str(message)), contents[0])
+  
+  def test_getinfo_response(self):
+    """
+    Checks parsing of actual GETINFO responses.
+    """
+    
+    # GETINFO version (basic single-line results)
+    message = self.assert_message_parses(GETINFO_VERSION)
+    self.assertEquals(2, len(list(message)))
+    self.assertEquals(2, len(str(message).split("\n")))
+    
+    # manually checks the contents
+    contents = message.content()
+    self.assertEquals(2, len(contents))
+    self.assertEquals(("250", "-", "version=0.2.2.23-alpha (git-b85eb949b528f4d7)"), contents[0])
+    self.assertEquals(("250", " ", "OK"), contents[1])
+    
+    # GETINFO info/names (data entry)
+    message = self.assert_message_parses(GETINFO_INFONAMES)
+    self.assertEquals(2, len(list(message)))
+    self.assertEquals(8, len(str(message).split("\n")))
+    
+    # manually checks the contents
+    contents = message.content()
+    self.assertEquals(2, len(contents))
+    
+    first_entry = (contents[0][0], contents[0][1], contents[0][2][:contents[0][2].find("\n")])
+    self.assertEquals(("250", "+", "info/names="), first_entry)
+    self.assertEquals(("250", " ", "OK"), contents[1])
+  
+  def test_no_crlf(self):
+    """
+    Checks that we get a ProtocolError when we don't have both a carrage
+    returna and newline for line endings. This doesn't really check for
+    newlines (since that's what readline would break on), but not the end of
+    the world.
+    """
+    
+    # Replaces each of the CRLF entries with just LF, confirming that this
+    # causes a parsing error. This should test line endings for both data
+    # entry parsing and non-data.
+    
+    infonames_lines = [line + "\n" for line in GETINFO_INFONAMES.split("\n")[:-1]]
+    
+    for i in range(len(infonames_lines)):
+      # replace the CRLF for the line
+      infonames_lines[i] = infonames_lines[i].rstrip("\r\n") + "\n"
+      test_socket_file = StringIO.StringIO("".join(infonames_lines))
+      self.assertRaises(stem.types.ProtocolError, stem.types.read_message, test_socket_file)
+      
+      # puts the CRLF back
+      infonames_lines[i] = infonames_lines[i].rstrip("\n") + "\r\n"
+    
+    # sanity check the above test isn't broken due to leaving infonames_lines
+    # with invalid data
+    
+    self.assert_message_parses("".join(infonames_lines))
+  
+  def test_malformed_prefix(self):
+    """
+    Checks parsing for responses where the header is missing a digit or divider.
+    """
+    
+    for i in range(len(EVENT_BW)):
+      # makes test input with that character missing or replaced
+      removal_test_input = EVENT_BW[:i] + EVENT_BW[i + 1:]
+      replacement_test_input = EVENT_BW[:i] + "#" + EVENT_BW[i + 1:]
+      
+      if i < 4 or i >= (len(EVENT_BW) - 2):
+        # dropping the character should cause an error if...
+        # - this is part of the message prefix
+        # - this is disrupting the line ending
+        
+        self.assertRaises(stem.types.ProtocolError, stem.types.read_message, StringIO.StringIO(removal_test_input))
+        self.assertRaises(stem.types.ProtocolError, stem.types.read_message, StringIO.StringIO(replacement_test_input))
+      else:
+        # otherwise the data will be malformed, but this goes undetected
+        self.assert_message_parses(removal_test_input)
+        self.assert_message_parses(replacement_test_input)
+  
+  def test_disconnected_socket(self):
+    """
+    Tests when the read function is given a file derived from a disconnected
+    socket.
+    """
+    
+    control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+    control_socket_file = control_socket.makefile()
+    self.assertRaises(stem.types.ControlSocketClosed, stem.types.read_message, control_socket_file)
+  
+  def assert_message_parses(self, controller_reply):
+    """
+    Performs some basic sanity checks that a reply mirrors its parsed result.
+    
+    Returns:
+      types.ControlMessage for the given input
+    """
+    
+    message = stem.types.read_message(StringIO.StringIO(controller_reply))
+    
+    # checks that the raw_content equals the input value
+    self.assertEqual(controller_reply, message.raw_content())
+    
+    # checks that the contents match the input
+    message_lines = str(message).split("\n")
+    controller_lines = controller_reply.split("\r\n")
+    controller_lines.pop() # the ControlMessage won't have a trailing newline
+    
+    while controller_lines:
+      line = controller_lines.pop(0)
+      
+      # mismatching lines with just a period are probably data termination
+      if line == "." and (not message_lines or line != message_lines[0]):
+        continue
+      
+      self.assertTrue(line.endswith(message_lines.pop(0)))
+    
+    return message
+
diff --git a/test/unit/types/version.py b/test/unit/types/version.py
new file mode 100644
index 0000000..fb04641
--- /dev/null
+++ b/test/unit/types/version.py
@@ -0,0 +1,121 @@
+"""
+Unit tests for the types.Version parsing and class.
+"""
+
+import unittest
+import stem.types
+
+class TestVerion(unittest.TestCase):
+  """
+  Tests methods and functions related to 'types.Version'.
+  """
+  
+  def test_parsing(self):
+    """
+    Tests parsing by the Version class constructor.
+    """
+    
+    # valid versions with various number of compontents to the version
+    version = stem.types.Version("0.1.2.3-tag")
+    self.assert_versions_match(version, 0, 1, 2, 3, "tag")
+    
+    version = stem.types.Version("0.1.2.3")
+    self.assert_versions_match(version, 0, 1, 2, 3, None)
+    
+    version = stem.types.Version("0.1.2-tag")
+    self.assert_versions_match(version, 0, 1, 2, None, "tag")
+    
+    version = stem.types.Version("0.1.2")
+    self.assert_versions_match(version, 0, 1, 2, None, None)
+    
+    # checks an empty tag
+    version = stem.types.Version("0.1.2.3-")
+    self.assert_versions_match(version, 0, 1, 2, 3, "")
+    
+    version = stem.types.Version("0.1.2-")
+    self.assert_versions_match(version, 0, 1, 2, None, "")
+    
+    # checks invalid version strings
+    self.assertRaises(ValueError, stem.types.Version, "")
+    self.assertRaises(ValueError, stem.types.Version, "1.2.3.4nodash")
+    self.assertRaises(ValueError, stem.types.Version, "1.2.3.a")
+    self.assertRaises(ValueError, stem.types.Version, "1.2.a.4")
+    self.assertRaises(ValueError, stem.types.Version, "12.3")
+    self.assertRaises(ValueError, stem.types.Version, "1.-2.3")
+  
+  def test_comparison(self):
+    """
+    Tests comparision between Version instances.
+    """
+    
+    # check for basic incrementing in each portion
+    self.assert_version_is_greater("1.1.2.3-tag", "0.1.2.3-tag")
+    self.assert_version_is_greater("0.2.2.3-tag", "0.1.2.3-tag")
+    self.assert_version_is_greater("0.1.3.3-tag", "0.1.2.3-tag")
+    self.assert_version_is_greater("0.1.2.4-tag", "0.1.2.3-tag")
+    self.assert_version_is_greater("0.1.2.3-ugg", "0.1.2.3-tag")
+    self.assert_version_is_equal("0.1.2.3-tag", "0.1.2.3-tag")
+    
+    # checks that a missing patch level equals zero
+    self.assert_version_is_equal("0.1.2", "0.1.2.0")
+    self.assert_version_is_equal("0.1.2-tag", "0.1.2.0-tag")
+    
+    # checks for missing patch or status
+    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2.3")
+    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2-tag")
+    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2")
+    
+    self.assert_version_is_equal("0.1.2.3", "0.1.2.3")
+    self.assert_version_is_equal("0.1.2", "0.1.2")
+  
+  def test_string(self):
+    """
+    Tests the Version -> string conversion.
+    """
+    
+    # checks conversion with various numbers of arguments
+    
+    self.assert_string_matches("0.1.2.3-tag")
+    self.assert_string_matches("0.1.2.3")
+    self.assert_string_matches("0.1.2")
+  
+  def assert_versions_match(self, version, major, minor, micro, patch, status):
+    """
+    Asserts that the values for a types.Version instance match the given
+    values.
+    """
+    
+    self.assertEqual(version.major, major)
+    self.assertEqual(version.minor, minor)
+    self.assertEqual(version.micro, micro)
+    self.assertEqual(version.patch, patch)
+    self.assertEqual(version.status, status)
+  
+  def assert_version_is_greater(self, first_version, second_version):
+    """
+    Asserts that the parsed version of the first version is greate than the
+    second (also checking the inverse).
+    """
+    
+    version1 = stem.types.Version(first_version)
+    version2 = stem.types.Version(second_version)
+    self.assertEqual(version1 > version2, True)
+    self.assertEqual(version1 < version2, False)
+  
+  def assert_version_is_equal(self, first_version, second_version):
+    """
+    Asserts that the parsed version of the first version equals the second.
+    """
+    
+    version1 = stem.types.Version(first_version)
+    version2 = stem.types.Version(second_version)
+    self.assertEqual(version1, version2)
+  
+  def assert_string_matches(self, version):
+    """
+    Parses the given version string then checks that its string representation
+    matches the input.
+    """
+    
+    self.assertEqual(version, str(stem.types.Version(version)))
+
diff --git a/test/unit/version.py b/test/unit/version.py
deleted file mode 100644
index 3200d05..0000000
--- a/test/unit/version.py
+++ /dev/null
@@ -1,121 +0,0 @@
-"""
-Unit tests for the types.Version parsing and class.
-"""
-
-import unittest
-import stem.types
-
-class TestVerionFunctions(unittest.TestCase):
-  """
-  Tests methods and functions related to 'types.Version'.
-  """
-  
-  def test_parsing(self):
-    """
-    Tests parsing by the Version class constructor.
-    """
-    
-    # valid versions with various number of compontents to the version
-    version = stem.types.Version("0.1.2.3-tag")
-    self.assert_versions_match(version, 0, 1, 2, 3, "tag")
-    
-    version = stem.types.Version("0.1.2.3")
-    self.assert_versions_match(version, 0, 1, 2, 3, None)
-    
-    version = stem.types.Version("0.1.2-tag")
-    self.assert_versions_match(version, 0, 1, 2, None, "tag")
-    
-    version = stem.types.Version("0.1.2")
-    self.assert_versions_match(version, 0, 1, 2, None, None)
-    
-    # checks an empty tag
-    version = stem.types.Version("0.1.2.3-")
-    self.assert_versions_match(version, 0, 1, 2, 3, "")
-    
-    version = stem.types.Version("0.1.2-")
-    self.assert_versions_match(version, 0, 1, 2, None, "")
-    
-    # checks invalid version strings
-    self.assertRaises(ValueError, stem.types.Version, "")
-    self.assertRaises(ValueError, stem.types.Version, "1.2.3.4nodash")
-    self.assertRaises(ValueError, stem.types.Version, "1.2.3.a")
-    self.assertRaises(ValueError, stem.types.Version, "1.2.a.4")
-    self.assertRaises(ValueError, stem.types.Version, "12.3")
-    self.assertRaises(ValueError, stem.types.Version, "1.-2.3")
-  
-  def test_comparison(self):
-    """
-    Tests comparision between Version instances.
-    """
-    
-    # check for basic incrementing in each portion
-    self.assert_version_is_greater("1.1.2.3-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.2.2.3-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.1.3.3-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.1.2.4-tag", "0.1.2.3-tag")
-    self.assert_version_is_greater("0.1.2.3-ugg", "0.1.2.3-tag")
-    self.assert_version_is_equal("0.1.2.3-tag", "0.1.2.3-tag")
-    
-    # checks that a missing patch level equals zero
-    self.assert_version_is_equal("0.1.2", "0.1.2.0")
-    self.assert_version_is_equal("0.1.2-tag", "0.1.2.0-tag")
-    
-    # checks for missing patch or status
-    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2.3")
-    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2-tag")
-    self.assert_version_is_greater("0.1.2.3-tag", "0.1.2")
-    
-    self.assert_version_is_equal("0.1.2.3", "0.1.2.3")
-    self.assert_version_is_equal("0.1.2", "0.1.2")
-  
-  def test_string(self):
-    """
-    Tests the Version -> string conversion.
-    """
-    
-    # checks conversion with various numbers of arguments
-    
-    self.assert_string_matches("0.1.2.3-tag")
-    self.assert_string_matches("0.1.2.3")
-    self.assert_string_matches("0.1.2")
-  
-  def assert_versions_match(self, version, major, minor, micro, patch, status):
-    """
-    Asserts that the values for a types.Version instance match the given
-    values.
-    """
-    
-    self.assertEqual(version.major, major)
-    self.assertEqual(version.minor, minor)
-    self.assertEqual(version.micro, micro)
-    self.assertEqual(version.patch, patch)
-    self.assertEqual(version.status, status)
-  
-  def assert_version_is_greater(self, first_version, second_version):
-    """
-    Asserts that the parsed version of the first version is greate than the
-    second (also checking the inverse).
-    """
-    
-    version1 = stem.types.Version(first_version)
-    version2 = stem.types.Version(second_version)
-    self.assertEqual(version1 > version2, True)
-    self.assertEqual(version1 < version2, False)
-  
-  def assert_version_is_equal(self, first_version, second_version):
-    """
-    Asserts that the parsed version of the first version equals the second.
-    """
-    
-    version1 = stem.types.Version(first_version)
-    version2 = stem.types.Version(second_version)
-    self.assertEqual(version1, version2)
-  
-  def assert_string_matches(self, version):
-    """
-    Parses the given version string then checks that its string representation
-    matches the input.
-    """
-    
-    self.assertEqual(version, str(stem.types.Version(version)))
-





More information about the tor-commits mailing list