Commits

Lynn Rees committed f152d9c

- better test coverage
- prune some methods
- fix compatibility layer
- fix list like methods on queue

  • Participants
  • Parent commits d8911d7
  • Branches pu
  • Tags 0.1.1

Comments (0)

Files changed (6)

 
 setup(
     name='twoq',
-    version='0.1.0',
+    version='0.1.1',
     description='''iterator manipulation, underscored by two queues''',
     long_description=open(os.path.join(os.getcwd(), 'README.rst'), 'r').read(),
     author='L. C. Rees',
 # -*- coding: utf-8 -*-
 '''twoq iterator utilities'''
 
-from twoq.active import twoq
+from twoq.compat import port
+from twoq.active import twoq, iterexcept
 
-__all__ = ['twoq']
+__all__ = ('twoq', 'port', 'iterexcept')
+
+__version__ = (0, 1, 1)
 # -*- coding: utf-8 -*-
 '''active twoq'''
 
+from collections import deque
 from bisect import bisect_right
-from collections import deque,  Iterable
-
-from stuf.six import string_types
 
 from twoq.core import coreq
 
-__all__ = ['twoq']
+__all__ = ['twoq', 'iterexcept']
 
 
-def iterexcept(func, exception, first=None):
+def iterexcept(func, exception):
     '''
     call a function repeatedly until an exception is raised
 
     of a sentinel to end the loop.
     '''
     try:
-        if first is not None:
-            yield first()
         while 1:
             yield func()
     except exception:
 
 class SyncContext(object):
 
-    '''sync context manager'''
+    '''_sync context manager'''
 
     def __init__(self, queue):
         '''
         return len(self.incoming)
 
     @property
-    def sync(self):
-        '''sync incoming things with outgoing things'''
+    def _sync(self):
+        '''_sync incoming things with outgoing things'''
         return SyncContext(self)
 
     def clear(self):
         incoming.rotate(index)
         return self
 
-    def shift(self):
+    def insync(self):
         '''sync incoming things with outgoing things'''
+        # extend incoming items with outgoing items
+        self._inextend(self.outgoing)
+        return self
+
+    def inshift(self):
+        '''
+        sync incoming things with outgoing things, clearing incoming things
+        '''
         # clear incoming items
         self._inclear()
         # extend incoming items with outgoing items
         self._inextend(self.outgoing)
         return self
 
+    def outsync(self):
+        '''sync outgoing things with incoming things'''
+        # extend incoming items with outgoing items
+        self._outextend(self.incoming)
+        return self
+
+    def outshift(self):
+        '''
+        sync outgoing things with incoming things, clearing outgoing things
+        '''
+        # clear incoming items
+        self._outclear()
+        # extend incoming items with outgoing items
+        self._outextend(self.incoming)
+        return self
+
     def index(self, thing):
         '''
         insert thing into incoming things
 
         @param thing: some thing
         '''
-        return bisect_right(self.outgoing, thing) - 1
+        return bisect_right(self.incoming, thing) - 1
 
     def results(self):
-        '''iterate over outgoing things, clearing as it goes'''
-        for thing in iterexcept(self._outpop, IndexError):
-            yield thing
-
-    def reversed(self):
         '''iterate over reversed outgoing things, clearing as it goes'''
-        for thing in iterexcept(self._outpopleft, IndexError):
+        for thing in iterexcept(self.outgoing.popleft, IndexError):
             yield thing
 
 
         incoming = deque()
         # extend if just one argument
         if len(args) == 1:
-            args = args[0]
-            if all([
-                isinstance(args, Iterable), not isinstance(args, string_types)
-            ]):
-                incoming.extend(args)
-            else:
-                incoming.append(args)
+            incoming.extend(args[0])
         else:
             incoming.extend(args)
         super(twoq, self).__init__(incoming, deque())
 # -*- coding: utf-8 -*-
-'''base compatibility layer'''
+'''python compatibility layer'''
 
 from stuf import six
+# pylint: disable-msg=f0401,w0611
+from stuf.six.moves import map, filterfalse, filter, zip, zip_longest  # @UnresolvedImport @UnusedImport @IgnorePep8
+# pylint: enable-msg=f0401
 
-__all__ = ['Port']
+__all__ = ['port']
 
 
-class Port(object):
+class port(object):
 
     '''python 2/3 helper'''
 
     BytesIO = six.BytesIO
     StringIO = six.StringIO
     # character data
-    b = six.b
-    int2byte = six.int2byte
-    u = six.u
+    b = staticmethod(six.b)
+    int2byte = staticmethod(six.int2byte)
+    u = staticmethod(six.u)
     # dictionary
-    items = six.iteritems
-    keys = six.iterkeys
-    values = six.itervalues
+    items = staticmethod(six.iteritems)
+    keys = staticmethod(six.iterkeys)
+    values = staticmethod(six.itervalues)
     # iterables
-    iterator = six.advance_iterator
+    iterator = staticmethod(six.advance_iterator)
     # classes
-    metaclass = six.with_metaclass
+    metaclass = staticmethod(six.with_metaclass)
     # methods
-    code = six.get_function_code
-    defaults = six.get_function_defaults
-    method_function = six.get_method_function
-    method_self = six.get_method_self
-    unbound = six.get_unbound_function
+    code = staticmethod(six.get_function_code)
+    defaults = staticmethod(six.get_function_defaults)
+    method_function = staticmethod(six.get_method_function)
+    method_self = staticmethod(six.get_method_self)
+    unbound = staticmethod(six.get_unbound_function)
     # exception
-    reraise = six.reraise
+    reraise = staticmethod(six.reraise)
 
     @classmethod
     def isbinary(cls, value):
     groupby, islice, repeat, starmap, cycle, tee, chain)
 from operator import itemgetter as iget, attrgetter, methodcaller, contains
 
-from stuf.six import string_types
-# pylint: disable-msg=f0401
-from stuf.six.moves import (
-    map, filterfalse, filter, zip, zip_longest)  # @UnresolvedImport
-# pylint: enable-msg=f0401
+from twoq.compat import port, filter, filterfalse, map, zip_longest
 
 __all__ = ['coreq']
 
 
     def tap(self, call):
         '''
-        add callable
+        add call
 
-        @param call: a callable
+        @param call: a call
         '''
         self.call = call
         return self
 
     def detap(self):
-        '''clear callable'''
+        '''clear call'''
         self.call = None
         return self
 
+    def wrap(self, call):
+        '''build factory callable and make call'''
+        def factory(*args, **kw):
+            return call(*args, **kw)
+        self.call = factory
+        return self
+
     # alias
-    clear = detap
+    clear = unwrap = detap
 
     def swap(self):
         '''swap queues'''
         self.clear()
         return results
 
+    def reup(self):
+        '''put incoming things in incoming things as one incoming thing'''
+        with self._sync as _sync:
+            _sync.append(list(self.incoming))
+        return self
+
     ##########################################################################
     ## filter ################################################################
     ##########################################################################
 
     def filter(self):
-        '''incoming things for which callable is `True`'''
-        with self.sync as sync:
-            sync(filter(self.call, self.incoming))
+        '''incoming things for which call is `True`'''
+        with self._sync as _sync:
+            _sync(filter(self.call, self.incoming))
         return self
 
     def find(self):
-        '''first incoming thing for which callable is `True`'''
+        '''first incoming thing for which call is `True`'''
         def _find(call, incoming):
             for thing in filter(call, incoming):
                 yield thing
                 break
-        with self.sync as sync:
-            sync(_find(self.call, self.incoming))
+        with self._sync as _sync:
+            _sync(_find(self.call, self.incoming))
         return self
 
     def reject(self):
-        '''incoming things for which callable is `False`'''
-        with self.sync as sync:
-            sync(filterfalse(self.call, self.incoming))
+        '''incoming things for which call is `False`'''
+        with self._sync as _sync:
+            _sync(filterfalse(self.call, self.incoming))
         return self
 
     ##########################################################################
 
     def each(self):
         '''
-        invoke callable with passed arguments, keywords in incoming things
+        invoke call with passed arguments, keywords in incoming things
         '''
-        with self.sync as sync:
-            sync(map(lambda x: self.call(*x[0], **x[1]), self.incoming))
+        with self._sync as _sync:
+            _sync(map(lambda x: self.call(*x[0], **x[1]), self.incoming))
         return self
 
     def invoke(self, name, *args, **kw):
         '''
-        invoke callable on each incoming thing with passed arguments, keywords
+        invoke call on each incoming thing with passed arguments, keywords
+        but return incoming thing instead if call returns None
         '''
         caller = methodcaller(name, *args, **kw)
-        with self.sync as sync:
-            sync.iter(map(caller, self.incoming))
+        def call(thing): #@IgnorePep8
+            results = caller(thing)
+            return thing if results is None else results
+        with self._sync as _sync:
+            _sync(map(call, self.incoming))
         return self
 
     def map(self):
-        '''invoke callable on each incoming thing'''
-        with self.sync as sync:
-            sync(map(self.call, self.incoming))
+        '''invoke call on each incoming thing'''
+        with self._sync as _sync:
+            _sync(map(self.call, self.incoming))
         return self
 
     ##########################################################################
 
     def flatten(self):
         '''flatten nested incoming things'''
-        with self.sync as sync:
-            sync(chain.from_iterable(self.incoming))
+        with self._sync as _sync:
+            _sync(chain.from_iterable(self.incoming))
         return self
 
     def max(self):
         '''
-        find maximum value in incoming things using callable for key function
+        find maximum value in incoming things using call for key function
         '''
-        with self.sync as sync:
+        with self._sync as _sync:
             if self.call is None:
-                sync(max(self.incoming))
+                _sync.append(max(self.incoming))
             else:
-                sync(max(self.incoming, key=self.call))
+                _sync.append(max(self.incoming, key=self.call))
         return self
 
     def smash(self):
         '''flatten deeply nested incoming things'''
         def _smash(iterable):
+            isstring = port.isstring
             for i in iterable:
-                if isinstance(i, Iterable) and not isinstance(i, string_types):
+                if isinstance(i, Iterable) and not isstring(i):
                     for j in _smash(i):
                         yield j
                 else:
                     yield i
-        with self.sync as sync:
-            sync(_smash(self.incoming))
+        with self._sync as _sync:
+            _sync(_smash(self.incoming))
         return self
 
     def min(self):
         '''
-        find minimum value in incoming things using callable for key function
+        find minimum value in incoming things using call for key function
         '''
-        with self.sync as sync:
+        with self._sync as _sync:
             if self.call is None:
-                sync.append(min(self.incoming))
+                _sync.append(min(self.incoming))
             else:
-                sync.append(min(self.incoming, key=self.call))
+                _sync.append(min(self.incoming, key=self.call))
         return self
 
     def pairwise(self):
         '''
         a, b = tee(self.incoming)
         next(b, None)
-        with self.sync as sync:
-            sync(zip(a, b))
+        with self._sync as _sync:
+            _sync(zip(a, b))
         return self
 
     def reduce(self, initial=None):
         '''
-        reduce incoming things to one thing using callable
+        reduce incoming things to one thing using call
 
         @param initial: initial thing (default: None)
         '''
-        with self.sync as sync:
+        with self._sync as _sync:
             if initial:
-                sync.append(reduce(self.call, self.incoming, initial))
+                _sync.append(reduce(self.call, self.incoming, initial))
             else:
-                sync.append(reduce(self.call, self.incoming))
+                _sync.append(reduce(self.call, self.incoming))
         return self
 
     def reduce_right(self, initial=None):
         '''
-        reduce incoming things to one thing from right side using callable
+        reduce incoming things to one thing from right side using call
 
         @param initial: initial thing (default: None)
         '''
-        with self.sync as sync:
+        with self._sync as _sync:
             func = lambda x, y: self.call(y, x)
             if initial:
-                sync(reduce(func, self.incoming, initial))
+                _sync(reduce(func, self.incoming, initial))
             else:
-                sync(reduce(func, self.incoming))
+                _sync(reduce(func, self.incoming))
         return self
 
     def roundrobin(self):
                 except StopIteration:
                     pending -= 1
                     nexts = cycle(islice(nexts, pending))
-        with self.sync as sync:
-            sync(_roundrobin(self.incoming))
+        with self._sync as _sync:
+            _sync(_roundrobin(self.incoming))
         return self
 
     def zip(self):
         smash incoming things into single thing, pairing things by iterable
         position
         '''
-        with self.sync as sync:
-            sync(zip(*self.incoming))
+        with self._sync as _sync:
+            _sync(zip(*self.incoming))
         return self
 
     ##########################################################################
     ##########################################################################
 
     def group(self):
-        '''group incoming things using callable for key function'''
-        with self.sync as sync:
+        '''group incoming things using call for key function'''
+        with self._sync as _sync:
             if self.call is None:
-                sync(map(
+                _sync(map(
                     lambda x: [x[0], list(x[1])], groupby(self.incoming)
                 ))
             else:
-                sync(map(
+                _sync(map(
                     lambda x: [x[0], list(x[1])],
                     groupby(self.incoming, self.call),
                 ))
 
         grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
         '''
-        with self.sync as sync:
-            sync(zip_longest(fillvalue=fill, *[iter(self.incoming)] * n))
+        with self._sync as _sync:
+            _sync(zip_longest(fillvalue=fill, *[iter(self.incoming)] * n))
         return self
 
     def reverse(self):
         '''iterate over reversed incoming things, clearing as it goes'''
-        with self.sync as sync:
-            sync(reversed(self.incoming))
+        self.outgoing.extendleft(self.incoming)
+        self._inclear()
+        self._inextend(self.outgoing)
         return self
 
     def sort(self):
-        '''sort incoming things using callable for key function'''
-        with self.sync as sync:
+        '''sort incoming things using call for key function'''
+        with self._sync as _sync:
             if self.call is None:
-                sync(sorted(self.incoming))
+                _sync(sorted(self.incoming))
             else:
-                sync(sorted(self.incoming, key=self.call))
+                _sync(sorted(self.incoming, key=self.call))
         return self
 
     ##########################################################################
 
     def choice(self):
         '''random choice from incoming things'''
-        with self.sync as sync:
-            sync.append(choice(self.incoming))
+        with self._sync as _sync:
+            _sync.append(choice(self.incoming))
         return self
 
     def sample(self, n):
 
         @param n: number of things
         '''
-        with self.sync as sync:
-            sync(sample(list(self.incoming), n))
+        with self._sync as _sync:
+            _sync(sample(list(self.incoming), n))
         return self
 
     def shuffle(self):
         '''shuffle incoming things'''
         incoming = self.incoming
-        with self.sync as sync:
+        with self._sync as _sync:
             shuffle(incoming)
-            sync(incoming)
+            _sync(incoming)
         return self
 
     ##########################################################################
 
     def first(self):
         '''first thing among incoming things'''
-        with self.sync as sync:
-            sync.append(self.incoming.popleft())
+        with self._sync as _sync:
+            _sync.append(self.incoming.popleft())
         return self
 
     def nth(self, n, default=None):
         @param n: number of things
         @param default: default thing (default: None)
         '''
-        with self.sync as sync:
-            sync.append(next(islice(self.incoming, n, None), default))
+        with self._sync as _sync:
+            _sync.append(next(islice(self.incoming, n, None), default))
         return self
 
     def last(self):
         '''last thing among incoming things'''
-        with self.sync as sync:
-            sync.append(self.incoming.pop())
+        with self._sync as _sync:
+            _sync.append(self.incoming.pop())
         return self
 
     ##########################################################################
     def initial(self):
         '''all incoming things except the last thing'''
         incoming = self.incoming
-        with self.sync as sync:
-            sync(islice(incoming, len(incoming) - 1))
+        with self._sync as _sync:
+            _sync(islice(incoming, len(incoming) - 1))
         return self
 
     def rest(self):
         '''all incoming things except the first thing'''
-        with self.sync as sync:
-            sync(islice(self.incoming, 1, None))
+        with self._sync as _sync:
+            _sync(islice(self.incoming, 1, None))
         return self
 
     def take(self, n):
 
         @param n: number of things
         '''
-        with self.sync as sync:
-            sync(islice(self.incoming, n))
+        with self._sync as _sync:
+            _sync(islice(self.incoming, n))
         return self
 
     def snatch(self, n):
         @param n: number of things
         '''
         incoming = self.incoming
-        with self.sync as sync:
-            sync(islice(incoming, len(incoming) - n, None))
+        with self._sync as _sync:
+            _sync(islice(incoming, len(incoming) - n, None))
         return self
 
     ##########################################################################
                     pass
                 else:
                     yield key, thing
-        with self.sync as sync:
-            sync.iter(chain.from_iterable(map(_members, self.incoming)))
+        with self._sync as _sync:
+            _sync.iter(chain.from_iterable(map(_members, self.incoming)))
         return self
 
     def pick(self, *names):
                     yield find(thing)
                 except AttributeError:
                     pass
-        with self.sync as sync:
-            sync(_pick(names, self.incoming))
+        with self._sync as _sync:
+            _sync(_pick(names, self.incoming))
         return self
 
     def pluck(self, *keys):
             for thing in iterable:
                 try:
                     yield find(thing)
-                except IndexError:
+                except (IndexError, KeyError, TypeError):
                     pass
-        with self.sync as sync:
-            sync(_pluck(keys, self.incoming))
+        with self._sync as _sync:
+            _sync(_pluck(keys, self.incoming))
         return self
 
     ##########################################################################
 
         @param n: number of times to repeat
         '''
-        with self.sync as sync:
-            sync(repeat(tuple(self.incoming), n))
+        with self._sync as _sync:
+            _sync(repeat(tuple(self.incoming), n))
         return self
 
     def padnone(self):
 
         (Useful for emulating the behavior of 2.x classic `builtin` `map`)
         '''
-        with self.sync as sync:
-            sync.iter(chain(self.incoming, repeat(None)))
+        with self._sync as _sync:
+            _sync.iter(chain(self.incoming, repeat(None)))
         return self
 
     def times(self, n=None):
         '''
-        repeat callable with passed arguments
+        repeat call with passed arguments
 
-        @param n: number of times to repeat callables (default: None)
+        @param n: number of times to repeat calls (default: None)
         '''
-        with self.sync as sync:
+        with self._sync as _sync:
             if n is None:
-                sync(starmap(self.call, repeat(self.incoming)))
-            sync(starmap(self.call, repeat(self.incoming, n)))
+                _sync(starmap(self.call, repeat(self.incoming)))
+            _sync(starmap(self.call, repeat(self.incoming, n)))
         return self
 
     ##########################################################################
 
     def all(self):
         '''if `all` incoming things are `True`'''
-        with self.sync as sync:
-            sync.append(all(map(self.call, self.incoming)))
+        with self._sync as _sync:
+            _sync.append(all(map(self.call, self.incoming)))
         return self
 
     def any(self):
         '''if `any` incoming things are `True`'''
-        with self.sync as sync:
-            sync.append(any(map(self.call, self.incoming)))
+        with self._sync as _sync:
+            _sync.append(any(map(self.call, self.incoming)))
         return self
 
     def contains(self, thing):
 
         @param thing: some thing
         '''
-        with self.sync as sync:
-            sync.append(contains(self.incoming, thing))
+        with self._sync as _sync:
+            _sync.append(contains(self.incoming, thing))
         return self
 
     def quantify(self):
-        '''how many times callable is True for incoming things'''
-        with self.sync as sync:
-            sync.append(sum(map(self.call, self.incoming)))
+        '''how many times call is True for incoming things'''
+        with self._sync as _sync:
+            _sync.append(sum(map(self.call, self.incoming)))
         return self
 
     ##########################################################################
 
     def compact(self):
         '''strip "untrue" things from incoming things'''
-        with self.sync as sync:
-            sync.iter(filter(bool, self.incoming))
+        with self._sync as _sync:
+            _sync.iter(filter(bool, self.incoming))
         return self
 
     def without(self, *things):
         '''strip things from incoming things'''
-        with self.sync as sync:
-            sync(filterfalse(lambda x: x in things, self.incoming))
+        with self._sync as _sync:
+            _sync(filterfalse(lambda x: x in things, self.incoming))
         return self
 
     ##########################################################################
 
     def difference(self):
         '''difference between incoming things'''
-        with self.sync as sync:
-            sync(reduce(
+        with self._sync as _sync:
+            _sync(reduce(
                 lambda x, y: set(x).difference(set(y)), self.incoming,
             ))
         return self
 
     def intersection(self):
         '''intersection between incoming things'''
-        with self.sync as sync:
-            sync(reduce(
+        with self._sync as _sync:
+            _sync(reduce(
                 lambda x, y: set(x).intersection(set(y)), self.incoming,
             ))
         return self
 
     def union(self):
         '''union between incoming things'''
-        with self.sync as sync:
-            sync(reduce(
+        with self._sync as _sync:
+            _sync(reduce(
                 lambda x, y: set(x).union(set(y)), self.incoming,
             ))
         return self
                     if k not in seen:
                         seen_add(k)
                         yield element
-        with self.sync as sync:
-            sync.iter(_unique_everseen(self.incoming, self.call))
+        with self._sync as _sync:
+            _sync.iter(_unique_everseen(self.incoming, self.call))
         return self

twoq/tests/test_twoq.py

 # -*- coding: utf-8 -*-
 '''test twoq'''
 
-import unittest
-
-from stuf import stuf
+try:
+    import unittest2 as unittest
+except ImportError:
+    import unittest
 
 
 class TestTwoQ(unittest.TestCase):
     ## queue management & execution ##########################################
     ##########################################################################
 
+    def test_index(self):
+        self.assertEquals(self.qclass([1, 2, 3, 4, 5, 6]).index(3), 2)
+
+    def test_remove(self):
+        self.assertEquals(
+            self.qclass([1, 2, 3, 4, 5, 6]).remove(5).swap().value(),
+            [1, 2, 3, 4, 6]
+        )
+
+    def test_results(self):
+        self.assertEquals(
+            list(self.qclass([1, 2, 3, 4, 5, 6]).outshift().results()),
+            [1, 2, 3, 4, 5, 6]
+        )
+
+    def test_delitem(self):
+        q = self.qclass([1, 2, 3, 4, 5, 6])
+        del q[2]
+        self.assertEquals(q.swap().value(), [1, 2, 4, 5, 6])
+
+    def test_insync(self):
+        q = self.qclass([1, 2, 3, 4, 5, 6]).outsync().inclear().insync()
+        self.assertSequenceEqual(q.incoming, q.outgoing)
+
+    def test_inshift(self):
+        q = self.qclass([1, 2, 3, 4, 5, 6]).outsync().inshift()
+        self.assertSequenceEqual(q.incoming, q.outgoing)
+
+    def test_outsync(self):
+        q = self.qclass([1, 2, 3, 4, 5, 6]).outsync()
+        self.assertSequenceEqual(q.incoming, q.outgoing)
+
+    def test_outshift(self):
+        q = self.qclass([1, 2, 3, 4, 5, 6]).outshift()
+        self.assertSequenceEqual(q.incoming, q.outgoing)
+
+    def test_contains(self):
+        self.assertTrue(5 in self.qclass([1, 2, 3, 4, 5, 6]))
+
+    def test_inclear(self):
+        self.assertEqual(len(self.qclass([1, 2, 5, 6]).inclear()), 0)
+
+    def test_outclear(self):
+        self.assertEqual(len(self.qclass([1, 2, 5, 6]).outclear().outgoing), 0)
+
+    def test_insert(self):
+        q = self.qclass([1, 2, 3, 4, 5, 6])
+        q.insert(2, 10)
+        self.assertEquals(q.swap().value(), [1, 2, 10, 4, 5, 6])
+
     def test_extend(self):
         self.assertEquals(
             self.qclass().extend([1, 2, 3, 4, 5, 6]).swap().value(),
             self.qclass([5, 1, 7], [3, 2, 1]).invoke('index', 1).value(),
             [1, 2],
         )
+        self.assertEquals(
+            self.qclass([5, 1, 7], [3, 2, 1]).invoke('sort').value(),
+            [[1, 5, 7], [1, 2, 3]],
+        )
+
+    def test_wrap(self):
+        from stuf import stuf
+        self.assertDictEqual(
+            self.qclass(
+                [('a', 1), ('b', 2), ('c', 3)]
+            ).reup().wrap(stuf).map().value(),
+            stuf(a=1, b=2, c=3),
+        )
 
     ##########################################################################
     ## reduction #############################################################
         )
 
     def test_max(self):
+        from stuf import stuf
         stooges = [
             stuf(name='moe', age=40),
             stuf(name='larry', age=50),
             stuf(self.qclass(stooges).tap(lambda x: x.age).max().value()),
             stuf(name='curly', age=60),
         )
+        self.assertEquals(
+            self.qclass([1, 2, 4]).max().value(), 4,
+        )
 
     def test_merge(self):
         self.assertEquals(
         self.assertEquals(
             self.qclass([10, 5, 100, 2, 1000]).min().value(), 2,
         )
+        self.assertEquals(
+            self.qclass([10, 5, 100, 2, 1000]).tap(lambda x: x).min().value(),
+            2,
+        )
 
     def test_pairwise(self):
         self.assertEquals(
         self.assertEquals(
             self.qclass([1, 2, 3]).tap(lambda x, y: x + y).reduce().value(), 6,
         )
+        self.assertEquals(
+            self.qclass([1, 2, 3]).tap(lambda x, y: x + y).reduce(1).value(),
+            7,
+        )
 
     def test_reduce_right(self):
         self.assertEquals(
                 lambda x, y: x + y
             ).reduce_right().value(), [4, 5, 2, 3, 0, 1],
         )
+        self.assertEquals(
+            self.qclass([[0, 1], [2, 3], [4, 5]]).tap(
+                lambda x, y: x + y
+            ).reduce_right([0, 0]).value(), [4, 5, 2, 3, 0, 1, 0, 0],
+        )
 
     def test_roundrobin(self):
         self.assertEquals(
         self.qclass([1.3, 2.1, 2.4]).tap(lambda x: floor(x)).group().value(),
             [[1.0, [1.3]], [2.0, [2.1, 2.4]]]
         )
+        self.assertEquals(
+            self.qclass([1.3, 2.1, 2.4]).group().value(),
+            [[1.3, [1.3]], [2.1, [2.1]], [2.4, [2.4]]],
+        )
 
     def test_grouper(self):
         self.assertEquals(
         class stooges:
             name = 'moe'
             age = 40
-        class stoog2:
+        class stoog2: #@IgnorePep8
             name = 'larry'
             age = 50
-        class stoog3:
+        class stoog3: #@IgnorePep8
             name = 'curly'
             age = 60
         test = lambda x: not x.startswith('__')
         )
 
     def test_pick(self):
+        from stuf import stuf
         stooges = [
             stuf(name='moe', age=40),
             stuf(name='larry', age=50),
             self.qclass(stooges).pick('name', 'age').value(),
             [('moe', 40), ('larry', 50), ('curly', 60)],
         )
+        self.assertEqual(
+            self.qclass(stooges).pick('place').value(), [],
+        )
 
     def test_pluck(self):
+        from stuf import stuf
         stooges = [
             stuf(name='moe', age=40),
             stuf(name='larry', age=50),
             self.qclass(stooges).pluck(1).value(),
             [40, 50, 60],
         )
+        self.assertEqual(
+            self.qclass(stooges).pluck('place').value(), [],
+        )
 
     ##########################################################################
     ## repetition ############################################################
             self.qclass([1, 2, 1, 3, 1, 4]).unique().value(),
             [1, 2, 3, 4],
         )
+        self.assertEqual(
+            self.qclass([1, 2, 1, 3, 1, 4]).tap(round).unique().value(),
+            [1, 2, 3, 4],
+        )
 
 
 if __name__ == '__main__':