2323from qiime2 .core .cache import Cache
2424from qiime2 .sdk .result import Result
2525from qiime2 .sdk .plugin_manager import PluginManager
26+ from qiime2 .core .annotate import Note
2627
2728from q2cli .util import load_metadata
2829from q2cli .builtin .tools import tools
@@ -1280,24 +1281,32 @@ def test_replay_supplement_zipfile(self):
12801281
12811282class TestAnnotations (unittest .TestCase ):
12821283 def setUp (self ):
1283- get_dummy_plugin ()
12841284 self .runner = CliRunner ()
12851285 self .tempdir = tempfile .mkdtemp (prefix = 'qiime2-q2cli-test-temp-' )
12861286
1287+ # artifact without any starting annotations
12871288 self .art1 = os .path .join (self .tempdir , 'ints1.qza' )
12881289 Artifact .import_data ('IntSequence1' , [0 , 1 , 2 ]).save (self .art1 )
1290+
1291+ # artifact with one starting annotation
1292+ self .art2 = os .path .join (self .tempdir , 'ints2.qza' )
1293+ Artifact .import_data ('IntSequence1' , [1 , 2 , 3 ]).save (self .art2 )
1294+ self .note1 = Note (name = 'mynote' , text = 'my special text' )
1295+ Artifact .load (self .art2 ).add_annotation (self .note1 )
1296+
1297+ # output path for self.art1 after adding annotation
12891298 self .output1 = os .path .join (self .tempdir , 'ints1_annotated.qza' )
12901299
1300+ # annotation path for note from file
12911301 self .note_file = os .path .join (
12921302 self .tempdir , 'note_file.txt' )
1293-
12941303 with open (self .note_file , 'w' ) as f :
12951304 f .write ('my special text' )
12961305
12971306 def tearDown (self ):
12981307 shutil .rmtree (self .tempdir )
12991308
1300- def test_annotation_commands_roundtrip (self ):
1309+ def test_annotation_commands_roundtrip_success (self ):
13011310 create_result = self .runner .invoke (
13021311 tools ,
13031312 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1327,7 +1336,8 @@ def test_annotation_commands_roundtrip(self):
13271336 )
13281337 self .assertEqual (remove_result .exit_code , 0 )
13291338
1330- def test_annotation_create_with_text (self ):
1339+ # ANNOTATION_CREATE
1340+ def test_annotation_create_with_text_success (self ):
13311341 create_result = self .runner .invoke (
13321342 tools ,
13331343 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1372,7 +1382,7 @@ def test_annotation_create_with_text(self):
13721382 self .assertEqual (exp_contents , annotation )
13731383
13741384 # make sure we see same results as w/inline text for input
1375- def test_annotation_create_with_file (self ):
1385+ def test_annotation_create_with_file_success (self ):
13761386 create_result = self .runner .invoke (
13771387 tools ,
13781388 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1418,7 +1428,7 @@ def test_annotation_create_with_file(self):
14181428
14191429 # make sure we don't run into any errors & see same result
14201430 # when overwriting the original artifact fp
1421- def test_annotation_create_overwriting_input_file (self ):
1431+ def test_annotation_create_overwriting_input_file_success (self ):
14221432 create_result = self .runner .invoke (
14231433 tools ,
14241434 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1462,7 +1472,7 @@ def test_annotation_create_overwriting_input_file(self):
14621472 # confirm the annotation file contains the text we expect
14631473 self .assertEqual (exp_contents , annotation )
14641474
1465- def test_annotation_create_invalid_annotation_type (self ):
1475+ def test_annotation_create_invalid_annotation_type_failure (self ):
14661476 create_result = self .runner .invoke (
14671477 tools ,
14681478 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1475,7 +1485,7 @@ def test_annotation_create_invalid_annotation_type(self):
14751485 self .assertIn ("Invalid value for '--annotation-type': 'Foo'" ,
14761486 create_result .output )
14771487
1478- def test_annotation_create_text_and_filepath_provided (self ):
1488+ def test_annotation_create_text_and_filepath_provided_failure (self ):
14791489 create_result = self .runner .invoke (
14801490 tools ,
14811491 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1488,7 +1498,7 @@ def test_annotation_create_text_and_filepath_provided(self):
14881498 self .assertIn ("Exactly one of `--text` or `--file` must be provided" ,
14891499 create_result .output )
14901500
1491- def test_annotation_create_no_text_or_filepath_provided (self ):
1501+ def test_annotation_create_no_text_or_filepath_provided_failure (self ):
14921502 create_result = self .runner .invoke (
14931503 tools ,
14941504 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1500,7 +1510,7 @@ def test_annotation_create_no_text_or_filepath_provided(self):
15001510 self .assertIn ("Exactly one of `--text` or `--file` must be provided" ,
15011511 create_result .output )
15021512
1503- def test_annotation_create_invalid_name (self ):
1513+ def test_annotation_create_invalid_annotation_name_failure (self ):
15041514 create_result = self .runner .invoke (
15051515 tools ,
15061516 ['annotation-create' , '--input-path' , self .art1 ,
@@ -1514,6 +1524,80 @@ def test_annotation_create_invalid_name(self):
15141524 self .assertIn ('Name "@#$%^&*" is not a valid Python identifier' ,
15151525 str (create_result .exception ))
15161526
1527+ def test_annotation_create_existing_annotation_name_failure (self ):
1528+ create_result = self .runner .invoke (
1529+ tools ,
1530+ ['annotation-create' , '--input-path' , self .art2 ,
1531+ '--annotation-type' , 'Note' ,
1532+ '--name' , 'mynote' , '--file' , self .note_file ,
1533+ '--output-path' , self .output1 ]
1534+ )
1535+ # confirm the command does produce an error
1536+ self .assertEqual (create_result .exit_code , 1 )
1537+ self .assertIn ('Duplicate name detected when attempting to add '
1538+ 'Annotation with name: "mynote"' , create_result .output )
1539+
1540+ # ANNOTATION_REMOVE
1541+ def test_annotation_remove_new_filepath_success (self ):
1542+ remove_result = self .runner .invoke (
1543+ tools ,
1544+ ['annotation-remove' , '--input-path' , self .art2 ,
1545+ '--name' , 'mynote' , '--output-path' , self .output1 ]
1546+ )
1547+ # confirm the command doesn't produce an error
1548+ self .assertEqual (remove_result .exit_code , 0 )
1549+
1550+ with zipfile .ZipFile (self .output1 , 'r' ) as zfh :
1551+ # confirm annotations dir has been removed
1552+ self .assertNotIn ('annotations' , set (zfh .namelist ()))
1553+
1554+ def test_annotation_remove_existing_filepath_success (self ):
1555+ remove_result = self .runner .invoke (
1556+ tools ,
1557+ ['annotation-remove' , '--input-path' , self .art2 ,
1558+ '--name' , 'mynote' , '--output-path' , self .art2 ]
1559+ )
1560+ # confirm the command doesn't produce an error
1561+ self .assertEqual (remove_result .exit_code , 0 )
1562+
1563+ with zipfile .ZipFile (self .art2 , 'r' ) as zfh :
1564+ # confirm annotations dir has been removed
1565+ self .assertNotIn ('annotations' , set (zfh .namelist ()))
1566+
1567+ def test_annotation_remove_no_annotations_failure (self ):
1568+ remove_result = self .runner .invoke (
1569+ tools ,
1570+ ['annotation-remove' , '--input-path' , self .art1 ,
1571+ '--name' , 'mynote' , '--output-path' , self .output1 ]
1572+ )
1573+ # confirm the command does produce an error
1574+ self .assertEqual (remove_result .exit_code , 1 )
1575+ self .assertIn ('No Annotation found with name: "mynote"' ,
1576+ remove_result .output )
1577+
1578+ def test_annotation_remove_wrong_annotation_name_failure (self ):
1579+ remove_result = self .runner .invoke (
1580+ tools ,
1581+ ['annotation-remove' , '--input-path' , self .art2 ,
1582+ '--name' , 'myspecialnote' , '--output-path' , self .output1 ]
1583+ )
1584+ # confirm the command does produce an error
1585+ self .assertEqual (remove_result .exit_code , 1 )
1586+ self .assertIn ('No Annotation found with name: "myspecialnote"' ,
1587+ remove_result .output )
1588+
1589+ # ANNOTATION_FETCH
1590+ def test_annotation_fetch_no_verbose_success (self ):
1591+ fetch_result = self .runner .invoke (
1592+ tools ,
1593+ ['annotation-fetch' , '--input-path' , self .art2 , '--name' , 'mynote' ]
1594+ )
1595+ # confirm the command doesn't produce an error
1596+ self .assertEqual (fetch_result .exit_code , 0 )
1597+ # ensure the annotation type & name we expect is present in the output
1598+ self .assertRegex (fetch_result .output ,
1599+ r'name:\s*mynote\s*type:\s*Note\b' )
1600+
15171601
15181602if __name__ == "__main__" :
15191603 unittest .main ()
0 commit comments