[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [stem/master] Handle keyword arguments with mocking.return_for_args()



commit 1dbb7befdbd10169a35e27977a0736a9dc9465d0
Author: Sean Robinson <seankrobinson@xxxxxxxxx>
Date:   Sat Dec 22 04:29:46 2012 -0700

    Handle keyword arguments with mocking.return_for_args()
    
    Allow a structured way to match keyword arguments to be included in the
    mapping keys for return_for_args().  This changes the API for
    return_for_args to require tuples as the mapping keys.
    
    Signed-off-by: Sean Robinson <seankrobinson@xxxxxxxxx>
---
 test/mocking.py       |   34 +++++++++++++++++++++++++++++-----
 test/unit/tutorial.py |    4 ++--
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/test/mocking.py b/test/mocking.py
index fa9e71f..697fd0f 100644
--- a/test/mocking.py
+++ b/test/mocking.py
@@ -210,15 +210,39 @@ def return_for_args(args_to_return_value, default = None):
   'argument => return value' mapping. Otherwise, a default function
   is called with the arguments.
   
-  :param dict args_to_return_value: mapping of arguments to the value we should provide
+  The mapped argument is a tuple (not a list) of parameters to a function (or
+  method). Positional arguments must be in the order used to call the mocked
+  function and keyword arguments must be strings of the form 'k=v' in
+  alphabetical order.  Some examples:
+  
+  ::
+  
+    Mocked functions can return different types depending on input:
+    
+      mocking.mock("get_answer", mocking.return_for_args({
+        ("breakfast_menu",): "spam",
+        ("lunch_menu",): "eggs and spam",
+        (42,): ["life", "universe", "everything"],
+      })
+      
+      mocking.mock("align_text", {
+        ("Stem", "alignment=left", "size=10"):   "Stem      ",
+        ("Stem", "alignment=center", "size=10"): "   Stem   ",
+        ("Stem", "alignment=right", "size=10"):  "      Stem",
+      })
+  
+  :param dict,tuple args_to_return_value: mapping of arguments to the value we should provide
   :param functor default: returns the value of this function if the args don't match something that we have, we raise a ValueError by default
   """
   
-  def _return_value(*args):
+  def _return_value(*args, **kwargs):
     # strip off the 'self' for mock clases
     if args and 'MockClass' in str(type(args[0])):
-      args = args[1:] if len(args) > 2 else args[1]
+      args = args[1:] if len(args) > 2 else [args[1]]
     
+    if kwargs:
+      args.extend(['='.join((str(k),str(kwargs[k]))) for k in sorted(kwargs.keys())])
+    args = tuple(args)
     if args in args_to_return_value:
       return args_to_return_value[args]
     elif default is None:
@@ -275,7 +299,7 @@ def mock(target, mock_call, target_module=None):
     target_function = target.__name__
     MOCK_STATE[mocking_id] = (target_module, target_function, target)
   
-  mock_wrapper = lambda *args: mock_call(*args)
+  mock_wrapper = lambda *args, **kwargs: mock_call(*args, **kwargs)
   mock_wrapper.__dict__["mock_id"] = mocking_id
   
   # mocks the function with this wrapper
@@ -323,7 +347,7 @@ def mock_method(target_class, method_name, mock_call):
     mocking_id = MOCK_ID.next()
     MOCK_STATE[mocking_id] = (target_class, method_name, target_method)
   
-  mock_wrapper = lambda *args: mock_call(*args)
+  mock_wrapper = lambda *args, **kwargs: mock_call(*args, **kwargs)
   setattr(mock_wrapper, "mock_id", mocking_id)
   
   # mocks the function with this wrapper
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index bb50e11..343258b 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -19,8 +19,8 @@ class TestTutorial(unittest.TestCase):
       'authenticate': mocking.no_op(),
       'close': mocking.no_op(),
       'get_info': mocking.return_for_args({
-        'traffic/read': '1234',
-        'traffic/written': '5678',
+        ('traffic/read',): '1234',
+        ('traffic/written',): '5678',
       }),
     })
     



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits