text: import toolz
  import toolz.curried
  from toolz.curried import (take, first, second, sorted, merge_with, reduce,
                             merge, operator as cop)
  from toolz.compatibility import import_module
  from collections import defaultdict
  from operator import add
  
  
  def test_take():
      assert list(take(2)([1, 2, 3])) == [1, 2]
  
  
  def test_first():
      assert first is toolz.itertoolz.first
  
  
  def test_merge():
      assert merge(factory=lambda: defaultdict(int))({1: 1}) == {1: 1}
      assert merge({1: 1}) == {1: 1}
      assert merge({1: 1}, factory=lambda: defaultdict(int)) == {1: 1}
  
  
  def test_merge_with():
      assert merge_with(sum)({1: 1}, {1: 2}) == {1: 3}
  
  
  def test_merge_with_list():
      assert merge_with(sum, [{'a': 1}, {'a': 2}]) == {'a': 3}
  
  
  def test_sorted():
      assert sorted(key=second)([(1, 2), (2, 1)]) == [(2, 1), (1, 2)]
  
  
  def test_reduce():
      assert reduce(add)((1, 2, 3)) == 6
  
  
  def test_module_name():
      assert toolz.curried.__name__ == 'toolz.curried'
  
  
  def test_curried_operator():
      for k, v in vars(cop).items():
          if not callable(v):
              continue
  
          if not isinstance(v, toolz.curry):
              try:
                  # Make sure it is unary
                  v(1)
              except TypeError:
                  try:
                      v('x')
                  except TypeError:
                      pass
                  else:
                      continue
                  raise AssertionError(
                      'toolz.curried.operator.%s is not curried!' % k,
                  )
  
      # Make sure this isn't totally empty.
      assert len(set(vars(cop)) & set(['add', 'sub', 'mul'])) == 3
  
  
  def test_curried_namespace():
      exceptions = import_module('toolz.curried.exceptions')
      namespace = {}
  
      def should_curry(func):
          if not callable(func) or isinstance(func, toolz.curry):
              return False
          nargs = toolz.functoolz.num_required_args(func)
          if nargs is None or nargs > 1:
              return True
          return nargs == 1 and toolz.functoolz.has_keywords(func)
  
  
      def curry_namespace(ns):
          return dict(
              (name, toolz.curry(f) if should_curry(f) else f)
              for name, f in ns.items() if '__' not in name
          )
  
      from_toolz = curry_namespace(vars(toolz))
      from_exceptions = curry_namespace(vars(exceptions))
      namespace.update(toolz.merge(from_toolz, from_exceptions))
  
      namespace = toolz.valfilter(callable, namespace)
      curried_namespace = toolz.valfilter(callable, toolz.curried.__dict__)
  
      if namespace != curried_namespace:
          missing = set(namespace) - set(curried_namespace)
          if missing:
              raise AssertionError('There are missing functions in toolz.curried:\n    %s'
                                   % '    \n'.join(sorted(missing)))
          extra = set(curried_namespace) - set(namespace)
          if extra:
              raise AssertionError('There are extra functions in toolz.curried:\n    %s'
                                   % '    \n'.join(sorted(extra)))
          unequal = toolz.merge_with(list, namespace, curried_namespace)
          unequal = toolz.valfilter(lambda x: x[0] != x[1], unequal)
          messages = []
          for name, (orig_func, auto_func) in sorted(unequal.items()):
              if name in from_exceptions:
                  messages.append('%s should come from toolz.curried.exceptions' % name)
              elif should_curry(getattr(toolz, name)):
                  messages.append('%s should be curried from toolz' % name)
              else:
                  messages.append('%s should come from toolz and NOT be curried' % name)
          raise AssertionError('\n'.join(messages))
  