1import sys 2import unittest 3 4from .. import tool_imports_for_tests 5with tool_imports_for_tests(): 6 from c_analyzer.variables import info 7 from cpython import SOURCE_DIRS 8 from cpython.supported import IGNORED_FILE 9 from cpython.known import DATA_FILE as KNOWN_FILE 10 from cpython.__main__ import ( 11 cmd_check, cmd_show, parse_args, main, 12 ) 13 14 15TYPICAL = [ 16 (info.Variable.from_parts('src1/spam.c', None, 'var1', 'const char *'), 17 True, 18 ), 19 (info.Variable.from_parts('src1/spam.c', 'ham', 'initialized', 'int'), 20 True, 21 ), 22 (info.Variable.from_parts('src1/spam.c', None, 'var2', 'PyObject *'), 23 False, 24 ), 25 (info.Variable.from_parts('src1/eggs.c', 'tofu', 'ready', 'int'), 26 True, 27 ), 28 (info.Variable.from_parts('src1/spam.c', None, 'freelist', '(PyTupleObject *)[10]'), 29 False, 30 ), 31 (info.Variable.from_parts('src1/sub/ham.c', None, 'var1', 'const char const *'), 32 True, 33 ), 34 (info.Variable.from_parts('src2/jam.c', None, 'var1', 'int'), 35 True, 36 ), 37 (info.Variable.from_parts('src2/jam.c', None, 'var2', 'MyObject *'), 38 False, 39 ), 40 (info.Variable.from_parts('Include/spam.h', None, 'data', 'const int'), 41 True, 42 ), 43 ] 44 45 46class CMDBase(unittest.TestCase): 47 48 maxDiff = None 49 50# _return_known_from_file = None 51# _return_ignored_from_file = None 52 _return_find = () 53 54 @property 55 def calls(self): 56 try: 57 return self._calls 58 except AttributeError: 59 self._calls = [] 60 return self._calls 61 62# def _known_from_file(self, *args): 63# self.calls.append(('_known_from_file', args)) 64# return self._return_known_from_file or {} 65# 66# def _ignored_from_file(self, *args): 67# self.calls.append(('_ignored_from_file', args)) 68# return self._return_ignored_from_file or {} 69 70 def _find(self, known, ignored, skip_objects=False): 71 self.calls.append(('_find', (known, ignored, skip_objects))) 72 return self._return_find 73 74 def _show(self, *args): 75 self.calls.append(('_show', args)) 76 77 def _print(self, *args): 78 self.calls.append(('_print', args)) 79 80 81class CheckTests(CMDBase): 82 83 def test_defaults(self): 84 self._return_find = [] 85 86 cmd_check('check', 87 _find=self._find, 88 _show=self._show, 89 _print=self._print, 90 ) 91 92 self.assertEqual( 93 self.calls[0], 94 ('_find', (KNOWN_FILE, IGNORED_FILE, False)), 95 ) 96 97 def test_all_supported(self): 98 self._return_find = [(v, s) for v, s in TYPICAL if s] 99 dirs = ['src1', 'src2', 'Include'] 100 101 cmd_check('check', 102 known='known.tsv', 103 ignored='ignored.tsv', 104 _find=self._find, 105 _show=self._show, 106 _print=self._print, 107 ) 108 109 self.assertEqual(self.calls, [ 110 ('_find', ('known.tsv', 'ignored.tsv', False)), 111 #('_print', ('okay',)), 112 ]) 113 114 def test_some_unsupported(self): 115 self._return_find = TYPICAL 116 117 with self.assertRaises(SystemExit) as cm: 118 cmd_check('check', 119 known='known.tsv', 120 ignored='ignored.tsv', 121 _find=self._find, 122 _show=self._show, 123 _print=self._print, 124 ) 125 126 unsupported = [v for v, s in TYPICAL if not s] 127 self.assertEqual(self.calls, [ 128 ('_find', ('known.tsv', 'ignored.tsv', False)), 129 ('_print', ('ERROR: found unsupported global variables',)), 130 ('_print', ()), 131 ('_show', (sorted(unsupported),)), 132 ('_print', (' (3 total)',)), 133 ]) 134 self.assertEqual(cm.exception.code, 1) 135 136 137class ShowTests(CMDBase): 138 139 def test_defaults(self): 140 self._return_find = [] 141 142 cmd_show('show', 143 _find=self._find, 144 _show=self._show, 145 _print=self._print, 146 ) 147 148 self.assertEqual( 149 self.calls[0], 150 ('_find', (KNOWN_FILE, IGNORED_FILE, False)), 151 ) 152 153 def test_typical(self): 154 self._return_find = TYPICAL 155 156 cmd_show('show', 157 known='known.tsv', 158 ignored='ignored.tsv', 159 _find=self._find, 160 _show=self._show, 161 _print=self._print, 162 ) 163 164 supported = [v for v, s in TYPICAL if s] 165 unsupported = [v for v, s in TYPICAL if not s] 166 self.assertEqual(self.calls, [ 167 ('_find', ('known.tsv', 'ignored.tsv', False)), 168 ('_print', ('supported:',)), 169 ('_print', ('----------',)), 170 ('_show', (sorted(supported),)), 171 ('_print', (' (6 total)',)), 172 ('_print', ()), 173 ('_print', ('unsupported:',)), 174 ('_print', ('------------',)), 175 ('_show', (sorted(unsupported),)), 176 ('_print', (' (3 total)',)), 177 ]) 178 179 180class ParseArgsTests(unittest.TestCase): 181 182 maxDiff = None 183 184 def test_no_args(self): 185 self.errmsg = None 186 def fail(msg): 187 self.errmsg = msg 188 sys.exit(msg) 189 190 with self.assertRaises(SystemExit): 191 parse_args('cg', [], _fail=fail) 192 193 self.assertEqual(self.errmsg, 'missing command') 194 195 def test_check_no_args(self): 196 cmd, cmdkwargs = parse_args('cg', [ 197 'check', 198 ]) 199 200 self.assertEqual(cmd, 'check') 201 self.assertEqual(cmdkwargs, { 202 'ignored': IGNORED_FILE, 203 'known': KNOWN_FILE, 204 #'dirs': SOURCE_DIRS, 205 }) 206 207 def test_check_full_args(self): 208 cmd, cmdkwargs = parse_args('cg', [ 209 'check', 210 '--ignored', 'spam.tsv', 211 '--known', 'eggs.tsv', 212 #'dir1', 213 #'dir2', 214 #'dir3', 215 ]) 216 217 self.assertEqual(cmd, 'check') 218 self.assertEqual(cmdkwargs, { 219 'ignored': 'spam.tsv', 220 'known': 'eggs.tsv', 221 #'dirs': ['dir1', 'dir2', 'dir3'] 222 }) 223 224 def test_show_no_args(self): 225 cmd, cmdkwargs = parse_args('cg', [ 226 'show', 227 ]) 228 229 self.assertEqual(cmd, 'show') 230 self.assertEqual(cmdkwargs, { 231 'ignored': IGNORED_FILE, 232 'known': KNOWN_FILE, 233 #'dirs': SOURCE_DIRS, 234 'skip_objects': False, 235 }) 236 237 def test_show_full_args(self): 238 cmd, cmdkwargs = parse_args('cg', [ 239 'show', 240 '--ignored', 'spam.tsv', 241 '--known', 'eggs.tsv', 242 #'dir1', 243 #'dir2', 244 #'dir3', 245 ]) 246 247 self.assertEqual(cmd, 'show') 248 self.assertEqual(cmdkwargs, { 249 'ignored': 'spam.tsv', 250 'known': 'eggs.tsv', 251 #'dirs': ['dir1', 'dir2', 'dir3'], 252 'skip_objects': False, 253 }) 254 255 256def new_stub_commands(*names): 257 calls = [] 258 def cmdfunc(cmd, **kwargs): 259 calls.append((cmd, kwargs)) 260 commands = {name: cmdfunc for name in names} 261 return commands, calls 262 263 264class MainTests(unittest.TestCase): 265 266 def test_no_command(self): 267 with self.assertRaises(ValueError): 268 main(None, {}) 269 270 def test_check(self): 271 commands, calls = new_stub_commands('check', 'show') 272 273 cmdkwargs = { 274 'ignored': 'spam.tsv', 275 'known': 'eggs.tsv', 276 'dirs': ['dir1', 'dir2', 'dir3'], 277 } 278 main('check', cmdkwargs, _COMMANDS=commands) 279 280 self.assertEqual(calls, [ 281 ('check', cmdkwargs), 282 ]) 283 284 def test_show(self): 285 commands, calls = new_stub_commands('check', 'show') 286 287 cmdkwargs = { 288 'ignored': 'spam.tsv', 289 'known': 'eggs.tsv', 290 'dirs': ['dir1', 'dir2', 'dir3'], 291 } 292 main('show', cmdkwargs, _COMMANDS=commands) 293 294 self.assertEqual(calls, [ 295 ('show', cmdkwargs), 296 ]) 297