Esempio n. 1
0
    def setUp(self):
        """ Set load the test files """

        if KiCADTests.good is None:
            KiCADTests.good = JSON().parse(GOOD_OUTPUT_FILE)

        if KiCADTests.actual is None:
            KiCADTests.actual = KiCAD().parse(TEST_INPUT_FILE)
Esempio n. 2
0
    def test_write(self):
        """
        We can write out a complete design file.
        """

        design = JSON().parse(TEST_UPV_FILE)
        writer = KiCAD()
        filedesc, filename = tempfile.mkstemp()
        os.close(filedesc)
        os.remove(filename)
        writer.write(design, filename)
        self.assertTrue(os.path.exists(filename))
 def setUp(self):
     self.geda_writer = GEDA()
     self.oj_parser = JSON()
class GEDATests(unittest.TestCase):
    """ The tests of the geda writer """

    # pylint: disable=W0212

    def setUp(self):
        self.geda_writer = GEDA()
        self.oj_parser = JSON()

    def test_converter_methods(self):
        """ Test if converter methods are available for all known
            shapes in the core. 
        """
        shape_types = ["line", "bezier", "label", "rectangle", "rounded_rectangle", "circle", "polygon"]

        for typ in shape_types:
            self.assertTrue(hasattr(self.geda_writer, "_convert_" + typ))

    def test_create_project_files(self):
        """ Test creating project files in the directory derived from the
            output filename. Should try to create *gafrc* file and *symbol*
            directory.
        """
        geda_filename = "/tmp/test_geda.sch"

        self.geda_writer.create_project_files(geda_filename)

        self.assertEquals(self.geda_writer.project_dirs["project"], "/tmp")
        self.assertEquals(self.geda_writer.project_dirs["symbol"], "/tmp/symbols")
        self.assertTrue(os.path.exists("/tmp/gafrc"))

        filh = open("/tmp/gafrc", "r")
        data = "".join(filh.readlines())
        filh.close()
        self.assertEquals(data, '(component-library "./symbols")')

    def test_write_schematic_file(self):
        """ Reads the gEDA *simple_example* file into a design using the
            gEDA parser, writes the result to a gEDA file and reads it into
            a new design. Both designs are then compared regarding their 
            respective components, instances and nets. """
        # pylint: disable=R0914
        # pylint: disable=R0915

        sym_dir = "/tmp/sym"

        if os.path.exists("/tmp/converted.sch"):
            os.remove("/tmp/converted.sch")

        if os.path.exists(sym_dir):
            shutil.rmtree(sym_dir)

        geda_parser = upconvert.parser.geda.GEDA(symbol_dirs=["test/geda/simple_example/symbols"])
        geda_parser.set_offset(shape.Point(0, 0))
        simple_design = geda_parser.parse("test/geda/simple_example/simple_example.sch")

        geda_writer = GEDA()
        geda_writer.write(simple_design, "/tmp/converted.sch")

        converted_design = geda_parser.parse("/tmp/converted.sch")

        ## parse design again to make sure it is a clean slate
        geda_parser = upconvert.parser.geda.GEDA(symbol_dirs=["test/geda/simple_example/symbols"])
        geda_parser.set_offset(shape.Point(0, 0))
        simple_design = geda_parser.parse("test/geda/simple_example/simple_example.sch")

        ##compare nets
        self.assertEquals(
            sorted([(net.net_id, len(net.points)) for net in simple_design.nets]),
            sorted([(net.net_id, len(net.points)) for net in converted_design.nets]),
        )

        snets = dict([(net.net_id, net) for net in simple_design.nets])
        cnets = dict([(net.net_id, net) for net in converted_design.nets])

        for snet_id, snet in snets.items():
            cnet = cnets[snet_id]

            spoints = dict([(pt.point_id, pt) for pt in snet.points.values()])
            cpoints = dict([(pt.point_id, pt) for pt in cnet.points.values()])
            self.assertEqual(sorted(spoints.keys()), sorted(cpoints.keys()))

            for spoint_id, spoint in spoints.items():
                cpoint = cpoints[spoint_id]

                self.assertEquals(spoint.x, cpoint.x)
                self.assertEquals(spoint.y, cpoint.y)

        ## compare component library
        self.assertEqual(
            sorted(simple_design.components.components.keys()), sorted(converted_design.components.components.keys())
        )

        for lib_id in simple_design.components.components:
            scomponent = simple_design.components.components[lib_id]
            ccomponent = converted_design.components.components[lib_id]

            self.assertEquals(scomponent.name, ccomponent.name)
            self.assertEquals(scomponent.attributes, ccomponent.attributes)

            self.assertEquals(len(scomponent.symbols), 1)
            self.assertEquals(len(scomponent.symbols), len(ccomponent.symbols))

            self.assertEquals(len(scomponent.symbols[0].bodies), 1)
            self.assertEquals(len(scomponent.symbols[0].bodies), len(ccomponent.symbols[0].bodies))
            sbody = scomponent.symbols[0].bodies[0]
            cbody = ccomponent.symbols[0].bodies[0]

            self.assertEquals(len(sbody.shapes), len(cbody.shapes))
            self.assertEquals(len(sbody.pins), len(cbody.pins))

            for spin, cpin in zip(sbody.pins, cbody.pins):
                self.assertEquals(spin.p1.x, cpin.p1.x)
                self.assertEquals(spin.p1.x, cpin.p1.x)
                self.assertEquals(spin.p2.y, cpin.p2.y)
                self.assertEquals(spin.p2.y, cpin.p2.y)
                self.assertEquals(spin.label.text, cpin.label.text)

            for sshape, cshape in zip(sbody.shapes, cbody.shapes):
                self.assertEquals(sshape.type, cshape.type)

        ## compare component instances
        scomp_instances = dict([(comp.instance_id, comp) for comp in simple_design.component_instances])
        ccomp_instances = dict([(comp.instance_id, comp) for comp in converted_design.component_instances])

        for instance_id in scomp_instances:
            sinst = scomp_instances[instance_id]
            cinst = ccomp_instances[instance_id]

            self.assertEquals(sinst.instance_id, cinst.instance_id)
            self.assertEquals(sinst.library_id, cinst.library_id)
            self.assertEquals(sinst.symbol_index, cinst.symbol_index)

            self.assertEquals(sinst.symbol_attributes[0].x, cinst.symbol_attributes[0].x)
            self.assertEquals(sinst.symbol_attributes[0].y, cinst.symbol_attributes[0].y)
            self.assertEquals(sinst.symbol_attributes[0].rotation, cinst.symbol_attributes[0].rotation)

    def test_write_component_to_file(self):
        """ Tests writing a component to a symbol file. """
        sym_dir = "/tmp/sym"
        if os.path.exists(sym_dir):
            shutil.rmtree(sym_dir)

        os.mkdir(sym_dir)

        self.geda_writer.set_offset(shape.Point(-500, -500))

        self.geda_writer.component_library = dict()
        self.geda_writer.project_dirs["symbol"] = sym_dir

        simple_design = self.oj_parser.parse("test/openjson/simple.upv")

        library_id = "0000000000000001"
        component = simple_design.components.components[library_id]
        self.geda_writer.write_component_to_file(library_id, component)

        component_library = self.geda_writer.component_library
        self.assertEquals(len(component_library), 4)

        self.assertEquals(
            component_library,
            {
                (library_id, 0): "Flag_1-0.sym",
                (library_id, 1): "Flag_2-1.sym",
                (library_id, 2): "GND-2.sym",
                (library_id, 3): "VCC-3.sym",
            },
        )
        self.assertEquals(sorted(os.listdir(sym_dir)), ["Flag_1-0.sym", "Flag_2-1.sym", "GND-2.sym", "VCC-3.sym"])

        if os.path.exists(sym_dir):
            shutil.rmtree(sym_dir)

        os.mkdir(sym_dir)

        self.geda_writer = GEDA()
        self.geda_writer.component_library = dict()
        self.geda_writer.project_dirs["symbol"] = sym_dir

        geda_parser = upconvert.parser.geda.GEDA(symbol_dirs=["test/geda/simple_example/symbols"])
        converted_design = geda_parser.parse("test/geda/simple_example/simple_example.sch")

        library_id = "opamp"
        component = converted_design.components.components[library_id]
        self.geda_writer.write_component_to_file(library_id, component)

        component_library = self.geda_writer.component_library
        self.assertEquals(len(component_library), 1)

        self.assertEquals(component_library, {(library_id, 0): "opamp.sym"})
        library_id = "capacitor-1"
        component = converted_design.components.components[library_id]
        self.geda_writer.write_component_to_file(library_id, component)

        component_library = self.geda_writer.component_library
        self.assertEquals(len(component_library), 2)

        self.assertEquals(component_library, {("opamp", 0): "opamp.sym", (library_id, 0): "capacitor-1.sym"})
        self.assertEquals(sorted(os.listdir(sym_dir)), ["opamp.sym"])

    def test_generate_net_commands(self):
        """ Tests creating commands for nets that can then be 
            written to the schematic file. 
        """
        design = self.oj_parser.parse("test/geda/nets_exported.upv")

        self.geda_writer.set_offset(design.bounds()[0])

        commands = self.geda_writer.generate_net_commands(design.nets)
        self.assertTrue(len(commands) > 0)

        segment_count = 0
        for command in commands:
            if command.startswith("N "):
                segment_count += 1

        self.assertEquals(segment_count, 21)

        env_count = 0
        for command in commands:
            if command.startswith("{"):
                env_count += 1
        self.assertEquals(env_count, 4)

        commands += ["v 20110115 2\n"]
        geda_parser = upconvert.parser.geda.GEDA()
        new_design = geda_parser.parse_schematic(StringIO.StringIO("\n".join(commands)))
        self.assertEquals(len(design.nets), len(new_design.nets))

    def test_create_component(self):
        """ Tests creating components from various gEDA commands. """
        component = self.geda_writer._create_component(0, 0, "test-1.sym")
        self.assertEquals(component, ["C 0 0 0 0 0 test-1.sym"])

    def test_create_attribute(self):
        """ Tests creating attribute commands. """
        attribute = self.geda_writer._create_attribute("_refdes", "U1", 0, 0)
        self.assertEquals(attribute, [])
        attribute = self.geda_writer._create_attribute("_refdes", "", 0, 0)
        self.assertEquals(attribute, [])

        attribute = self.geda_writer._create_attribute("_private_attr", "U1", 0, 0)
        self.assertEquals(attribute, ["T 0 0 5 10 0 1 0 0 1", "private_attr=U1"])
        attribute = self.geda_writer._create_attribute("attr", "U1", 0, 0, size=25)
        self.assertEquals(attribute, ["T 0 0 5 25 1 1 0 0 1", "attr=U1"])

    def test_create_text(self):
        """ Tests creating text commands. """
        text = self.geda_writer._create_text("some text", 0, 0)
        self.assertEquals(len(text), 2)
        self.assertEquals(text, ["T 0 0 9 10 1 1 0 0 1", "some text"])

        text = self.geda_writer._create_text(
            "some text\nmulti line\ntext", 0, 0, size=25, visibility=0, alignment="right"
        )
        self.assertEquals(len(text), 4)
        self.assertEquals(text, ["T 0 0 9 25 0 1 0 4 3", "some text", "multi line", "text"])

    def test_create_pin(self):
        """ Tests creating pin commands. """
        pin = components.Pin("E", (0, 0), (0, 30))
        command = self.geda_writer._create_pin(1, pin)

        self.assertEquals(
            command,
            [
                "P 0 300 0 0 1 0 0",
                "{",
                "T 100 400 5 10 0 1 0 0 1",
                "pinseq=1",
                "T 100 500 5 10 0 1 0 0 1",
                "pinnumber=E",
                "}",
            ],
        )

        label = shape.Label(10, 0, "p1", "left", 0.5)

        pin = components.Pin("E", (0, 0), (0, 30), label=label)
        command = self.geda_writer._create_pin(1, pin)

        self.assertEquals(
            command,
            [
                "P 0 300 0 0 1 0 0",
                "{",
                "T 100 0 5 10 1 1 270 0 1",
                "pinlabel=p1",
                "T 100 400 5 10 0 1 0 0 1",
                "pinseq=1",
                "T 100 500 5 10 0 1 0 0 1",
                "pinnumber=E",
                "}",
            ],
        )

    def test_convert_arc(self):
        """ Tests converting Arc objects to arc commands."""
        arc = shape.Arc(0, 0, 0.0, 0.7, 30)
        command = self.geda_writer._convert_arc(arc)

        self.assertEquals(command, ["A 0 0 300 0 235 3 10 0 0 -1 -1"])

        arc = shape.Arc(200, 400, 1.0, 0.5, 10)
        command = self.geda_writer._convert_arc(arc)

        self.assertEquals(command, ["A 2000 4000 100 180 90 3 10 0 0 -1 -1"])

        arc = shape.Arc(200, 400, 0.2, 0.1, 10)
        command = self.geda_writer._convert_arc(arc)

        self.assertEquals(command, ["A 2000 4000 100 324 18 3 10 0 0 -1 -1"])

    def test_convert_circle(self):
        """ Tests converting Circle objects to circle commands."""
        circle = shape.Circle(0, 0, 300)
        command = self.geda_writer._convert_circle(circle)

        self.assertEquals(command, ["V 0 0 3000 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1"])

        circle = shape.Circle(10, 30, 10)
        command = self.geda_writer._convert_circle(circle)

        self.assertEquals(command, ["V 100 300 100 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1"])

    def test_convert_rectangle(self):
        """ Tests converting Rectancle and RoundedRectangle
            objects to box commands.
        """
        rect = shape.Rectangle(0, 0, 40, 50)
        command = self.geda_writer._convert_rectangle(rect)

        self.assertEquals(command, ["B -500 0 400 500 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1"])

        rect = shape.Rectangle(100, 50, 150, 30)
        command = self.geda_writer._convert_rectangle(rect)

        self.assertEquals(command, ["B 700 500 1500 300 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1"])

        rect = shape.RoundedRectangle(0, 0, 40, 50, 0.5)
        command = self.geda_writer._convert_rounded_rectangle(rect)

        self.assertEquals(command, ["B -500 0 400 500 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1"])

        rect = shape.RoundedRectangle(100, 50, 150, 30, 0.1)
        command = self.geda_writer._convert_rounded_rectangle(rect)

        self.assertEquals(command, ["B 700 500 1500 300 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1"])

    def test_convert_line(self):
        """ Tests converting Line objects to line commands. """
        line = shape.Line((0, 0), (0, 50))
        command = self.geda_writer._convert_line(line)
        self.assertEquals(command, ["L 0 0 0 500 3 10 0 0 -1 -1"])

        line = shape.Line((20, 40), (-20, 40))
        command = self.geda_writer._convert_line(line)
        self.assertEquals(command, ["L 200 400 -200 400 3 10 0 0 -1 -1"])

        line = shape.Line((20, 40), (-30, 50))
        command = self.geda_writer._convert_line(line)
        self.assertEquals(command, ["L 200 400 -300 500 3 10 0 0 -1 -1"])

    def test_convert_label(self):
        """ Tests converting Lable objects to label commands. """
        label = shape.Label(0, 0, "test label", "center", 0.0)
        command = self.geda_writer._convert_label(label)
        self.assertEquals(command, ["T 0 0 9 10 1 1 0 3 1", "test label"])

        label = shape.Label(0, 0, "test label", "left", 0.5)
        command = self.geda_writer._convert_label(label)
        self.assertEquals(command, ["T 0 0 9 10 1 1 270 0 1", "test label"])

    def test_create_segment(self):
        """ Tests creating segment commands from NetPoint objects. """
        np1 = NetPoint("0a0", 0, 0)
        np2 = NetPoint("0a10", 0, 10)
        self.assertEquals(self.geda_writer._create_segment(np1, np2), ["N 0 0 0 100 4"])
        np1 = NetPoint("100a40", 100, 40)
        np2 = NetPoint("50a40", 50, 40)
        attrs = {"netname": "test_net"}
        self.assertEquals(
            self.geda_writer._create_segment(np1, np2, attributes=attrs),
            ["N 1000 400 500 400 4", "{", "T 1100 500 5 10 1 1 0 0 1", "netname=test_net", "}"],
        )

    def test_convert_polygon(self):
        """ Tests converting Polygon objects to path commands."""
        polygon = shape.Polygon()
        polygon.add_point((0, 0))
        polygon.add_point((100, 200))
        polygon.add_point((150, 200))
        polygon.add_point((200, 100))

        self.assertEquals(
            self.geda_writer._convert_polygon(polygon),
            ["H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 5", "M 0,0", "L 1000,2000", "L 1500,2000", "L 2000,1000", "z"],
        )

    def test_convert_bezier(self):
        """ Tests converting BezierCurve objects to path commands. """
        curve = shape.BezierCurve((9, -10), (11, -10), (3, -12), (17, -12))

        self.assertEquals(
            self.geda_writer._convert_bezier(curve),
            ["H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 2", "M 30,-120", "C 90,-100 110,-100 170,-120"],
        )

    def test_create_path(self):
        """ Test creating path commands from Body objects. """
        shapes = [
            shape.Line((10, 10), (50, 10)),
            shape.BezierCurve((70, 10), (80, 30), (50, 10), (80, 40)),
            shape.BezierCurve((80, 50), (70, 70), (80, 40), (50, 70)),
            shape.Line((50, 70), (10, 70)),
        ]

        body = components.Body()
        body.shapes = shapes

        self.assertEquals(
            self.geda_writer._create_path(body),
            [
                "H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 5",
                "M 100,100",
                "L 500,100",
                "C 700,100 800,300 800,400",
                "C 800,500 700,700 500,700",
                "L 100,700",
            ],
        )

        body.add_shape(shape.Line((10, 70), (10, 10)))

        self.assertEquals(
            self.geda_writer._create_path(body),
            [
                "H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 6",
                "M 100,100",
                "L 500,100",
                "C 700,100 800,300 800,400",
                "C 800,500 700,700 500,700",
                "L 100,700",
                "z",
            ],
        )

    def test_is_valid_path(self):
        """ Tests if Body objects contain valid paths."""
        shapes = [
            shape.Line((10, 10), (50, 10)),  # L 500,100
            shape.BezierCurve((70, 10), (80, 30), (50, 10), (80, 40)),  # C 700,100 800,300 800,400
            shape.BezierCurve((80, 50), (70, 70), (80, 40), (50, 70)),  # C 800,500 700,700 500,700
            shape.Line((50, 70), (10, 70)),  # L 100,700
        ]

        body = components.Body()
        body.shapes = shapes
        self.assertTrue(self.geda_writer.is_valid_path(body))

        body.add_shape(shape.Line((10, 70), (10, 10)))
        self.assertTrue(self.geda_writer.is_valid_path(body))

        shapes = [
            shape.Line((10, 10), (50, 10)),  # L 500,100
            shape.BezierCurve((70, 10), (80, 30), (50, 10), (80, 40)),  # C 700,100 800,300 800,400
            shape.Line((50, 70), (10, 70)),  # L 100,700
        ]
        body.shapes = shapes
        self.assertFalse(self.geda_writer.is_valid_path(body))

        body.add_shape(shape.Circle(0, 0, 10))
        self.assertFalse(self.geda_writer.is_valid_path(body))

    def test_conv_angle(self):
        """ Test conversion of angles from pi radians to degrees. """
        angle_samples = [
            # angle, steps, expected result
            (0.0, 1, 0),
            (0.0, 10.0, 0),
            (0.5, 90, 270),
            (0.8, 1, 216),
            (0.8, 90, 270),
            (1.5, 1, 90),
            (1.5, 90, 90),
        ]

        for angle, steps, expected in angle_samples:
            self.assertEquals(self.geda_writer.conv_angle(angle, steps), expected)
Esempio n. 5
0
 def test_create_new_json_parser(self):
     """ Test creating an empty parser. """
     parser = JSON()
     assert parser != None
Esempio n. 6
0
 def setUp(self):
     self.geda_writer = GEDA()
     self.oj_parser = JSON()
class GEDATests(unittest.TestCase):
    """ The tests of the geda writer """
    # pylint: disable=W0212

    def setUp(self):
        self.geda_writer = GEDA()
        self.oj_parser = JSON()

    def test_converter_methods(self):
        """ Test if converter methods are available for all known
            shapes in the core. 
        """
        shape_types = [
            'line', 
            'bezier',
            'label',
            'rectangle',
            'rounded_rectangle',
            'circle',
            'polygon',
        ]

        for typ in shape_types:
            self.assertTrue(hasattr(self.geda_writer, "_convert_"+typ))

    def test_create_project_files(self):
        """ Test creating project files in the directory derived from the
            output filename. Should try to create *gafrc* file and *symbol*
            directory.
        """
        geda_filename = '/tmp/test_geda.sch'

        self.geda_writer.create_project_files(geda_filename)

        self.assertEquals(
            self.geda_writer.project_dirs['project'], 
            '/tmp'
        )
        self.assertEquals(
            self.geda_writer.project_dirs['symbol'], 
            '/tmp/symbols'
        )
        self.assertTrue(os.path.exists('/tmp/gafrc'))
        
        filh = open('/tmp/gafrc', 'r')
        data = ''.join(filh.readlines())
        filh.close()
        self.assertEquals(data, '(component-library "./symbols")') 

    def test_write_schematic_file(self):
        """ Reads the gEDA *simple_example* file into a design using the
            gEDA parser, writes the result to a gEDA file and reads it into
            a new design. Both designs are then compared regarding their 
            respective components, instances and nets. """
        # pylint: disable=R0914
        # pylint: disable=R0915

        sym_dir = '/tmp/sym'

        if os.path.exists('/tmp/converted.sch'):
            os.remove('/tmp/converted.sch')

        if os.path.exists(sym_dir):
            shutil.rmtree(sym_dir)

        geda_parser = upconvert.parser.geda.GEDA(
            symbol_dirs=['test/geda/simple_example/symbols']
        )
        geda_parser.set_offset(shape.Point(0, 0))
        simple_design = geda_parser.parse(
            'test/geda/simple_example/simple_example.sch'
        )

        geda_writer = GEDA()
        geda_writer.write(simple_design, '/tmp/converted.sch')

        converted_design = geda_parser.parse(
            '/tmp/converted.sch'
        )

        ## parse design again to make sure it is a clean slate
        geda_parser = upconvert.parser.geda.GEDA(
            symbol_dirs=['test/geda/simple_example/symbols']
        )
        geda_parser.set_offset(shape.Point(0, 0))
        simple_design = geda_parser.parse(
            'test/geda/simple_example/simple_example.sch'
        )

        ##compare nets
        self.assertEquals(
            sorted([(net.net_id, len(net.points)) for net in simple_design.nets]),
            sorted([(net.net_id, len(net.points)) for net in converted_design.nets])
        )

        snets = dict([(net.net_id, net) for net in simple_design.nets]) 
        cnets = dict([(net.net_id, net) for net in converted_design.nets]) 

        for snet_id, snet in snets.items():
            cnet = cnets[snet_id]

            spoints = dict([(pt.point_id, pt) for pt in snet.points.values()]) 
            cpoints = dict([(pt.point_id, pt) for pt in cnet.points.values()]) 
            self.assertEqual(sorted(spoints.keys()), sorted(cpoints.keys()))

            for spoint_id, spoint in spoints.items():
                cpoint = cpoints[spoint_id]

                self.assertEquals(spoint.x, cpoint.x)
                self.assertEquals(spoint.y, cpoint.y)

        ## compare component library
        self.assertEqual(
            sorted(simple_design.components.components.keys()),
            sorted(converted_design.components.components.keys())
        )

        for lib_id in simple_design.components.components:
            scomponent = simple_design.components.components[lib_id]
            ccomponent = converted_design.components.components[lib_id]

            self.assertEquals(scomponent.name, ccomponent.name)
            self.assertEquals(scomponent.attributes, ccomponent.attributes)

            self.assertEquals(len(scomponent.symbols), 1)
            self.assertEquals(
                len(scomponent.symbols), 
                len(ccomponent.symbols)
            )

            self.assertEquals(len(scomponent.symbols[0].bodies), 1)
            self.assertEquals(
                len(scomponent.symbols[0].bodies), 
                len(ccomponent.symbols[0].bodies)
            )
            sbody = scomponent.symbols[0].bodies[0]
            cbody = ccomponent.symbols[0].bodies[0]

            self.assertEquals(len(sbody.shapes), len(cbody.shapes))
            self.assertEquals(len(sbody.pins), len(cbody.pins))

            for spin, cpin in zip(sbody.pins, cbody.pins):
                self.assertEquals(spin.p1.x, cpin.p1.x)
                self.assertEquals(spin.p1.x, cpin.p1.x)
                self.assertEquals(spin.p2.y, cpin.p2.y)
                self.assertEquals(spin.p2.y, cpin.p2.y)
                if spin.label is None:
                    self.assertEquals(cpin.label, None)
                else:
                    self.assertEquals(spin.label.text, cpin.label.text)

            for sshape, cshape in zip(sbody.shapes, cbody.shapes):
                self.assertEquals(sshape.type, cshape.type)

        ## compare component instances
        scomp_instances = dict([(comp.instance_id, comp) for comp in simple_design.component_instances])
        ccomp_instances = dict([(comp.instance_id, comp) for comp in converted_design.component_instances])

        for instance_id in scomp_instances:
            sinst = scomp_instances[instance_id]
            cinst = ccomp_instances[instance_id]
            
            self.assertEquals(sinst.instance_id, cinst.instance_id)
            self.assertEquals(sinst.library_id, cinst.library_id)
            self.assertEquals(sinst.symbol_index, cinst.symbol_index)

            self.assertEquals(
                sinst.symbol_attributes[0].x, 
                cinst.symbol_attributes[0].x
            )
            self.assertEquals(
                sinst.symbol_attributes[0].y, 
                cinst.symbol_attributes[0].y
            )
            self.assertEquals(
                sinst.symbol_attributes[0].rotation, 
                cinst.symbol_attributes[0].rotation
            )

    def test_write_component_to_file(self):
        """ Tests writing a component to a symbol file. """
        sym_dir = '/tmp/sym'
        if os.path.exists(sym_dir):
            shutil.rmtree(sym_dir)

        os.mkdir(sym_dir)

        self.geda_writer.set_offset(shape.Point(-500, -500))

        self.geda_writer.component_library = dict()
        self.geda_writer.project_dirs['symbol'] = sym_dir 

        simple_design = self.oj_parser.parse('test/openjson/simple.upv')

        library_id = '0000000000000001'
        component = simple_design.components.components[library_id]
        self.geda_writer.write_component_to_file(library_id, component)

        component_library = self.geda_writer.component_library
        self.assertEquals(len(component_library), 4)

        self.assertEquals(
            component_library,
            {
                (library_id, 0): 'Flag_1-0.sym', 
                (library_id, 1): 'Flag_2-1.sym', 
                (library_id, 2): 'GND-2.sym', 
                (library_id, 3): 'VCC-3.sym'
            } 
        )
        self.assertEquals(
            sorted(os.listdir(sym_dir)),
            ['Flag_1-0.sym', 'Flag_2-1.sym', 'GND-2.sym', 'VCC-3.sym']
        )


    def test_write_component_to_file_symbol_dirs(self):
        """ Tests writing a component to a symbol file with symbol dirs.
        """
        sym_dir = '/tmp/sym'

        if os.path.exists(sym_dir):
            shutil.rmtree(sym_dir)

        os.mkdir(sym_dir)

        self.geda_writer = GEDA(
            symbol_dirs=['test/geda/simple_example/symbols'])
        self.geda_writer.component_library = dict()
        self.geda_writer.project_dirs['symbol'] = sym_dir 

        geda_parser = upconvert.parser.geda.GEDA(
            symbol_dirs=['test/geda/simple_example/symbols']
        )
        converted_design = geda_parser.parse(
            'test/geda/simple_example/simple_example.sch'
        )

        library_id = 'opamp'
        component = converted_design.components.components[library_id]
        self.geda_writer.write_component_to_file(library_id, component)

        component_library = self.geda_writer.component_library
        self.assertEquals(len(component_library), 1)

        self.assertEquals(
            component_library,
            {
                (library_id, 0): 'opamp.sym', 
            } 
        )
        library_id = 'capacitor-1'
        component = converted_design.components.components[library_id]
        self.geda_writer.write_component_to_file(library_id, component)

        component_library = self.geda_writer.component_library
        self.assertEquals(len(component_library), 2)

        self.assertEquals(
            component_library,
            {
                ('opamp', 0): 'opamp.sym', 
                (library_id, 0): 'capacitor-1.sym', 
            } 
        )
        self.assertEquals(sorted(os.listdir(sym_dir)), [])


    def test_generate_net_commands(self):
        """ Tests creating commands for nets that can then be 
            written to the schematic file. 
        """
        design = self.oj_parser.parse('test/geda/nets_exported.upv')

        self.geda_writer.set_offset(design.bounds()[0])

        commands = self.geda_writer.generate_net_commands(design.nets)
        self.assertTrue(len(commands) > 0)

        segment_count = 0
        for command in commands:
            if command.startswith('N '):
                segment_count += 1

        self.assertEquals(segment_count, 21) 

        env_count = 0
        for command in commands:
            if command.startswith('{'):
                env_count += 1
        self.assertEquals(env_count, 4) 

        commands += ['v 20110115 2\n']
        geda_parser = upconvert.parser.geda.GEDA()
        new_design = geda_parser.parse_schematic(
            StringIO.StringIO('\n'.join(commands))
        )
        self.assertEquals(len(design.nets), len(new_design.nets))


    def test_create_component(self):
        """ Tests creating components from various gEDA commands. """
        component = self.geda_writer._create_component(0, 0, 'test-1.sym')
        self.assertEquals(
            component,
            ['C 0 0 0 0 0 test-1.sym']
        )

    def test_create_attribute(self):
        """ Tests creating attribute commands. """
        attribute = self.geda_writer._create_attribute('_refdes', 'U1', 0, 0) 
        self.assertEquals(
            attribute,
            []
        )
        attribute = self.geda_writer._create_attribute('_refdes', '', 0, 0) 
        self.assertEquals(
            attribute,
            []
        )

        attribute = self.geda_writer._create_attribute('_private_attr', 'U1', 0, 0) 
        self.assertEquals(
            attribute,
            ['T 0 0 5 10 0 1 0 0 1', 'private_attr=U1']
        )
        attribute = self.geda_writer._create_attribute('attr', 'U1', 0, 0, size=25) 
        self.assertEquals(
            attribute,
            ['T 0 0 5 25 1 1 0 0 1', 'attr=U1']
        )

    def test_create_text(self):
        """ Tests creating text commands. """
        text = self.geda_writer._create_text('some text', 0, 0)
        self.assertEquals(len(text), 2)
        self.assertEquals(
            text,
            ['T 0 0 9 10 1 1 0 0 1', 'some text']
        )

        text = self.geda_writer._create_text(
            "some text\nmulti line\ntext", 
            0, 0, size=25, visibility=0, 
            alignment='right',
        )
        self.assertEquals(len(text), 4)
        self.assertEquals(
            text,
            ['T 0 0 9 25 0 1 0 4 3', "some text", "multi line", "text"]
        )

    def test_create_pin(self):
        """ Tests creating pin commands. """
        pin = components.Pin('E', (0, 0), (0, 30))
        command = self.geda_writer._create_pin(1, pin) 

        self.assertEquals(
            command,
            [
                'P 0 300 0 0 1 0 0', 
                '{',
                'T 100 400 5 10 0 1 0 0 1',
                'pinseq=1',
                'T 100 500 5 10 0 1 0 0 1',
                'pinnumber=E',
                '}'
            ]
        )

        label = shape.Label(10, 0, 'p1', 'left', 0.5)

        pin = components.Pin('E', (0, 0), (0, 30), label=label)
        command = self.geda_writer._create_pin(1, pin) 

        self.assertEquals(
            command,
            [
                'P 0 300 0 0 1 0 0', 
                '{',
                'T 100 0 5 10 1 1 270 0 1',
                'pinlabel=p1',
                'T 100 400 5 10 0 1 0 0 1',
                'pinseq=1',
                'T 100 500 5 10 0 1 0 0 1',
                'pinnumber=E',
                '}'
            ]
        )


    def test_convert_arc(self):
        """ Tests converting Arc objects to arc commands."""
        arc = shape.Arc(0, 0, 0.0, 0.7, 30)
        command = self.geda_writer._convert_arc(arc)
        
        self.assertEquals(
            command,
            ['A 0 0 300 0 235 3 10 0 0 -1 -1'] 
        )

        arc = shape.Arc(200, 400, 1.0, 0.5, 10)
        command = self.geda_writer._convert_arc(arc)
        
        self.assertEquals(
            command,
            ['A 2000 4000 100 180 90 3 10 0 0 -1 -1'] 
        )

        arc = shape.Arc(200, 400, 0.2, 0.1, 10)
        command = self.geda_writer._convert_arc(arc)
        
        self.assertEquals(
            command,
            ['A 2000 4000 100 324 18 3 10 0 0 -1 -1'] 
        )

    def test_convert_circle(self):
        """ Tests converting Circle objects to circle commands."""
        circle = shape.Circle(0, 0, 300)
        command = self.geda_writer._convert_circle(circle)

        self.assertEquals(
            command,
            ['V 0 0 3000 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1']
        )

        circle = shape.Circle(10, 30, 10)
        command = self.geda_writer._convert_circle(circle)

        self.assertEquals(
            command,
            ['V 100 300 100 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1']
        )

    def test_convert_rectangle(self):
        """ Tests converting Rectancle and RoundedRectangle
            objects to box commands.
        """
        rect = shape.Rectangle(0, 0, 40, 50)
        command = self.geda_writer._convert_rectangle(rect)

        self.assertEquals(
            command,
            ['B -500 0 400 500 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1']
        )

        rect = shape.Rectangle(100, 50, 150, 30)
        command = self.geda_writer._convert_rectangle(rect)

        self.assertEquals(
            command,
            ['B 700 500 1500 300 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1']
        )

        rect = shape.RoundedRectangle(0, 0, 40, 50, 0.5)
        command = self.geda_writer._convert_rounded_rectangle(rect)

        self.assertEquals(
            command,
            ['B -500 0 400 500 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1']
        )

        rect = shape.RoundedRectangle(100, 50, 150, 30, 0.1)
        command = self.geda_writer._convert_rounded_rectangle(rect)

        self.assertEquals(
            command,
            ['B 700 500 1500 300 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1']
        )

    def test_convert_line(self):
        """ Tests converting Line objects to line commands. """
        line = shape.Line((0, 0), (0, 50))
        command = self.geda_writer._convert_line(line)
        self.assertEquals(
            command,
            ['L 0 0 0 500 3 10 0 0 -1 -1']
        )

        line = shape.Line((20, 40), (-20, 40))
        command = self.geda_writer._convert_line(line)
        self.assertEquals(
            command,
            ['L 200 400 -200 400 3 10 0 0 -1 -1']
        )

        line = shape.Line((20, 40), (-30, 50))
        command = self.geda_writer._convert_line(line)
        self.assertEquals(
            command,
            ['L 200 400 -300 500 3 10 0 0 -1 -1']
        )

    def test_convert_label(self):
        """ Tests converting Lable objects to label commands. """
        label = shape.Label(0, 0, 'test label', 'center', 0.0)
        command = self.geda_writer._convert_label(label)
        self.assertEquals(
            command,
            [
                'T 0 0 9 10 1 1 0 3 1',
                'test label'
            ]
        )

        label = shape.Label(0, 0, 'test label', 'left', 0.5)
        command = self.geda_writer._convert_label(label)
        self.assertEquals(
            command,
            [
                'T 0 0 9 10 1 1 270 0 1',
                'test label'
            ]
        )

    def test_create_segment(self):
        """ Tests creating segment commands from NetPoint objects. """
        np1 = NetPoint('0a0', 0, 0)
        np2 = NetPoint('0a10', 0, 10)
        self.assertEquals(
            self.geda_writer._create_segment(np1, np2),
            ['N 0 0 0 100 4']
        )
        np1 = NetPoint('100a40', 100, 40)
        np2 = NetPoint('50a40', 50, 40)
        attrs = {'netname': 'test_net'}
        self.assertEquals(
            self.geda_writer._create_segment(np1, np2, attributes=attrs),
            [
                'N 1000 400 500 400 4',
                '{',
                'T 1100 500 5 10 1 1 0 0 1',
                'netname=test_net',
                '}',
            ]
        )

    def test_convert_polygon(self):
        """ Tests converting Polygon objects to path commands."""
        polygon = shape.Polygon()
        polygon.add_point((0, 0))
        polygon.add_point((100, 200))
        polygon.add_point((150, 200))
        polygon.add_point((200, 100))

        self.assertEquals(
            self.geda_writer._convert_polygon(polygon),
            [
                'H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 5',
                'M 0,0',
                'L 1000,2000',
                'L 1500,2000',
                'L 2000,1000',
                'z'
            ]
        )
    
    def test_convert_bezier(self):
        """ Tests converting BezierCurve objects to path commands. """
        curve = shape.BezierCurve((9, -10), (11, -10), (3, -12), (17, -12))

        self.assertEquals(
            self.geda_writer._convert_bezier(curve),
            [
                'H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 2',
                'M 30,-120',
                'C 90,-100 110,-100 170,-120',
            ]
        )

    def test_create_path(self):
        """ Test creating path commands from Body objects. """
        shapes = [
            shape.Line((10, 10), (50, 10)),
            shape.BezierCurve((70, 10), (80, 30), (50, 10), (80, 40)),
            shape.BezierCurve((80, 50), (70, 70), (80, 40), (50, 70)),
            shape.Line((50, 70), (10, 70)),
        ]
        
        body = components.Body()
        body.shapes = shapes

        self.assertEquals(
            self.geda_writer._create_path(body),
            [
                'H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 5',
                'M 100,100',
                'L 500,100',
                'C 700,100 800,300 800,400',
                'C 800,500 700,700 500,700',
                'L 100,700',
            ]
        )

        body.add_shape(shape.Line((10, 70), (10, 10)))

        self.assertEquals(
            self.geda_writer._create_path(body),
            [
                'H 3 10 0 0 -1 -1 0 -1 -1 -1 -1 -1 6',
                'M 100,100',
                'L 500,100',
                'C 700,100 800,300 800,400',
                'C 800,500 700,700 500,700',
                'L 100,700',
                'z',
            ]
        )

    def test_is_valid_path(self):
        """ Tests if Body objects contain valid paths."""
        shapes = [
            shape.Line((10, 10), (50, 10)), #L 500,100
            shape.BezierCurve((70, 10), (80, 30), (50, 10), (80, 40)), #C 700,100 800,300 800,400
            shape.BezierCurve((80, 50), (70, 70), (80, 40), (50, 70)), #C 800,500 700,700 500,700
            shape.Line((50, 70), (10, 70)), #L 100,700
        ]
        
        body = components.Body()
        body.shapes = shapes
        self.assertTrue(self.geda_writer.is_valid_path(body))

        body.add_shape(shape.Line((10, 70), (10, 10)))
        self.assertTrue(self.geda_writer.is_valid_path(body))

        shapes = [
            shape.Line((10, 10), (50, 10)), #L 500,100
            shape.BezierCurve((70, 10), (80, 30), (50, 10), (80, 40)), #C 700,100 800,300 800,400
            shape.Line((50, 70), (10, 70)), #L 100,700
        ]
        body.shapes = shapes
        self.assertFalse(self.geda_writer.is_valid_path(body))

        body.add_shape(shape.Circle(0, 0, 10))
        self.assertFalse(self.geda_writer.is_valid_path(body))

    def test_conv_angle(self):
        """ Test conversion of angles from pi radians to degrees. """
        angle_samples = [
            # angle, steps, expected result
            (0.0, 1, 0),
            (0.0, 10.0, 0),
            (0.5, 90, 270),
            (0.8,  1, 216), 
            (0.8,  90, 270), 
            (1.5,  1, 90), 
            (1.5,  90, 90),
        ]

        for angle, steps, expected in angle_samples:
            self.assertEquals(
                self.geda_writer.conv_angle(angle, steps), 
                expected
            )