Commit 34cc0501 authored by Edward Lemur's avatar Edward Lemur Committed by Commit Bot

depot_tools: Update pymox to a Python 3 compatible version.

Bug: 984182
Change-Id: Ib28cec16883bb5269453c27c74d8124fbfba8920
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/1717248Reviewed-by: 's avatarAndrii Shyshkalov <tandrii@chromium.org>
Reviewed-by: 's avatarRobbie Iannucci <iannucci@chromium.org>
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
parent c420221f
python_version: "2.7"
# Used by:
# testing_support/super_mox.py
wheel: <
name: "infra/python/wheels/mox-py2_py3"
version: "version:0.5.3"
>
...@@ -10,12 +10,12 @@ import os ...@@ -10,12 +10,12 @@ import os
import random import random
import shutil import shutil
import string import string
import StringIO
import subprocess import subprocess
import sys import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__))) sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from third_party.pymox import mox import mox
from third_party.six.moves import StringIO
class IsOneOf(mox.Comparator): class IsOneOf(mox.Comparator):
...@@ -36,15 +36,15 @@ class TestCaseUtils(object): ...@@ -36,15 +36,15 @@ class TestCaseUtils(object):
_OS_SEP = os.sep _OS_SEP = os.sep
_RANDOM_CHOICE = random.choice _RANDOM_CHOICE = random.choice
_RANDOM_RANDINT = random.randint _RANDOM_RANDINT = random.randint
_STRING_LETTERS = string.letters _STRING_LETTERS = string.ascii_letters
## Some utilities for generating arbitrary arguments. ## Some utilities for generating arbitrary arguments.
def String(self, max_length): def String(self, max_length):
return ''.join([self._RANDOM_CHOICE(self._STRING_LETTERS) return ''.join([self._RANDOM_CHOICE(self._STRING_LETTERS)
for _ in xrange(self._RANDOM_RANDINT(1, max_length))]) for _ in range(self._RANDOM_RANDINT(1, max_length))])
def Strings(self, max_arg_count, max_arg_length): def Strings(self, max_arg_count, max_arg_length):
return [self.String(max_arg_length) for _ in xrange(max_arg_count)] return [self.String(max_arg_length) for _ in range(max_arg_count)]
def Args(self, max_arg_count=8, max_arg_length=16): def Args(self, max_arg_count=8, max_arg_length=16):
return self.Strings(max_arg_count, return self.Strings(max_arg_count,
...@@ -87,7 +87,7 @@ class StdoutCheck(object): ...@@ -87,7 +87,7 @@ class StdoutCheck(object):
def setUp(self): def setUp(self):
# Override the mock with a StringIO, it's much less painful to test. # Override the mock with a StringIO, it's much less painful to test.
self._old_stdout = sys.stdout self._old_stdout = sys.stdout
stdout = StringIO.StringIO() stdout = StringIO()
stdout.flush = lambda: None stdout.flush = lambda: None
sys.stdout = stdout sys.stdout = stdout
...@@ -96,7 +96,7 @@ class StdoutCheck(object): ...@@ -96,7 +96,7 @@ class StdoutCheck(object):
# If sys.stdout was used, self.checkstdout() must be called. # If sys.stdout was used, self.checkstdout() must be called.
# pylint: disable=no-member # pylint: disable=no-member
if not sys.stdout.closed: if not sys.stdout.closed:
self.assertEquals('', sys.stdout.getvalue()) self.assertEqual('', sys.stdout.getvalue())
except AttributeError: except AttributeError:
pass pass
sys.stdout = self._old_stdout sys.stdout = self._old_stdout
...@@ -105,7 +105,7 @@ class StdoutCheck(object): ...@@ -105,7 +105,7 @@ class StdoutCheck(object):
value = sys.stdout.getvalue() value = sys.stdout.getvalue()
sys.stdout.close() sys.stdout.close()
# pylint: disable=no-member # pylint: disable=no-member
self.assertEquals(expected, value) self.assertEqual(expected, value)
class SuperMoxTestBase(TestCaseUtils, StdoutCheck, mox.MoxTestBase): class SuperMoxTestBase(TestCaseUtils, StdoutCheck, mox.MoxTestBase):
......
...@@ -1449,8 +1449,7 @@ class InputApiUnittest(PresubmitTestsBase): ...@@ -1449,8 +1449,7 @@ class InputApiUnittest(PresubmitTestsBase):
self.fake_change, self.fake_change,
presubmit_path='foo/path/PRESUBMIT.py', presubmit_path='foo/path/PRESUBMIT.py',
is_committing=False, gerrit_obj=None, verbose=False) is_committing=False, gerrit_obj=None, verbose=False)
input_api.tempfile.NamedTemporaryFile = self.mox.CreateMock( self.mox.StubOutWithMock(presubmit.tempfile, 'NamedTemporaryFile')
input_api.tempfile.NamedTemporaryFile)
input_api.tempfile.NamedTemporaryFile( input_api.tempfile.NamedTemporaryFile(
delete=False).AndReturn(MockTemporaryFile('foo')) delete=False).AndReturn(MockTemporaryFile('foo'))
input_api.tempfile.NamedTemporaryFile( input_api.tempfile.NamedTemporaryFile(
......
This diff is collapsed.
include COPYING
include mox_test.py
include mox_test_helper.py
include stubout_test.py
include stubout_testee.py
Mox is an open source mock object framework for Python, inspired by
the Java library EasyMock.
To install:
$ python setup.py install
To run Mox's internal tests:
$ python mox_test.py
Basic usage:
import unittest
import mox
class PersonTest(mox.MoxTestBase):
def testUsingMox(self):
# Create a mock Person
mock_person = self.mox.CreateMock(Person)
test_person = ...
test_primary_key = ...
unknown_person = ...
# Expect InsertPerson to be called with test_person; return
# test_primary_key at that point
mock_person.InsertPerson(test_person).AndReturn(test_primary_key)
# Raise an exception when this is called
mock_person.DeletePerson(unknown_person).AndRaise(UnknownPersonError())
# Switch from record mode to replay mode
self.mox.ReplayAll()
# Run the test
ret_pk = mock_person.InsertPerson(test_person)
self.assertEquals(test_primary_key, ret_pk)
self.assertRaises(UnknownPersonError, mock_person, unknown_person)
For more documentation, see:
http://code.google.com/p/pymox/wiki/MoxDocumentation
For more information, see:
http://code.google.com/p/pymox/
Our user and developer discussion group is:
http://groups.google.com/group/mox-discuss
Mox is Copyright 2008 Google Inc, and licensed under the Apache
License, Version 2.0; see the file COPYING for details. If you would
like to help us improve Mox, join the group.
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/python2.4
#
# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A very basic test class derived from mox.MoxTestBase, used by mox_test.py.
The class defined in this module is used to test the features of
MoxTestBase and is not intended to be a standalone test. It needs to
be in a separate module, because otherwise the tests in this class
(which should not all pass) would be executed as part of the
mox_test.py test suite.
See mox_test.MoxTestBaseTest for how this class is actually used.
"""
import os
import mox
class ExampleMoxTestMixin(object):
"""Mix-in class for mox test case class.
It stubs out the same function as one of the test methods in
the example test case. Both tests must pass as meta class wraps
test methods in all base classes.
"""
def testStat(self):
self.mox.StubOutWithMock(os, 'stat')
os.stat(self.DIR_PATH)
self.mox.ReplayAll()
os.stat(self.DIR_PATH)
class ExampleMoxTest(mox.MoxTestBase, ExampleMoxTestMixin):
DIR_PATH = '/path/to/some/directory'
def testSuccess(self):
self.mox.StubOutWithMock(os, 'listdir')
os.listdir(self.DIR_PATH)
self.mox.ReplayAll()
os.listdir(self.DIR_PATH)
def testExpectedNotCalled(self):
self.mox.StubOutWithMock(os, 'listdir')
os.listdir(self.DIR_PATH)
self.mox.ReplayAll()
def testUnexpectedCall(self):
self.mox.StubOutWithMock(os, 'listdir')
os.listdir(self.DIR_PATH)
self.mox.ReplayAll()
os.listdir('/path/to/some/other/directory')
os.listdir(self.DIR_PATH)
def testFailure(self):
self.assertTrue(False)
def testStatOther(self):
self.mox.StubOutWithMock(os, 'stat')
os.stat(self.DIR_PATH)
self.mox.ReplayAll()
os.stat(self.DIR_PATH)
#!/usr/bin/python2.4
from distutils.core import setup
setup(name='mox',
version='0.5.1',
py_modules=['mox', 'stubout'],
url='http://code.google.com/p/pymox/',
maintainer='pymox maintainers',
maintainer_email='mox-discuss@googlegroups.com',
license='Apache License, Version 2.0',
description='Mock object framework',
long_description='''Mox is a mock object framework for Python based on the
Java mock object framework EasyMock.''',
)
#!/usr/bin/python2.4
#
# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import inspect
class StubOutForTesting:
"""Sample Usage:
You want os.path.exists() to always return true during testing.
stubs = StubOutForTesting()
stubs.Set(os.path, 'exists', lambda x: 1)
...
stubs.UnsetAll()
The above changes os.path.exists into a lambda that returns 1. Once
the ... part of the code finishes, the UnsetAll() looks up the old value
of os.path.exists and restores it.
"""
def __init__(self):
self.cache = []
self.stubs = []
def __del__(self):
self.SmartUnsetAll()
self.UnsetAll()
def SmartSet(self, obj, attr_name, new_attr):
"""Replace obj.attr_name with new_attr. This method is smart and works
at the module, class, and instance level while preserving proper
inheritance. It will not stub out C types however unless that has been
explicitly allowed by the type.
This method supports the case where attr_name is a staticmethod or a
classmethod of obj.
Notes:
- If obj is an instance, then it is its class that will actually be
stubbed. Note that the method Set() does not do that: if obj is
an instance, it (and not its class) will be stubbed.
- The stubbing is using the builtin getattr and setattr. So, the __get__
and __set__ will be called when stubbing (TODO: A better idea would
probably be to manipulate obj.__dict__ instead of getattr() and
setattr()).
Raises AttributeError if the attribute cannot be found.
"""
if (inspect.ismodule(obj) or
(not inspect.isclass(obj) and obj.__dict__.has_key(attr_name))):
orig_obj = obj
orig_attr = getattr(obj, attr_name)
else:
if not inspect.isclass(obj):
mro = list(inspect.getmro(obj.__class__))
else:
mro = list(inspect.getmro(obj))
mro.reverse()
orig_attr = None
for cls in mro:
try:
orig_obj = cls
orig_attr = getattr(obj, attr_name)
except AttributeError:
continue
if orig_attr is None:
raise AttributeError("Attribute not found.")
# Calling getattr() on a staticmethod transforms it to a 'normal' function.
# We need to ensure that we put it back as a staticmethod.
old_attribute = obj.__dict__.get(attr_name)
if old_attribute is not None and isinstance(old_attribute, staticmethod):
orig_attr = staticmethod(orig_attr)
self.stubs.append((orig_obj, attr_name, orig_attr))
setattr(orig_obj, attr_name, new_attr)
def SmartUnsetAll(self):
"""Reverses all the SmartSet() calls, restoring things to their original
definition. Its okay to call SmartUnsetAll() repeatedly, as later calls
have no effect if no SmartSet() calls have been made.
"""
self.stubs.reverse()
for args in self.stubs:
setattr(*args)
self.stubs = []
def Set(self, parent, child_name, new_child):
"""Replace child_name's old definition with new_child, in the context
of the given parent. The parent could be a module when the child is a
function at module scope. Or the parent could be a class when a class'
method is being replaced. The named child is set to new_child, while
the prior definition is saved away for later, when UnsetAll() is called.
This method supports the case where child_name is a staticmethod or a
classmethod of parent.
"""
old_child = getattr(parent, child_name)
old_attribute = parent.__dict__.get(child_name)
if old_attribute is not None:
if isinstance(old_attribute, staticmethod):
old_child = staticmethod(old_child)
elif isinstance(old_attribute, classmethod):
old_child = classmethod(old_child.im_func)
self.cache.append((parent, old_child, child_name))
setattr(parent, child_name, new_child)
def UnsetAll(self):
"""Reverses all the Set() calls, restoring things to their original
definition. Its okay to call UnsetAll() repeatedly, as later calls have
no effect if no Set() calls have been made.
"""
# Undo calls to Set() in reverse order, in case Set() was called on the
# same arguments repeatedly (want the original call to be last one undone)
self.cache.reverse()
for (parent, old_child, child_name) in self.cache:
setattr(parent, child_name, old_child)
self.cache = []
#!/usr/bin/python2.4
#
# Unit tests for stubout.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import mox
import stubout
import stubout_testee
class StubOutForTestingTest(unittest.TestCase):
def setUp(self):
self.mox = mox.Mox()
self.sample_function_backup = stubout_testee.SampleFunction
def tearDown(self):
stubout_testee.SampleFunction = self.sample_function_backup
def testSmartSetOnModule(self):
mock_function = self.mox.CreateMockAnything()
mock_function()
stubber = stubout.StubOutForTesting()
stubber.SmartSet(stubout_testee, 'SampleFunction', mock_function)
self.mox.ReplayAll()
stubout_testee.SampleFunction()
self.mox.VerifyAll()
if __name__ == '__main__':
unittest.main()
def SampleFunction():
raise Exception('I should never be called!')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment