def test_validate_bad_field(self): badch = tuple(c for c in string.punctuation + string.digits) notnames = ( '1a', 'a.b', 'a-b', '&a', 'a++', ) + badch tests = [ ('id', ()), # Any non-empty str is okay. ('storage', ('external', 'global') + notnames), ('vartype', ()), # Any non-empty str is okay. ] seen = set() for field, invalid in tests: for value in invalid: seen.add(value) with self.subTest(f'{field}={value!r}'): static = Variable(**self.VALID_KWARGS) static = static._replace(**{field: value}) with self.assertRaises(ValueError): static.validate() for field, invalid in tests: if field == 'id': continue valid = seen - set(invalid) for value in valid: with self.subTest(f'{field}={value!r}'): static = Variable(**self.VALID_KWARGS) static = static._replace(**{field: value}) static.validate() # This does not fail.
def test_not_supported(self): statics = [ Variable('src1/spam.c', None, 'var1', 'PyObject *'), Variable('src1/spam.c', None, 'var1', 'PyObject[10]'), ] for static in statics: with self.subTest(static): result = is_supported(static) self.assertFalse(result)
def test_supported(self): statics = [ Variable('src1/spam.c', None, 'var1', 'const char *'), Variable('src1/spam.c', None, 'var1', 'int'), ] for static in statics: with self.subTest(static): result = is_supported(static) self.assertTrue(result)
def test_validate_missing_field(self): for field in Variable._fields: with self.subTest(field): static = Variable(**self.VALID_KWARGS) static = static._replace(**{field: None}) with self.assertRaises(TypeError): static.validate() for field in ('storage', 'vartype'): with self.subTest(field): static = Variable(**self.VALID_KWARGS) static = static._replace(**{field: UNKNOWN}) with self.assertRaises(TypeError): static.validate()
def test_validate_typical(self): validstorage = ('static', 'extern', 'implicit', 'local') self.assertEqual(set(validstorage), set(Variable.STORAGE)) for storage in validstorage: with self.subTest(storage): static = Variable( id=ID( filename='x/y/z/spam.c', funcname='func', name='eggs', ), storage=storage, vartype='int', ) static.validate() # This does not fail.
def test_iterable(self): static = Variable(**self.VALID_KWARGS) id, storage, vartype = static values = (id, storage, vartype) for value, expected in zip(values, self.VALID_EXPECTED): self.assertEqual(value, expected)
def test_init_all_coerced(self): id = ID('x/y/z/spam.c', 'func', 'spam') tests = [ ('str subclass', dict( id=( PseudoStr('x/y/z/spam.c'), PseudoStr('func'), PseudoStr('spam'), ), storage=PseudoStr('static'), vartype=PseudoStr('int'), ), ( id, 'static', 'int', )), ('non-str 1', dict( id=id, storage=Object(), vartype=Object(), ), ( id, '<object>', '<object>', )), ('non-str 2', dict( id=id, storage=StrProxy('static'), vartype=StrProxy('variable'), ), ( id, 'static', 'variable', )), ('non-str', dict( id=id, storage=('a', 'b', 'c'), vartype=('x', 'y', 'z'), ), ( id, "('a', 'b', 'c')", "('x', 'y', 'z')", )), ] for summary, kwargs, expected in tests: with self.subTest(summary): static = Variable(**kwargs) for field in Variable._fields: value = getattr(static, field) if field == 'id': self.assertIs(type(value), ID) else: self.assertIs(type(value), str) self.assertEqual(tuple(static), expected)
def test_typical(self): expected = [ Variable.from_parts('file1.c', '', 'var1', 'static int'), Variable.from_parts('file1.c', 'func1', 'local1', 'static int'), Variable.from_parts('file1.c', '', 'var2', 'int'), Variable.from_parts('file1.c', 'func2', 'local2', 'char *'), Variable.from_parts('file2.c', '', 'var1', 'char *'), ] self._return_read_file = [('variable', v.id, v.vartype) for v in expected] # ('variable', ID('file1.c', '', 'var1'), 'static int'), # ('variable', ID('file1.c', 'func1', 'local1'), 'static int'), # ('variable', ID('file1.c', '', 'var2'), 'int'), # ('variable', ID('file1.c', 'func2', 'local2'), 'char *'), # ('variable', ID('file2.c', '', 'var1'), 'char *'), # ] self._return_handle_var = list(expected) # a copy known = from_file( 'known.tsv', handle_var=self._handle_var, _read_file=self._read_file, ) self.assertEqual(known, { 'variables': {v.id: v for v in expected}, }) # Variable.from_parts('file1.c', '', 'var1', 'static int'), # Variable.from_parts('file1.c', 'func1', 'local1', 'static int'), # Variable.from_parts('file1.c', '', 'var2', 'int'), # Variable.from_parts('file1.c', 'func2', 'local2', 'char *'), # Variable.from_parts('file2.c', '', 'var1', 'char *'), # ]}, # }) self.assertEqual(self.calls, [ ('_read_file', ('known.tsv', )), *[('_handle_var', (v.id, v.vartype)) for v in expected], ])
def test_init_all_missing(self): for value in ('', None): with self.subTest(repr(value)): static = Variable( id=value, storage=value, vartype=value, ) self.assertEqual(static, ( None, None, None, ))
def test_init_typical_local(self): for storage in ('static', 'local'): with self.subTest(storage): static = Variable( id=ID( filename='x/y/z/spam.c', funcname='func', name='eggs', ), storage=storage, vartype='int', ) self.assertEqual(static, ( ('x/y/z/spam.c', 'func', 'eggs'), storage, 'int', ))
def test_init_typical_global(self): for storage in ('static', 'extern', 'implicit'): with self.subTest(storage): static = Variable( id=ID( filename='x/y/z/spam.c', funcname=None, name='eggs', ), storage=storage, vartype='int', ) self.assertEqual(static, ( ('x/y/z/spam.c', None, 'eggs'), storage, 'int', ))
def _handle_var(varid, decl): # if varid.name == 'id' and decl == UNKNOWN: # # None of these are variables. # decl = 'int id'; storage = _get_storage(decl, varid.funcname) return Variable(varid, storage, decl)
def test___getattr__(self): static = Variable(('a', 'b', 'z'), 'x', 'y') self.assertEqual(static.filename, 'a') self.assertEqual(static.funcname, 'b') self.assertEqual(static.name, 'z')
def test_fields(self): static = Variable(('a', 'b', 'z'), 'x', 'y') self.assertEqual(static.id, ('a', 'b', 'z')) self.assertEqual(static.storage, 'x') self.assertEqual(static.vartype, 'y')