importloggingimportos.pathimportshutilimporttempfileimportunittestimportgitimportruamel.yamlimportlesanaclasstestCollection(unittest.TestCase):deftearDown(self):shutil.rmtree(os.path.join(self.collection.basedir,'.lesana'))deftest_empty(self):self.collection=lesana.Collection('tests/data/empty')self.assertEqual(self.collection.settings,{})self.collection.update_cache()self.assertIsNotNone(self.collection.stemmer)deftest_load_simple(self):self.collection=lesana.Collection('tests/data/simple')self.assertIsNotNone(self.collection.settings)self.assertEqual(self.collection.settings['name'],"Simple lesana collection")self.assertEqual(len(self.collection.settings['fields']),5)self.assertEqual(len(self.collection.indexed_fields),2)self.collection.update_cache()self.assertIsNotNone(self.collection.stemmer)deftest_load_wrong_language(self):# This loads a collection with an invalid value in langwithself.assertLogs(level=logging.WARNING)ascm:self.collection=lesana.Collection('tests/data/wrong')self.assertEqual(len(cm.output),1)self.assertIn("Invalid language",cm.output[0])# The collection will default to english, but should still work.self.collection.update_cache()self.assertIsNotNone(self.collection.settings)self.assertIsNotNone(self.collection.stemmer)deftest_load_no_index_for_one_entry(self):# This loads a collection where some of the entries have no# "index" fieldwithself.assertLogs(level=logging.WARNING):self.collection=lesana.Collection('tests/data/wrong')self.collection.update_cache()self.assertIsNotNone(self.collection.settings)self.assertIsNotNone(self.collection.stemmer)# Fields with no "index" entry are not indexedself.assertEqual(len(self.collection.settings['fields']),4)self.assertEqual(len(self.collection.indexed_fields),1)deftest_load_safe(self):self.collection=lesana.Collection('tests/data/simple')self.collection.safe=Trueself.collection.update_cache()deftest_full_search(self):self.collection=lesana.Collection('tests/data/simple')self.collection.start_search('Item')res=self.collection.get_all_search_results()matches=list(res)self.assertEqual(len(matches),2)forminmatches:self.assertIsInstance(m,lesana.Entry)deftest_search(self):self.collection=lesana.Collection('tests/data/simple')self.collection.start_search('Item')res=self.collection.get_search_results()matches=list(res)self.assertEqual(len(matches),2)forminmatches:self.assertIsInstance(m,lesana.Entry)deftest_search_wildcard(self):self.collection=lesana.Collection('tests/data/simple')self.collection.start_search('Ite*')res=self.collection.get_search_results()matches=list(res)self.assertEqual(len(matches),2)forminmatches:self.assertIsInstance(m,lesana.Entry)deftest_search_non_init(self):self.collection=lesana.Collection('tests/data/simple')matches=list(self.collection.get_search_results())self.assertEqual(matches,[])matches=list(self.collection.get_all_search_results())self.assertEqual(matches,[])deftest_all_entries(self):self.collection=lesana.Collection('tests/data/simple')res=self.collection.get_all_documents()matches=list(res)self.assertEqual(len(matches),3)forminmatches:self.assertIsInstance(m,lesana.Entry)deftest_entry_from_uid(self):self.collection=lesana.Collection('tests/data/simple')entry=self.collection.entry_from_uid('11189ee47ddf4796b718a483b379f976')self.assertEqual(entry.uid,'11189ee47ddf4796b718a483b379f976')self.collection.safe=Trueentry=self.collection.entry_from_uid('11189ee47ddf4796b718a483b379f976')self.assertEqual(entry.uid,'11189ee47ddf4796b718a483b379f976')deftest_index_missing_file(self):self.collection=lesana.Collection('tests/data/simple')withself.assertLogs(level=logging.WARNING)ascm:self.collection.update_cache(['non_existing_file'])self.assertEqual(len(cm.output),1)self.assertIn("non_existing_file",cm.output[0])deftest_get_entry_missing_uid(self):self.collection=lesana.Collection('tests/data/simple')entry=self.collection.entry_from_uid('this is not an uid')self.assertIsNone(entry)classtestEntries(unittest.TestCase):defsetUp(self):self.collection=lesana.Collection('tests/data/simple')self.basepath='tests/data/simple/items'self.filenames=[]deftearDown(self):forfnameinself.filenames:os.remove(fname)shutil.rmtree(os.path.join(self.collection.basedir,'.lesana'))deftest_simple(self):fname='085682ed-6792-499d-a3ab-9aebd683c011.yaml'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)entry=lesana.Entry(self.collection,data=data,fname=fname)self.assertEqual(entry.idterm,'Q'+data['uid'])fname='11189ee47ddf4796b718a483b379f976.yaml'uid='11189ee47ddf4796b718a483b379f976'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)entry=lesana.Entry(self.collection,data=data,fname=fname)self.assertEqual(entry.idterm,'Q'+uid)deftest_write_new(self):new_entry=lesana.Entry(self.collection)self.collection.save_entries(entries=[new_entry])entry_fname='tests/data/simple/items/'+new_entry.fnameself.filenames.append(entry_fname)withopen(entry_fname)asfp:text=fp.read()self.assertIn('quantity (integer): how many items are there',text)self.assertIn('other (yaml):',text)self.assertNotIn('position (string)',text)written=ruamel.yaml.safe_load(text)self.assertIsInstance(written['quantity'],int)self.assertIsInstance(written['name'],str)deftest_entry_representation(self):uid='11189ee47ddf4796b718a483b379f976'entry=self.collection.entry_from_uid(uid)self.assertEqual(str(entry),uid)label='{{ uid }}: {{ name }}'self.collection.settings['entry_label']=labelself.assertEqual(str(entry),'{uid}: {name}'.format(uid=uid,name='Another item'))deftest_entry_creation_uid_but_no_filename(self):fname='11189ee47ddf4796b718a483b379f976.yaml'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)data['uid']='11189ee47ddf4796b718a483b379f976'entry=lesana.Entry(self.collection,data=data)self.assertEqual(entry.fname,fname)deftest_entry_creation_no_uid_no_filename(self):fname='11189ee47ddf4796b718a483b379f976.yaml'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)entry=lesana.Entry(self.collection,data=data)self.assertIsNotNone(entry.uid)self.assertIsNotNone(entry.fname)deftest_entry_creation_filename_but_no_uid(self):fname='11189ee47ddf4796b718a483b379f976.yaml'uid='11189ee47ddf4796b718a483b379f976'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)entry=lesana.Entry(self.collection,data=data,fname=fname)self.assertEqual(entry.uid,uid)deftest_entry_str_filename_and_uid(self):fname='11189ee47ddf4796b718a483b379f976.yaml'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)data['uid']='11189ee47ddf4796b718a483b379f976'entry=lesana.Entry(self.collection,data=data)self.assertEqual(str(entry),data['uid'])self.collection.settings['entry_label']='{{ uid }}: {{ name }}'self.assertEqual(str(entry),data['uid']+': Another item')deftest_entry_str_filename_no_uid(self):fname='11189ee47ddf4796b718a483b379f976.yaml'withopen(os.path.join(self.basepath,fname))asfp:data=ruamel.yaml.safe_load(fp)entry=lesana.Entry(self.collection,data=data)uid=entry.uidself.assertEqual(str(entry),uid)self.collection.settings['entry_label']='{{ uid }}: {{ name }}'self.assertEqual(str(entry),uid+': Another item')classtestComplexCollection(unittest.TestCase):@classmethoddefsetUpClass(self):self.collection=lesana.Collection('tests/data/complex')@classmethoddeftearDownClass(self):shutil.rmtree(os.path.join(self.collection.basedir,'.lesana'))deftest_init(self):self.assertIsNotNone(self.collection.settings)self.assertEqual(self.collection.settings['name'],"Fully featured lesana collection")self.assertEqual(len(self.collection.settings['fields']),5)self.assertIsNotNone(self.collection.stemmer)self.assertEqual(len(self.collection.indexed_fields),4)deftest_index(self):self.collection.update_cache()deftest_indexing_list(self):self.collection.update_cache(['73097121f1874a6ea2f927db7dc4f11e.yaml'])self.collection.start_search('tags:this')res=self.collection.get_search_results()matches=list(res)self.assertEqual(len(matches),1)forminmatches:self.assertIsInstance(m,lesana.Entry)classtestCollectionWithErrors(unittest.TestCase):@classmethoddefsetUpClass(self):self.collection=lesana.Collection('tests/data/wrong')@classmethoddeftearDownClass(self):shutil.rmtree(os.path.join(self.collection.basedir,'.lesana'))deftest_init(self):self.assertIsNotNone(self.collection.settings)self.assertEqual(self.collection.settings['name'],"Lesana collection with certain errors")self.assertEqual(len(self.collection.settings['fields']),4)self.assertIsNotNone(self.collection.stemmer)self.assertEqual(len(self.collection.indexed_fields),1)deftest_index(self):loaded=self.collection.update_cache()self.assertEqual(loaded,0)classtestCollectionCreation(unittest.TestCase):deftest_init(self):tmpdir=tempfile.mkdtemp()collection=lesana.Collection.init(tmpdir)self.assertIsInstance(collection,lesana.Collection)self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.git')))self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.lesana')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'settings.yaml')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'.gitignore')))# and then run it twice on the same directory, nothing should breakcollection=lesana.Collection.init(tmpdir)self.assertIsInstance(collection,lesana.Collection)self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.git')))self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.lesana')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'settings.yaml')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'.gitignore')))created=lesana.Collection(tmpdir)self.assertTrue(created.settings['git'])shutil.rmtree(tmpdir)defdo_nothing(*args,**kwargs):# A function that does nothing instead of editing a filepassdeftest_init_edit_file(self):tmpdir=tempfile.mkdtemp()collection=lesana.Collection.init(tmpdir,edit_file=self.do_nothing)self.assertIsInstance(collection,lesana.Collection)self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.git')))self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.lesana')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'settings.yaml')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'.gitignore')))shutil.rmtree(tmpdir)deftest_init_no_git(self):tmpdir=tempfile.mkdtemp()collection=lesana.Collection.init(tmpdir,git_enabled=False)self.assertIsInstance(collection,lesana.Collection)self.assertFalse(os.path.isdir(os.path.join(tmpdir,'.git')))self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.lesana')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'settings.yaml')))self.assertFalse(os.path.isfile(os.path.join(tmpdir,'.gitignore')))# and then run it twice on the same directory, nothing should breakcollection=lesana.Collection.init(tmpdir,git_enabled=False)self.assertIsInstance(collection,lesana.Collection)self.assertFalse(os.path.isdir(os.path.join(tmpdir,'.git')))self.assertTrue(os.path.isdir(os.path.join(tmpdir,'.lesana')))self.assertTrue(os.path.isfile(os.path.join(tmpdir,'settings.yaml')))self.assertFalse(os.path.isfile(os.path.join(tmpdir,'.gitignore')))created=lesana.Collection(tmpdir)self.assertFalse(created.settings['git'])shutil.rmtree(tmpdir)deftest_deletion(self):tmpdir=tempfile.mkdtemp()shutil.copy('tests/data/simple/settings.yaml',tmpdir)shutil.copytree('tests/data/simple/items',os.path.join(tmpdir,'items'),)collection=lesana.Collection.init(tmpdir)# We start with one item indexed with the term "another"collection.start_search('another')mset=collection._enquire.get_mset(0,10)self.assertEqual(mset.get_matches_estimated(),1)# Then delete itcollection.remove_entries(['11189ee47ddf4796b718a483b379f976'])# An now we should have noneself.assertFalse(os.path.exists(os.path.join(tmpdir,'items','11189ee47ddf4796b718a483b379f976.yaml')))collection.start_search('another')mset=collection._enquire.get_mset(0,10)self.assertEqual(mset.get_matches_estimated(),0)def_find_file_in_git_index(self,fname,index):found=Falsefor(path,stage)inindex.entries:iffnameinpath:found=Truebreakreturnfounddeftest_git_adding(self):tmpdir=tempfile.mkdtemp()shutil.copy('tests/data/simple/settings.yaml',tmpdir)shutil.copytree('tests/data/simple/items',os.path.join(tmpdir,'items'),)collection=lesana.Collection.init(tmpdir)fname='11189ee47ddf4796b718a483b379f976.yaml'repo=git.Repo(tmpdir)# By default, this collection doesn't have any git entry in the# settings (but there is a repo)collection.git_add_files([os.path.join(collection.itemdir,fname)])self.assertFalse(self._find_file_in_git_index(fname,repo.index))# Then we set it to falsecollection.settings['git']=Falsecollection.git_add_files([os.path.join(collection.itemdir,fname)])self.assertFalse(self._find_file_in_git_index(fname,repo.index))# And only when it's set to true we should find the file in the# staging areacollection.settings['git']=Truecollection.git_add_files([os.path.join(collection.itemdir,fname)])self.assertTrue(self._find_file_in_git_index(fname,repo.index))shutil.rmtree(tmpdir)deftest_init_custom_settings(self):tmpdir=tempfile.mkdtemp()collection=lesana.Collection.init(tmpdir,edit_file=self.do_nothing,settings={'name':'A different name','fields':[{'name':'title','type':'string'},{'name':'author','type':'string'},],},)self.assertIsInstance(collection,lesana.Collection)self.assertTrue(os.path.isfile(os.path.join(tmpdir,'settings.yaml')))self.assertEqual(collection.settings['name'],'A different name')self.assertEqual(len(collection.settings['fields']),2)shutil.rmtree(tmpdir)if__name__=='__main__':unittest.main()