1+ import io
2+ import unittest
3+ from argparse import Namespace
4+ from unittest import mock
5+
6+ from gff3tool .bin import gff3_merge
7+
8+
9+ class TestGff3MergeCli (unittest .TestCase ):
10+ def test_script_main_exits_when_gff_file1_missing (self ):
11+ args = Namespace (
12+ gff_file1 = None ,
13+ gff_file2 = "ref.gff3" ,
14+ fasta = "ref.fa" ,
15+ user_defined_file1 = None ,
16+ user_defined_file2 = None ,
17+ output_gff = "merged.gff" ,
18+ report_file = "report.txt" ,
19+ all = False ,
20+ auto_assignment = True ,
21+ )
22+ stdin = mock .Mock ()
23+ stdin .isatty .return_value = True
24+
25+ with mock .patch ("argparse.ArgumentParser.parse_args" , return_value = args ), \
26+ mock .patch ("sys.stdin" , stdin ), \
27+ mock .patch ("argparse.ArgumentParser.print_help" ) as print_help , \
28+ self .assertRaises (SystemExit ) as exc :
29+ gff3_merge .script_main ()
30+
31+ print_help .assert_called_once ()
32+ self .assertEqual (exc .exception .code , 1 )
33+
34+ def test_script_main_exits_when_gff_file2_missing (self ):
35+ args = Namespace (
36+ gff_file1 = "new.gff3" ,
37+ gff_file2 = None ,
38+ fasta = "ref.fa" ,
39+ user_defined_file1 = None ,
40+ user_defined_file2 = None ,
41+ output_gff = "merged.gff" ,
42+ report_file = "report.txt" ,
43+ all = False ,
44+ auto_assignment = True ,
45+ )
46+ stdin = mock .Mock ()
47+ stdin .isatty .return_value = True
48+
49+ with mock .patch ("argparse.ArgumentParser.parse_args" , return_value = args ), \
50+ mock .patch ("sys.stdin" , stdin ), \
51+ mock .patch ("argparse.ArgumentParser.print_help" ) as print_help , \
52+ self .assertRaises (SystemExit ) as exc :
53+ gff3_merge .script_main ()
54+
55+ print_help .assert_called_once ()
56+ self .assertEqual (exc .exception .code , 2 )
57+
58+ def test_script_main_exits_on_conflicting_all_and_no_auto (self ):
59+ args = Namespace (
60+ gff_file1 = "new.gff3" ,
61+ gff_file2 = "ref.gff3" ,
62+ fasta = "ref.fa" ,
63+ user_defined_file1 = None ,
64+ user_defined_file2 = None ,
65+ output_gff = "merged.gff" ,
66+ report_file = "report.txt" ,
67+ all = True ,
68+ auto_assignment = False ,
69+ )
70+
71+ with mock .patch ("argparse.ArgumentParser.parse_args" , return_value = args ), \
72+ self .assertRaises (SystemExit ) as exc :
73+ gff3_merge .script_main ()
74+
75+ self .assertEqual (exc .exception .code , 0 )
76+
77+ def test_script_main_parses_user_defined_files_and_calls_main (self ):
78+ args = Namespace (
79+ gff_file1 = "new.gff3" ,
80+ gff_file2 = "ref.gff3" ,
81+ fasta = "ref.fa" ,
82+ user_defined_file1 = "u1.txt" ,
83+ user_defined_file2 = "u2.txt" ,
84+ output_gff = "out.gff3" ,
85+ report_file = "report.txt" ,
86+ all = False ,
87+ auto_assignment = True ,
88+ )
89+
90+ def open_side_effect (path , mode = "r" , * args , ** kwargs ):
91+ if path == "u1.txt" :
92+ return io .StringIO ("gene mRNA\n gene mRNA\n " )
93+ if path == "u2.txt" :
94+ return io .StringIO ("gene mRNA\n " )
95+ if path == "report.txt" :
96+ return io .StringIO ()
97+ raise AssertionError (path )
98+
99+ with mock .patch ("argparse.ArgumentParser.parse_args" , return_value = args ), \
100+ mock .patch ("builtins.open" , side_effect = open_side_effect ), \
101+ mock .patch .object (gff3_merge , "main" , autospec = True ) as main_mock :
102+ gff3_merge .script_main ()
103+
104+ main_mock .assert_called_once_with (
105+ "new.gff3" ,
106+ "ref.gff3" ,
107+ "ref.fa" ,
108+ mock .ANY ,
109+ "out.gff3" ,
110+ False ,
111+ True ,
112+ [["gene" , "mRNA" ]],
113+ [["gene" , "mRNA" ]],
114+ logger = mock .ANY ,
115+ )
116+
117+ def test_script_main_uses_default_report_and_output_names (self ):
118+ args = Namespace (
119+ gff_file1 = "new.gff3" ,
120+ gff_file2 = "ref.gff3" ,
121+ fasta = "ref.fa" ,
122+ user_defined_file1 = None ,
123+ user_defined_file2 = None ,
124+ output_gff = None ,
125+ report_file = None ,
126+ all = False ,
127+ auto_assignment = True ,
128+ )
129+
130+ def open_side_effect (path , mode = "r" , * args , ** kwargs ):
131+ if path == "merge_report.txt" :
132+ return io .StringIO ()
133+ raise AssertionError (path )
134+
135+ with mock .patch ("argparse.ArgumentParser.parse_args" , return_value = args ), \
136+ mock .patch ("builtins.open" , side_effect = open_side_effect ), \
137+ mock .patch .object (gff3_merge , "main" , autospec = True ) as main_mock :
138+ gff3_merge .script_main ()
139+
140+ called = main_mock .call_args
141+ self .assertEqual (called .args [4 ], "merged.gff" )
142+ self .assertEqual (called .args [5 ], False )
143+ self .assertEqual (called .args [6 ], True )
144+
145+
146+ if __name__ == "__main__" :
147+ unittest .main ()
0 commit comments