commit 10d1423d93bc68114ed22d909e17e96aca621bbe
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sat Oct 26 20:18:59 2013 -0700
Testing interpretor-style examples in our pydocs
Using python's doctest module to test interpretor examples (those with '>>>').
Unfortunately this doesn't include sphinx code blocks (those started with a
'::') nor some of our examples that aren't easy to mock.
---
stem/descriptor/router_status_entry.py | 3 ++-
stem/exit_policy.py | 4 +--
stem/util/connection.py | 5 ++--
stem/util/str_tools.py | 6 +++++
stem/version.py | 2 +-
test/settings.cfg | 1 +
test/unit/doctest.py | 43 ++++++++++++++++++++++++++++++++
7 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py
index 4018b22..6622b72 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -699,7 +699,8 @@ def _base64_to_hex(identity, validate, check_if_fingerprint = True):
::
- >>> _base64_to_hex('p1aag7VwarGxqctS7/fS0y5FU+s')
+ >>> from stem.descriptor.router_status_entry import _base64_to_hex
+ >>> _base64_to_hex('p1aag7VwarGxqctS7/fS0y5FU+s', True)
'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB'
:param str identity: encoded fingerprint from the consensus
diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 0f033de..4664c57 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -228,11 +228,11 @@ class ExitPolicy(object):
>>> policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
>>> policy.summary()
- "accept 80, 443"
+ 'accept 80, 443'
>>> policy = ExitPolicy('accept *:443', 'reject *:1-1024', 'accept *:*')
>>> policy.summary()
- "reject 1-442, 444-1024"
+ 'reject 1-442, 444-1024'
:returns: **str** with a concise summary for our policy
"""
diff --git a/stem/util/connection.py b/stem/util/connection.py
index d21ab0d..6e87f94 100644
--- a/stem/util/connection.py
+++ b/stem/util/connection.py
@@ -403,11 +403,12 @@ def expand_ipv6_address(address):
::
+ >>> from stem.util.connection import expand_ipv6_address
>>> expand_ipv6_address("2001:db8::ff00:42:8329")
- "2001:0db8:0000:0000:0000:ff00:0042:8329"
+ '2001:0db8:0000:0000:0000:ff00:0042:8329'
>>> expand_ipv6_address("::")
- "0000:0000:0000:0000:0000:0000:0000:0000"
+ '0000:0000:0000:0000:0000:0000:0000:0000'
:param str address: IPv6 address to be expanded
diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 33d5e1b..100bd0c 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -109,6 +109,7 @@ def _to_camel_case(label, divider = "_", joiner = " "):
::
+ >>> from stem.util.str_tools import _to_camel_case
>>> _to_camel_case("I_LIKE_PEPPERJACK!")
'I Like Pepperjack!'
@@ -141,6 +142,7 @@ def get_size_label(byte_count, decimal = 0, is_long = False, is_bytes = True):
::
+ >>> from stem.util.str_tools import get_size_label
>>> get_size_label(2000000)
'1 MB'
@@ -176,6 +178,7 @@ def get_time_label(seconds, decimal = 0, is_long = False):
::
+ >>> from stem.util.str_tools import get_time_label
>>> get_time_label(10000)
'2h'
@@ -203,6 +206,7 @@ def get_time_labels(seconds, is_long = False):
::
+ >>> from stem.util.str_tools import get_time_labels
>>> get_time_labels(400)
['6m', '40s']
@@ -232,6 +236,7 @@ def get_short_time_label(seconds):
::
+ >>> from stem.util.str_tools import get_short_time_label
>>> get_short_time_label(111)
'01:51'
@@ -273,6 +278,7 @@ def parse_short_time_label(label):
::
+ >>> from stem.util.str_tools import parse_short_time_label
>>> parse_short_time_label('01:51')
111
diff --git a/stem/version.py b/stem/version.py
index 44f1d02..5efc1e0 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -11,7 +11,7 @@ easily parsed and compared, for instance...
>>> my_version = get_system_tor_version()
>>> print my_version
0.2.1.30
- >>> my_version >= Requirement.CONTROL_SOCKET
+ >>> my_version >= Requirement.TORRC_CONTROL_SOCKET
True
**Module Overview:**
diff --git a/test/settings.cfg b/test/settings.cfg
index 222a7a4..9717d24 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -184,6 +184,7 @@ test.unit_tests
|test.unit.response.mapaddress.TestMapAddressResponse
|test.unit.connection.authentication.TestAuthenticate
|test.unit.control.controller.TestControl
+|test.unit.doctest.TestDocumentation
test.integ_tests
|test.integ.util.conf.TestConf
diff --git a/test/unit/doctest.py b/test/unit/doctest.py
new file mode 100644
index 0000000..cae58a7
--- /dev/null
+++ b/test/unit/doctest.py
@@ -0,0 +1,43 @@
+"""
+Tests examples from our documentation.
+"""
+
+from __future__ import absolute_import
+
+import doctest
+import os
+import unittest
+
+import stem.version
+
+import test.util
+
+try:
+ # added in python 3.3
+ from unittest.mock import Mock, patch
+except ImportError:
+ from mock import Mock, patch
+
+
+class TestDocumentation(unittest.TestCase):
+ def test_examples(self):
+ cwd = os.getcwd()
+
+ for path in test.util._get_files_with_suffix(os.path.join(test.util.STEM_BASE, 'stem')):
+ path = '../../' + path[len(cwd) + 1:]
+ test_run = None
+
+ if path.endswith('/stem/util/conf.py'):
+ pass # too much context to easily test
+ elif path.endswith('/stem/response/__init__.py'):
+ pass # the escaped slashes seem to be confusing doctest
+ elif path.endswith('/stem/control.py'):
+ pass # examples refrence a control instance
+ elif path.endswith('/stem/version.py'):
+ with patch('stem.version.get_system_tor_version', Mock(return_value = stem.version.Version('0.2.1.30'))):
+ test_run = doctest.testfile(path)
+ else:
+ test_run = doctest.testfile(path)
+
+ if test_run and test_run.failed > 0:
+ self.fail()