# Path: tidings/compat.py
# def iteritems(d, **kw):
# def iterkeys(d, **kw):
# 
# Path: tidings/utils.py
# def collate(*iterables, **kwargs):
#     """Return an iterable ordered collation of the already-sorted items
#     from each of ``iterables``, compared by kwarg ``key``.
# 
#     If ``reverse=True`` is passed, iterables must return their results in
#     descending order rather than ascending.
# 
#     """
#     key = kwargs.pop('key', lambda a: a)
#     reverse = kwargs.pop('reverse', False)
#     min_or_max = max if reverse else min
# 
#     rows = [iter(iterable) for iterable in iterables if iterable]
#     next_values = {}
#     by_key = []
# 
#     def gather_next_value(row, index):
#         try:
#             next_value = next(row)
#         except StopIteration:
#             pass
#         else:
#             next_values[index] = next_value
#             by_key.append((key(next_value), index))
# 
#     for index, row in enumerate(rows):
#         gather_next_value(row, index)
# 
#     while by_key:
#         key_value, index = min_or_max(by_key)
#         by_key.remove((key_value, index))
#         next_value = next_values.pop(index)
#         yield next_value
#         gather_next_value(rows[index], index)
# 
# def import_from_setting(setting_name, fallback):
#     """Return the resolution of an import path stored in a Django setting.
# 
#     :arg setting_name: The name of the setting holding the import path
#     :arg fallback: An alternate object to use if the setting is empty or
#       doesn't exist
# 
#     Raise ImproperlyConfigured if a path is given that can't be resolved.
# 
#     """
#     path = getattr(settings, setting_name, None)
#     if path:
#         try:
#             return import_string(path)
#         except ImportError:
#             raise ImproperlyConfigured('%s: No such path.' % path)
#     else:
#         return fallback


from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings, TestCase
from tidings.compat import range, reduce
from tidings.utils import collate, import_from_setting
        from django.db.models import Model
    def test_key(self):
        """Test using a custom `key` function."""
        iterables = [range(5, 0, -1), range(4, 0, -1)]
        self.assertEqual(list(sorted(reduce(list.__add__,
                                            [list(it) for it in iterables]),
                                     reverse=True)),
                         list(collate(*iterables, key=lambda x: -x)))

    def test_empty(self):
        """Be nice if passed an empty list of iterables."""
        self.assertEqual([], list(collate()))

    def test_one(self):
        """Work when only 1 iterable is passed."""
        self.assertEqual([0, 1], list(collate(range(2))))

    def test_reverse(self):
        """Test the `reverse` kwarg."""
        iterables = [range(4, 0, -1), range(7, 0, -1), range(3, 6, -1)]
        self.assertEqual(sorted(reduce(list.__add__,
                                       [list(it) for it in iterables]),
                                reverse=True),
                         list(collate(*iterables, reverse=True)))


class ImportedFromSettingTests(TestCase):
    """Tests for import_from_setting() and _imported_symbol()"""

    @override_settings(TIDINGS_MODEL_BASE='django.db.models.Model')
    def test_success(self):

# Path: tidings/compat.py
# def iteritems(d, **kw):
# def iterkeys(d, **kw):
# 
# Path: tidings/utils.py
# def collate(*iterables, **kwargs):
#     """Return an iterable ordered collation of the already-sorted items
#     from each of ``iterables``, compared by kwarg ``key``.
# 
#     If ``reverse=True`` is passed, iterables must return their results in
#     descending order rather than ascending.
# 
#     """
#     key = kwargs.pop('key', lambda a: a)
#     reverse = kwargs.pop('reverse', False)
#     min_or_max = max if reverse else min
# 
#     rows = [iter(iterable) for iterable in iterables if iterable]
#     next_values = {}
#     by_key = []
# 
#     def gather_next_value(row, index):
#         try:
#             next_value = next(row)
#         except StopIteration:
#             pass
#         else:
#             next_values[index] = next_value
#             by_key.append((key(next_value), index))
# 
#     for index, row in enumerate(rows):
#         gather_next_value(row, index)
# 
#     while by_key:
#         key_value, index = min_or_max(by_key)
#         by_key.remove((key_value, index))
#         next_value = next_values.pop(index)
#         yield next_value
#         gather_next_value(rows[index], index)
# 
# def import_from_setting(setting_name, fallback):
#     """Return the resolution of an import path stored in a Django setting.
# 
#     :arg setting_name: The name of the setting holding the import path
#     :arg fallback: An alternate object to use if the setting is empty or
#       doesn't exist
# 
#     Raise ImproperlyConfigured if a path is given that can't be resolved.
# 
#     """
#     path = getattr(settings, setting_name, None)
#     if path:
#         try:
#             return import_string(path)
#         except ImportError:
#             raise ImproperlyConfigured('%s: No such path.' % path)
#     else:
#         return fallback


# Path: tests/test_utils.py
from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings, TestCase
from tidings.compat import range, reduce
from tidings.utils import collate, import_from_setting
        from django.db.models import Model

    def test_key(self):
        """Test using a custom `key` function."""
        iterables = [range(5, 0, -1), range(4, 0, -1)]
        self.assertEqual(list(sorted(reduce(list.__add__,
                                            [list(it) for it in iterables]),
                                     reverse=True)),
                         list(collate(*iterables, key=lambda x: -x)))

    def test_empty(self):
        """Be nice if passed an empty list of iterables."""
        self.assertEqual([], list(collate()))

    def test_one(self):
        """Work when only 1 iterable is passed."""
        self.assertEqual([0, 1], list(collate(range(2))))

    def test_reverse(self):
        """Test the `reverse` kwarg."""
        iterables = [range(4, 0, -1), range(7, 0, -1), range(3, 6, -1)]
        self.assertEqual(sorted(reduce(list.__add__,
                                       [list(it) for it in iterables]),
                                reverse=True),
                         list(collate(*iterables, reverse=True)))


class ImportedFromSettingTests(TestCase):
    """Tests for import_from_setting() and _imported_symbol()"""

    @override_settings(TIDINGS_MODEL_BASE='django.db.models.Model')
    def test_success(self):

        assert import_from_setting('TIDINGS_MODEL_BASE', 'blah') == Model