diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 7fdea58..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.pyc
-*.egg-info
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 414bf35..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2011 Hatem Nassrat
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.rst b/README.rst
index 8386c1b..8c33253 100644
--- a/README.rst
+++ b/README.rst
@@ -1,59 +1,3 @@
-MiniMockTest
-============
+This branch contains the gh-page for MiniMockTest.
-.. image:: https://img.shields.io/pypi/v/MiniMockTest.svg
- :target: https://crate.io/packages/MiniMockTest/#info
-
-.. image:: https://img.shields.io/pypi/dm/MiniMockTest.svg
- :target: https://crate.io/packages/MiniMockTest/#info
-
-.. image:: https://requires.io/github/pykler/MiniMockTest/requirements.png?branch=master
- :target: https://requires.io/github/pykler/MiniMockTest/requirements/?branch=master
-
-Documentation
--------------
-
-This module provides a class which extends unittest.TestCase which can
-be used to easily mock objects in a test case. This module can be used
-in conjunction with other test case classes by means of multiple
-inheritance http://docs.python.org/tutorial/classes.html#multiple-inheritance
-
-An example of using Django's test case with this module's test case is
-simply as follows::
-
- from minimocktest import MockTestCase
- from django.test import TestCase
- from django.test.client import Client
-
- class DjangoTestCase(TestCase, MockTestCase):
- '''
- A TestCase class that combines minimocktest and django.test.TestCase
- '''
-
- def _pre_setup(self):
- TestCase._pre_setup(self)
- MockTestCase.setUp(self)
- # optional: shortcut client handle for quick testing
- self.client = Client()
-
- def _post_teardown(self):
- MockTestCase.tearDown(self)
- TestCase._post_teardown(self)
-
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
-
-COPYING
--------
-
-This module is provided under the terms of the MIT Licence. The code in
-this module relies on the "minimock" library which is included as part of
-the package. The copyright notice for "minimock" is included at the
-beginning of its source code file.
-
-For more information, see the file LICENCSE or
-http://www.opensource.org/licenses/mit-license.php
+All files and content in this branch fall under the same licencse as MiniMockTest itself.
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..6d67c09
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,2 @@
+markdown: rdiscount
+pygments: true
diff --git a/_layouts/default.html b/_layouts/default.html
new file mode 100644
index 0000000..ab71b12
--- /dev/null
+++ b/_layouts/default.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+ {{ page.title }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ content }}
+
+
+
+
+
+
diff --git a/css/screen.css b/css/screen.css
new file mode 100644
index 0000000..defb5c9
--- /dev/null
+++ b/css/screen.css
@@ -0,0 +1,21 @@
+body {
+ margin-top: 1.0em;
+ background-color: #ffcc22;
+ font-family: Helvetica, Arial, FreeSans, san-serif;
+ color: #000000;
+}
+#container {
+ margin: 0 auto;
+ width: 750px;
+}
+h1 { font-size: 3.8em; color: #0033dd; margin-bottom: 3px; }
+h1 .small { font-size: 0.4em; }
+h1 a { text-decoration: none }
+h2 { font-size: 1.5em; color: #0033dd; }
+h3 { text-align: center; color: #0033dd; }
+a { color: #0033dd; }
+.description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
+.download { float: right; }
+pre { background: #000; color: #fff; padding: 15px;}
+hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
+.footer { text-align:center; padding-top:30px; font-style: italic; }
diff --git a/css/syntax.css b/css/syntax.css
new file mode 100644
index 0000000..2774b76
--- /dev/null
+++ b/css/syntax.css
@@ -0,0 +1,60 @@
+.highlight { background: #ffffff; }
+.highlight .c { color: #999988; font-style: italic } /* Comment */
+.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.highlight .k { font-weight: bold } /* Keyword */
+.highlight .o { font-weight: bold } /* Operator */
+.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
+.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #aa0000 } /* Generic.Error */
+.highlight .gh { color: #999999 } /* Generic.Heading */
+.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #555555 } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
+.highlight .gt { color: #aa0000 } /* Generic.Traceback */
+.highlight .kc { font-weight: bold } /* Keyword.Constant */
+.highlight .kd { font-weight: bold } /* Keyword.Declaration */
+.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #009999 } /* Literal.Number */
+.highlight .s { color: #d14 } /* Literal.String */
+.highlight .na { color: #008080 } /* Name.Attribute */
+.highlight .nb { color: #0086B3 } /* Name.Builtin */
+.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
+.highlight .no { color: #008080 } /* Name.Constant */
+.highlight .ni { color: #800080 } /* Name.Entity */
+.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
+.highlight .nn { color: #555555 } /* Name.Namespace */
+.highlight .nt { color: #000080 } /* Name.Tag */
+.highlight .nv { color: #008080 } /* Name.Variable */
+.highlight .ow { font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #009999 } /* Literal.Number.Float */
+.highlight .mh { color: #009999 } /* Literal.Number.Hex */
+.highlight .mi { color: #009999 } /* Literal.Number.Integer */
+.highlight .mo { color: #009999 } /* Literal.Number.Oct */
+.highlight .sb { color: #d14 } /* Literal.String.Backtick */
+.highlight .sc { color: #d14 } /* Literal.String.Char */
+.highlight .sd { color: #d14 } /* Literal.String.Doc */
+.highlight .s2 { color: #d14 } /* Literal.String.Double */
+.highlight .se { color: #d14 } /* Literal.String.Escape */
+.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
+.highlight .si { color: #d14 } /* Literal.String.Interpol */
+.highlight .sx { color: #d14 } /* Literal.String.Other */
+.highlight .sr { color: #009926 } /* Literal.String.Regex */
+.highlight .s1 { color: #d14 } /* Literal.String.Single */
+.highlight .ss { color: #990073 } /* Literal.String.Symbol */
+.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #008080 } /* Name.Variable.Class */
+.highlight .vg { color: #008080 } /* Name.Variable.Global */
+.highlight .vi { color: #008080 } /* Name.Variable.Instance */
+.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..ea84bcd
--- /dev/null
+++ b/index.html
@@ -0,0 +1,124 @@
+---
+layout: default
+title: MiniMockTest
+---
+
+
+
+
+
+
+ Python unittest TestCase that wraps minimock for easier use
+
+
+ minimocktest.MockTestCase provides a full featured unittest.TestCase subclass that allows for mocking. Using this class as the basis of your unittests allows you to mock functions by calling
+
+{% highlight python %}
+self.mock('urllib2.urlopen', returns=StringIO.StringIO('{"error": 1}'))
+{% endhighlight %}
+
+or creating mock objects
+
+{% highlight python %}
+someobj = self.Mock('someobj')
+{% endhighlight %}
+
+Also you do not have to worry about resetting the mock, all that is taken care of by the MockTestCase tearDown function.
+
+Examples
+
+Simple Testing
+
+{% highlight python %}
+import unittest
+from minimocktest import MockTestCase
+
+import StringIO
+import urllib2
+
+def urldump(url):
+ ''' simple function to be tested '''
+ f = urllib2.urlopen(url)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+class MySimpleTestCase(MockTestCase):
+ def setUp(self):
+ super(self.__class__, self).setUp()
+ self.file = StringIO.StringIO('MiniMockTest')
+ self.file.close = self.Mock('file_close_function')
+ def test_urldump_dumpsContentProperly(self):
+ self.mock('urllib2.urlopen', returns=self.file)
+ self.assertEquals(urldump('http://pykler.github.com/'), 'MiniMockTest')
+ self.assertSameTrace('\n'.join([
+ "Called urllib2.urlopen('http://pykler.github.com/')",
+ "Called file_close_function()",
+ ]))
+ urllib2.urlopen('anything')
+ self.mock('urllib2.urlopen', returns=self.file, tracker=None)
+ urllib2.urlopen('this is not tracked')
+ self.assertTrace("Called urllib2.urlopen('anything')")
+ self.assertTrace("Called urllib2.urlopen('this is not tracked')", includes=False)
+ self.assertSameTrace('\n'.join([
+ "Called urllib2.urlopen('http://pykler.github.com/')",
+ "Called file_close_function()",
+ "Called urllib2.urlopen('anything')",
+ ]))
+
+suite = unittest.TestLoader().loadTestsFromTestCase(MySimpleTestCase)
+unittest.TextTestRunner().run(suite)
+{% endhighlight %}
+
+Django Integration
+
+To integrate with Django, simply create the following class, and use it as your base instead of using the django.test.TestCase directly.
+
+{% highlight python %}
+from minimocktest import MockTestCase
+from django.test import TestCase
+from django.test.client import Client
+
+class DjangoTestCase(TestCase, MockTestCase):
+ '''
+ A TestCase class that combines minimocktest and django.test.TestCase
+ '''
+ def _pre_setup(self):
+ TestCase._pre_setup(self)
+ MockTestCase.setUp(self)
+ # optional: shortcut client handle for quick testing
+ self.client = Client()
+
+ def _post_teardown(self):
+ MockTestCase.tearDown(self)
+ TestCase._post_teardown(self)
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+{% endhighlight %}
+
+
+ Download
+
+ You can download this project in either
+ zip or
+ tar formats.
+
+ You can also clone the project with Git
+ by running:
+
$ git clone git://github.com/pykler/MiniMockTest
+
+
+
diff --git a/minimocktest/__init__.py b/minimocktest/__init__.py
deleted file mode 100644
index 0acbb49..0000000
--- a/minimocktest/__init__.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# (c) 2011 Hatem Nassrat
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-'''
-MiniMockTest module, holds MockTestCase class for easy to use mocking in testcases
-'''
-
-import __builtin__
-import inspect
-from unittest import TestCase
-import minimock
-
-class MockTestCase(TestCase):
- '''
- A TestCase class that integrates minimock functionailty
- `self.tt` minimock tracker object
- `self.mock` calls minimock.mock using tracker=`self.tt`
- `self.assertSameTrace` calls minimock.assert_same_trace with `self.tt`
- '''
-
- def setUp(self):
- TestCase.setUp(self)
- self.tt = minimock.TraceTracker()
-
- def tearDown(self):
- self.mockRestore()
- TestCase.tearDown(self)
-
- def Mock(self, *args, **kwargs):
- if 'tracker' not in kwargs:
- kwargs['tracker'] = self.tt
- return minimock.Mock(*args, **kwargs)
-
- def mock(self, *args, **kwargs):
- if len(args) <= 1 and 'nsdicts' not in kwargs:
- # custom nsdicts not used, inspect caller's stack
- stack = inspect.stack()
- try:
- # stack[1][0] is the frame object of the caller to this function
- globals_ = stack[1][0].f_globals
- locals_ = stack[1][0].f_locals
- nsdicts = (locals_, globals_, __builtin__.__dict__)
- finally:
- del(stack)
- kwargs['nsdicts'] = nsdicts
- if 'tracker' not in kwargs:
- kwargs['tracker'] = self.tt
- return minimock.mock(*args, **kwargs)
-
- def mockRestore(self):
- minimock.restore()
-
- def assertSameTrace(self, want):
- '''
- Asserts if want == trace
- '''
- minimock.assert_same_trace(self.tt, want)
-
- def assertTrace(self, want, includes=True):
- '''
- Asserts if want is included in trace, or excluded when includes=False
- '''
- trace = self.tt.dump()
- condition = want in trace
- fragment = 'not in'
- if not includes:
- condition = not condition
- fragment = 'in'
- self.assertTrue(condition, '%s %s trace:\n%s' %(want, fragment, trace))
diff --git a/minimocktest/minimock.py b/minimocktest/minimock.py
deleted file mode 100644
index ebd1500..0000000
--- a/minimocktest/minimock.py
+++ /dev/null
@@ -1,644 +0,0 @@
-# (c) 2006-2009 Ian Bicking, Mike Beachy, and contributors
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
-r"""
-minimock is a simple library for doing Mock objects with doctest.
-When using doctest, mock objects can be very simple.
-
-Here's an example of something we might test, a simple email sender::
-
- >>> import smtplib
- >>> def send_email(from_addr, to_addr, subject, body):
- ... conn = smtplib.SMTP('localhost')
- ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % (
- ... to_addr, from_addr, subject, body)
- ... conn.sendmail(from_addr, [to_addr], msg)
- ... conn.quit()
-
-Now we want to make a mock ``smtplib.SMTP`` object. We'll have to
-inject our mock into the ``smtplib`` module::
-
- >>> smtplib.SMTP = Mock('smtplib.SMTP')
- >>> smtplib.SMTP.mock_returns = Mock('smtp_connection')
-
-Now we do the test::
-
- >>> send_email('ianb@colorstudy.com', 'joe@example.com',
- ... 'Hi there!', 'How is it going?')
- Called smtplib.SMTP('localhost')
- Called smtp_connection.sendmail(
- 'ianb@colorstudy.com',
- ['joe@example.com'],
- 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?')
- Called smtp_connection.quit()
-
-Voila! We've tested implicitly that no unexpected methods were called
-on the object. We've also tested the arguments that the mock object
-got. We've provided fake return calls (for the ``smtplib.SMTP()``
-constructor). These are all the core parts of a mock library. The
-implementation is simple because most of the work is done by doctest.
-"""
-
-__all__ = ["mock", "restore", "Mock", "TraceTracker", "assert_same_trace"]
-
-import sys
-import inspect
-import doctest
-import re
-import textwrap
-
-try:
- import builtins
-except ImportError:
- # python < 3
- import __builtin__ as builtins
- try:
- from cStringIO import StringIO
- except ImportError:
- from StringIO import StringIO
-else:
- # python 3
- from io import StringIO
-try:
- next
-except NameError:
- # python < 2.6
- def next(x):
- return x.next()
-
-# A list of mocked objects. Each item is a tuple of (original object,
-# namespace dict, object name, and a list of object attributes).
-#
-mocked = []
-
-def lookup_by_name(name, nsdicts):
- """
- Look up an object by name from a sequence of namespace dictionaries.
- Returns a tuple of (nsdict, obj_name, attrs); nsdict is the namespace
- dictionary the name was found in, obj_name is the name of the base object
- the name is bound to, and the attrs list is the chain of attributes
- of the object that completes the name.
-
- >>> import os
- >>> nsdict, obj_name, attrs = lookup_by_name("os.path.isdir",
- ... (locals(),))
- >>> obj_name, attrs
- ('os', ['path', 'isdir'])
- >>> getattr(getattr(nsdict[obj_name], attrs[0]), attrs[1]) # doctest: +ELLIPSIS
-
- >>> lookup_by_name("os.monkey", (locals(),))
- Traceback (most recent call last):
- ...
- NameError: name 'os.monkey' is not defined
-
- """
- for nsdict in nsdicts:
- attrs = name.split(".")
- names = []
-
- while attrs:
- names.append(attrs.pop(0))
- obj_name = ".".join(names)
-
- if obj_name in nsdict:
- attr_copy = attrs[:]
- tmp = nsdict[obj_name]
- try:
- while attr_copy:
- tmp = getattr(tmp, attr_copy.pop(0))
- except AttributeError:
- pass
- else:
- return nsdict, obj_name, attrs
-
- raise NameError("name '%s' is not defined" % name)
-
-def mock(name, nsdicts=None, mock_obj=None, **kw):
- """
- Mock the named object, placing a Mock instance in the correct namespace
- dictionary. If no iterable of namespace dicts is provided, use
- introspection to get the locals and globals of the caller of this
- function, as well as __builtin__.__dict__ to allow mocking built-ins.
-
- All additional keyword args are passed on to the Mock object
- initializer.
-
- An example of how os.path.isfile is replaced::
-
- >>> import os
- >>> os.path.isfile # doctest: +ELLIPSIS
-
- >>> isfile_id = id(os.path.isfile)
- >>> mock("os.path.isfile", returns=True)
- >>> os.path.isfile # doctest: +ELLIPSIS
-
- >>> os.path.isfile("/foo/bar/baz")
- Called os.path.isfile('/foo/bar/baz')
- True
- >>> mock_id = id(os.path.isfile)
- >>> mock_id != isfile_id
- True
-
- A second mock object will replace the first, but the original object
- will be the one replaced with the replace() function.
-
- >>> mock("os.path.isfile", returns=False)
- >>> mock_id != id(os.path.isfile)
- True
- >>> restore()
- >>> os.path.isfile # doctest: +ELLIPSIS
-
- >>> isfile_id == id(os.path.isfile)
- True
-
- Test mocking a built-in function::
-
- >>> try:
- ... input = raw_input
- ... except NameError:
- ... pass # for Python 3
- >>> mock("input", returns="okay")
- >>> input()
- Called input()
- 'okay'
- >>> restore()
-
- Test mocking and restoring a classmethod and staticmethod::
-
- >>> class Test(object):
- ... @classmethod
- ... def cm(cls):
- ... return 'cm'
- ... @staticmethod
- ... def sm():
- ... return 'sm'
- >>> mock('Test.cm', returns='mocked')
- >>> mock('Test.sm', returns='mocked')
- >>> Test.cm()
- Called Test.cm()
- 'mocked'
- >>> Test.sm()
- Called Test.sm()
- 'mocked'
- >>> restore()
- >>> Test.cm()
- 'cm'
- >>> Test.sm()
- 'sm'
-
- Test mocking a proxy object::
-
- >>> class Proxy(object):
- ... def __init__(self, obj):
- ... self._obj = obj
- ... def __getattr__(self, name):
- ... return getattr(self._obj, name)
- >>> import os
- >>> os = Proxy(os)
- >>> os.path.isfile # doctest: +ELLIPSIS
-
- >>> mock('os.path.isfile')
- >>> os.path.isfile # doctest: +ELLIPSIS
-
- >>> restore()
-
- """
- if nsdicts is None:
- stack = inspect.stack()
- try:
- # stack[1][0] is the frame object of the caller to this function
- globals_ = stack[1][0].f_globals
- locals_ = stack[1][0].f_locals
- nsdicts = (locals_, globals_, builtins.__dict__)
- finally:
- del(stack)
-
- if mock_obj is None:
- mock_obj = Mock(name, **kw)
-
- nsdict, obj_name, attrs = lookup_by_name(name, nsdicts)
-
- # Get the original object and replace it with the mock object.
- tmp = nsdict[obj_name]
-
- # if run from a doctest, nsdict may point to a *copy* of the
- # global namespace, so instead use tmp.func_globals if present.
- # we use isinstance(gettattr(...), dict) rather than hasattr
- # because if tmp is itself a mock object, tmp.func_globals will
- # return another mock object
- if isinstance(getattr(tmp, 'func_globals', None), dict):
- nsdict = tmp.__globals__
- if not attrs:
- original = tmp
- nsdict[obj_name] = mock_obj
- else:
- for attr in attrs[:-1]:
- try:
- tmp = tmp.__dict__[attr]
- except KeyError:
- tmp = getattr(tmp, attr)
- try:
- original = tmp.__dict__[attrs[-1]]
- except KeyError:
- original = getattr(tmp, attrs[-1])
- setattr(tmp, attrs[-1], mock_obj)
-
- mocked.append((original, nsdict, obj_name, attrs))
-
-def restore():
- """
- Restore all mocked objects.
- """
- global mocked
-
- # Restore the objects in the reverse order of their mocking to assure
- # the original state is retrieved.
- while mocked:
- original, nsdict, name, attrs = mocked.pop()
- if not attrs:
- nsdict[name] = original
- else:
- tmp = nsdict[name]
- for attr in attrs[:-1]:
- try:
- tmp = tmp.__dict__[attr]
- except KeyError:
- tmp = getattr(tmp, attr)
- setattr(tmp, attrs[-1], original)
-
-def assert_same_trace(tracker, want):
- r"""
- Check that the mock objects using ``tracker`` have been used as expected.
-
- :param tracker: a :class:`TraceTracker` instance
- :param want: the expected :class:`Printer` output
- :type want: string
- :raises: :exc:`AssertionError` if the expected and observed outputs don't
- match
-
- Example::
-
- >>> tt = TraceTracker()
- >>> m = Mock('mock_obj', tracker=tt)
- >>> m.some_meth('dummy argument')
- >>> assert_same_trace(tt,
- ... "Called mock_obj.some_meth('dummy argument')\n")
- >>> assert_same_trace(tt, "Non-matching trace") # doctest: +ELLIPSIS
- Traceback (most recent call last):
- ...
- AssertionError...
- """
- assert tracker.check(want), tracker.diff(want)
-
-class AbstractTracker(object):
- def __init__(self, *args, **kw):
- raise NotImplementedError
-
- def call(self, *args, **kw):
- raise NotImplementedError
-
- def set(self, *args, **kw):
- raise NotImplementedError
-
-class Printer(AbstractTracker):
- """Prints all calls to the file it's instantiated with.
- Can take any object that implements `write'.
- """
- def __init__(self, file):
- self.file = file
-
- def call(self, func_name, *args, **kw):
- parts = [repr(a) for a in args]
- parts.extend(
- '%s=%r' % (items) for items in sorted(kw.items()))
- msg = 'Called %s(%s)\n' % (func_name, ', '.join(parts))
- if len(msg) > 80:
- msg = 'Called %s(\n %s)\n' % (
- func_name, ',\n '.join(parts))
- self.file.write(msg)
-
- def set(self, obj_name, attr, value):
- """
- >>> z = Mock('z', show_attrs=True)
- >>> z.a = 2
- Set z.a = 2
- """
- self.file.write('Set %s.%s = %r\n' % (obj_name, attr, value))
-
-class TraceTracker(Printer):
- """
- :class:`AbstractTracker` implementation for using MiniMock in non-
- :mod:`doctest` tests. Follows the pattern of recording minimocked
- object usage as strings, then using the facilities of :mod:`doctest`
- to assert the correctness of these usage strings.
- """
- def __init__(self, *args, **kw):
- self.out = StringIO()
- super(TraceTracker, self).__init__(self.out, *args, **kw)
- self.checker = MinimockOutputChecker()
- self.options = doctest.ELLIPSIS
- self.options |= doctest.NORMALIZE_INDENTATION
- self.options |= doctest.NORMALIZE_FUNCTION_PARAMETERS
- self.options |= doctest.REPORT_UDIFF
-
- def check(self, want):
- r"""
- Compare observed MiniMock usage with that which we expected.
-
- :param want: the :class:`Printer` output that results from expected
- usage of mocked objects
- :type want: string
- :rtype: a ``True`` value if the check passed, ``False`` otherwise
-
- Example::
-
- >>> tt = TraceTracker()
- >>> m = Mock('mock_obj', tracker=tt)
- >>> m.some_meth('arg1')
- >>> tt.check("Called mock_obj.some_meth('arg1')")
- True
- >>> tt.clear()
- >>> m.some_meth('arg2')
- >>> tt.check("does not match")
- False
- """
- return self.checker.check_output(want, self.dump(),
- optionflags=self.options)
-
- def diff(self, want):
- r"""
- Analyse differences between observed MiniMock usage and that which
- we expected, if any.
-
- :param want: the :class:`Printer` output that results from expected
- usage of mocked objects
- :type want: string
- :rtype: a string summary of differences between the observed usage and
- the ``want`` parameter
-
- Example::
-
- >>> tt = TraceTracker()
- >>> m = Mock('mock_obj', tracker=tt)
- >>> m.some_meth('dummy argument')
- >>> tt.diff("does not match")
- "Expected:\n does not match\nGot:\n Called mock_obj.some_meth('dummy argument')\n"
- >>> tt.diff("Called mock_obj.some_meth('dummy argument')")
- ''
- """
- if self.check(want):
- # doctest's output_difference always returns a diff, even if
- # there's no difference: short circuit that feature.
- return ''
- else:
- return self.checker.output_difference(doctest.Example("", want),
- self.dump(), optionflags=self.options)
-
- def dump(self):
- r"""
- Return the MiniMock object usage so far.
-
- Example::
-
- >>> tt = TraceTracker()
- >>> m = Mock('mock_obj', tracker=tt)
- >>> m.some_meth('dummy argument')
- >>> tt.dump()
- "Called mock_obj.some_meth('dummy argument')\n"
- """
- return self.out.getvalue()
-
- def clear(self):
- """Clear the MiniMock object usage that has been tracked so far.
-
- truncate() was modified not to change the file position anymore
- in Python 3.1.2, so should be sought explicitly.
- http://bugs.python.org/issue8558
- """
- self.out.truncate(0)
- self.out.seek(0)
-
-
-def normalize_function_parameters(text):
- r"""
- Return a version of ``text`` with function parameters normalized.
-
- The normalisations performed are:
-
- * Remove any whitespace sequence between an opening
- parenthesis '(' and a subsequent non-whitespace character.
-
- * Remove any whitespace sequence between a non-whitespace
- character and a closing parenthesis ')'.
-
- * Ensure a comma ',' and a subsequent non-whitespace character
- are separated by a single space ' '.
-
- Example::
-
- >>> tt = TraceTracker()
- >>> foo = Mock("foo", tracker=tt)
- >>> expect_mock_output = '''\
- ... Called foo.bar('baz')
- ... '''
- >>> foo.bar('baz')
- >>> tt.check(expect_mock_output)
- True
- >>> tt.clear()
- >>> expect_mock_output = '''\
- ... Called foo.bar(
- ... 'baz')
- ... '''
- >>> foo.bar('baz')
- >>> tt.check(expect_mock_output)
- True
- """
- normalized_text = text
- normalize_map = {
- re.compile(r"\(\s+(\S)"): r"(\1",
- re.compile(r"(\S)\s+\)"): r"\1)",
- re.compile(r",\s*(\S)"): r", \1",
- }
- for search_pattern, replace_pattern in normalize_map.items():
- normalized_text = re.sub(
- search_pattern, replace_pattern, normalized_text)
-
- return normalized_text
-
-
-doctest.NORMALIZE_INDENTATION = (
- doctest.register_optionflag('NORMALIZE_INDENTATION'))
-doctest.NORMALIZE_FUNCTION_PARAMETERS = (
- doctest.register_optionflag('NORMALIZE_FUNCTION_PARAMETERS'))
-
-
-class MinimockOutputChecker(doctest.OutputChecker, object):
- """Class for matching output of MiniMock objects against expectations.
- """
-
- def check_output(self, want, got, optionflags):
- if (optionflags & doctest.NORMALIZE_INDENTATION):
- want = textwrap.dedent(want).rstrip()
- got = textwrap.dedent(got).rstrip()
- if (optionflags & doctest.NORMALIZE_FUNCTION_PARAMETERS):
- want = normalize_function_parameters(want)
- got = normalize_function_parameters(got)
- output_match = super(MinimockOutputChecker, self).check_output(
- want, got, optionflags)
- return output_match
- check_output.__doc__ = doctest.OutputChecker.check_output.__doc__
-
-
-class _DefaultTracker(object):
- def __repr__(self):
- return '(default tracker)'
-DefaultTracker = _DefaultTracker()
-del _DefaultTracker
-
-class Mock(object):
-
- def __init__(self, name, returns=None, returns_iter=None,
- returns_func=None, raises=None, show_attrs=False,
- tracker=DefaultTracker, **kw):
- _obsetattr = object.__setattr__
- _obsetattr(self, 'mock_name', name)
- _obsetattr(self, 'mock_returns', returns)
- if returns_iter is not None:
- returns_iter = iter(returns_iter)
- _obsetattr(self, 'mock_returns_iter', returns_iter)
- _obsetattr(self, 'mock_returns_func', returns_func)
- _obsetattr(self, 'mock_raises', raises)
- _obsetattr(self, 'mock_attrs', kw)
- _obsetattr(self, 'mock_show_attrs', show_attrs)
- if tracker is DefaultTracker:
- tracker = Printer(sys.stdout)
- _obsetattr(self, 'mock_tracker', tracker)
-
- def __repr__(self):
- return '' % (hex(id(self)), self.mock_name)
-
- def __call__(self, *args, **kw):
- if self.mock_tracker is not None:
- self.mock_tracker.call(self.mock_name, *args, **kw)
- return self._mock_return(*args, **kw)
-
- def _mock_return(self, *args, **kw):
- if self.mock_raises is not None:
- raise self.mock_raises
- elif self.mock_returns is not None:
- return self.mock_returns
- elif self.mock_returns_iter is not None:
- try:
- return next(self.mock_returns_iter)
- except StopIteration:
- raise Exception("No more mock return values are present.")
- elif self.mock_returns_func is not None:
- return self.mock_returns_func(*args, **kw)
- else:
- return None
-
- def __getattr__(self, attr):
- if attr not in self.mock_attrs:
- if self.mock_name:
- new_name = self.mock_name + '.' + attr
- else:
- new_name = attr
- self.mock_attrs[attr] = Mock(new_name,
- show_attrs=self.mock_show_attrs,
- tracker=self.mock_tracker)
- return self.mock_attrs[attr]
-
- def __setattr__(self, attr, value):
- if attr in frozenset((
- 'mock_raises',
- 'mock_returns',
- 'mock_returns_func',
- 'mock_returns_iter',
- 'mock_tracker',
- 'mock_show_attrs',
- )):
- if attr == 'mock_returns_iter' and value is not None:
- value = iter(value)
- object.__setattr__(self, attr, value)
- else:
- if self.mock_show_attrs and self.mock_tracker is not None:
- self.mock_tracker.set(self.mock_name, attr, value)
- self.mock_attrs[attr] = value
-
-__test__ = {
- "Mock" :
- r"""
- Test setting various "mock_" attributes on an existing Mock object.
-
- >>> m = Mock('mock_obj', tracker=None)
- >>> m.mock_returns = 42
- >>> m()
- 42
- >>> m.mock_returns = None
- >>> m.mock_returns_func = lambda x: x*x
- >>> m(3)
- 9
- >>> m.mock_returns_func = None
- >>> m.mock_returns_iter = [True, False]
- >>> m()
- True
- >>> m()
- False
- >>> m.mock_returns_iter = None
- >>> m.mock_raises = ValueError
- >>> try:
- ... m()
- ... except ValueError:
- ... pass
- ... else:
- ... raise AssertionError('m() should have raised ValueError')
- >>> m.mock_tracker = Printer(sys.stdout)
- >>> m.mock_show_attrs = True
- >>> m.a = 2
- Set mock_obj.a = 2
- """,
-
- "mock" :
- r"""
- An additional test for mocking a function accessed directly (i.e.
- not via object attributes).
-
- >>> import os
- >>> rename = os.rename
- >>> orig_id = id(rename)
- >>> mock("rename")
- >>> mock_id = id(rename)
- >>> mock("rename")
- >>> mock_id != id(rename)
- True
- >>> restore()
- >>> orig_id == id(rename) == id(os.rename)
- True
-
- The example from the module docstring, done with the mock/restore
- functions.
-
- >>> import smtplib
- >>> def send_email(from_addr, to_addr, subject, body):
- ... conn = smtplib.SMTP('localhost')
- ... msg = 'To: %s\nFrom: %s\nSubject: %s\n\n%s' % (
- ... to_addr, from_addr, subject, body)
- ... conn.sendmail(from_addr, [to_addr], msg)
- ... conn.quit()
-
- >>> mock("smtplib.SMTP", returns=Mock('smtp_connection'))
- >>> send_email('ianb@colorstudy.com', 'joe@example.com',
- ... 'Hi there!', 'How is it going?')
- Called smtplib.SMTP('localhost')
- Called smtp_connection.sendmail(
- 'ianb@colorstudy.com',
- ['joe@example.com'],
- 'To: joe@example.com\nFrom: ianb@colorstudy.com\nSubject: Hi there!\n\nHow is it going?')
- Called smtp_connection.quit()
- >>> restore()
-
- """,
-}
-
-if __name__ == '__main__':
- import doctest
- doctest.testmod(optionflags=doctest.ELLIPSIS)
diff --git a/setup.py b/setup.py
deleted file mode 100644
index f15656f..0000000
--- a/setup.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from setuptools import setup, find_packages
-import sys, os
-
-setup(name='MiniMockTest',
- version='0.5',
- description="Custom unittest TestCase that wraps minimock",
- long_description="""\
-Custom unittest TestCase that wraps minimock for easier use """,
- classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
- keywords='minimock mock mocking test unittest TestCase MockTestCase',
- author='Hatem Nassrat',
- author_email='hnassrat@gmail.com',
- url='http://pykler.github.com/MiniMockTest/',
- license='MIT',
- packages=find_packages(exclude=['ez_setup']),
- include_package_data=True,
- zip_safe=True,
- install_requires=[
- # -*- Extra requirements: -*-
- ],
- entry_points="""
- # -*- Entry points: -*-
- """,
- )