test_tcl_shell.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import sys
  2. import unittest
  3. from PyQt5 import QtWidgets, QtGui
  4. from PyQt5.QtCore import QThread
  5. from FlatCAMApp import App
  6. from os import listdir
  7. from os.path import isfile
  8. from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMCNCjob, FlatCAMExcellon
  9. from flatcamGUI.ObjectUI import GerberObjectUI, GeometryObjectUI
  10. from time import sleep
  11. import os
  12. import tempfile
  13. class TclShellTest(unittest.TestCase):
  14. svg_files = 'tests/svg'
  15. svg_filename = 'Arduino Nano3_pcb.svg'
  16. gerber_files = 'tests/gerber_files'
  17. copper_bottom_filename = 'detector_copper_bottom.gbr'
  18. copper_top_filename = 'detector_copper_top.gbr'
  19. cutout_filename = 'detector_contour.gbr'
  20. excellon_filename = 'detector_drill.txt'
  21. gerber_name = "gerber"
  22. geometry_name = "geometry"
  23. excellon_name = "excellon"
  24. gerber_top_name = "top"
  25. gerber_bottom_name = "bottom"
  26. gerber_cutout_name = "cutout"
  27. engraver_diameter = 0.3
  28. cutout_diameter = 3
  29. drill_diameter = 0.8
  30. # load test methods to split huge test file into smaller pieces
  31. # reason for this is reuse one test window only,
  32. # CANNOT DO THIS HERE!!!
  33. # from tests.test_tclCommands import *
  34. @classmethod
  35. def setUpClass(cls):
  36. cls.setup = True
  37. cls.app = QtWidgets.QApplication(sys.argv)
  38. # Create App, keep app defaults (do not load
  39. # user-defined defaults).
  40. cls.fc = App(user_defaults=False)
  41. cls.fc.ui.shell_dock.show()
  42. def setUp(self):
  43. self.fc.exec_command_test('set_sys units MM')
  44. self.fc.exec_command_test('new')
  45. @classmethod
  46. def tearDownClass(cls):
  47. cls.fc.tcl = None
  48. cls.app.closeAllWindows()
  49. del cls.fc
  50. del cls.app
  51. pass
  52. def test_set_get_units(self):
  53. """
  54. Tests setting and getting units via the ``set_sys`` command,
  55. and persistance after ``new`` command.
  56. :return: None
  57. """
  58. # MM
  59. self.fc.exec_command_test('set_sys units MM')
  60. self.fc.exec_command_test('new')
  61. # IN
  62. self.fc.exec_command_test('set_sys units IN')
  63. self.fc.exec_command_test('new')
  64. # ----------------------------------------
  65. # Units must be IN
  66. # ----------------------------------------
  67. units = self.fc.exec_command_test('get_sys units')
  68. self.assertEqual(units, "IN")
  69. # MM
  70. self.fc.exec_command_test('set_sys units MM')
  71. self.fc.exec_command_test('new')
  72. # ----------------------------------------
  73. # Units must be MM
  74. # ----------------------------------------
  75. units = self.fc.exec_command_test('get_sys units')
  76. self.assertEqual(units, "MM")
  77. def test_gerber_flow(self):
  78. """
  79. Typical workflow from Gerber to GCode.
  80. :return: None
  81. """
  82. gbr_cmd = 'open_gerber {path}/{filename} -outname {outname}'
  83. # -----------------------------------------
  84. # Open top layer and check for object type
  85. # -----------------------------------------
  86. cmd = gbr_cmd.format(
  87. path=self.gerber_files,
  88. filename=self.copper_top_filename,
  89. outname=self.gerber_top_name)
  90. self.fc.exec_command_test(cmd)
  91. gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
  92. self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber),
  93. "Expected FlatCAMGerber, instead, %s is %s" %
  94. (self.gerber_top_name, type(gerber_top_obj)))
  95. # --------------------------------------------
  96. # Open bottom layer and check for object type
  97. # --------------------------------------------
  98. cmd = gbr_cmd.format(
  99. path=self.gerber_files,
  100. filename=self.copper_bottom_filename,
  101. outname=self.gerber_bottom_name)
  102. self.fc.exec_command_test(cmd)
  103. gerber_bottom_obj = self.fc.collection.get_by_name(self.gerber_bottom_name)
  104. self.assertTrue(isinstance(gerber_bottom_obj, FlatCAMGerber),
  105. "Expected FlatCAMGerber, instead, %s is %s" %
  106. (self.gerber_bottom_name, type(gerber_bottom_obj)))
  107. # --------------------------------------------
  108. # Open cutout layer and check for object type
  109. # --------------------------------------------
  110. cmd = gbr_cmd.format(
  111. path=self.gerber_files,
  112. filename=self.cutout_filename,
  113. outname=self.gerber_cutout_name
  114. )
  115. self.fc.exec_command_test(cmd)
  116. gerber_cutout_obj = self.fc.collection.get_by_name(self.gerber_cutout_name)
  117. self.assertTrue(isinstance(gerber_cutout_obj, FlatCAMGerber),
  118. "Expected FlatCAMGerber, instead, %s is %s" %
  119. (self.gerber_cutout_name, type(gerber_cutout_obj)))
  120. # exteriors delete and join geometries for top layer
  121. cmd = 'isolate {objname} -dia {dia}'.format(
  122. objname=self.gerber_cutout_name,
  123. dia=self.engraver_diameter)
  124. self.fc.exec_command_test(cmd)
  125. cmd = 'exteriors {objname} -outname {outname}'.format(
  126. objname=self.gerber_cutout_name + '_iso',
  127. outname=self.gerber_cutout_name + '_iso_exterior')
  128. self.fc.exec_command_test(cmd)
  129. cmd = 'delete {objname}'.format(
  130. objname=self.gerber_cutout_name + '_iso')
  131. self.fc.exec_command_test(cmd)
  132. # TODO: Check deleteb object is gone.
  133. # --------------------------------------------
  134. # Exteriors of cutout layer, check type
  135. # --------------------------------------------
  136. obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_iso_exterior')
  137. self.assertTrue(isinstance(obj, FlatCAMGeometry),
  138. "Expected FlatCAMGeometry, instead, %s is %s" %
  139. (self.gerber_cutout_name + '_iso_exterior', type(obj)))
  140. # mirror bottom gerbers
  141. self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_bottom_name, self.gerber_cutout_name))
  142. self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_cutout_name, self.gerber_cutout_name))
  143. # exteriors delete and join geometries for bottom layer
  144. self.fc.exec_command_test(
  145. 'isolate %s -dia %f -outname %s' %
  146. (self.gerber_cutout_name, self.engraver_diameter, self.gerber_cutout_name + '_bottom_iso')
  147. )
  148. self.fc.exec_command_test(
  149. 'exteriors %s -outname %s' %
  150. (self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior')
  151. )
  152. self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
  153. obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
  154. self.assertTrue(isinstance(obj, FlatCAMGeometry),
  155. "Expected FlatCAMGeometry, instead, %s is %s" %
  156. (self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
  157. # at this stage we should have 5 objects
  158. names = self.fc.collection.get_names()
  159. self.assertEqual(len(names), 5,
  160. "Expected 5 objects, found %d" % len(names))
  161. # isolate traces
  162. self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_top_name, self.engraver_diameter))
  163. self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_bottom_name, self.engraver_diameter))
  164. # join isolated geometries for top and bottom
  165. self.fc.exec_command_test(
  166. 'join_geometries %s %s %s' %
  167. (self.gerber_top_name + '_join_iso', self.gerber_top_name + '_iso',
  168. self.gerber_cutout_name + '_iso_exterior')
  169. )
  170. self.fc.exec_command_test(
  171. 'join_geometries %s %s %s' %
  172. (self.gerber_bottom_name + '_join_iso', self.gerber_bottom_name + '_iso',
  173. self.gerber_cutout_name + '_bottom_iso_exterior')
  174. )
  175. # at this stage we should have 9 objects
  176. names = self.fc.collection.get_names()
  177. self.assertEqual(len(names), 9,
  178. "Expected 9 objects, found %d" % len(names))
  179. # clean unused isolations
  180. self.fc.exec_command_test('delete %s' % (self.gerber_bottom_name + '_iso'))
  181. self.fc.exec_command_test('delete %s' % (self.gerber_top_name + '_iso'))
  182. self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso_exterior'))
  183. self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso_exterior'))
  184. # at this stage we should have 5 objects again
  185. names = self.fc.collection.get_names()
  186. self.assertEqual(len(names), 5,
  187. "Expected 5 objects, found %d" % len(names))
  188. # geocutout bottom test (it cuts to same object)
  189. self.fc.exec_command_test(
  190. 'isolate %s -dia %f -outname %s' %
  191. (self.gerber_cutout_name, self.cutout_diameter, self.gerber_cutout_name + '_bottom_iso')
  192. )
  193. self.fc.exec_command_test(
  194. 'exteriors %s -outname %s' %
  195. (self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior')
  196. )
  197. self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
  198. obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
  199. self.assertTrue(isinstance(obj, FlatCAMGeometry),
  200. "Expected FlatCAMGeometry, instead, %s is %s" %
  201. (self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
  202. self.fc.exec_command_test('geocutout %s -dia %f -gapsize 0.3 -gaps 4' %
  203. (self.gerber_cutout_name + '_bottom_iso_exterior', self.cutout_diameter))
  204. # at this stage we should have 6 objects
  205. names = self.fc.collection.get_names()
  206. self.assertEqual(len(names), 6,
  207. "Expected 6 objects, found %d" % len(names))
  208. # TODO: tests for tcl
  209. def test_open_gerber(self):
  210. self.fc.exec_command_test('open_gerber %s/%s -outname %s' %
  211. (self.gerber_files, self.copper_top_filename, self.gerber_top_name))
  212. gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
  213. self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber),
  214. "Expected FlatCAMGerber, instead, %s is %s" %
  215. (self.gerber_top_name, type(gerber_top_obj)))
  216. def test_excellon_flow(self):
  217. self.fc.exec_command_test('open_excellon %s/%s -outname %s' %
  218. (self.gerber_files, self.excellon_filename, self.excellon_name))
  219. excellon_obj = self.fc.collection.get_by_name(self.excellon_name)
  220. self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon),
  221. "Expected FlatCAMExcellon, instead, %s is %s" %
  222. (self.excellon_name, type(excellon_obj)))
  223. # mirror bottom excellon
  224. self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.excellon_name, self.gerber_cutout_name))
  225. # TODO: tests for tcl