def setUp(self):
     stub_file_stack()
     self.sym = ViewDrawSym('library/', 'file.1')
     self.sym.stream = FileStack(self.sym.filename)
class ViewDrawSymTests(unittest.TestCase):
    """ Tests for ViewDraw library symbol files """

    def setUp(self):
        stub_file_stack()
        self.sym = ViewDrawSym('library/', 'file.1')
        self.sym.stream = FileStack(self.sym.filename)

    def tearDown(self):
        unstub_file_stack()
        del self.sym

    def test_parser_dispatch(self):
        """ Check that the parsers used have the proper call signatures """
        valid_cmds = 'Y U P L'.split()
        for cmd in valid_cmds:
            parser  = self.sym.parsenode(cmd)
            # make sure it only needs two argument (self, args)
            self.assertEqual(len(getargspec(parser)[0]), 2)
        # currently not testing invalid commands, their behaviour can be
        # considered 'undefined'

    def test_sym_type(self):
        """ Test symbol type extraction, based on found documents """
        for i, txt in enumerate(['composite', 'module', 'annotate', 'pin',
                               'power', 'unknown']):
            k, v = self.sym.parse_type(str(i))
            self.assertEqual(k, 'attr')
            self.assertEqual(v, ('symtype', txt))

    def test_attr_key_val(self):
        """ Test attribute parsing, when it has a key and value """
        k, v = self.sym.parse_attr('0 1 2 3 4 5 KEY=VAL')
        self.assertEqual(k, 'attr')
        self.assertEqual(v, ('KEY', 'VAL'))

    def test_attr_just_key(self):
        """ Test attribute parsing, when it has a key but no value """
        k, v = self.sym.parse_attr('0 1 2 3 4 5 KEY')
        self.assertEqual(k, 'attr')
        self.assertEqual(v, ('KEY', ''))

    def subtest_pin(self):
        """ Common tests for both pin test cases """
        k, v = self.sym.parse_pin('13 2 4 3 5 0 0 0')
        self.assertEqual(k, 'pin')
        self.assertEqual(v.p1, Point(3, 5))
        self.assertEqual(v.p2, Point(2, 4))
        self.assertEqual(v.pin_number, 13)
        return(v)

    def test_pin(self):
        """ Test parsing a simple pin """
        v = self.subtest_pin()
        self.assertTrue(v.label == None)

    def test_pin_with_label(self):
        """ Test parsing a pin with an attached label """
        self.sym.stream.f = iter(['L testlabel'])
        # create a fake label parser
        # NOTE not sure if this test is too coupled to internal
        # state/architecture. Fix it if there's a better way
        def fake_label(args):
            return ('label', Label(1, 2, args, 'left', 0))

        p = self.sym.parsenode
        def parsenode_shim(cmd):
            if cmd is 'L':
                return fake_label
            return p(cmd)
        self.sym.parsenode = parsenode_shim

        label = self.subtest_pin().label
        self.assertEqual(label.type, 'label')
        self.assertEqual((label.x, label.y), (1, 2))
        self.assertEqual(label.text, 'testlabel')
        self.assertEqual(label.align, 'left')
        self.assertEqual(label.rotation, 0)

    def test_label(self):
        """ Test parsing a text label """
        k, v = self.sym.parse_label('2 3 12 0 1 1 1 0 foobar')
        # values of 1 aren't used by parser
        self.assertEqual(k, 'label')
        self.assertEqual(v.type, 'label')
        self.assertEqual((v.x, v.y), (2, 3))
        self.assertEqual(v.text, 'foobar')
        self.assertEqual(v.align, 'left')
        self.assertEqual(v.rotation, 0)

    def test_label_inverted(self):
        """ Test parsing a label (for a pin) for an inverted signal """
        _k, v = self.sym.parse_label('2 3 12 0 1 1 1 1 foobar')
        # everything else already tested in test_label()
        self.assertEqual(v.text, '/foobar')