1
1
import unittest
2
2
from unittest .mock import mock_open , patch
3
3
import argparse
4
- from bioclip .__main__ import parse_args , Rank , create_classes_str , main
4
+ import pandas as pd
5
+ from bioclip .__main__ import parse_args , Rank , create_classes_str , main , parse_bins_csv
5
6
6
7
7
8
class TestParser (unittest .TestCase ):
@@ -15,6 +16,7 @@ def test_parse_args(self):
15
16
self .assertEqual (args .rank , Rank .SPECIES )
16
17
self .assertEqual (args .k , 5 )
17
18
self .assertEqual (args .cls , None )
19
+ self .assertEqual (args .bins , None )
18
20
self .assertEqual (args .device , 'cpu' )
19
21
20
22
args = parse_args (['predict' , 'image.jpg' , 'image2.png' ])
@@ -41,12 +43,29 @@ def test_parse_args(self):
41
43
self .assertEqual (args .rank , None ) # default ignored for the --cls variation
42
44
self .assertEqual (args .k , None )
43
45
self .assertEqual (args .cls , 'class1,class2' )
46
+ self .assertEqual (args .bins , None )
47
+ self .assertEqual (args .device , 'cuda' )
48
+
49
+ # test binning version of predict
50
+ args = parse_args (['predict' , 'image.jpg' , '--format' , 'table' , '--output' , 'output.csv' , '--bins' , 'bins.csv' , '--device' , 'cuda' ])
51
+ self .assertEqual (args .command , 'predict' )
52
+ self .assertEqual (args .image_file , ['image.jpg' ])
53
+ self .assertEqual (args .format , 'table' )
54
+ self .assertEqual (args .output , 'output.csv' )
55
+ self .assertEqual (args .rank , None ) # default ignored for the --cls variation
56
+ self .assertEqual (args .k , None )
57
+ self .assertEqual (args .cls , None )
58
+ self .assertEqual (args .bins , 'bins.csv' )
44
59
self .assertEqual (args .device , 'cuda' )
45
60
46
61
# test error when using --cls with --rank
47
- with self .assertRaises (ValueError ):
62
+ with self .assertRaises (SystemExit ):
48
63
parse_args (['predict' , 'image.jpg' , '--cls' , 'class1,class2' , '--rank' , 'genus' ])
49
64
65
+ # test error when using --cls with --bins
66
+ with self .assertRaises (SystemExit ):
67
+ parse_args (['predict' , 'image.jpg' , '--cls' , 'class1,class2' , '--bins' , 'somefile.csv' ])
68
+
50
69
# not an error when using --cls with --k
51
70
args = parse_args (['predict' , 'image.jpg' , '--cls' , 'class1,class2' , '--k' , '10' ])
52
71
self .assertEqual (args .k , 10 )
@@ -77,10 +96,10 @@ def test_create_classes_str(self):
77
96
def test_predict_no_class (self , mock_parse_args , mock_predict ):
78
97
mock_parse_args .return_value = argparse .Namespace (command = 'predict' , image_file = 'image.jpg' , format = 'csv' ,
79
98
output = 'stdout' , rank = Rank .SPECIES , k = 5 , cls = None , device = 'cpu' ,
80
- model = None , pretrained = None )
99
+ model = None , pretrained = None , bins = None )
81
100
main ()
82
- mock_predict .assert_called_with ('image.jpg' , format = 'csv' , output = 'stdout' , cls_str = None , rank = Rank .SPECIES , k = 5 ,
83
- device = 'cpu' , model_str = None , pretrained_str = None )
101
+ mock_predict .assert_called_with ('image.jpg' , format = 'csv' , output = 'stdout' , cls_str = None , rank = Rank .SPECIES ,
102
+ bins_path = None , k = 5 , device = 'cpu' , model_str = None , pretrained_str = None )
84
103
85
104
@patch ('bioclip.__main__.predict' )
86
105
@patch ('bioclip.__main__.parse_args' )
@@ -89,10 +108,10 @@ def test_predict_class_list(self, mock_os, mock_parse_args, mock_predict):
89
108
mock_os .path .exists .return_value = False
90
109
mock_parse_args .return_value = argparse .Namespace (command = 'predict' , image_file = 'image.jpg' , format = 'csv' ,
91
110
output = 'stdout' , rank = Rank .SPECIES , k = 5 , cls = 'dog,fish,bird' ,
92
- device = 'cpu' , model = None , pretrained = None )
111
+ device = 'cpu' , model = None , pretrained = None , bins = None )
93
112
main ()
94
113
mock_predict .assert_called_with ('image.jpg' , format = 'csv' , output = 'stdout' , cls_str = 'dog,fish,bird' , rank = Rank .SPECIES ,
95
- k = 5 , device = 'cpu' , model_str = None , pretrained_str = None )
114
+ bins_path = None , k = 5 , device = 'cpu' , model_str = None , pretrained_str = None )
96
115
97
116
@patch ('bioclip.__main__.predict' )
98
117
@patch ('bioclip.__main__.parse_args' )
@@ -101,8 +120,38 @@ def test_predict_class_file(self, mock_os, mock_parse_args, mock_predict):
101
120
mock_os .path .exists .return_value = True
102
121
mock_parse_args .return_value = argparse .Namespace (command = 'predict' , image_file = 'image.jpg' , format = 'csv' ,
103
122
output = 'stdout' , rank = Rank .SPECIES , k = 5 , cls = 'somefile.txt' ,
104
- device = 'cpu' , model = None , pretrained = None )
123
+ device = 'cpu' , model = None , pretrained = None , bins = None )
105
124
with patch ("builtins.open" , mock_open (read_data = 'dog\n fish\n bird' )) as mock_file :
106
125
main ()
107
126
mock_predict .assert_called_with ('image.jpg' , format = 'csv' , output = 'stdout' , cls_str = 'dog,fish,bird' , rank = Rank .SPECIES ,
108
- k = 5 , device = 'cpu' , model_str = None , pretrained_str = None )
127
+ bins_path = None , k = 5 , device = 'cpu' , model_str = None , pretrained_str = None )
128
+
129
+ @patch ('bioclip.__main__.predict' )
130
+ @patch ('bioclip.__main__.parse_args' )
131
+ @patch ('bioclip.__main__.os' )
132
+ def test_predict_bins (self , mock_os , mock_parse_args , mock_predict ):
133
+ mock_os .path .exists .return_value = True
134
+ mock_parse_args .return_value = argparse .Namespace (command = 'predict' , image_file = 'image.jpg' , format = 'csv' ,
135
+ output = 'stdout' , rank = None , k = 5 , cls = None ,
136
+ device = 'cpu' , model = None , pretrained = None ,
137
+ bins = 'some.csv' )
138
+ with patch ("builtins.open" , mock_open (read_data = 'dog\n fish\n bird' )) as mock_file :
139
+ main ()
140
+ mock_predict .assert_called_with ('image.jpg' , format = 'csv' , output = 'stdout' , cls_str = None , rank = None ,
141
+ bins_path = 'some.csv' , k = 5 , device = 'cpu' , model_str = None , pretrained_str = None )
142
+ @patch ('bioclip.__main__.os.path' )
143
+ def test_parse_bins_csv_file_missing (self , mock_path ):
144
+ mock_path .exists .return_value = False
145
+ with self .assertRaises (FileNotFoundError ) as raised_exception :
146
+ parse_bins_csv ("somefile.csv" )
147
+ self .assertEqual (str (raised_exception .exception ), 'File not found: somefile.csv' )
148
+
149
+ @patch ('bioclip.__main__.pd' )
150
+ @patch ('bioclip.__main__.os.path' )
151
+ def test_parse_bins_csv (self , mock_path , mock_pd ):
152
+ mock_path .exists .return_value = True
153
+ data = {'bin' : ['a' , 'b' ]}
154
+ mock_pd .read_csv .return_value = pd .DataFrame (data = data , index = ['dog' , 'cat' ])
155
+ with patch ("builtins.open" , mock_open (read_data = 'dog\n fish\n bird' )) as mock_file :
156
+ cls_to_bin = parse_bins_csv ("somefile.csv" )
157
+ self .assertEqual (cls_to_bin , {'cat' : 'b' , 'dog' : 'a' })
0 commit comments