@@ -0,0 +1,2742 @@
+import unittest%0Aimport os%0Aimport re%0Aimport tempfile%0Aimport json%0A%0Aimport signac.contrib%0A%0ASIGNAC_ACCESS_MODULE = %22%22%22import os%0Aimport re%0A%0Aimport signac.contrib%0A%0ARE_TXT = re.compile(%22.*a_(?P%3Ca%3E%5Cd)%5C.json%22)%0Aclass Crawler(signac.contrib.RegexFileCrawler):%0A    pass%0ACrawler.definitions.update(%7BRE_TXT: signac.contrib.formats.TextFile%7D)%0A%0Adef get_crawlers(root):%0A    return %7B'main':  Crawler(os.path.join(root, '.'))%7D%0A%22%22%22%0A%0Aclass CrawlerBaseTest(unittest.TestCase):%0A%0A    def setUp(self):%0A        self._tmp_dir = tempfile.TemporaryDirectory(prefix='signac_')%0A        self.addCleanup(self._tmp_dir.cleanup)%0A%0A    def test_regex_file_crawler(self):%0A        def fn(name):%0A            return os.path.join(self._tmp_dir.name, name)%0A        with open(fn('a_0.txt'), 'w') as file:%0A            file.write('%7B%22a%22: 0%7D')%0A        with open(fn('a_1.txt'), 'w') as file:%0A            file.write('%7B%22a%22: 1%7D')%0A        class MyType(object):%0A            pass%0A        crawler = signac.contrib.RegexFileCrawler(root=self._tmp_dir.name)%0A        regex = re.compile(%22.*a_(?P%3Ca%3E%5Cd)%5C.txt%22)%0A        crawler.definitions.update(%7Bregex : MyType%7D)%0A        no_find=True%0A        for doc_id, doc in crawler.crawl():%0A            no_find=False%0A            self.assertEqual(doc_id, doc%5B'_id'%5D)%0A            ffn = os.path.join(doc%5B'root'%5D, doc%5B'filename'%5D)%0A            m = regex.match(ffn)%0A            self.assertIsNotNone(m)%0A            self.assertTrue(os.path.isfile(ffn))%0A            with open(ffn) as file:%0A                doc2 = json.load(file)%0A                self.assertEqual(doc2%5B'a'%5D, doc%5B'a'%5D)%0A        self.assertFalse(no_find)%0A%0A    def test_master_crawler(self):%0A        def fn(name):%0A            return os.path.join(self._tmp_dir.name, name)%0A        with open(fn('a_0.json'), 'w') as file:%0A            file.write('%7B%22a%22: 0%7D')%0A        with open(fn('a_1.json'), 'w') as file:%0A            file.write('%7B%22a%22: 1%7D')%0A        with open(fn('signac_access.py'), 'w') as module:%0A            module.write(SIGNAC_ACCESS_MODULE)%0A        crawler = signac.contrib.MasterCrawler(root=self._tmp_dir.name)%0A        no_find=True%0A        for doc_id, doc in crawler.crawl():%0A            no_find=False%0A            self.assertEqual(doc_id, doc%5B'_id'%5D)%0A            ffn = os.path.join(doc%5B'root'%5D, doc%5B'filename'%5D)%0A            self.assertTrue(os.path.isfile(ffn))%0A            with open(ffn) as file:%0A                doc2 = json.load(file)%0A                self.assertEqual(doc2%5B'a'%5D, doc%5B'a'%5D)%0A            for data in signac.contrib.fetch(doc):%0A                self.assertEqual(signac.contrib.formats.TextFile, type(data))%0A                # prevents resource warning, usually not required%0A                data._file_object.close()%0A        self.assertFalse(no_find)%0A%0A%0Aif __name__ == '__main__':%0A    unittest.main()%0A

Add crawler unit tests.