import sys import os import unittest from unittest import mock from scrapy.item import Item, Field from scrapy.utils.misc import arg_to_iter, create_instance, load_object, set_environ, walk_modules __doctests__ = ['scrapy.utils.misc'] class UtilsMiscTestCase(unittest.TestCase): def test_load_object_class(self): obj = load_object(Field) self.assertIs(obj, Field) obj = load_object('scrapy.item.Field') self.assertIs(obj, Field) def test_load_object_function(self): obj = load_object(load_object) self.assertIs(obj, load_object) obj = load_object('scrapy.utils.misc.load_object') self.assertIs(obj, load_object) def test_load_object_exceptions(self): self.assertRaises(ImportError, load_object, 'nomodule999.mod.function') self.assertRaises(NameError, load_object, 'scrapy.utils.misc.load_object999') self.assertRaises(TypeError, load_object, dict()) def test_walk_modules(self): mods = walk_modules('tests.test_utils_misc.test_walk_modules') expected = [ 'tests.test_utils_misc.test_walk_modules', 'tests.test_utils_misc.test_walk_modules.mod', 'tests.test_utils_misc.test_walk_modules.mod.mod0', 'tests.test_utils_misc.test_walk_modules.mod1', ] self.assertEqual({m.__name__ for m in mods}, set(expected)) mods = walk_modules('tests.test_utils_misc.test_walk_modules.mod') expected = [ 'tests.test_utils_misc.test_walk_modules.mod', 'tests.test_utils_misc.test_walk_modules.mod.mod0', ] self.assertEqual({m.__name__ for m in mods}, set(expected)) mods = walk_modules('tests.test_utils_misc.test_walk_modules.mod1') expected = [ 'tests.test_utils_misc.test_walk_modules.mod1', ] self.assertEqual({m.__name__ for m in mods}, set(expected)) self.assertRaises(ImportError, walk_modules, 'nomodule999') def test_walk_modules_egg(self): egg = os.path.join(os.path.dirname(__file__), 'test.egg') sys.path.append(egg) try: mods = walk_modules('testegg') expected = [ 'testegg.spiders', 'testegg.spiders.a', 'testegg.spiders.b', 'testegg' ] self.assertEqual({m.__name__ for m in mods}, set(expected)) finally: sys.path.remove(egg) def test_arg_to_iter(self): class TestItem(Item): name = Field() assert hasattr(arg_to_iter(None), '__iter__') assert hasattr(arg_to_iter(100), '__iter__') assert hasattr(arg_to_iter('lala'), '__iter__') assert hasattr(arg_to_iter([1, 2, 3]), '__iter__') assert hasattr(arg_to_iter(c for c in 'abcd'), '__iter__') self.assertEqual(list(arg_to_iter(None)), []) self.assertEqual(list(arg_to_iter('lala')), ['lala']) self.assertEqual(list(arg_to_iter(100)), [100]) self.assertEqual(list(arg_to_iter(c for c in 'abc')), ['a', 'b', 'c']) self.assertEqual(list(arg_to_iter([1, 2, 3])), [1, 2, 3]) self.assertEqual(list(arg_to_iter({'a': 1})), [{'a': 1}]) self.assertEqual(list(arg_to_iter(TestItem(name="john"))), [TestItem(name="john")]) def test_create_instance(self): settings = mock.MagicMock() crawler = mock.MagicMock(spec_set=['settings']) args = (True, 100.) kwargs = {'key': 'val'} def _test_with_settings(mock, settings): create_instance(mock, settings, None, *args, **kwargs) if hasattr(mock, 'from_crawler'): self.assertEqual(mock.from_crawler.call_count, 0) if hasattr(mock, 'from_settings'): mock.from_settings.assert_called_once_with(settings, *args, **kwargs) self.assertEqual(mock.call_count, 0) else: mock.assert_called_once_with(*args, **kwargs) def _test_with_crawler(mock, settings, crawler): create_instance(mock, settings, crawler, *args, **kwargs) if hasattr(mock, 'from_crawler'): mock.from_crawler.assert_called_once_with(crawler, *args, **kwargs) if hasattr(mock, 'from_settings'): self.assertEqual(mock.from_settings.call_count, 0) self.assertEqual(mock.call_count, 0) elif hasattr(mock, 'from_settings'): mock.from_settings.assert_called_once_with(settings, *args, **kwargs) self.assertEqual(mock.call_count, 0) else: mock.assert_called_once_with(*args, **kwargs) # Check usage of correct constructor using four mocks: # 1. with no alternative constructors # 2. with from_settings() constructor # 3. with from_crawler() constructor # 4. with from_settings() and from_crawler() constructor spec_sets = ( ['__qualname__'], ['__qualname__', 'from_settings'], ['__qualname__', 'from_crawler'], ['__qualname__', 'from_settings', 'from_crawler'], ) for specs in spec_sets: m = mock.MagicMock(spec_set=specs) _test_with_settings(m, settings) m.reset_mock() _test_with_crawler(m, settings, crawler) # Check adoption of crawler settings m = mock.MagicMock(spec_set=['__qualname__', 'from_settings']) create_instance(m, None, crawler, *args, **kwargs) m.from_settings.assert_called_once_with(crawler.settings, *args, **kwargs) with self.assertRaises(ValueError): create_instance(m, None, None) m.from_settings.return_value = None with self.assertRaises(TypeError): create_instance(m, settings, None) def test_set_environ(self): assert os.environ.get('some_test_environ') is None with set_environ(some_test_environ='test_value'): assert os.environ.get('some_test_environ') == 'test_value' assert os.environ.get('some_test_environ') is None os.environ['some_test_environ'] = 'test' assert os.environ.get('some_test_environ') == 'test' with set_environ(some_test_environ='test_value'): assert os.environ.get('some_test_environ') == 'test_value' assert os.environ.get('some_test_environ') == 'test' if __name__ == "__main__": unittest.main()