implement basic set of tests for tcl_shell, need to be completed

This commit is contained in:
Kamil Sopko 2016-03-11 01:50:12 +01:00
parent e2eb5f293a
commit fd1c8afef9
6 changed files with 2666 additions and 190 deletions

View File

@ -675,8 +675,19 @@ class App(QtCore.QObject):
"""
Handles input from the shell. See FlatCAMApp.setup_shell for shell commands.
:param text:
:return: output if there was any
"""
return self.exec_command_test(self, text, False)
def exec_command_test(self, text, reraise=True):
"""
Handles input from the shell. See FlatCAMApp.setup_shell for shell commands.
:param text: Input command
:return: None
:param reraise: raise exception and not hide it, used mainly in unittests
:return: output if there was any
"""
self.report_usage('exec_command')
@ -691,8 +702,10 @@ class App(QtCore.QObject):
result = self.tcl.eval("set errorInfo")
self.log.error("Exec command Exception: %s" % (result + '\n'))
self.shell.append_error('ERROR: ' + result + '\n')
#show error in console and just return
return
#show error in console and just return or in test raise exception
if reraise:
raise e
return result
"""
Code below is unsused. Saved for later.
@ -2167,85 +2180,96 @@ class App(QtCore.QObject):
return 'Ok'
def geocutout(name, *args):
"""
def geocutout(name=None, *args):
'''
TCL shell command - see help section
Subtract gaps from geometry, this will not create new object
:param name:
:param args:
:return:
"""
a, kwa = h(*args)
types = {'dia': float,
'gapsize': float,
'gaps': str}
# How gaps wil be rendered:
# lr - left + right
# tb - top + bottom
# 4 - left + right +top + bottom
# 2lr - 2*left + 2*right
# 2tb - 2*top + 2*bottom
# 8 - 2*left + 2*right +2*top + 2*bottom
for key in kwa:
if key not in types:
return 'Unknown parameter: %s' % key
kwa[key] = types[key](kwa[key])
:param name: name of object
:param args: array of arguments
:return: "Ok" if completed without errors
'''
try:
obj = self.collection.get_by_name(str(name))
except:
return "Could not retrieve object: %s" % name
a, kwa = h(*args)
types = {'dia': float,
'gapsize': float,
'gaps': str}
# Get min and max data for each object as we just cut rectangles across X or Y
xmin, ymin, xmax, ymax = obj.bounds()
px = 0.5 * (xmin + xmax)
py = 0.5 * (ymin + ymax)
lenghtx = (xmax - xmin)
lenghty = (ymax - ymin)
gapsize = kwa['gapsize'] + kwa['dia'] / 2
if kwa['gaps'] == '8' or kwa['gaps']=='2lr':
subtract_rectangle(name,
xmin - gapsize,
py - gapsize + lenghty / 4,
xmax + gapsize,
py + gapsize + lenghty / 4)
subtract_rectangle(name,
xmin-gapsize,
py - gapsize - lenghty / 4,
xmax + gapsize,
py + gapsize - lenghty / 4)
if kwa['gaps'] == '8' or kwa['gaps']=='2tb':
subtract_rectangle(name,
px - gapsize + lenghtx / 4,
ymin-gapsize,
px + gapsize + lenghtx / 4,
ymax + gapsize)
subtract_rectangle(name,
px - gapsize - lenghtx / 4,
ymin - gapsize,
px + gapsize - lenghtx / 4,
ymax + gapsize)
if kwa['gaps'] == '4' or kwa['gaps']=='lr':
subtract_rectangle(name,
xmin - gapsize,
py - gapsize,
xmax + gapsize,
py + gapsize)
if kwa['gaps'] == '4' or kwa['gaps']=='tb':
subtract_rectangle(name,
px - gapsize,
ymin - gapsize,
px + gapsize,
ymax + gapsize)
return 'Ok'
# How gaps wil be rendered:
# lr - left + right
# tb - top + bottom
# 4 - left + right +top + bottom
# 2lr - 2*left + 2*right
# 2tb - 2*top + 2*bottom
# 8 - 2*left + 2*right +2*top + 2*bottom
if name is None:
self.raiseTclError('Argument name is missing.')
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, str(types[key])))
try:
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
# Get min and max data for each object as we just cut rectangles across X or Y
xmin, ymin, xmax, ymax = obj.bounds()
px = 0.5 * (xmin + xmax)
py = 0.5 * (ymin + ymax)
lenghtx = (xmax - xmin)
lenghty = (ymax - ymin)
gapsize = kwa['gapsize'] + kwa['dia'] / 2
if kwa['gaps'] == '8' or kwa['gaps']=='2lr':
subtract_rectangle(name,
xmin - gapsize,
py - gapsize + lenghty / 4,
xmax + gapsize,
py + gapsize + lenghty / 4)
subtract_rectangle(name,
xmin-gapsize,
py - gapsize - lenghty / 4,
xmax + gapsize,
py + gapsize - lenghty / 4)
if kwa['gaps'] == '8' or kwa['gaps']=='2tb':
subtract_rectangle(name,
px - gapsize + lenghtx / 4,
ymin-gapsize,
px + gapsize + lenghtx / 4,
ymax + gapsize)
subtract_rectangle(name,
px - gapsize - lenghtx / 4,
ymin - gapsize,
px + gapsize - lenghtx / 4,
ymax + gapsize)
if kwa['gaps'] == '4' or kwa['gaps']=='lr':
subtract_rectangle(name,
xmin - gapsize,
py - gapsize,
xmax + gapsize,
py + gapsize)
if kwa['gaps'] == '4' or kwa['gaps']=='tb':
subtract_rectangle(name,
px - gapsize,
ymin - gapsize,
px + gapsize,
ymax + gapsize)
except Exception as unknown:
self.raiseTclUnknownError(unknown)
def mirror(name, *args):
a, kwa = h(*args)
@ -2519,59 +2543,63 @@ class App(QtCore.QObject):
:param args: array of arguments
:return: "Ok" if completed without errors
'''
a, kwa = h(*args)
types = {'tools': str,
'outname': str,
'drillz': float,
'travelz': float,
'feedrate': float,
'spindlespeed': int,
'toolchange': int
}
if name is None:
self.raiseTclError('Argument name is missing.')
try:
a, kwa = h(*args)
types = {'tools': str,
'outname': str,
'drillz': float,
'travelz': float,
'feedrate': float,
'spindlespeed': int,
'toolchange': int
}
if name is None:
self.raiseTclError('Argument name is missing.')
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, str(types[key])))
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
if obj is None:
self.raiseTclError('Object not found: %s' % name)
if not isinstance(obj, FlatCAMExcellon):
self.raiseTclError('Only Excellon objects can be drilled, got %s %s.' % (name, type(obj)))
try:
# Get the tools from the list
job_name = kwa["outname"]
# Object initialization function for app.new_object()
def job_init(job_obj, app_obj):
job_obj.z_cut = kwa["drillz"]
job_obj.z_move = kwa["travelz"]
job_obj.feedrate = kwa["feedrate"]
job_obj.spindlespeed = kwa["spindlespeed"] if "spindlespeed" in kwa else None
toolchange = True if "toolchange" in kwa and kwa["toolchange"] == 1 else False
job_obj.generate_from_excellon_by_tool(obj, kwa["tools"], toolchange)
job_obj.gcode_parse()
job_obj.create_geometry()
obj.app.new_object("cncjob", job_name, job_init)
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, str(types[key])))
self.raiseTclError("Operation failed: %s" % str(e))
try:
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
except Exception as unknown:
self.raiseTclUnknownError(unknown)
if obj is None:
self.raiseTclError('Object not found: %s' % name)
if not isinstance(obj, FlatCAMExcellon):
self.raiseTclError('Only Excellon objects can be drilled, got %s %s.' % (name, type(obj)))
try:
# Get the tools from the list
job_name = kwa["outname"]
# Object initialization function for app.new_object()
def job_init(job_obj, app_obj):
job_obj.z_cut = kwa["drillz"]
job_obj.z_move = kwa["travelz"]
job_obj.feedrate = kwa["feedrate"]
job_obj.spindlespeed = kwa["spindlespeed"] if "spindlespeed" in kwa else None
toolchange = True if "toolchange" in kwa and kwa["toolchange"] == 1 else False
job_obj.generate_from_excellon_by_tool(obj, kwa["tools"], toolchange)
job_obj.gcode_parse()
job_obj.create_geometry()
obj.app.new_object("cncjob", job_name, job_init)
except Exception, e:
self.raiseTclError("Operation failed: %s" % str(e))
return 'Ok'
def millholes(name=None, *args):
'''
@ -2580,48 +2608,51 @@ class App(QtCore.QObject):
:param args: array of arguments
:return: "Ok" if completed without errors
'''
a, kwa = h(*args)
types = {'tooldia': float,
'tools': str,
'outname': str}
if name is None:
self.raiseTclError('Argument name is missing.')
try:
a, kwa = h(*args)
types = {'tooldia': float,
'tools': str,
'outname': str}
if name is None:
self.raiseTclError('Argument name is missing.')
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
if 'tools' in kwa:
kwa['tools'] = [x.strip() for x in kwa['tools'].split(",")]
except Exception as e:
self.raiseTclError("Bad tools: %s" % str(e))
try:
if 'tools' in kwa:
kwa['tools'] = [x.strip() for x in kwa['tools'].split(",")]
except Exception as e:
self.raiseTclError("Bad tools: %s" % str(e))
try:
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
try:
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
if obj is None:
self.raiseTclError("Object not found: %s" % name)
if obj is None:
self.raiseTclError("Object not found: %s" % name)
if not isinstance(obj, FlatCAMExcellon):
self.raiseTclError('Only Excellon objects can be mill drilled, got %s %s.' % (name, type(obj)))
if not isinstance(obj, FlatCAMExcellon):
self.raiseTclError('Only Excellon objects can be mill drilled, got %s %s.' % (name, type(obj)))
try:
success, msg = obj.generate_milling(**kwa)
except Exception as e:
self.raiseTclError("Operation failed: %s" % str(e))
try:
success, msg = obj.generate_milling(**kwa)
except Exception as e:
self.raiseTclError("Operation failed: %s" % str(e))
if not success:
self.raiseTclError(msg)
if not success:
self.raiseTclError(msg)
return 'Ok'
except Exception as unknown:
self.raiseTclUnknownError(unknown)
def exteriors(name=None, *args):
'''
@ -2630,46 +2661,49 @@ class App(QtCore.QObject):
:param args: array of arguments
:return: "Ok" if completed without errors
'''
a, kwa = h(*args)
types = {'outname': str}
if name is None:
self.raiseTclError('Argument name is missing.')
try:
a, kwa = h(*args)
types = {'outname': str}
if name is None:
self.raiseTclError('Argument name is missing.')
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
for key in kwa:
if key not in types:
self.raiseTclError('Unknown parameter: %s' % key)
try:
kwa[key] = types[key](kwa[key])
except Exception, e:
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
try:
obj = self.collection.get_by_name(str(name))
except:
self.raiseTclError("Could not retrieve object: %s" % name)
if obj is None:
self.raiseTclError("Object not found: %s" % name)
if obj is None:
self.raiseTclError("Object not found: %s" % name)
if not isinstance(obj, Geometry):
self.raiseTclError('Expected Geometry, got %s %s.' % (name, type(obj)))
if not isinstance(obj, Geometry):
self.raiseTclError('Expected Geometry, got %s %s.' % (name, type(obj)))
def geo_init(geo_obj, app_obj):
geo_obj.solid_geometry = obj_exteriors
def geo_init(geo_obj, app_obj):
geo_obj.solid_geometry = obj_exteriors
if 'outname' in kwa:
outname = kwa['outname']
else:
outname = name + ".exteriors"
if 'outname' in kwa:
outname = kwa['outname']
else:
outname = name + ".exteriors"
try:
obj_exteriors = obj.get_exteriors()
self.new_object('geometry', outname, geo_init)
except Exception as e:
self.raiseTclError("Failed: %s" % str(e))
try:
obj_exteriors = obj.get_exteriors()
self.new_object('geometry', outname, geo_init)
except Exception as e:
self.raiseTclError("Failed: %s" % str(e))
return 'Ok'
except Exception as unknown:
self.raiseTclUnknownError(unknown)
def interiors(name=None, *args):
'''
@ -2722,8 +2756,6 @@ class App(QtCore.QObject):
except Exception as unknown:
self.raiseTclUnknownError(unknown)
return 'Ok'
def isolate(name=None, *args):
'''
TCL shell command - see help section

View File

@ -0,0 +1,26 @@
G04 MADE WITH FRITZING*
G04 WWW.FRITZING.ORG*
G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%ASAXBY*%
%FSLAX23Y23*%
%MOIN*%
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10R,1.771650X1.181100*%
%ADD11C,0.008000*%
%ADD10C,0.008*%
%LNCONTOUR*%
G90*
G70*
G54D10*
G54D11*
X4Y1177D02*
X1768Y1177D01*
X1768Y4D01*
X4Y4D01*
X4Y1177D01*
D02*
G04 End of contour*
M02*

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
G04 MADE WITH FRITZING*
G04 WWW.FRITZING.ORG*
G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%ASAXBY*%
%FSLAX23Y23*%
%MOIN*%
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10C,0.075000*%
%ADD11C,0.099055*%
%ADD12C,0.078740*%
%ADD13R,0.075000X0.075000*%
%ADD14C,0.024000*%
%ADD15C,0.020000*%
%LNCOPPER1*%
G90*
G70*
G54D10*
X1149Y872D03*
X1349Y872D03*
X749Y722D03*
X749Y522D03*
X1149Y522D03*
X1449Y522D03*
X1149Y422D03*
X1449Y422D03*
X1149Y322D03*
X1449Y322D03*
X1149Y222D03*
X1449Y222D03*
X949Y472D03*
X949Y72D03*
G54D11*
X749Y972D03*
X599Y972D03*
X349Y322D03*
X349Y472D03*
X349Y672D03*
X349Y822D03*
G54D10*
X699Y122D03*
X699Y322D03*
G54D12*
X699Y222D03*
X949Y972D03*
X749Y622D03*
X1049Y222D03*
X1249Y872D03*
G54D13*
X1149Y872D03*
X1149Y522D03*
G54D14*
X952Y946D02*
X1045Y249D01*
G54D15*
X776Y695D02*
X721Y695D01*
X721Y750D01*
X776Y750D01*
X776Y695D01*
D02*
X671Y150D02*
X726Y150D01*
X726Y95D01*
X671Y95D01*
X671Y150D01*
D02*
G04 End of Copper1*
M02*

View File

@ -0,0 +1,46 @@
; NON-PLATED HOLES START AT T1
; THROUGH (PLATED) HOLES START AT T100
M48
INCH
T1C0.125984
T100C0.031496
T101C0.035000
T102C0.059055
%
T1
X001488Y010223
X001488Y001223
X016488Y001223
X016488Y010223
T100
X009488Y009723
X007488Y006223
X012488Y008723
X010488Y002223
X006988Y002223
T101
X014488Y004223
X006988Y003223
X013488Y008723
X011488Y008723
X007488Y005223
X014488Y003223
X014488Y002223
X011488Y005223
X009488Y000723
X011488Y004223
X006988Y001223
X009488Y004723
X007488Y007223
X011488Y003223
X014488Y005223
X011488Y002223
T102
X003488Y008223
X003488Y004723
X007488Y009723
X003488Y006723
X005988Y009723
X003488Y003223
T00
M30

155
tests/test_tcl_shell.py Normal file
View File

@ -0,0 +1,155 @@
import sys
import unittest
from PyQt4 import QtGui
from FlatCAMApp import App
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMCNCjob, FlatCAMExcellon
from ObjectUI import GerberObjectUI, GeometryObjectUI
from time import sleep
import os
import tempfile
class TclShellCommandTest(unittest.TestCase):
gerber_files = 'tests/gerber_files'
copper_bottom_filename = 'detector_copper_bottom.gbr'
copper_top_filename = 'detector_copper_top.gbr'
cutout_filename = 'detector_contour.gbr'
excellon_filename = 'detector_drill.txt'
excellon_name = "excellon"
gerber_top_name = "top"
gerber_bottom_name = "bottom"
gerber_cutout_name = "cutout"
engraver_diameter = 0.3
cutout_diameter = 3
drill_diameter = 0.8
def setUp(self):
self.app = QtGui.QApplication(sys.argv)
# Create App, keep app defaults (do not load
# user-defined defaults).
self.fc = App(user_defaults=False)
def tearDown(self):
del self.fc
del self.app
def test_set_get_units(self):
self.fc.exec_command_test('set_sys units IN')
self.fc.exec_command_test('new')
units=self.fc.exec_command_test('get_sys units')
self.assertEquals(units, "IN")
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
units=self.fc.exec_command_test('get_sys units')
self.assertEquals(units, "MM")
def test_gerber_flow(self):
# open gerber files top, bottom and cutout
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
self.fc.exec_command_test('open_gerber %s/%s -outname %s' % (self.gerber_files, self.copper_top_filename, self.gerber_top_name))
gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_top_name, type(gerber_top_obj)))
self.fc.exec_command_test('open_gerber %s/%s -outname %s' % (self.gerber_files, self.copper_bottom_filename, self.gerber_bottom_name))
gerber_bottom_obj = self.fc.collection.get_by_name(self.gerber_bottom_name)
self.assertTrue(isinstance(gerber_bottom_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_bottom_name, type(gerber_bottom_obj)))
self.fc.exec_command_test('open_gerber %s/%s -outname %s' % (self.gerber_files, self.cutout_filename, self.gerber_cutout_name))
gerber_cutout_obj = self.fc.collection.get_by_name(self.gerber_cutout_name)
self.assertTrue(isinstance(gerber_cutout_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_cutout_name, type(gerber_cutout_obj)))
# exteriors delete and join geometries for top layer
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_cutout_name, self.engraver_diameter))
self.fc.exec_command_test('exteriors %s -outname %s' % (self.gerber_cutout_name + '_iso', self.gerber_cutout_name + '_iso_exterior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(self.gerber_cutout_name + '_iso_exterior', type(obj)))
# mirror bottom gerbers
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_bottom_name, self.gerber_cutout_name))
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_cutout_name, self.gerber_cutout_name))
# exteriors delete and join geometries for bottom layer
self.fc.exec_command_test('isolate %s -dia %f -outname %s' % (self.gerber_cutout_name, self.engraver_diameter, self.gerber_cutout_name + '_bottom_iso'))
self.fc.exec_command_test('exteriors %s -outname %s' % (self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
# at this stage we should have 5 objects
names = self.fc.collection.get_names()
self.assertEqual(len(names), 5,
"Expected 5 objects, found %d" % len(names))
# isolate traces
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_top_name, self.engraver_diameter))
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_bottom_name, self.engraver_diameter))
# join isolated geometries for top and bottom
self.fc.exec_command_test('join_geometries %s %s %s' % (self.gerber_top_name + '_join_iso', self.gerber_top_name + '_iso', self.gerber_cutout_name + '_iso_exterior'))
self.fc.exec_command_test('join_geometries %s %s %s' % (self.gerber_bottom_name + '_join_iso', self.gerber_bottom_name + '_iso', self.gerber_cutout_name + '_bottom_iso_exterior'))
# at this stage we should have 9 objects
names = self.fc.collection.get_names()
self.assertEqual(len(names), 9,
"Expected 9 objects, found %d" % len(names))
# clean unused isolations
self.fc.exec_command_test('delete %s' % (self.gerber_bottom_name + '_iso'))
self.fc.exec_command_test('delete %s' % (self.gerber_top_name + '_iso'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso_exterior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso_exterior'))
# at this stage we should have 5 objects again
names = self.fc.collection.get_names()
self.assertEqual(len(names), 5,
"Expected 5 objects, found %d" % len(names))
# geocutout bottom test (it cuts to same object)
self.fc.exec_command_test('isolate %s -dia %f -outname %s' % (self.gerber_cutout_name, self.cutout_diameter, self.gerber_cutout_name + '_bottom_iso'))
self.fc.exec_command_test('exteriors %s -outname %s' % (self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
self.fc.exec_command_test('geocutout %s -dia %f -gapsize 0.3 -gaps 4' % (self.gerber_cutout_name + '_bottom_iso_exterior', self.cutout_diameter))
# at this stage we should have 6 objects
names = self.fc.collection.get_names()
self.assertEqual(len(names), 6,
"Expected 6 objects, found %d" % len(names))
# TODO: tests for tcl
def test_excellon_flow(self):
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('open_excellon %s/%s -outname %s' % (self.gerber_files, self.excellon_filename, self.excellon_name))
excellon_obj = self.fc.collection.get_by_name(self.excellon_name)
self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon),
"Expected FlatCAMExcellon, instead, %s is %s" %
(self.excellon_name, type(excellon_obj)))
# mirror bottom excellon
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.excellon_name, self.gerber_cutout_name))
# TODO: tests for tcl