def setUp(self): """ setup gEDA parser instance with offset (0,0) for easier comparsion. """ self.geda_parser = GEDA() ## for easier validation self.geda_parser.SCALE_FACTOR = 10 self.geda_parser.set_offset(core.shape.Point(0, 0))
def test_parse_full(self): """ Test parsing a complete schematic file generating OpenJSON. """ self.geda_parser = GEDA([ './test/geda/simple_example/symbols', ]) design = self.geda_parser.parse('test/geda/simple_example/simple_example.sch') self.assertEquals(len(design.nets), 2) net_names = [net.net_id for net in design.nets] self.assertEquals( sorted(net_names), sorted(['+_1', '-_In+']), )
def test_parse_component_data(self): """ Tests parsing component data from symbol files and embedded sections. """ self.geda_parser = GEDA([ './test/geda/simple_example/symbols', ]) fpath = open('test/geda/path.sch') component = self.geda_parser.parse_component_data(fpath, { 'basename': 'test.sym', }) fpath.close() self.assertEquals(component.name, 'test') self.assertEquals(len(component.symbols), 1) self.assertEquals(len(component.symbols[0].bodies), 1) self.assertEquals(len(component.symbols[0].bodies[0].shapes), 9)
def test_parse(self): """ Tests parsing valid and invalid schematic files. """ self.geda_parser = GEDA([ './test/geda/simple_example/symbols', ]) invalid_sch = open('/tmp/invalid.sch', 'w') invalid_sch.write('C 18600 21500 1 0 0 EMBEDDED555-1') invalid_sch.close() self.assertRaises( GEDAError, self.geda_parser.parse, '/tmp/invalid.sch' ) ## testing EMBEDDED component design = self.geda_parser.parse('./test/geda/embedded_component.sch') components = design.components.components #test components dictionary self.assertEquals(components.keys(), ['EMBEDDEDbattery-1']) component = components['EMBEDDEDbattery-1'] self.assertEquals(component.name, 'EMBEDDEDbattery-1') keys = ['p1x', 'p1y', 'p2x', 'p2y', 'num', 'seq', 'label', 'type'] expected_pins = [ dict(zip(keys, [0, 200, 200, 200, '1', 1, '+', 'pwr'])), dict(zip(keys, [700, 200, 500, 200, '2', 2, '-', 'pwr'])), ] for pin, expected_pin in zip(component.symbols[0].bodies[0].pins, expected_pins): self.assertEquals(pin.label.text, expected_pin['label']) ## test reversed pin order due to different handling in direction self.assertEquals(pin.p1.x, expected_pin['p2x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p1.y, expected_pin['p2y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.x, expected_pin['p1x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.y, expected_pin['p1y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.pin_number, expected_pin['num']) ## testing referenced component design = self.geda_parser.parse('test/geda/component.sch') components = design.components.components #test components dictionary self.assertEquals(components.keys(), ['battery-1']) component = components['battery-1'] self.assertEquals(component.name, 'battery-1') keys = ['p1x', 'p1y', 'p2x', 'p2y', 'num', 'seq', 'label', 'type'] expected_pins = [ dict(zip(keys, [0, 200, 200, 200, '1', 1, '+', 'pwr'])), dict(zip(keys, [700, 200, 500, 200, '2', 2, '-', 'pwr'])), ] for pin, expected_pin in zip(component.symbols[0].bodies[0].pins, expected_pins): self.assertEquals(pin.label.text, expected_pin['label']) ## test reversed pin order due to different handling in direction self.assertEquals(pin.p1.x, expected_pin['p2x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p1.y, expected_pin['p2y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.x, expected_pin['p1x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.y, expected_pin['p1y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.pin_number, expected_pin['num'])
def test__parse_title_frame(self): title_frames = { 'title-E': (44000, 34000), 'title-bordered-E': (44000, 34000), 'title-bordered-D': (34000, 22000), 'title-bordered-A': (11000, 8500), 'title-bordered-C': (22000, 17000), 'title-bordered-B': (17000, 11000), 'title-A0': (46800, 33100), 'title-A1': (33100, 23300), 'title-A2': (23300, 16500), 'title-A3': (16500, 11600), 'title-A4': (11600, 8200), 'title-A0-2': (46800, 33100), 'title-A1-2': (33100, 23300), 'title-A2-2': (23300, 16500), 'title-A3-2': (16500, 11600), 'title-A4-2': (11600, 8200), 'title-D': (34000, 22000), 'title-B': (17000, 11000), 'title-C': (22000, 17000), 'title-A': (11000, 8500), 'title-bordered-A4': (11600, 8200), 'title-bordered-A1': (33100, 23300), 'title-bordered-A0': (46800, 33100), 'title-bordered-A3': (16500, 11600), 'title-bordered-A2': (23300, 16500), 'title-dg-1': (17000, 11000), 'title-small-square': (7600, 6900), 'titleblock': (7500, 1800), 'titleblock1': (11000, 8500), 'titleblock2': (22000, 17000), 'titleblock3': (33000, 25500), 'titleblock4': (44000, 34000), 'title-B-nameOnEdge': (26600, 17000), 'title-B-cibolo': (26600, 17000), 'title-block': (7500, 1800), } params = { 'x': 3200, 'y': 3109, } geda_parser = GEDA() for name, filename in geda_parser.known_symbols.items(): if name.startswith('title'): params['basename'] = name print name ## reset geda parser geda_parser.frame_width = 0 geda_parser.frame_height = 0 geda_parser._parse_title_frame(params) self.assertEquals(geda_parser.offset.x, params['x']) self.assertEquals(geda_parser.offset.y, params['y']) self.assertEquals( geda_parser.frame_width, title_frames[name][0] ) self.assertEquals( geda_parser.frame_height, title_frames[name][1] ) ## check that method does not break when invalid file is passed params['basename'] = 'invalid_symbol.sym' geda_parser = GEDA() geda_parser._parse_title_frame(params) self.assertEquals(geda_parser.offset.x, params['x']) self.assertEquals(geda_parser.offset.y, params['y']) ## check if default is set correctly self.assertEquals(geda_parser.frame_width, 46800) self.assertEquals(geda_parser.frame_height, 34000)
class GEDATests(unittest.TestCase): """ The tests of the geda parser """ # pylint: disable=W0212 def setUp(self): """ setup gEDA parser instance with offset (0,0) for easier comparsion. """ self.geda_parser = GEDA() ## for easier validation self.geda_parser.SCALE_FACTOR = 10 self.geda_parser.set_offset(core.shape.Point(0, 0)) def test_constructor(self): """ Test constructor with different parameters to ensure that symbols and symbol directories are handled correctly. """ ## get number of symbols in symbols directory symbols = set() for dummy, dummy, filenames in os.walk('library/geda'): for filename in filenames: if filename.endswith('.sym'): symbols.add(filename) geda_parser = GEDA() self.assertEquals(len(geda_parser.known_symbols), len(symbols)) geda_parser = GEDA([ './test/geda/simple_example/symbols', '/invalid/dir/gEDA', ]) self.assertEquals(len(geda_parser.known_symbols), len(symbols)) self.assertEquals( geda_parser.known_symbols['opamp'], './test/geda/simple_example/symbols/opamp.sym' ) geda_parser = GEDA([ './test/geda/simple_example/symbols', '/invalid/dir/gEDA', ]) self.assertTrue('title-B' in geda_parser.known_symbols) geda_parser = GEDA() self.assertTrue('title-B' in geda_parser.known_symbols) def test__parse_title_frame(self): title_frames = { 'title-E': (44000, 34000), 'title-bordered-E': (44000, 34000), 'title-bordered-D': (34000, 22000), 'title-bordered-A': (11000, 8500), 'title-bordered-C': (22000, 17000), 'title-bordered-B': (17000, 11000), 'title-A0': (46800, 33100), 'title-A1': (33100, 23300), 'title-A2': (23300, 16500), 'title-A3': (16500, 11600), 'title-A4': (11600, 8200), 'title-A0-2': (46800, 33100), 'title-A1-2': (33100, 23300), 'title-A2-2': (23300, 16500), 'title-A3-2': (16500, 11600), 'title-A4-2': (11600, 8200), 'title-D': (34000, 22000), 'title-B': (17000, 11000), 'title-C': (22000, 17000), 'title-A': (11000, 8500), 'title-bordered-A4': (11600, 8200), 'title-bordered-A1': (33100, 23300), 'title-bordered-A0': (46800, 33100), 'title-bordered-A3': (16500, 11600), 'title-bordered-A2': (23300, 16500), 'title-dg-1': (17000, 11000), 'title-small-square': (7600, 6900), 'titleblock': (7500, 1800), 'titleblock1': (11000, 8500), 'titleblock2': (22000, 17000), 'titleblock3': (33000, 25500), 'titleblock4': (44000, 34000), 'title-B-nameOnEdge': (26600, 17000), 'title-B-cibolo': (26600, 17000), 'title-block': (7500, 1800), } params = { 'x': 3200, 'y': 3109, } geda_parser = GEDA() for name, filename in geda_parser.known_symbols.items(): if name.startswith('title'): params['basename'] = name print name ## reset geda parser geda_parser.frame_width = 0 geda_parser.frame_height = 0 geda_parser._parse_title_frame(params) self.assertEquals(geda_parser.offset.x, params['x']) self.assertEquals(geda_parser.offset.y, params['y']) self.assertEquals( geda_parser.frame_width, title_frames[name][0] ) self.assertEquals( geda_parser.frame_height, title_frames[name][1] ) ## check that method does not break when invalid file is passed params['basename'] = 'invalid_symbol.sym' geda_parser = GEDA() geda_parser._parse_title_frame(params) self.assertEquals(geda_parser.offset.x, params['x']) self.assertEquals(geda_parser.offset.y, params['y']) ## check if default is set correctly self.assertEquals(geda_parser.frame_width, 46800) self.assertEquals(geda_parser.frame_height, 34000) def test__parse_text(self): """ Test extracting text commands from input stream. """ valid_text = """T 16900 35800 3 10 1 0 0 0 1 Text string!""" text_stream = StringIO.StringIO(valid_text) typ, params = self.geda_parser._parse_command(text_stream) self.assertEquals(typ, 'T') key, value = self.geda_parser._parse_text(text_stream, params) self.assertEquals(key, None) annotation = self.geda_parser._create_annotation(value, params) self.assertEquals(annotation.value, "Text string!") self.assertEquals(annotation.x, 1690) self.assertEquals(annotation.y, 3580) self.assertEquals(annotation.visible, 'true') self.assertEquals(annotation.rotation, 0) valid_text = """T 16900 35800 3 10 1 0 0 0 4 Text string! And more ... and more ... text!""" text_stream = StringIO.StringIO(valid_text) typ, params = self.geda_parser._parse_command(text_stream) self.assertEquals(typ, 'T') key, value = self.geda_parser._parse_text(text_stream, params) text = """Text string! And more ... and more ... text!""" self.assertEquals(key, None) annotation = self.geda_parser._create_annotation(value, params) self.assertEquals(annotation.value, text) self.assertEquals(annotation.x, 1690) self.assertEquals(annotation.y, 3580) self.assertEquals(annotation.visible, 'true') self.assertEquals(annotation.rotation, 0) def test_conv_angle(self): """ Test converting angles from degrees to pi radians. """ angles = [ (0, 0), (90, 1.5), (180, 1.0), (220, 0.8), (270, 0.5), (510, 1.2), ] for angle, expected in angles: converted = self.geda_parser.conv_angle(angle) self.assertEquals(expected, converted) def test_conv_bool(self): """ Tests converting various values to boolean. """ for test_bool in ['1', 1, True, 'true']: self.assertEquals('true', self.geda_parser.conv_bool(test_bool)) for test_bool in ['0', 0, False, 'false']: self.assertEquals('false', self.geda_parser.conv_bool(test_bool)) def test_conv_mils(self): """ Test converting MILS to pixels. """ test_mils = [ (2, 0), (100, 10), (3429, 342), (0, 0), (-50, -5), (-1238, -123), ] self.geda_parser.set_offset(core.shape.Point(0, 0)) for mils, expected in test_mils: self.assertEquals( self.geda_parser.y_to_px(mils), expected ) self.assertEquals( self.geda_parser.x_to_px(mils), expected ) def test__parse_environment(self): """ Tests parsing attribute environments and enclosed attribute commands. """ no_env = "P 100 600 200 600 1 0 0" stream = StringIO.StringIO(no_env) attributes = self.geda_parser._parse_environment(stream) self.assertEquals(attributes, None) self.assertEquals(stream.tell(), 0) valid_env = """{ T 150 650 5 8 1 1 0 6 1 pinnumber=3 T 150 650 5 8 0 1 0 6 1 pinseq=3 T 250 500 9 16 0 1 0 0 1 pinlabel=+=? T 150 550 5 8 1 1 0 8 1 sometype=in }""" expected_attributes = { '_pinnumber': '3', '_pinseq': '3', '_pinlabel': '+=?', 'sometype': 'in', } stream = StringIO.StringIO(valid_env) attributes = self.geda_parser._parse_environment(stream) self.assertEquals(attributes, expected_attributes) def test_calculate_nets(self): """ Test calculating and creating nets from net segment commands. """ net_sample = """N 52100 44400 54300 44400 4 N 54300 44400 54300 46400 4 { T 54300 44400 5 8 0 1 0 8 1 netname=test } N 53200 45100 53200 43500 4 N 55000 44400 56600 44400 4 { T 55000 44400 5 8 0 1 0 8 1 netname=another name } N 55700 45100 55700 44400 4 { T 55700 45100 5 8 0 1 0 8 1 netname=another name } N 55700 44400 55700 43500 4""" stream = StringIO.StringIO(net_sample) self.geda_parser.parse_schematic(stream) design = self.geda_parser.design ## check nets from design self.assertEquals(len(design.nets), 3) self.assertEquals( sorted([net.net_id for net in design.nets]), sorted(['another name', 'test', '']) ) self.assertEquals( sorted([net.attributes['_name'] for net in design.nets]), sorted(['another name', 'test', '']) ) sorted_nets = {} for net in design.nets: sorted_nets[len(net.points)] = net.points self.assertEquals(sorted_nets.keys(), [2, 3, 5]) points_n1 = sorted_nets[2] points_n2 = sorted_nets[3] points_n3 = sorted_nets[5] self.assertEquals( sorted(points_n1.keys()), sorted([ '5320a4510', '5320a4350' ]) ) self.assertEquals( points_n1['5320a4510'].connected_points, ['5320a4350'] ) self.assertEquals( points_n1['5320a4350'].connected_points, ['5320a4510'] ) self.assertEquals( sorted(points_n2.keys()), sorted([ '5210a4440', '5430a4640', '5430a4440' ]) ) self.assertEquals( sorted(points_n2['5210a4440'].connected_points), ['5430a4440'] ) self.assertEquals( sorted(points_n2['5430a4640'].connected_points), ['5430a4440'] ) self.assertEquals( sorted(points_n2['5430a4440'].connected_points), ['5210a4440', '5430a4640'] ) self.assertEquals( sorted(points_n3.keys()), sorted([ '5500a4440', '5660a4440', '5570a4510', '5570a4440', '5570a4350' ]) ) self.assertEquals( sorted(points_n3['5500a4440'].connected_points), ['5570a4440'], ) self.assertEquals( sorted(points_n3['5660a4440'].connected_points), ['5570a4440'], ) self.assertEquals( sorted(points_n3['5570a4510'].connected_points), ['5570a4440'], ) self.assertEquals( sorted(points_n3['5570a4440'].connected_points), ['5500a4440', '5570a4350', '5570a4510', '5660a4440'], ) self.assertEquals( sorted(points_n3['5570a4350'].connected_points), ['5570a4440'], ) #run more complex test with nets sample file net_schematic = 'test/geda/nets.sch' design = self.geda_parser.parse(net_schematic) self.assertEquals(len(design.nets), 4) net_names = [net.net_id for net in design.nets] self.assertEquals( sorted(net_names), sorted(['advanced', 'long test', 'short_test', 'simple']), ) def test__parse_buses_from_stream(self): """ Tests parsing bus commands from stream, extracting busripper components and substituting the corresponding net segments. """ bus_data = """U 800 0 800 1000 10 -1 N 1000 800 1200 800 4 C 1000 800 1 180 0 busripper-1.sym { T 1000 400 5 8 0 0 180 0 1 device=none } N 600 400 300 400 4 C 600 400 1 270 0 busripper-1.sym { T 1000 400 5 8 0 0 270 0 1 device=none }""" stream = StringIO.StringIO(bus_data) self.geda_parser.parse_schematic(stream) design = self.geda_parser.design ## check nets from design self.assertEquals(len(design.nets), 1) point_ids = design.nets[0].points.keys() expected_points = [ '80a100', '80a0', '120a80', '100a80', '80a60', '30a40', '60a40', '80a20' ] self.assertEquals( sorted(point_ids), sorted(expected_points), ) def test_skip_embedded_section(self): """ Tests skipping an embedded section (enclosed in '[' & ']').""" data = """C 1000 800 1 180 0 busripper-1.sym\n""" stream = StringIO.StringIO(data) self.assertEquals(stream.tell(), 0) self.geda_parser.skip_embedded_section(stream) self.assertEquals(stream.tell(), 0) data += """[ T 1000 400 5 8 0 0 180 0 1 device=none ]\n""" stream = StringIO.StringIO(data) self.assertEquals(stream.tell(), 0) self.geda_parser._parse_command(stream) self.geda_parser.skip_embedded_section(stream) self.assertEquals(stream.tell(), len(data)) def test__parse_segment(self): """ Tests parsing a net segment command into NetPoints.""" simple_segment = "N 47300 48500 43500 48500 4" self.geda_parser.segments = set() self.geda_parser.net_points = dict() self.geda_parser.net_names = dict() stream = StringIO.StringIO(simple_segment) typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'N') self.geda_parser._parse_segment(stream, params) np_a, np_b = self.geda_parser.segments.pop() self.assertEquals(np_a.point_id, '4730a4850') self.assertEquals(np_a.x, 4730) self.assertEquals(np_a.y, 4850) self.assertEquals(np_b.point_id, '4350a4850') self.assertEquals(np_b.x, 4350) self.assertEquals(np_b.y, 4850) expected_points = [(4730, 4850), (4350, 4850)] for x, y in expected_points: point = self.geda_parser.net_points[(x, y)] self.assertEquals(point.point_id, '%da%d' % (x, y)) self.assertEquals(point.x, x) self.assertEquals(point.y, y) complex_segment = """N 47300 48500 43500 48500 4 { T 43800 48300 5 10 1 1 0 0 1 netname=+_1 }""" self.geda_parser.segments = set() self.geda_parser.net_points = dict() self.geda_parser.net_names = dict() stream = StringIO.StringIO(complex_segment) typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'N') self.geda_parser._parse_segment(stream, params) expected_points = [(4730, 4850), (4350, 4850)] for x, y in expected_points: point = self.geda_parser.net_points[(x, y)] self.assertEquals(point.point_id, '%da%d' % (x, y)) self.assertEquals(point.x, x) self.assertEquals(point.y, y) def test__parse_arc(self): """ Tests parsing an arc command into an Arc object. """ typ, params = self.geda_parser._parse_command( StringIO.StringIO("A 41100 48500 1900 0 90 3 0 0 0 -1 -1") ) self.assertEquals(typ, 'A') arc_obj = self.geda_parser._parse_arc(params) self.assertEquals(arc_obj.type, 'arc') self.assertEquals(arc_obj.x, 4110) self.assertEquals(arc_obj.y, 4850) self.assertEquals(arc_obj.radius, 190) self.assertEquals(arc_obj.start_angle, 0.0) self.assertEquals(arc_obj.end_angle, 1.5) ## mirrored arc arc_obj = self.geda_parser._parse_arc(params, mirrored=True) self.assertEquals(arc_obj.x, -4110) self.assertEquals(arc_obj.y, 4850) self.assertEquals(arc_obj.radius, 190) self.assertEquals(arc_obj.start_angle, 1.5) self.assertEquals(arc_obj.end_angle, 1.0) typ, params = self.geda_parser._parse_command( StringIO.StringIO("A 44300 49800 500 30 200 3 0 0 0 -1 -1") ) self.assertEquals(typ, 'A') arc_obj = self.geda_parser._parse_arc(params) self.assertEquals(arc_obj.type, 'arc') self.assertEquals(arc_obj.x, 4430) self.assertEquals(arc_obj.y, 4980) self.assertEquals(arc_obj.radius, 50) self.assertEquals(arc_obj.start_angle, 1.8) self.assertEquals(arc_obj.end_angle, 0.7) ## mirrored arc arc_obj = self.geda_parser._parse_arc(params, mirrored=True) self.assertEquals(arc_obj.type, 'arc') self.assertEquals(arc_obj.x, -4430) self.assertEquals(arc_obj.y, 4980) self.assertEquals(arc_obj.radius, 50) self.assertEquals(arc_obj.start_angle, 0.3) self.assertEquals(arc_obj.end_angle, 1.2) typ, params = self.geda_parser._parse_command( StringIO.StringIO("A 45100 48400 700 123 291 3 0 0 0 -1 -1") ) self.assertEquals(typ, 'A') arc_obj = self.geda_parser._parse_arc(params) self.assertEquals(arc_obj.type, 'arc') self.assertEquals(arc_obj.x, 4510) self.assertEquals(arc_obj.y, 4840) self.assertEquals(arc_obj.radius, 70) self.assertEquals(arc_obj.start_angle, 1.3) self.assertEquals(arc_obj.end_angle, 1.7) typ, params = self.geda_parser._parse_command( StringIO.StringIO("A 45100 48400 700 123 651 3 0 0 0 -1 -1") ) self.assertEquals(typ, 'A') arc_obj = self.geda_parser._parse_arc(params) self.assertEquals(arc_obj.type, 'arc') self.assertEquals(arc_obj.x, 4510) self.assertEquals(arc_obj.y, 4840) self.assertEquals(arc_obj.radius, 70) self.assertEquals(arc_obj.start_angle, 1.3) self.assertEquals(arc_obj.end_angle, 1.7) typ, params = self.geda_parser._parse_command( StringIO.StringIO("A 0 0 500 30 200 3 0 0 0 -1 -1") ) self.assertEquals(typ, 'A') arc_obj = self.geda_parser._parse_arc(params, mirrored=True) self.assertEquals(arc_obj.type, 'arc') self.assertEquals(arc_obj.x, 0) self.assertEquals(arc_obj.y, 0) self.assertEquals(arc_obj.radius, 50) ## mirrored to 310 (0.3) + 200 = 510 (1.2) self.assertEquals(arc_obj.start_angle, 0.3) self.assertEquals(arc_obj.end_angle, 1.2) def test__parse_line(self): """ Test parsing a line command into a Line object. """ test_strings = [ "L 40800 46600 45700 46600 3 0 0 0 -1 -1", "L 42300 45900 42900 45500 3 0 0 0 -1 -1", "L -400 500 440 560 3 0 0 0 -1 -1", ] for line_string in test_strings: typ, params = self.geda_parser._parse_command( StringIO.StringIO(line_string) ) self.assertEquals(typ, 'L') line_obj = self.geda_parser._parse_line(params) self.assertEquals(line_obj.type, 'line') self.assertEquals( line_obj.p1.x, params['x1']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( line_obj.p1.y, params['y1']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( line_obj.p2.x, params['x2']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( line_obj.p2.y, params['y2']/self.geda_parser.SCALE_FACTOR ) for line_string in test_strings: typ, params = self.geda_parser._parse_command( StringIO.StringIO(line_string) ) self.assertEquals(typ, 'L') line_obj = self.geda_parser._parse_line(params, mirrored=True) self.assertEquals(line_obj.type, 'line') self.assertEquals( line_obj.p1.x, 0-params['x1']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( line_obj.p1.y, params['y1']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( line_obj.p2.x, 0-params['x2']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( line_obj.p2.y, params['y2']/self.geda_parser.SCALE_FACTOR ) def test__parse_box(self): """ Tests parsing box commands into Rectangle objects. """ test_strings = [ "B 41700 42100 2900 1500 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1", "B 46100 41100 1200 2600 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1", ] for rect_string in test_strings: typ, params = self.geda_parser._parse_command( StringIO.StringIO(rect_string) ) self.assertEquals(typ, 'B') rect_obj = self.geda_parser._parse_box(params) self.assertEquals(rect_obj.type, 'rectangle') self.assertEquals( rect_obj.x, params['x']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( rect_obj.y, (params['y']+params['height'])/self.geda_parser.SCALE_FACTOR ) self.assertEquals( rect_obj.width, params['width']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( rect_obj.height, params['height']/self.geda_parser.SCALE_FACTOR ) mirror_test_strings = [ ( "B 100 300 300 500 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1", {'x': -40, 'y': 80, 'width': 30, 'height': 50}, ), ( "B -200 400 500 200 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1", {'x': -30, 'y': 60, 'width': 50, 'height': 20}, ) ] ## check mirrored rectangle for rect_string, result_dict in mirror_test_strings: typ, params = self.geda_parser._parse_command( StringIO.StringIO(rect_string) ) rect_obj = self.geda_parser._parse_box(params, mirrored=True) self.assertEquals(rect_obj.type, 'rectangle') self.assertEquals(rect_obj.x, result_dict['x']) self.assertEquals(rect_obj.y, result_dict['y']) self.assertEquals(rect_obj.width, result_dict['width']) self.assertEquals(rect_obj.height, result_dict['height']) def test__parse_path(self): """ Tests parsing path commands into lists of shapes. """ simple_example = """H 3 0 0 0 -1 -1 1 -1 -1 -1 -1 -1 5 M 510,240 L 601,200 L 555,295 L 535,265 z""" stream = StringIO.StringIO(simple_example) typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'H') shapes = self.geda_parser._parse_path(stream, params) expected_results = [ ['line', (51, 24), (60, 20)], ['line', (60, 20), (55, 29)], ['line', (55, 29), (53, 26)], ['line', (53, 26), (51, 24)], ] self.assertEquals(len(shapes), 4) for shape, expected in zip(shapes, expected_results): self.assertEquals(shape.type, expected[0]) start_x, start_y = expected[1] self.assertEquals(shape.p1.x, start_x) self.assertEquals(shape.p1.y, start_y) end_x, end_y = expected[2] self.assertEquals(shape.p2.x, end_x) self.assertEquals(shape.p2.y, end_y) ##NOTE: parse mirrored path stream = StringIO.StringIO(simple_example) typ, params = self.geda_parser._parse_command(stream) shapes = self.geda_parser._parse_path(stream, params, mirrored=True) expected_results = [ ['line', (-51, 24), (-60, 20)], ['line', (-60, 20), (-55, 29)], ['line', (-55, 29), (-53, 26)], ['line', (-53, 26), (-51, 24)], ] self.assertEquals(len(shapes), 4) for shape, expected in zip(shapes, expected_results): self.assertEquals(shape.type, expected[0]) start_x, start_y = expected[1] self.assertEquals(shape.p1.x, start_x) self.assertEquals(shape.p1.y, start_y) end_x, end_y = expected[2] self.assertEquals(shape.p2.x, end_x) self.assertEquals(shape.p2.y, end_y) curve_example = """H 3 0 0 0 -1 -1 0 2 20 100 -1 -1 6 M 100,100 L 500,100 C 700,100 800,275 800,400 C 800,500 700,700 500,700 L 100,700 z""" stream = StringIO.StringIO(curve_example) typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'H') shapes = self.geda_parser._parse_path(stream, params) self.assertEquals(len(shapes), 5) expected_shapes = ['line', 'bezier', 'bezier', 'line', 'line'] for shape, expected in zip(shapes, expected_shapes): self.assertEquals(shape.type, expected) def test__parse_circle(self): """ Tests parsing circle commands into Circle objects. """ test_strings = [ "V 49100 48800 900 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1", "V 51200 49000 400 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1", ] for circle_string in test_strings: typ, params = self.geda_parser._parse_command( StringIO.StringIO(circle_string) ) self.assertEquals(typ, 'V') circle_obj = self.geda_parser._parse_circle(params) self.assertEquals(circle_obj.type, 'circle') self.assertEquals( circle_obj.x, params['x']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( circle_obj.y, params['y']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( circle_obj.radius, params['radius']/self.geda_parser.SCALE_FACTOR ) ##mirrored circles for circle_string in test_strings: typ, params = self.geda_parser._parse_command( StringIO.StringIO(circle_string) ) self.assertEquals(typ, 'V') circle_obj = self.geda_parser._parse_circle(params, mirrored=True) self.assertEquals(circle_obj.type, 'circle') self.assertEquals( circle_obj.x, 0-params['x']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( circle_obj.y, params['y']/self.geda_parser.SCALE_FACTOR ) self.assertEquals( circle_obj.radius, params['radius']/self.geda_parser.SCALE_FACTOR ) def test__parse_pin(self): """ Tests parsing pin commands into Pin objects. """ stream = StringIO.StringIO('P 100 600 200 600 1 0 0\n') typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'P') self.assertRaises( GEDAError, self.geda_parser._parse_pin, stream, params ) pin_sample = """P 100 600 200 600 1 0 0 { T 150 650 5 8 1 1 0 6 1 pinnumber=3 T 150 650 5 8 0 1 0 6 1 pinseq=3 T 250 500 9 16 0 1 0 0 1 pinlabel=+ T 150 550 5 8 0 1 0 8 1 pintype=in }""" stream = StringIO.StringIO(pin_sample) typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'P') pin = self.geda_parser._parse_pin(stream, params) self.assertEquals(pin.pin_number, '3') self.assertEquals(pin.label.text, '+') ## null_end self.assertEquals(pin.p1.x, 20) self.assertEquals(pin.p1.y, 60) ## connect_end self.assertEquals(pin.p2.x, 10) self.assertEquals(pin.p2.y, 60) ##NOTE: test mirrored pin stream = StringIO.StringIO(pin_sample) typ, params = self.geda_parser._parse_command(stream) pin = self.geda_parser._parse_pin(stream, params, mirrored=True) ## null_end self.assertEquals(pin.p1.x, -20) self.assertEquals(pin.p1.y, 60) ## connect_end self.assertEquals(pin.p2.x, -10) self.assertEquals(pin.p2.y, 60) reversed_pin_sample = """P 100 600 200 600 1 0 1 { T 150 650 5 8 1 1 0 6 1 pinnumber=E T 150 650 5 8 0 1 0 6 1 pinseq=3 T 150 550 5 8 0 1 0 8 1 pintype=in }""" stream = StringIO.StringIO(reversed_pin_sample) typ, params = self.geda_parser._parse_command(stream) self.assertEquals(typ, 'P') pin = self.geda_parser._parse_pin(stream, params) self.assertEquals(pin.pin_number, 'E') self.assertEquals(pin.label, None) ## null_end self.assertEquals(pin.p1.x, 10) self.assertEquals(pin.p1.y, 60) ## connect_end self.assertEquals(pin.p2.x, 20) self.assertEquals(pin.p2.y, 60) ##NOTE: test mirrored pin stream = StringIO.StringIO(reversed_pin_sample) typ, params = self.geda_parser._parse_command(stream) pin = self.geda_parser._parse_pin(stream, params, mirrored=True) ## null_end self.assertEquals(pin.p1.x, -10) self.assertEquals(pin.p1.y, 60) ## connect_end self.assertEquals(pin.p2.x, -20) self.assertEquals(pin.p2.y, 60) def test__parse_command(self): """ Test parsing commands from a stream. """ typ, params = self.geda_parser._parse_command(StringIO.StringIO('{')) self.assertEquals(typ, '{') self.assertEquals(params, {}) typ, params = self.geda_parser._parse_command( StringIO.StringIO('A 49 34 223 30 90') ) self.assertEquals(typ, 'A') self.assertEquals(params, { 'x': 49, 'y': 34, 'radius': 223, 'startangle': 30, 'sweepangle': 90, }) self.assertEquals(len(params), 5) expected_params = { 'x': 18600, 'y': 21500, 'selectable': 1, 'angle': 0, 'mirror': 0, 'basename': 'EMBEDDED555-1', } string = 'C 18600 21500 1 0 0 EMBEDDED555-1' typ, params = self.geda_parser._parse_command( StringIO.StringIO(string) ) self.assertEquals(typ, 'C') self.assertEquals(params, expected_params) def test_parse(self): """ Tests parsing valid and invalid schematic files. """ self.geda_parser = GEDA([ './test/geda/simple_example/symbols', ]) invalid_sch = open('/tmp/invalid.sch', 'w') invalid_sch.write('C 18600 21500 1 0 0 EMBEDDED555-1') invalid_sch.close() self.assertRaises( GEDAError, self.geda_parser.parse, '/tmp/invalid.sch' ) ## testing EMBEDDED component design = self.geda_parser.parse('./test/geda/embedded_component.sch') components = design.components.components #test components dictionary self.assertEquals(components.keys(), ['EMBEDDEDbattery-1']) component = components['EMBEDDEDbattery-1'] self.assertEquals(component.name, 'EMBEDDEDbattery-1') keys = ['p1x', 'p1y', 'p2x', 'p2y', 'num', 'seq', 'label', 'type'] expected_pins = [ dict(zip(keys, [0, 200, 200, 200, '1', 1, '+', 'pwr'])), dict(zip(keys, [700, 200, 500, 200, '2', 2, '-', 'pwr'])), ] for pin, expected_pin in zip(component.symbols[0].bodies[0].pins, expected_pins): self.assertEquals(pin.label.text, expected_pin['label']) ## test reversed pin order due to different handling in direction self.assertEquals(pin.p1.x, expected_pin['p2x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p1.y, expected_pin['p2y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.x, expected_pin['p1x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.y, expected_pin['p1y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.pin_number, expected_pin['num']) ## testing referenced component design = self.geda_parser.parse('test/geda/component.sch') components = design.components.components #test components dictionary self.assertEquals(components.keys(), ['battery-1']) component = components['battery-1'] self.assertEquals(component.name, 'battery-1') keys = ['p1x', 'p1y', 'p2x', 'p2y', 'num', 'seq', 'label', 'type'] expected_pins = [ dict(zip(keys, [0, 200, 200, 200, '1', 1, '+', 'pwr'])), dict(zip(keys, [700, 200, 500, 200, '2', 2, '-', 'pwr'])), ] for pin, expected_pin in zip(component.symbols[0].bodies[0].pins, expected_pins): self.assertEquals(pin.label.text, expected_pin['label']) ## test reversed pin order due to different handling in direction self.assertEquals(pin.p1.x, expected_pin['p2x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p1.y, expected_pin['p2y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.x, expected_pin['p1x'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.p2.y, expected_pin['p1y'] / self.geda_parser.SCALE_FACTOR) self.assertEquals(pin.pin_number, expected_pin['num']) def test_parse_component_data(self): """ Tests parsing component data from symbol files and embedded sections. """ self.geda_parser = GEDA([ './test/geda/simple_example/symbols', ]) fpath = open('test/geda/path.sch') component = self.geda_parser.parse_component_data(fpath, { 'basename': 'test.sym', }) fpath.close() self.assertEquals(component.name, 'test') self.assertEquals(len(component.symbols), 1) self.assertEquals(len(component.symbols[0].bodies), 1) self.assertEquals(len(component.symbols[0].bodies[0].shapes), 9) def test_parse_full(self): """ Test parsing a complete schematic file generating OpenJSON. """ self.geda_parser = GEDA([ './test/geda/simple_example/symbols', ]) design = self.geda_parser.parse('test/geda/simple_example/simple_example.sch') self.assertEquals(len(design.nets), 2) net_names = [net.net_id for net in design.nets] self.assertEquals( sorted(net_names), sorted(['+_1', '-_In+']), )